Merge pull request #42 from aztech-digital/pecl-uuid

Add PECL based UUID factory for UUID1/4
This commit is contained in:
Ben Ramsey
2015-01-06 14:17:20 -06:00
6 changed files with 257 additions and 4 deletions
+5
View File
@@ -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
+107
View File
@@ -0,0 +1,107 @@
<?php
namespace Rhumsaa\Uuid;
/**
* Factory relying on PECL UUID library whenever possible, otherwise defaulting
* to pure PHP factory.
* @author thibaud
*
*/
class PeclUuidFactory implements UuidFactoryInterface
{
/**
*
* @var UuidFactoryInterface
*/
private $factory;
/**
*
* @var boolean
*/
private $hasExt = false;
/**
*
* @param UuidFactoryInterface $factory
*/
public function __construct(UuidFactoryInterface $factory)
{
$this->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);
}
}
+3 -3
View File
@@ -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;
}
+1 -1
View File
@@ -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
{
/**
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace Rhumsaa\Uuid;
interface UuidFactoryInterface
{
public function uuid1($node = null, $clockSeq = null);
public function uuid3($ns, $name);
public function uuid4();
public function uuid5($ns, $name);
public function fromBytes($bytes);
public function fromString($name);
public function fromInteger($integer);
}
+120
View File
@@ -0,0 +1,120 @@
<?php
namespace Rhumsaa\Uuid;
class PeclUuidTest extends \PHPUnit_Framework_TestCase
{
private $mockFactory;
protected function setUp()
{
$this->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__));
}
}