diff --git a/.travis.yml b/.travis.yml index 7dba238..b54bbf0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,9 +6,14 @@ php: - 5.6 - hhvm +before_install: + - sudo apt-get update && sudo apt-get install uuid-dev + before_script: - composer self-update - composer install --dev --prefer-source + - sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then printf "\n" | pecl install uuid; fi;' + - phpenv rehash script: - ./vendor/bin/phpunit --coverage-text --coverage-clover ./build/logs/clover.xml diff --git a/src/PeclUuidFactory.php b/src/PeclUuidFactory.php new file mode 100644 index 0000000..5436ece --- /dev/null +++ b/src/PeclUuidFactory.php @@ -0,0 +1,107 @@ +hasExt = extension_loaded('uuid'); + $this->factory = $factory; + } + + /** + * Forces factory to act as if PECL extension is not available + */ + public function disablePecl() + { + $this->hasExt = false; + } + + /** + * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::uuid1() + */ + public function uuid1($node = null, $clockSeq = null) + { + if (! $this->hasExt || $node !== null || $clockSeq !== null) { + // If either param is not null, we cannot use PECL without breaking LSP. + return $this->factory->uuid1($node, $clockSeq); + } + + return $this->fromString(uuid_create(UUID_TYPE_TIME)); + } + + /** + * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::uuid3() + */ + public function uuid3($ns, $name) + { + return $this->factory->uuid3($ns, $name); + } + + /** + * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::uuid4() + */ + public function uuid4() + { + if (! $this->hasExt) { + return $this->factory->uuid4(); + } + + return $this->fromString(uuid_create(UUID_TYPE_RANDOM)); + } + + /** + * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::uuid5() + */ + public function uuid5($ns, $name) + { + return $this->factory->uuid5($ns, $name); + } + + /** + * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::fromBytes() + */ + public function fromBytes($bytes) + { + return $this->factory->fromBytes($bytes); + } + + /** + * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::fromString() + */ + public function fromString($name) + { + return $this->factory->fromString($name); + } + + /** + * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::fromInteger() + */ + public function fromInteger($integer) + { + return $this->factory->fromInteger($integer); + } +} \ No newline at end of file diff --git a/src/Uuid.php b/src/Uuid.php index 0da5200..30589ff 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -99,7 +99,7 @@ class Uuid implements UuidInterface, \JsonSerializable /** * - * @var UuidFactory + * @var UuidFactoryInterface */ private static $factory = null; @@ -719,13 +719,13 @@ class Uuid implements UuidInterface, \JsonSerializable public static function getFactory() { if (! self::$factory) { - self::$factory = new UuidFactory(); + self::$factory = new PeclUuidFactory(new UuidFactory()); } return self::$factory; } - public static function setFactory(UuidFactory $factory) + public static function setFactory(UuidFactoryInterface $factory) { self::$factory = $factory; } diff --git a/src/UuidFactory.php b/src/UuidFactory.php index 5919968..9885742 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -8,7 +8,7 @@ use Rhumsaa\Uuid\Converter\TimeConverterInterface; use Rhumsaa\Uuid\Provider\NodeProviderInterface; use Rhumsaa\Uuid\Provider\TimeProviderInterface; -class UuidFactory +class UuidFactory implements UuidFactoryInterface { /** diff --git a/src/UuidFactoryInterface.php b/src/UuidFactoryInterface.php new file mode 100644 index 0000000..99a743e --- /dev/null +++ b/src/UuidFactoryInterface.php @@ -0,0 +1,21 @@ +mockFactory = $this->getMock('Rhumsaa\Uuid\UuidFactoryInterface'); + + Uuid::setFactory(new PeclUuidFactory($this->mockFactory)); + } + + public function getUuid1Params() + { + return [ + [ true, null ], + [ null, true ], + [ true, true ] + ]; + } + + /** + * @dataProvider getUuid1Params + */ + public function testUuid1WithParametersIsDelegated($node, $clockSeq) + { + $this->mockFactory->expects($this->once()) + ->method('uuid1') + ->with($node, $clockSeq); + + Uuid::uuid1($node, $clockSeq); + } + + public function testUuid1WithoutParametersIsNotDelegated() + { + if (defined('HHVM_VERSION')) { + $this->markTestSkipped('PECL Uuid extension not available in HHVM'); + } + + $this->mockFactory->expects($this->never()) + ->method('uuid1'); + + Uuid::uuid1(); + } + + public function testUuid1WithoutExtensionIsDelegated() + { + $factory = new PeclUuidFactory($this->mockFactory); + $factory->disablePecl(); + + Uuid::setFactory($factory); + + $this->mockFactory->expects($this->once()) + ->method('uuid1'); + + Uuid::uuid1(); + } + + public function testUuid1Version() + { + Uuid::setFactory(new PeclUuidFactory(new UuidFactory())); + + $uuid = Uuid::uuid1(); + + $this->assertEquals(1, $uuid->getVersion()); + } + + public function testUuid3IsDelegated() + { + $this->mockFactory->expects($this->once()) + ->method('uuid3'); + + Uuid::uuid3(Uuid::NAMESPACE_DNS, str_replace('\\', '.', __NAMESPACE__)); + } + + public function testUuid4WithoutExtensionIsDelegated() + { + $factory = new PeclUuidFactory($this->mockFactory); + $factory->disablePecl(); + + Uuid::setFactory($factory); + + $this->mockFactory->expects($this->once()) + ->method('uuid4'); + + Uuid::uuid4(); + } + + public function testUuid4WithParametersIsNeverDelegated() + { + if (defined('HHVM_VERSION')) { + $this->markTestSkipped('PECL Uuid extension not available in HHVM'); + } + + $this->mockFactory->expects($this->never()) + ->method('uuid4'); + + Uuid::uuid4(); + } + + public function testUuid4Version() + { + Uuid::setFactory(new PeclUuidFactory(new UuidFactory())); + + $uuid = Uuid::uuid4(); + + $this->assertEquals(4, $uuid->getVersion()); + } + + public function testUuid5IsDelegated() + { + $this->mockFactory->expects($this->once()) + ->method('uuid5'); + + Uuid::uuid5(Uuid::NAMESPACE_DNS, str_replace('\\', '.', __NAMESPACE__)); + } +} \ No newline at end of file