From 84123b206031ec81cd51317502bb991d3533ba02 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sat, 8 Nov 2014 12:41:40 +0100 Subject: [PATCH] Remove all env related logic from factory Defers all environment related decisions to factory initialization All behavior is customizable through DI, but all deps are initialized to proper default instances Removes static factory configuration --- src/Builder/DefaultUuidBuilder.php | 24 +++ src/Builder/DegradedUuidBuilder.php | 24 +++ src/Codec.php | 4 +- src/Codec/GuidStringCodec.php | 26 +-- src/Codec/StringCodec.php | 15 +- src/FeatureSet.php | 171 ++++++++++++++++++ src/Generator/RandomLibAdapter.php | 27 +++ src/Node/FallbackNodeProvider.php | 26 +++ src/Node/RandomNodeProvider.php | 15 ++ src/Node/SystemNodeProvider.php | 50 ++++++ src/NodeProvider.php | 8 + src/Time/BigNumberTimeConverter.php | 31 ++++ src/Time/DegradedTimeConverter.php | 18 ++ src/Time/FixedTimeProvider.php | 34 ++++ src/Time/PhpTimeConverter.php | 21 +++ src/Time/SystemTimeProvider.php | 13 ++ src/TimeConverter.php | 16 ++ src/TimeProvider.php | 11 ++ src/Uuid.php | 10 -- src/UuidBuilder.php | 8 + src/UuidFactory.php | 260 ++++++++-------------------- tests/UuidBcTag1_1_2Test.php | 4 +- tests/UuidFactoryTest.php | 4 +- tests/UuidTest.php | 143 ++++++++------- 24 files changed, 672 insertions(+), 291 deletions(-) create mode 100644 src/Builder/DefaultUuidBuilder.php create mode 100644 src/Builder/DegradedUuidBuilder.php create mode 100644 src/FeatureSet.php create mode 100644 src/Generator/RandomLibAdapter.php create mode 100644 src/Node/FallbackNodeProvider.php create mode 100644 src/Node/RandomNodeProvider.php create mode 100644 src/Node/SystemNodeProvider.php create mode 100644 src/NodeProvider.php create mode 100644 src/Time/BigNumberTimeConverter.php create mode 100644 src/Time/DegradedTimeConverter.php create mode 100644 src/Time/FixedTimeProvider.php create mode 100644 src/Time/PhpTimeConverter.php create mode 100644 src/Time/SystemTimeProvider.php create mode 100644 src/TimeConverter.php create mode 100644 src/TimeProvider.php create mode 100644 src/UuidBuilder.php diff --git a/src/Builder/DefaultUuidBuilder.php b/src/Builder/DefaultUuidBuilder.php new file mode 100644 index 0000000..449e68b --- /dev/null +++ b/src/Builder/DefaultUuidBuilder.php @@ -0,0 +1,24 @@ +converter = $converter; + } + + public function build(Codec $codec, array $fields) + { + return new Uuid($fields, $this->converter, $codec); + } +} diff --git a/src/Builder/DegradedUuidBuilder.php b/src/Builder/DegradedUuidBuilder.php new file mode 100644 index 0000000..8de0218 --- /dev/null +++ b/src/Builder/DegradedUuidBuilder.php @@ -0,0 +1,24 @@ +converter = $converter; + } + + public function build(Codec $codec, array $fields) + { + return new DegradedUuid($fields, $this->converter, $codec); + } +} diff --git a/src/Codec.php b/src/Codec.php index b88db75..9912851 100644 --- a/src/Codec.php +++ b/src/Codec.php @@ -8,7 +8,7 @@ interface Codec public function encodeBinary(UuidInterface $uuid); - public function decode(BigNumberConverter $converter, $encodedUuid); + public function decode($encodedUuid); - public function decodeBytes(BigNumberConverter $converter, $bytes); + public function decodeBytes($bytes); } diff --git a/src/Codec/GuidStringCodec.php b/src/Codec/GuidStringCodec.php index 9da1b47..e290b03 100644 --- a/src/Codec/GuidStringCodec.php +++ b/src/Codec/GuidStringCodec.php @@ -8,15 +8,19 @@ use Rhumsaa\Uuid\UuidInterface; use Rhumsaa\Uuid\Uuid; use Rhumsaa\Uuid\BigNumberConverter; use Rhumsaa\Uuid\UuidFactory; +use Rhumsaa\Uuid\UuidBuilder; class GuidStringCodec implements Codec { - private $factory; + private $builder; - public function __construct(UuidFactory $factory) + private $uuidCodec; + + public function __construct(UuidBuilder $builder, Codec $uuidCodec) { - $this->factory = $factory; + $this->builder = $builder; + $this->uuidCodec = $uuidCodec; } public function encode(UuidInterface $uuid) @@ -39,17 +43,17 @@ class GuidStringCodec implements Codec public function encodeBinary(UuidInterface $uuid) { - $reversed = $this->_decode($uuid->getConverter(), $this->encode($uuid), false); + $reversed = $this->_decode($this->encode($uuid), false); - return (new StringCodec())->encodeBinary($reversed); + return $this->uuidCodec->encodeBinary($reversed); } - public function decode(BigNumberConverter $converter, $encodedUuid) + public function decode($encodedUuid) { - return $this->_decode($converter, $encodedUuid, true); + return $this->_decode($encodedUuid, true); } - public function decodeBytes(BigNumberConverter $converter, $bytes) + public function decodeBytes($bytes) { if (strlen($bytes) !== 16) { throw new InvalidArgumentException('$bytes string should contain 16 characters.'); @@ -57,10 +61,10 @@ class GuidStringCodec implements Codec $hexUuid = unpack('H*', $bytes); - return $this->_decode($converter, $hexUuid[1], false); + return $this->_decode($hexUuid[1], false); } - private function _decode(BigNumberConverter $converter, $hex, $swap) + private function _decode($hex, $swap) { $nameParsed = str_replace(array( 'urn:', @@ -105,6 +109,6 @@ class GuidStringCodec implements Codec 'node' => sprintf('%012s', $components[4]) ); - return $this->factory->uuid($fields, $this); + return $this->builder->build($this, $fields); } } diff --git a/src/Codec/StringCodec.php b/src/Codec/StringCodec.php index 5e9fd43..ce451de 100644 --- a/src/Codec/StringCodec.php +++ b/src/Codec/StringCodec.php @@ -8,15 +8,16 @@ use Rhumsaa\Uuid\UuidInterface; use Rhumsaa\Uuid\Uuid; use Rhumsaa\Uuid\BigNumberConverter; use Rhumsaa\Uuid\UuidFactory; +use Rhumsaa\Uuid\UuidBuilder; class StringCodec implements Codec { - private $factory; + private $builder; - public function __construct(UuidFactory $factory) + public function __construct(UuidBuilder $builder) { - $this->factory = $factory; + $this->builder = $builder; } public function encode(UuidInterface $uuid) @@ -40,7 +41,7 @@ class StringCodec implements Codec return $bytes; } - public function decode(BigNumberConverter $converter, $encodedUuid) + public function decode($encodedUuid) { $nameParsed = str_replace(array( 'urn:', @@ -76,10 +77,10 @@ class StringCodec implements Codec 'node' => sprintf('%012s', $components[4]) ); - return $this->factory->uuid($fields, $this); + return $this->builder->build($this, $fields); } - public function decodeBytes(BigNumberConverter $converter, $bytes) + public function decodeBytes($bytes) { if (strlen($bytes) !== 16) { throw new InvalidArgumentException('$bytes string should contain 16 characters.'); @@ -87,6 +88,6 @@ class StringCodec implements Codec $hexUuid = unpack('H*', $bytes); - return $this->decode($converter, $hexUuid[1]); + return $this->decode($hexUuid[1]); } } diff --git a/src/FeatureSet.php b/src/FeatureSet.php new file mode 100644 index 0000000..7709ad1 --- /dev/null +++ b/src/FeatureSet.php @@ -0,0 +1,171 @@ +disableBigNumber = $forceNoBigNumber; + $this->disable64Bit = $force32Bit; + $this->ignoreSystemNode = $ignoreSystemNode; + + $this->numberConverter = $this->buildNumberConverter(); + $this->builder = $this->buildUuidBuilder(); + $this->codec = $this->buildCodec($useGuids); + $this->nodeProvider = $this->buildNodeProvider(); + $this->randomGenerator = $this->buildRandomGenerator(); + $this->timeConverter = $this->buildTimeConverter(); + $this->timeProvider = new SystemTimeProvider(); + } + + public function getBuilder() + { + return $this->builder; + } + + public function getCodec() + { + return $this->codec; + } + + public function getNodeProvider() + { + return $this->nodeProvider; + } + + public function getNumberConverter() + { + return $this->numberConverter; + } + + public function getRandomGenerator() + { + return $this->randomGenerator; + } + + public function getTimeConverter() + { + return $this->timeConverter; + } + + public function getTimeProvider() + { + return $this->timeProvider; + } + + protected function buildCodec($useGuids = false) + { + if ($useGuids) { + return new GuidStringCodec($this->builder, $this->buildCodec(false)); + } + + return new StringCodec($this->builder); + } + + protected function buildNodeProvider() + { + if ($this->ignoreSystemNode) { + return new RandomNodeProvider(); + } + + return new FallbackNodeProvider([ + new SystemNodeProvider(), + new RandomNodeProvider() + ]); + } + + protected function buildNumberConverter() + { + if ($this->hasBigNumber()) { + return new BigNumberConverter(); + } + + return new DegradedNumberConverter(); + } + + protected function buildRandomGenerator() + { + return (new RandomGeneratorFactory())->getGenerator(); + } + + protected function buildTimeConverter() + { + if ($this->is64BitSystem()) { + return new PhpTimeConverter(); + } + elseif ($this->hasBigNumber()) { + return new BigNumberTimeConverter(); + } + + return new DegradedTimeConverter(); + } + + protected function buildUuidBuilder() + { + if ($this->is64BitSystem()) { + return new DefaultUuidBuilder($this->numberConverter); + } + + return new DegradedUuidBuilder($this->numberConverter); + } + + /** + * Returns true if the system has Moontoast\Math\BigNumber + * + * @return bool + */ + protected function hasBigNumber() + { + return class_exists('Moontoast\Math\BigNumber') && ! $this->disableBigNumber; + } + + /** + * Returns true if the system is 64-bit, false otherwise + * + * @return bool + */ + protected function is64BitSystem() + { + return PHP_INT_SIZE == 8 && ! $this->disable64Bit; + } +} diff --git a/src/Generator/RandomLibAdapter.php b/src/Generator/RandomLibAdapter.php new file mode 100644 index 0000000..8dac106 --- /dev/null +++ b/src/Generator/RandomLibAdapter.php @@ -0,0 +1,27 @@ +generator = $generator; + + if ($this->generator == null) { + $factory = new Factory(); + + $this->generator = $factory->getLowStrengthGenerator(); + } + } + + public function generate($length) + { + return $this->generator->generate($length); + } +} diff --git a/src/Node/FallbackNodeProvider.php b/src/Node/FallbackNodeProvider.php new file mode 100644 index 0000000..947ca9a --- /dev/null +++ b/src/Node/FallbackNodeProvider.php @@ -0,0 +1,26 @@ +nodeProviders = $providers; + } + + public function getNode() + { + foreach ($this->nodeProviders as $provider) { + if ($node = $provider->getNode()) { + return $node; + } + } + + return null; + } +} diff --git a/src/Node/RandomNodeProvider.php b/src/Node/RandomNodeProvider.php new file mode 100644 index 0000000..1c4195c --- /dev/null +++ b/src/Node/RandomNodeProvider.php @@ -0,0 +1,15 @@ +getIfconfig(), $matches, PREG_PATTERN_ORDER)) { + $node = $matches[1][0]; + $node = str_replace(':', '', $node); + $node = str_replace('-', '', $node); + } + + return $node; + } + + /** + * Returns the network interface configuration for the system + * + * @todo Needs evaluation and possibly modification to ensure this works + * well across multiple platforms. + * @codeCoverageIgnore + */ + protected function getIfconfig() + { + switch (strtoupper(substr(php_uname('a'), 0, 3))) { + case 'WIN': + $ifconfig = `ipconfig /all 2>&1`; + break; + case 'DAR': + $ifconfig = `ifconfig 2>&1`; + break; + case 'LIN': + default: + $ifconfig = `netstat -ie 2>&1`; + break; + } + + return $ifconfig; + } +} diff --git a/src/NodeProvider.php b/src/NodeProvider.php new file mode 100644 index 0000000..70f58d2 --- /dev/null +++ b/src/NodeProvider.php @@ -0,0 +1,8 @@ +multiply('10000000'); + + $usec = new \Moontoast\Math\BigNumber($microSeconds); + $usec->multiply('10'); + + $uuidTime->add($sec) + ->add($usec) + ->add('122192928000000000'); + + $uuidTimeHex = sprintf('%016s', $uuidTime->convertToBase(16)); + + return array( + 'low' => substr($uuidTimeHex, 8), + 'mid' => substr($uuidTimeHex, 4, 4), + 'hi' => substr($uuidTimeHex, 0, 4), + ); + } +} diff --git a/src/Time/DegradedTimeConverter.php b/src/Time/DegradedTimeConverter.php new file mode 100644 index 0000000..f64ee30 --- /dev/null +++ b/src/Time/DegradedTimeConverter.php @@ -0,0 +1,18 @@ +fixedTime = $timestamp; + } + + public function setUsec($value) + { + $this->fixedTime['usec'] = $value; + } + + public function setSec($value) + { + $this->fixedTime['sec'] = $value; + } + + public function currentTime() + { + return $this->fixedTime; + } +} diff --git a/src/Time/PhpTimeConverter.php b/src/Time/PhpTimeConverter.php new file mode 100644 index 0000000..5e40540 --- /dev/null +++ b/src/Time/PhpTimeConverter.php @@ -0,0 +1,21 @@ + sprintf('%08x', $uuidTime & 0xffffffff), + 'mid' => sprintf('%04x', ($uuidTime >> 32) & 0xffff), + 'hi' => sprintf('%04x', ($uuidTime >> 48) & 0x0fff), + ); + } +} diff --git a/src/Time/SystemTimeProvider.php b/src/Time/SystemTimeProvider.php new file mode 100644 index 0000000..068ecc9 --- /dev/null +++ b/src/Time/SystemTimeProvider.php @@ -0,0 +1,13 @@ +fromBytes($bytes); } - public static function fromGuidBytes($bytes) - { - return self::getFactory()->fromGuidBytes($bytes); - } - /** * Creates a UUID from the string standard representation as described * in the toString() method. @@ -763,11 +758,6 @@ class Uuid implements UuidInterface, \JsonSerializable return self::getFactory()->fromString($name); } - public static function fromGuidString($name) - { - return self::getFactory()->fromGuidString($name); - } - /** * Creates a UUID from either the UUID as a 128-bit integer string or a Moontoast\Math\BigNumber object. * diff --git a/src/UuidBuilder.php b/src/UuidBuilder.php new file mode 100644 index 0000000..6f777be --- /dev/null +++ b/src/UuidBuilder.php @@ -0,0 +1,8 @@ + sprintf('%08x', $uuidTime & 0xffffffff), - 'mid' => sprintf('%04x', ($uuidTime >> 32) & 0xffff), - 'hi' => sprintf('%04x', ($uuidTime >> 48) & 0x0fff), - ); - } - - if (self::hasBigNumber()) { - - $uuidTime = new \Moontoast\Math\BigNumber('0'); - - $sec = new \Moontoast\Math\BigNumber($sec); - $sec->multiply('10000000'); - - $usec = new \Moontoast\Math\BigNumber($usec); - $usec->multiply('10'); - - $uuidTime->add($sec) - ->add($usec) - ->add('122192928000000000'); - - $uuidTimeHex = sprintf('%016s', $uuidTime->convertToBase(16)); - - return array( - 'low' => substr($uuidTimeHex, 8), - 'mid' => substr($uuidTimeHex, 4, 4), - 'hi' => substr($uuidTimeHex, 0, 4), - ); - } - - throw new Exception\UnsatisfiedDependencyException( - 'When calling ' . __METHOD__ . ' on a 32-bit system, ' - . 'Moontoast\Math\BigNumber must be present in order ' - . 'to generate version 1 UUIDs' - ); - } + private $timeConverter = null; /** - * Get the hardware address as a 48-bit positive integer. If all attempts to - * obtain the hardware address fail, we choose a random 48-bit number with - * its eighth bit set to 1 as recommended in RFC 4122. "Hardware address" - * means the MAC address of a network interface, and on a machine with - * multiple network interfaces the MAC address of any one of them may be - * returned. * - * @return string + * @var TimeProvider */ - protected static function getNodeFromSystem() - { - $node = null; - $pattern = '/[^:]([0-9A-Fa-f]{2}([:-])[0-9A-Fa-f]{2}(\2[0-9A-Fa-f]{2}){4})[^:]/'; - $matches = array(); - - // Search the ifconfig output for all MAC addresses and return - // the first one found - if (preg_match_all($pattern, self::getIfconfig(), $matches, PREG_PATTERN_ORDER)) { - $node = $matches[1][0]; - $node = str_replace(':', '', $node); - $node = str_replace('-', '', $node); - } - - return $node; - } + private $timeProvider = null; /** - * Returns the network interface configuration for the system * - * @todo Needs evaluation and possibly modification to ensure this works - * well across multiple platforms. - * @codeCoverageIgnore + * @var UuidBuilder */ - protected static function getIfconfig() - { - switch (strtoupper(substr(php_uname('a'), 0, 3))) { - case 'WIN': - $ifconfig = `ipconfig /all 2>&1`; - break; - case 'DAR': - $ifconfig = `ifconfig 2>&1`; - break; - case 'LIN': - default: - $ifconfig = `netstat -ie 2>&1`; - break; - } - - return $ifconfig; - } + private $uuidBuilder = null; /** - * Returns true if the system has Moontoast\Math\BigNumber + * Create a new a instance * - * @return bool */ - protected static function hasBigNumber() + public function __construct(FeatureSet $features = null) { - return (class_exists('Moontoast\Math\BigNumber') && !self::$forceNoBigNumber); + $features = $features ?: new FeatureSet(); + + $this->codec = $features->getCodec(); + $this->nodeProvider = $features->getNodeProvider(); + $this->numberConverter = $features->getNumberConverter(); + $this->randomGenerator = $features->getRandomGenerator(); + $this->timeConverter = $features->getTimeConverter(); + $this->timeProvider = $features->getTimeProvider(); + $this->uuidBuilder = $features->getBuilder(); } - /** - * Returns true if the system is 64-bit, false otherwise - * - * @return bool - */ - protected static function is64BitSystem() + public function setTimeConverter(TimeConverter $converter) { - return (PHP_INT_SIZE == 8 && !self::$force32Bit); + $this->timeConverter = $converter; } - - /** - * Generates random bytes for use in version 4 UUIDs - * - * @param int $length - * @return string - */ - private static function generateBytes($length) + public function setTimeProvider(TimeProvider $provider) { - if (! self::$prng) { - self::$prng = (new RandomGeneratorFactory())->getGenerator(); - } - - return self::$prng->generate($length); + $this->timeProvider = $provider; } - private $codec = null; - - public function __construct(Codec $uuidCodec = null, Codec $guidCodec = null) + public function setRandomGenerator(RandomGenerator $generator) { - $this->codec = $uuidCodec ?: new StringCodec($this); - $this->guidCodec = $guidCodec ?: new GuidStringCodec($this); + $this->randomGenerator = $generator; + } + + public function setNodeProvider(NodeProvider $provider) + { + $this->nodeProvider = $provider; + } + + public function setNumberConverter(BigNumberConverter $converter) + { + $this->numberConverter = $converter; + } + + public function setUuidBuilder(UuidBuilder $builder) + { + $this->uuidBuilder = $builder; } /** @@ -203,12 +118,7 @@ class UuidFactory */ public function fromBytes($bytes) { - return $this->codec->decodeBytes($this->getConverter(), $bytes); - } - - public function fromGuidBytes($bytes) - { - return $this->guidCodec->decodeBytes($this->getConverter(), $bytes); + return $this->codec->decodeBytes($bytes); } /** @@ -222,33 +132,17 @@ class UuidFactory */ public function fromString($name) { - return $this->codec->decode($this->getConverter(), $name); - } - - public function fromGuidString($name) - { - return $this->guidCodec->decode($this->getConverter(), $name); + return $this->codec->decode($name); } public function fromInteger($integer) { - $hex = $this->getConverter()->toHex($integer); + $hex = $this->numberConverter->toHex($integer); $hex = str_pad($hex, 32, '0', STR_PAD_LEFT); return $this->fromString($hex); } - public function getConverter() - { - $converter = new BigNumberConverter(); - - if (! self::hasBigNumber()) { - $converter = new DegradedNumberConverter(); - } - - return $converter; - } - /** * Generate a version 1 UUID from a host ID, sequence number, and the current time. * If $node is not given, we will attempt to obtain the local hardware @@ -266,14 +160,8 @@ class UuidFactory */ public function uuid1($node = null, $clockSeq = null) { - if ($node === null && !self::$ignoreSystemNode) { - $node = self::getNodeFromSystem(); - } - - // if $node is still null (couldn't get from system), randomly generate - // a node value, according to RFC 4122, Section 4.5 if ($node === null) { - $node = sprintf('%06x%06x', mt_rand(0, 1 << 24), mt_rand(0, 1 << 24)); + $node = $this->nodeProvider->getNode(); } // Convert the node to hex, if it is still an integer @@ -281,12 +169,12 @@ class UuidFactory $node = sprintf('%012x', $node); } - if (ctype_xdigit($node) && strlen($node) <= 12) { - $node = strtolower(sprintf('%012s', $node)); - } else { + if (! ctype_xdigit($node) || strlen($node) > 12) { throw new \InvalidArgumentException('Invalid node value'); } + $node = strtolower(sprintf('%012s', $node)); + if ($clockSeq === null) { // Not using "stable storage"; see RFC 4122, Section 4.2.1.1 $clockSeq = mt_rand(0, 1 << 14); @@ -294,13 +182,8 @@ class UuidFactory // Create a 60-bit time value as a count of 100-nanosecond intervals // since 00:00:00.00, 15 October 1582 - if (self::$timeOfDayTest === null) { - $timeOfDay = gettimeofday(); - } else { - $timeOfDay = self::$timeOfDayTest; - } - - $uuidTime = self::calculateUuidTime($timeOfDay['sec'], $timeOfDay['usec']); + $timeOfDay = $this->timeProvider->currentTime(); + $uuidTime = $this->timeConverter->calculateTime($timeOfDay['sec'], $timeOfDay['usec']); // Set the version number to 1 $timeHi = hexdec($uuidTime['hi']) & 0x0fff; @@ -336,7 +219,7 @@ class UuidFactory public function uuid3($ns, $name) { if (!($ns instanceof UuidInterface)) { - $ns = $this->codec->decode($this->getConverter(), $ns); + $ns = $this->codec->decode($ns); } $hash = md5($ns->getBytes() . $name); @@ -351,12 +234,13 @@ class UuidFactory */ public function uuid4() { - $bytes = self::generateBytes(16); + $bytes = $this->randomGenerator->generate(16); // When converting the bytes to hex, it turns into a 32-character // hexadecimal string that looks a lot like an MD5 hash, so at this // point, we can just pass it to uuidFromHashedName. $hex = bin2hex($bytes); + return $this->uuidFromHashedName($hex, 4); } @@ -371,7 +255,7 @@ class UuidFactory public function uuid5($ns, $name) { if (!($ns instanceof Uuid)) { - $ns = $this->codec->decode($this->getConverter(), $ns); + $ns = $this->codec->decode($ns); } $hash = sha1($ns->getBytes() . $name); @@ -379,15 +263,9 @@ class UuidFactory return $this->uuidFromHashedName($hash, 5); } - public function uuid(array $fields, Codec $codec = null) + public function uuid(array $fields) { - $codec = $codec ?: $this->codec; - - if (! self::is64BitSystem()) { - return new DegradedUuid($fields, $this->getConverter(), $codec); - } - - return new Uuid($fields, $this->getConverter(), $codec); + return $this->uuidBuilder->build($this->codec, $fields); } /** diff --git a/tests/UuidBcTag1_1_2Test.php b/tests/UuidBcTag1_1_2Test.php index fde737c..60966f1 100644 --- a/tests/UuidBcTag1_1_2Test.php +++ b/tests/UuidBcTag1_1_2Test.php @@ -12,6 +12,8 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase { protected function setUp() { + Uuid::setFactory(new UuidFactory()); + // Skip these tests if run on a 32-bit build of PHP if (PHP_INT_SIZE == 4) { $this->markTestSkipped( @@ -375,7 +377,7 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase */ public function testUuid1WithRandomNode() { - UuidFactory::$ignoreSystemNode = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, false, false, true))); $uuid = Uuid::uuid1(); $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); diff --git a/tests/UuidFactoryTest.php b/tests/UuidFactoryTest.php index c53d757..b5ca218 100644 --- a/tests/UuidFactoryTest.php +++ b/tests/UuidFactoryTest.php @@ -15,9 +15,9 @@ class UuidFactoryTest extends TestCase public function testParsesGuidCorrectly() { - $factory = new UuidFactory(); + $factory = new UuidFactory(new FeatureSet(true)); - $uuid = $factory->fromGuidString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); + $uuid = $factory->fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); } diff --git a/tests/UuidTest.php b/tests/UuidTest.php index 7858abb..c2f0d6d 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -2,15 +2,14 @@ namespace Rhumsaa\Uuid; +use Rhumsaa\Uuid\Time\SystemTimeProvider; +use Rhumsaa\Uuid\Time\FixedTimeProvider; + class UuidTest extends TestCase { protected function setUp() { - UuidFactory::$forceNoBigNumber = false; - - UuidFactory::$timeOfDayTest = null; - UuidFactory::$force32Bit = false; - UuidFactory::$ignoreSystemNode = false; + Uuid::setFactory(new UuidFactory()); RandomGeneratorFactory::$forceNoOpensslRandomPseudoBytes = false; } @@ -29,7 +28,10 @@ class UuidTest extends TestCase public function testFromLittleEndianString() { $uuid = Uuid::fromString('b08c6fff-7dc5-e111-9b21-0800200c9a66'); - $guid = Uuid::fromGuidString('b08c6fff-7dc5-e111-9b21-0800200c9a66'); + + Uuid::setFactory(new UuidFactory(new FeatureSet(true))); + + $guid = Uuid::fromString('b08c6fff-7dc5-e111-9b21-0800200c9a66'); $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $guid); // UUID's and GUID's share the same textual representation @@ -152,7 +154,7 @@ class UuidTest extends TestCase public function testGetDateTime32Bit() { $this->skipIfNoMoontoastMath(); - UuidFactory::$force32Bit = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); // Check a recent date $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); @@ -180,8 +182,7 @@ class UuidTest extends TestCase */ public function testGetDateTimeThrownException() { - UuidFactory::$force32Bit = true; - UuidFactory::$forceNoBigNumber = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true, true))); $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); @@ -227,7 +228,8 @@ class UuidTest extends TestCase */ public function testGetFields32Bit() { - UuidFactory::$force32Bit = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); + $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $fields = $uuid->getFields(); } @@ -266,7 +268,8 @@ class UuidTest extends TestCase */ public function testGetLeastSignificantBitsException() { - UuidFactory::$forceNoBigNumber = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, false, true))); + $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $bn = $uuid->getLeastSignificantBits(); } @@ -295,7 +298,8 @@ class UuidTest extends TestCase */ public function testGetMostSignificantBitsException() { - UuidFactory::$forceNoBigNumber = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, false, true))); + $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $bn = $uuid->getMostSignificantBits(); } @@ -323,7 +327,8 @@ class UuidTest extends TestCase */ public function testGetNode32Bit() { - UuidFactory::$force32Bit = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); + $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $node = $uuid->getNode(); } @@ -367,7 +372,8 @@ class UuidTest extends TestCase */ public function testGetTimeLow32Bit() { - UuidFactory::$force32Bit = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); + $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $timeLow = $uuid->getTimeLow(); } @@ -451,7 +457,8 @@ class UuidTest extends TestCase */ public function testGetTimestamp32Bit() { - UuidFactory::$force32Bit = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); + $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $ts = $uuid->getTimestamp(); } @@ -695,7 +702,7 @@ class UuidTest extends TestCase public function testUuid1WithRandomNode() { - UuidFactory::$ignoreSystemNode = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, false, false, true))); $uuid = Uuid::uuid1(); $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); @@ -877,15 +884,15 @@ class UuidTest extends TestCase */ public function testCalculateUuidTime() { - $timeOfDay = array( + $timeOfDay = new FixedTimeProvider(array( 'sec' => 1348845514, 'usec' => 277885, 'minuteswest' => 0, 'dsttime' => 0, - ); + )); // For usec = 277885 - UuidFactory::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c4dbe7e2-097f-11e2-9669-00007ffffffe', (string) $uuidA); @@ -894,7 +901,7 @@ class UuidTest extends TestCase $this->assertEquals('11e2', $uuidA->getTimeHiAndVersionHex()); // For usec = 0 - UuidFactory::$timeOfDayTest['usec'] = 0; + $timeOfDay->setUsec(0); $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c4b18100-097f-11e2-9669-00007ffffffe', (string) $uuidB); @@ -903,7 +910,7 @@ class UuidTest extends TestCase $this->assertEquals('11e2', $uuidB->getTimeHiAndVersionHex()); // For usec = 999999 - UuidFactory::$timeOfDayTest['usec'] = 999999; + $timeOfDay->setUsec(999999); $uuidC = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c54a1776-097f-11e2-9669-00007ffffffe', (string) $uuidC); @@ -917,17 +924,17 @@ class UuidTest extends TestCase public function testCalculateUuidTimeForce32BitPath() { $this->skipIfNoMoontoastMath(); - UuidFactory::$force32Bit = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); - $timeOfDay = array( + $timeOfDay = new FixedTimeProvider(array( 'sec' => 1348845514, 'usec' => 277885, 'minuteswest' => 0, 'dsttime' => 0, - ); + )); // For usec = 277885 - UuidFactory::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c4dbe7e2-097f-11e2-9669-00007ffffffe', (string) $uuidA); @@ -936,7 +943,7 @@ class UuidTest extends TestCase $this->assertEquals('11e2', $uuidA->getTimeHiAndVersionHex()); // For usec = 0 - UuidFactory::$timeOfDayTest['usec'] = 0; + $timeOfDay->setUsec(0); $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c4b18100-097f-11e2-9669-00007ffffffe', (string) $uuidB); @@ -945,7 +952,7 @@ class UuidTest extends TestCase $this->assertEquals('11e2', $uuidB->getTimeHiAndVersionHex()); // For usec = 999999 - UuidFactory::$timeOfDayTest['usec'] = 999999; + $timeOfDay->setUsec(999999); $uuidC = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c54a1776-097f-11e2-9669-00007ffffffe', (string) $uuidC); @@ -961,14 +968,14 @@ class UuidTest extends TestCase $this->skip64BitTest(); // 5235-03-31T21:20:59+00:00 - $timeOfDay = array( + $timeOfDay = new FixedTimeProvider(array( 'sec' => 103072857659, 'usec' => 999999, 'minuteswest' => 0, 'dsttime' => 0, - ); + )); - UuidFactory::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('ff9785f6-ffff-1fff-9669-00007ffffffe', (string) $uuidA); @@ -977,14 +984,14 @@ class UuidTest extends TestCase $this->assertEquals('1fff', $uuidA->getTimeHiAndVersionHex()); // 1582-10-15T00:00:00+00:00 - $timeOfDay = array( + $timeOfDay = new FixedTimeProvider(array( 'sec' => -12219292800, 'usec' => 0, 'minuteswest' => 0, 'dsttime' => 0, - ); + )); - UuidFactory::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('00000000-0000-1000-9669-00007ffffffe', (string) $uuidB); @@ -1003,17 +1010,17 @@ class UuidTest extends TestCase $this->skipIfNoMoontoastMath(); $this->skip64BitTest(); - UuidFactory::$force32Bit = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); // 5235-03-31T21:20:59+00:00 - $timeOfDay = array( + $timeOfDay = new FixedTimeProvider(array( 'sec' => 103072857659, 'usec' => 999999, 'minuteswest' => 0, 'dsttime' => 0, - ); + )); - UuidFactory::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('ff9785f6-ffff-1fff-9669-00007ffffffe', (string) $uuidA); @@ -1022,14 +1029,14 @@ class UuidTest extends TestCase $this->assertEquals('1fff', $uuidA->getTimeHiAndVersionHex()); // 1582-10-15T00:00:00+00:00 - $timeOfDay = array( + $timeOfDay = new FixedTimeProvider(array( 'sec' => -12219292800, 'usec' => 0, 'minuteswest' => 0, 'dsttime' => 0, - ); + )); - UuidFactory::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('00000000-0000-1000-9669-00007ffffffe', (string) $uuidB); @@ -1043,17 +1050,17 @@ class UuidTest extends TestCase public function testCalculateUuidTimeUpperLowerBounds32Bit() { $this->skipIfNoMoontoastMath(); - UuidFactory::$force32Bit = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); // 2038-01-19T03:14:07+00:00 - $timeOfDay = array( + $timeOfDay = new FixedTimeProvider(array( 'sec' => 2147483647, 'usec' => 999999, 'minuteswest' => 0, 'dsttime' => 0, - ); + )); - UuidFactory::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('13813ff6-6912-11fe-9669-00007ffffffe', (string) $uuidA); @@ -1062,14 +1069,14 @@ class UuidTest extends TestCase $this->assertEquals('11fe', $uuidA->getTimeHiAndVersionHex()); // 1901-12-13T20:45:53+00:00 - $timeOfDay = array( + $timeOfDay = new FixedTimeProvider(array( 'sec' => -2147483647, 'usec' => 0, 'minuteswest' => 0, 'dsttime' => 0, - ); + )); - UuidFactory::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('1419d680-d292-1165-9669-00007ffffffe', (string) $uuidB); @@ -1088,14 +1095,14 @@ class UuidTest extends TestCase $this->skip64BitTest(); // 2038-01-19T03:14:07+00:00 - $timeOfDay = array( + $timeOfDay = new FixedTimeProvider(array( 'sec' => 2147483647, 'usec' => 999999, 'minuteswest' => 0, 'dsttime' => 0, - ); + )); - UuidFactory::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('13813ff6-6912-11fe-9669-00007ffffffe', (string) $uuidA); @@ -1104,14 +1111,14 @@ class UuidTest extends TestCase $this->assertEquals('11fe', $uuidA->getTimeHiAndVersionHex()); // 1901-12-13T20:45:53+00:00 - $timeOfDay = array( + $timeOfDay = new FixedTimeProvider(array( 'sec' => -2147483647, 'usec' => 0, 'minuteswest' => 0, 'dsttime' => 0, - ); + )); - UuidFactory::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('1419d680-d292-1165-9669-00007ffffffe', (string) $uuidB); @@ -1132,24 +1139,25 @@ class UuidTest extends TestCase $currentTime = strtotime('2012-12-11T00:00:00+00:00'); $endTime = $currentTime + 3600; + $factory = new UuidFactory(); + $smallIntFactory = new UuidFactory(new FeatureSet(false, true)); + while ($currentTime <= $endTime) { foreach (array(0, 50000, 250000, 500000, 750000, 999999) as $usec) { - $timeOfDay = array( + $timeOfDay = new FixedTimeProvider(array( 'sec' => $currentTime, 'usec' => $usec, 'minuteswest' => 0, 'dsttime' => 0, - ); + )); - UuidFactory::$timeOfDayTest = $timeOfDay; + $factory->setTimeProvider($timeOfDay); + $smallIntFactory->setTimeProvider($timeOfDay); - UuidFactory::$force32Bit = true; - $uuid32 = Uuid::uuid1(0x00007ffffffe, 0x1669); - - UuidFactory::$force32Bit = false; - $uuid64 = Uuid::uuid1(0x00007ffffffe, 0x1669); + $uuid32 = $smallIntFactory->uuid1(0x00007ffffffe, 0x1669); + $uuid64 = $factory->uuid1(0x00007ffffffe, 0x1669); $this->assertTrue( $uuid32->equals($uuid64), @@ -1171,8 +1179,7 @@ class UuidTest extends TestCase */ public function testCalculateUuidTimeThrownException() { - UuidFactory::$force32Bit = true; - UuidFactory::$forceNoBigNumber = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true, true))); $uuid = Uuid::uuid1(0x00007ffffffe, 0x1669); } @@ -1291,16 +1298,18 @@ class UuidTest extends TestCase $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $bytes = $uuid->getBytes(); - $guid = Uuid::fromGuidBytes($bytes); + Uuid::setFactory(new UuidFactory(new FeatureSet(true))); + + $guid = Uuid::fromBytes($bytes); // First three fields should be reversed $this->assertEquals('b08c6fff-7dc5-e111-9b21-0800200c9a66', $guid->toString()); // Check that parsing LE bytes as LE preserves fields - $guid = Uuid::fromGuidString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); + $guid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $bytes = $guid->getBytes(); - $parsedGuid = Uuid::fromGuidBytes($bytes); + $parsedGuid = Uuid::fromBytes($bytes); $this->assertEquals($guid->toString(), $parsedGuid->toString()); } @@ -1679,7 +1688,7 @@ class UuidTest extends TestCase */ public function testGetInteger() { - UuidFactory::$forceNoBigNumber = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, false, true))); $uuid = Uuid::uuid1(); $uuid->getInteger();