From fead6f3223688c087b3e5e0e4c7456172ee5424b Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Thu, 30 Oct 2014 13:16:19 +0100 Subject: [PATCH] Refactor in the spirit of #1 & #34 --- src/BigNumberConverter.php | 13 + src/Codec.php | 4 +- src/Codec/GuidStringCodec.php | 23 +- src/Codec/StringCodec.php | 17 +- src/Generator/MtRandGenerator.php | 19 + src/Generator/OpenSslGenerator.php | 14 + src/RandomGenerator.php | 8 + src/RandomGeneratorFactory.php | 36 ++ src/SmallIntUuid.php | 151 ++++++++ src/UnsatisfiedNumberConverter.php | 16 + src/Uuid.php | 456 ++--------------------- src/UuidFactory.php | 416 +++++++++++++++++++++ src/UuidInterface.php | 2 + tests/Codec/GuidStringCodecTest.php | 18 - tests/Codec/StringCodecTest.php | 18 - tests/RandomGeneratorFactoryTest.php | 24 ++ tests/UnsatisfiedNumberConverterTest.php | 16 + tests/UuidBcTag1_1_2Test.php | 52 +-- tests/UuidFactoryTest.php | 24 ++ tests/UuidTest.php | 281 +++----------- tests/bootstrap.php | 6 + 21 files changed, 865 insertions(+), 749 deletions(-) create mode 100644 src/BigNumberConverter.php create mode 100644 src/Generator/MtRandGenerator.php create mode 100644 src/Generator/OpenSslGenerator.php create mode 100644 src/RandomGenerator.php create mode 100644 src/RandomGeneratorFactory.php create mode 100644 src/SmallIntUuid.php create mode 100644 src/UnsatisfiedNumberConverter.php create mode 100644 src/UuidFactory.php delete mode 100644 tests/Codec/GuidStringCodecTest.php delete mode 100644 tests/Codec/StringCodecTest.php create mode 100644 tests/RandomGeneratorFactoryTest.php create mode 100644 tests/UnsatisfiedNumberConverterTest.php create mode 100644 tests/UuidFactoryTest.php diff --git a/src/BigNumberConverter.php b/src/BigNumberConverter.php new file mode 100644 index 0000000..349ea33 --- /dev/null +++ b/src/BigNumberConverter.php @@ -0,0 +1,13 @@ +factory = $factory; + } + public function encode(UuidInterface $uuid) { $fields = array_values($uuid->getFieldsHex()); @@ -30,17 +39,17 @@ class GuidStringCodec implements Codec public function encodeBinary(UuidInterface $uuid) { - $reversed = $this->_decode($this->encode($uuid), false); + $reversed = $this->_decode($uuid->getConverter(), $this->encode($uuid), false); return (new StringCodec())->encodeBinary($reversed); } - public function decode($encodedUuid) + public function decode(BigNumberConverter $converter, $encodedUuid) { - return $this->_decode($encodedUuid, true); + return $this->_decode($converter, $encodedUuid, true); } - public function decodeBytes($bytes) + public function decodeBytes(BigNumberConverter $converter, $bytes) { if (strlen($bytes) !== 16) { throw new InvalidArgumentException('$bytes string should contain 16 characters.'); @@ -48,10 +57,10 @@ class GuidStringCodec implements Codec $hexUuid = unpack('H*', $bytes); - return $this->_decode($hexUuid[1], false); + return $this->_decode($converter, $hexUuid[1], false); } - private function _decode($hex, $swap) + private function _decode(BigNumberConverter $converter, $hex, $swap) { $nameParsed = str_replace(array( 'urn:', @@ -96,6 +105,6 @@ class GuidStringCodec implements Codec 'node' => sprintf('%012s', $components[4]) ); - return new Uuid($fields, $this); + return $this->factory->uuid($fields, $this); } } diff --git a/src/Codec/StringCodec.php b/src/Codec/StringCodec.php index b787a6e..5e9fd43 100644 --- a/src/Codec/StringCodec.php +++ b/src/Codec/StringCodec.php @@ -6,10 +6,19 @@ use InvalidArgumentException; use Rhumsaa\Uuid\Codec; use Rhumsaa\Uuid\UuidInterface; use Rhumsaa\Uuid\Uuid; +use Rhumsaa\Uuid\BigNumberConverter; +use Rhumsaa\Uuid\UuidFactory; class StringCodec implements Codec { + private $factory; + + public function __construct(UuidFactory $factory) + { + $this->factory = $factory; + } + public function encode(UuidInterface $uuid) { $fields = array_values($uuid->getFieldsHex()); @@ -31,7 +40,7 @@ class StringCodec implements Codec return $bytes; } - public function decode($encodedUuid) + public function decode(BigNumberConverter $converter, $encodedUuid) { $nameParsed = str_replace(array( 'urn:', @@ -67,10 +76,10 @@ class StringCodec implements Codec 'node' => sprintf('%012s', $components[4]) ); - return new Uuid($fields, $this); + return $this->factory->uuid($fields, $this); } - public function decodeBytes($bytes) + public function decodeBytes(BigNumberConverter $converter, $bytes) { if (strlen($bytes) !== 16) { throw new InvalidArgumentException('$bytes string should contain 16 characters.'); @@ -78,6 +87,6 @@ class StringCodec implements Codec $hexUuid = unpack('H*', $bytes); - return $this->decode($hexUuid[1]); + return $this->decode($converter, $hexUuid[1]); } } diff --git a/src/Generator/MtRandGenerator.php b/src/Generator/MtRandGenerator.php new file mode 100644 index 0000000..af24dcc --- /dev/null +++ b/src/Generator/MtRandGenerator.php @@ -0,0 +1,19 @@ +getVersion() != 1) { + throw new Exception\UnsupportedOperationException('Not a time-based UUID'); + } + + $time = $this->converter->fromHex($this->getTimestampHex()); + + $ts = new \Moontoast\Math\BigNumber($time, 20); + $ts->subtract('122192928000000000'); + $ts->divide('10000000.0'); + $ts->round(); + $unixTime = $ts->getValue(); + + return new \DateTime("@{$unixTime}"); + } + + /** + * Returns an array of the fields of this UUID, with keys named according + * to the RFC 4122 names for the fields. + * + * * **time_low**: The low field of the timestamp, an unsigned 32-bit integer + * * **time_mid**: The middle field of the timestamp, an unsigned 16-bit integer + * * **time_hi_and_version**: The high field of the timestamp multiplexed with + * the version number, an unsigned 16-bit integer + * * **clock_seq_hi_and_reserved**: The high field of the clock sequence + * multiplexed with the variant, an unsigned 8-bit integer + * * **clock_seq_low**: The low field of the clock sequence, an unsigned + * 8-bit integer + * * **node**: The spatially unique node identifier, an unsigned 48-bit + * integer + * + * @return array The UUID fields represented as integer values + * @throws Exception\UnsatisfiedDependencyException if called on a 32-bit system + * @link http://tools.ietf.org/html/rfc4122#section-4.1.2 + */ + public function getFields() + { + throw new Exception\UnsatisfiedDependencyException( + 'Cannot call ' . __METHOD__ . ' on a 32-bit system, since some ' + . 'values overflow the system max integer value' + . '; consider calling getFieldsHex instead' + ); + } + + /** + * Returns the node value associated with this UUID + * + * For UUID version 1, the node field consists of an IEEE 802 MAC + * address, usually the host address. For systems with multiple IEEE + * 802 addresses, any available one can be used. The lowest addressed + * octet (octet number 10) contains the global/local bit and the + * unicast/multicast bit, and is the first octet of the address + * transmitted on an 802.3 LAN. + * + * For systems with no IEEE address, a randomly or pseudo-randomly + * generated value may be used; see RFC 4122, Section 4.5. The + * multicast bit must be set in such addresses, in order that they + * will never conflict with addresses obtained from network cards. + * + * For UUID version 3 or 5, the node field is a 48-bit value constructed + * from a name as described in RFC 4122, Section 4.3. + * + * For UUID version 4, the node field is a randomly or pseudo-randomly + * generated 48-bit value as described in RFC 4122, Section 4.4. + * + * @return int Unsigned 48-bit integer value of node + * @link http://tools.ietf.org/html/rfc4122#section-4.1.6 + * @throws Exception\UnsatisfiedDependencyException if called on a 32-bit system + */ + public function getNode() + { + throw new Exception\UnsatisfiedDependencyException( + 'Cannot call ' . __METHOD__ . ' on a 32-bit system, since node ' + . 'is an unsigned 48-bit integer and can overflow the system ' + . 'max integer value' + . '; consider calling getNodeHex instead' + ); + } + + /** + * Returns the low field of the timestamp (the first 32 bits of the UUID). + * + * @return int Unsigned 32-bit integer value of time_low + * @throws Exception\UnsatisfiedDependencyException if called on a 32-bit system + */ + public function getTimeLow() + { + throw new Exception\UnsatisfiedDependencyException( + 'Cannot call ' . __METHOD__ . ' on a 32-bit system, since time_low ' + . 'is an unsigned 32-bit integer and can overflow the system ' + . 'max integer value' + . '; consider calling getTimeLowHex instead' + ); + } + + /** + * The timestamp value associated with this UUID + * + * The 60 bit timestamp value is constructed from the time_low, + * time_mid, and time_hi fields of this UUID. The resulting + * timestamp is measured in 100-nanosecond units since midnight, + * October 15, 1582 UTC. + * + * The timestamp value is only meaningful in a time-based UUID, which + * has version type 1. If this UUID is not a time-based UUID then + * this method throws UnsupportedOperationException. + * + * @return int Unsigned 60-bit integer value of the timestamp + * @throws Exception\UnsupportedOperationException If this UUID is not a version 1 UUID + * @throws Exception\UnsatisfiedDependencyException if called on a 32-bit system + * @link http://tools.ietf.org/html/rfc4122#section-4.1.4 + */ + public function getTimestamp() + { + if ($this->getVersion() != 1) { + throw new Exception\UnsupportedOperationException('Not a time-based UUID'); + } + + throw new Exception\UnsatisfiedDependencyException( + 'Cannot call ' . __METHOD__ . ' on a 32-bit system, since timestamp ' + . 'is an unsigned 60-bit integer and can overflow the system ' + . 'max integer value' + . '; consider calling getTimestampHex instead' + ); + } +} diff --git a/src/UnsatisfiedNumberConverter.php b/src/UnsatisfiedNumberConverter.php new file mode 100644 index 0000000..e6b7119 --- /dev/null +++ b/src/UnsatisfiedNumberConverter.php @@ -0,0 +1,16 @@ + '000000000000', ); - /** - * String codec - * @var Codec - */ - protected $codec; + protected $converter; /** * Creates a universally unique identifier (UUID) from an array of fields. @@ -168,10 +139,11 @@ final class Uuid implements UuidInterface, \JsonSerializable * @param Codec $codec String codec * @link Rhumsaa.Uuid.Uuid.html#method_getFields */ - public function __construct(array $fields, Codec $codec = null) + public function __construct(array $fields, BigNumberConverter $converter, Codec $codec) { $this->fields = $fields; - $this->codec = $codec ?: new StringCodec(); + $this->codec = $codec; + $this->converter = $converter; } /** @@ -335,6 +307,11 @@ final class Uuid implements UuidInterface, \JsonSerializable return sprintf('%04x', $this->getClockSequence()); } + public function getConverter() + { + return $this->converter; + } + /** * Returns a PHP DateTime object representing the timestamp associated * with this UUID. @@ -353,31 +330,8 @@ final class Uuid implements UuidInterface, \JsonSerializable throw new Exception\UnsupportedOperationException('Not a time-based UUID'); } - - if (self::is64BitSystem()) { - - $unixTime = ($this->getTimestamp() - 0x01b21dd213814000) / 1e7; - $unixTime = number_format($unixTime, 0, '', ''); - - } elseif (self::hasBigNumber()) { - - $time = \Moontoast\Math\BigNumber::baseConvert($this->getTimestampHex(), 16, 10); - - $ts = new \Moontoast\Math\BigNumber($time, 20); - $ts->subtract('122192928000000000'); - $ts->divide('10000000.0'); - $ts->round(); - $unixTime = $ts->getValue(); - - } else { - - throw new Exception\UnsatisfiedDependencyException( - 'When calling ' . __METHOD__ . ' on a 32-bit system, ' - . 'Moontoast\Math\BigNumber must be present in order ' - . 'to extract DateTime from version 1 UUIDs' - ); - - } + $unixTime = ($this->getTimestamp() - 0x01b21dd213814000) / 1e7; + $unixTime = number_format($unixTime, 0, '', ''); return new \DateTime("@{$unixTime}"); } @@ -403,14 +357,6 @@ final class Uuid implements UuidInterface, \JsonSerializable */ public function getFields() { - if (!self::is64BitSystem()) { - throw new Exception\UnsatisfiedDependencyException( - 'Cannot call ' . __METHOD__ . ' on a 32-bit system, since some ' - . 'values overflow the system max integer value' - . '; consider calling getFieldsHex instead' - ); - } - return array( 'time_low' => $this->getTimeLow(), 'time_mid' => $this->getTimeMid(), @@ -461,22 +407,7 @@ final class Uuid implements UuidInterface, \JsonSerializable */ public function getInteger() { - if (!self::hasBigNumber()) { - throw new Exception\UnsatisfiedDependencyException( - 'Cannot call ' . __METHOD__ . ' without support for large ' - . 'integers, since integer is an unsigned ' - . '128-bit integer; Moontoast\Math\BigNumber is required' - . '; consider calling getMostSignificantBitsHex instead' - ); - } - - $number = \Moontoast\Math\BigNumber::baseConvert( - $this->getHex(), - 16, - 10 - ); - - return new \Moontoast\Math\BigNumber($number); + return $this->converter->fromHex($this->getHex()); } /** @@ -487,22 +418,7 @@ final class Uuid implements UuidInterface, \JsonSerializable */ public function getLeastSignificantBits() { - if (!self::hasBigNumber()) { - throw new Exception\UnsatisfiedDependencyException( - 'Cannot call ' . __METHOD__ . ' without support for large ' - . 'integers, since least significant bits is an unsigned ' - . '64-bit integer; Moontoast\Math\BigNumber is required' - . '; consider calling getLeastSignificantBitsHex instead' - ); - } - - $number = \Moontoast\Math\BigNumber::baseConvert( - $this->getLeastSignificantBitsHex(), - 16, - 10 - ); - - return new \Moontoast\Math\BigNumber($number); + return $this->converter->fromHex($this->getLeastSignificantBitsHex()); } /** @@ -528,22 +444,7 @@ final class Uuid implements UuidInterface, \JsonSerializable */ public function getMostSignificantBits() { - if (!self::hasBigNumber()) { - throw new Exception\UnsatisfiedDependencyException( - 'Cannot call ' . __METHOD__ . ' without support for large ' - . 'integers, since most significant bits is an unsigned ' - . '64-bit integer; Moontoast\Math\BigNumber is required' - . '; consider calling getMostSignificantBitsHex instead' - ); - } - - $number = \Moontoast\Math\BigNumber::baseConvert( - $this->getMostSignificantBitsHex(), - 16, - 10 - ); - - return new \Moontoast\Math\BigNumber($number); + return $this->converter->fromHex($this->getMostSignificantBitsHex()); } /** @@ -588,15 +489,6 @@ final class Uuid implements UuidInterface, \JsonSerializable */ public function getNode() { - if (!self::is64BitSystem()) { - throw new Exception\UnsatisfiedDependencyException( - 'Cannot call ' . __METHOD__ . ' on a 32-bit system, since node ' - . 'is an unsigned 48-bit integer and can overflow the system ' - . 'max integer value' - . '; consider calling getNodeHex instead' - ); - } - return hexdec($this->getNodeHex()); } @@ -659,15 +551,6 @@ final class Uuid implements UuidInterface, \JsonSerializable */ public function getTimeLow() { - if (!self::is64BitSystem()) { - throw new Exception\UnsatisfiedDependencyException( - 'Cannot call ' . __METHOD__ . ' on a 32-bit system, since time_low ' - . 'is an unsigned 32-bit integer and can overflow the system ' - . 'max integer value' - . '; consider calling getTimeLowHex instead' - ); - } - return hexdec($this->getTimeLowHex()); } @@ -724,15 +607,6 @@ final class Uuid implements UuidInterface, \JsonSerializable throw new Exception\UnsupportedOperationException('Not a time-based UUID'); } - if (!self::is64BitSystem()) { - throw new Exception\UnsatisfiedDependencyException( - 'Cannot call ' . __METHOD__ . ' on a 32-bit system, since timestamp ' - . 'is an unsigned 60-bit integer and can overflow the system ' - . 'max integer value' - . '; consider calling getTimestampHex instead' - ); - } - return hexdec($this->getTimestampHex()); } @@ -844,6 +718,20 @@ final class Uuid implements UuidInterface, \JsonSerializable return $this->codec->encode($this); } + public static function getFactory() + { + if (! self::$factory) { + self::$factory = new UuidFactory(); + } + + return self::$factory; + } + + public static function setFactory(UuidFactory $factory) + { + self::$factory = $factory; + } + /** * Creates a UUID from a byte string. * @@ -853,12 +741,12 @@ final class Uuid implements UuidInterface, \JsonSerializable */ public static function fromBytes($bytes) { - return (new StringCodec())->decodeBytes($bytes); + return self::getFactory()->fromBytes($bytes); } public static function fromGuidBytes($bytes) { - return (new GuidStringCodec())->decodeBytes($bytes); + return self::getFactory()->fromGuidBytes($bytes); } /** @@ -872,12 +760,12 @@ final class Uuid implements UuidInterface, \JsonSerializable */ public static function fromString($name) { - return (new StringCodec())->decode($name); + return self::getFactory()->fromString($name); } public static function fromGuidString($name) { - return (new GuidStringCodec())->decode($name); + return self::getFactory()->fromGuidString($name); } /** @@ -944,61 +832,7 @@ final class Uuid implements UuidInterface, \JsonSerializable */ public static 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)); - } - - // Convert the node to hex, if it is still an integer - if (is_int($node)) { - $node = sprintf('%012x', $node); - } - - if (ctype_xdigit($node) && strlen($node) <= 12) { - $node = strtolower(sprintf('%012s', $node)); - } else { - throw new InvalidArgumentException('Invalid node value'); - } - - if ($clockSeq === null) { - // Not using "stable storage"; see RFC 4122, Section 4.2.1.1 - $clockSeq = mt_rand(0, 1 << 14); - } - - // 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']); - - // Set the version number to 1 - $timeHi = hexdec($uuidTime['hi']) & 0x0fff; - $timeHi &= ~(0xf000); - $timeHi |= 1 << 12; - - // Set the variant to RFC 4122 - $clockSeqHi = ($clockSeq >> 8) & 0x3f; - $clockSeqHi &= ~(0xc0); - $clockSeqHi |= 0x80; - - $fields = array( - 'time_low' => $uuidTime['low'], - 'time_mid' => $uuidTime['mid'], - 'time_hi_and_version' => sprintf('%04x', $timeHi), - 'clock_seq_hi_and_reserved' => sprintf('%02x', $clockSeqHi), - 'clock_seq_low' => sprintf('%02x', $clockSeq & 0xff), - 'node' => $node, - ); - - return new self($fields); + return self::getFactory()->uuid1($node, $clockSeq); } /** @@ -1011,13 +845,7 @@ final class Uuid implements UuidInterface, \JsonSerializable */ public static function uuid3($ns, $name) { - if (!($ns instanceof Uuid)) { - $ns = self::fromString($ns); - } - - $hash = md5($ns->getBytes() . $name); - - return self::uuidFromHashedName($hash, 3); + return self::getFactory()->uuid3($ns, $name); } /** @@ -1027,13 +855,7 @@ final class Uuid implements UuidInterface, \JsonSerializable */ public static function uuid4() { - $bytes = self::generateBytes(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 self::uuidFromHashedName($hex, 4); + return self::getFactory()->uuid4(); } /** @@ -1046,202 +868,6 @@ final class Uuid implements UuidInterface, \JsonSerializable */ public static function uuid5($ns, $name) { - if (!($ns instanceof Uuid)) { - $ns = self::fromString($ns); - } - - $hash = sha1($ns->getBytes() . $name); - - return self::uuidFromHashedName($hash, 5); - } - - /** - * Calculates the UUID time fields from a UNIX timestamp - * - * UUID time is a 60-bit time value as a count of 100-nanosecond intervals - * since 00:00:00.00, 15 October 1582. - * - * @param int $sec Seconds since the Unix Epoch - * @param int $usec Microseconds - * @return array - * @throws Exception\UnsatisfiedDependencyException if called on a 32-bit system and Moontoast\Math\BigNumber is not present - */ - protected static function calculateUuidTime($sec, $usec) - { - if (self::is64BitSystem()) { - - // 0x01b21dd213814000 is the number of 100-ns intervals between the - // UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00. - $uuidTime = ($sec * 10000000) + ($usec * 10) + 0x01b21dd213814000; - - return array( - 'low' => 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' - ); - } - - /** - * Returns the network interface configuration for the system - * - * @todo Needs evaluation and possibly modification to ensure this works - * well across multiple platforms. - * @codeCoverageIgnore - */ - 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; - } - - /** - * 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 - */ - 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; - } - - /** - * Returns true if the system has Moontoast\Math\BigNumber - * - * @return bool - */ - protected static function hasBigNumber() - { - return (class_exists('Moontoast\Math\BigNumber') && !self::$forceNoBigNumber); - } - - /** - * Returns true if the system has openssl_random_pseudo_bytes() - * - * @return bool - */ - protected static function hasOpensslRandomPseudoBytes() - { - return (function_exists('openssl_random_pseudo_bytes') && !self::$forceNoOpensslRandomPseudoBytes); - } - - /** - * Returns true if the system is 64-bit, false otherwise - * - * @return bool - */ - protected static function is64BitSystem() - { - return (PHP_INT_SIZE == 8 && !self::$force32Bit); - } - - /** - * Returns a version 3 or 5 UUID based on the hash (md5 or sha1) of a - * namespace identifier (which is a UUID) and a name (which is a string) - * - * @param string $hash The hash to use when creating the UUID - * @param int $version The UUID version to be generated - * @return Uuid - */ - protected static function uuidFromHashedName($hash, $version) - { - // Set the version number - $timeHi = hexdec(substr($hash, 12, 4)) & 0x0fff; - $timeHi &= ~(0xf000); - $timeHi |= $version << 12; - - // Set the variant to RFC 4122 - $clockSeqHi = hexdec(substr($hash, 16, 2)) & 0x3f; - $clockSeqHi &= ~(0xc0); - $clockSeqHi |= 0x80; - - $fields = array( - 'time_low' => substr($hash, 0, 8), - 'time_mid' => substr($hash, 8, 4), - 'time_hi_and_version' => sprintf('%04x', $timeHi), - 'clock_seq_hi_and_reserved' => sprintf('%02x', $clockSeqHi), - 'clock_seq_low' => substr($hash, 18, 2), - 'node' => substr($hash, 20, 12), - ); - - return new self($fields); - } - - /** - * Generates random bytes for use in version 4 UUIDs - * - * @param int $length - * @return string - */ - private static function generateBytes($length) - { - if (self::hasOpensslRandomPseudoBytes()) { - return openssl_random_pseudo_bytes($length); - } - - $bytes = ''; - for ($i = 1; $i <= $length; $i++) { - $bytes = chr(mt_rand(0, 255)) . $bytes; - } - - return $bytes; + return self::getFactory()->uuid5($ns, $name); } } diff --git a/src/UuidFactory.php b/src/UuidFactory.php new file mode 100644 index 0000000..44dcba4 --- /dev/null +++ b/src/UuidFactory.php @@ -0,0 +1,416 @@ + 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' + ); + } + + /** + * 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 + */ + 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; + } + + /** + * Returns the network interface configuration for the system + * + * @todo Needs evaluation and possibly modification to ensure this works + * well across multiple platforms. + * @codeCoverageIgnore + */ + 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; + } + + /** + * Returns true if the system has Moontoast\Math\BigNumber + * + * @return bool + */ + protected static function hasBigNumber() + { + return (class_exists('Moontoast\Math\BigNumber') && !self::$forceNoBigNumber); + } + + /** + * Returns true if the system is 64-bit, false otherwise + * + * @return bool + */ + protected static function is64BitSystem() + { + return (PHP_INT_SIZE == 8 && !self::$force32Bit); + } + + + /** + * Generates random bytes for use in version 4 UUIDs + * + * @param int $length + * @return string + */ + private static function generateBytes($length) + { + if (! self::$prng) { + self::$prng = (new RandomGeneratorFactory())->getGenerator(); + } + + return self::$prng->generate($length); + } + + private $codec = null; + + public function __construct(Codec $uuidCodec = null, Codec $guidCodec = null) + { + $this->codec = $uuidCodec ?: new StringCodec($this); + $this->guidCodec = $guidCodec ?: new GuidStringCodec($this); + } + + /** + * Creates a UUID from a byte string. + * + * @param string $bytes + * @return Uuid + * @throws InvalidArgumentException If the $bytes string does not contain 16 characters + */ + public function fromBytes($bytes) + { + return $this->codec->decodeBytes($this->getConverter(), $bytes); + } + + public function fromGuidBytes($bytes) + { + return $this->guidCodec->decodeBytes($this->getConverter(), $bytes); + } + + /** + * Creates a UUID from the string standard representation as described + * in the toString() method. + * + * @param string $name A string that specifies a UUID + * @param bool $littleEndian A boolean specifying whether the time_low, time_mid, time_hi_and_version are encoded in little-endian format. + * @return Uuid + * @throws InvalidArgumentException If the $name isn't a valid UUID + */ + public function fromString($name) + { + return $this->codec->decode($this->getConverter(), $name); + } + + public function fromGuidString($name) + { + return $this->guidCodec->decode($this->getConverter(), $name); + } + + public function getConverter() + { + $converter = new BigNumberConverter(); + + if (! self::hasBigNumber()) { + $converter = new UnsatisfiedNumberConverter(); + } + + 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 + * address. If $clockSeq is given, it is used as the sequence number; + * otherwise a random 14-bit sequence number is chosen. + * + * @param int|string $node A 48-bit number representing the hardware + * address. This number may be represented as + * an integer or a hexadecimal string. + * @param int $clockSeq A 14-bit number used to help avoid duplicates that + * could arise when the clock is set backwards in time + * or if the node ID changes. + * @return Uuid + * @throws InvalidArgumentException if the $node is invalid + */ + 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)); + } + + // Convert the node to hex, if it is still an integer + if (is_int($node)) { + $node = sprintf('%012x', $node); + } + + if (ctype_xdigit($node) && strlen($node) <= 12) { + $node = strtolower(sprintf('%012s', $node)); + } else { + throw new \InvalidArgumentException('Invalid node value'); + } + + if ($clockSeq === null) { + // Not using "stable storage"; see RFC 4122, Section 4.2.1.1 + $clockSeq = mt_rand(0, 1 << 14); + } + + // 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']); + + // Set the version number to 1 + $timeHi = hexdec($uuidTime['hi']) & 0x0fff; + $timeHi &= ~(0xf000); + $timeHi |= 1 << 12; + + // Set the variant to RFC 4122 + $clockSeqHi = ($clockSeq >> 8) & 0x3f; + $clockSeqHi &= ~(0xc0); + $clockSeqHi |= 0x80; + + $fields = array( + 'time_low' => $uuidTime['low'], + 'time_mid' => $uuidTime['mid'], + 'time_hi_and_version' => sprintf('%04x', $timeHi), + 'clock_seq_hi_and_reserved' => sprintf('%02x', $clockSeqHi), + 'clock_seq_low' => sprintf('%02x', $clockSeq & 0xff), + 'node' => $node, + ); + + return $this->uuid($fields); + } + + + /** + * Generate a version 3 UUID based on the MD5 hash of a namespace identifier (which + * is a UUID) and a name (which is a string). + * + * @param Uuid|string $ns The UUID namespace in which to create the named UUID + * @param string $name The name to create a UUID for + * @return Uuid + */ + public function uuid3($ns, $name) + { + if (!($ns instanceof UuidInterface)) { + $ns = $this->codec->decode($this->getConverter(), $ns); + } + + $hash = md5($ns->getBytes() . $name); + + return $this->uuidFromHashedName($hash, 3); + } + + /** + * Generate a version 4 (random) UUID. + * + * @return Uuid + */ + public function uuid4() + { + $bytes = self::generateBytes(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); + } + + /** + * Generate a version 5 UUID based on the SHA-1 hash of a namespace identifier (which + * is a UUID) and a name (which is a string). + * + * @param Uuid|string $ns The UUID namespace in which to create the named UUID + * @param string $name The name to create a UUID for + * @return Uuid + */ + public function uuid5($ns, $name) + { + if (!($ns instanceof Uuid)) { + $ns = $this->codec->decode($this->getConverter(), $ns); + } + + $hash = sha1($ns->getBytes() . $name); + + return $this->uuidFromHashedName($hash, 5); + } + + public function uuid(array $fields, Codec $codec = null) + { + $codec = $codec ?: $this->codec; + + if (! self::is64BitSystem()) { + return new SmallIntUuid($fields, $this->getConverter(), $codec); + } + + return new Uuid($fields, $this->getConverter(), $codec); + } + + /** + * Returns a version 3 or 5 UUID based on the hash (md5 or sha1) of a + * namespace identifier (which is a UUID) and a name (which is a string) + * + * @param string $hash The hash to use when creating the UUID + * @param int $version The UUID version to be generated + * @return Uuid + */ + protected function uuidFromHashedName($hash, $version) + { + // Set the version number + $timeHi = hexdec(substr($hash, 12, 4)) & 0x0fff; + $timeHi &= ~(0xf000); + $timeHi |= $version << 12; + + // Set the variant to RFC 4122 + $clockSeqHi = hexdec(substr($hash, 16, 2)) & 0x3f; + $clockSeqHi &= ~(0xc0); + $clockSeqHi |= 0x80; + + $fields = array( + 'time_low' => substr($hash, 0, 8), + 'time_mid' => substr($hash, 8, 4), + 'time_hi_and_version' => sprintf('%04x', $timeHi), + 'clock_seq_hi_and_reserved' => sprintf('%02x', $clockSeqHi), + 'clock_seq_low' => substr($hash, 18, 2), + 'node' => substr($hash, 20, 12), + ); + + return $this->uuid($fields); + } +} diff --git a/src/UuidInterface.php b/src/UuidInterface.php index f82f161..7858fee 100644 --- a/src/UuidInterface.php +++ b/src/UuidInterface.php @@ -9,6 +9,8 @@ interface UuidInterface public function equals($other); + public function getConverter(); + public function getHex(); public function getFieldsHex(); diff --git a/tests/Codec/GuidStringCodecTest.php b/tests/Codec/GuidStringCodecTest.php deleted file mode 100644 index 4187f6b..0000000 --- a/tests/Codec/GuidStringCodecTest.php +++ /dev/null @@ -1,18 +0,0 @@ -decode('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); - $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); - } -} diff --git a/tests/Codec/StringCodecTest.php b/tests/Codec/StringCodecTest.php deleted file mode 100644 index 5426b66..0000000 --- a/tests/Codec/StringCodecTest.php +++ /dev/null @@ -1,18 +0,0 @@ -decode('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); - $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); - } -} diff --git a/tests/RandomGeneratorFactoryTest.php b/tests/RandomGeneratorFactoryTest.php new file mode 100644 index 0000000..130b7eb --- /dev/null +++ b/tests/RandomGeneratorFactoryTest.php @@ -0,0 +1,24 @@ +assertNotInstanceOf('\Rhumsaa\Uuid\Generator\OpenSslGenerator', $generator); + } + + public function testFactoryReturnsOpenSslGeneratorIfAvailable() + { + RandomGeneratorFactory::$forceNoOpensslRandomPseudoBytes = false; + + $generator = RandomGeneratorFactory::getGenerator(); + + $this->assertInstanceOf('\Rhumsaa\Uuid\Generator\OpenSslGenerator', $generator); + } +} diff --git a/tests/UnsatisfiedNumberConverterTest.php b/tests/UnsatisfiedNumberConverterTest.php new file mode 100644 index 0000000..32f8a52 --- /dev/null +++ b/tests/UnsatisfiedNumberConverterTest.php @@ -0,0 +1,16 @@ +fromHex('ffff'); + } +} diff --git a/tests/UuidBcTag1_1_2Test.php b/tests/UuidBcTag1_1_2Test.php index 1cd789f..fde737c 100644 --- a/tests/UuidBcTag1_1_2Test.php +++ b/tests/UuidBcTag1_1_2Test.php @@ -21,8 +21,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::fromString - * @covers Rhumsaa\Uuid\Uuid::__construct */ public function testFromString() { @@ -32,7 +30,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::fromString */ public function testFromStringWithCurlyBraces() { @@ -42,7 +39,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::fromString * @expectedException InvalidArgumentException * @expectedExceptionMessage Invalid UUID string: */ @@ -52,7 +48,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::fromString */ public function testFromStringWithUrn() { @@ -62,7 +57,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getBytes */ public function testGetBytes() { @@ -71,7 +65,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getClockSeqHiAndReserved */ public function testGetClockSeqHiAndReserved() { @@ -80,7 +73,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getClockSeqLow */ public function testGetClockSeqLow() { @@ -89,7 +81,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getClockSequence */ public function testGetClockSequence() { @@ -98,7 +89,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getDateTime */ public function testGetDateTime() { @@ -114,8 +104,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getDateTime - * @covers Rhumsaa\Uuid\Exception\UnsupportedOperationException * @expectedException Rhumsaa\Uuid\Exception\UnsupportedOperationException * @expectedExceptionMessage Not a time-based UUID */ @@ -127,7 +115,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getFields */ public function testGetFields() { @@ -141,7 +128,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getLeastSignificantBits */ public function testGetLeastSignificantBits() { @@ -158,7 +144,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getMostSignificantBits */ public function testGetMostSignificantBits() { @@ -175,7 +160,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getNode */ public function testGetNode() { @@ -184,7 +168,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeHiAndVersion */ public function testGetTimeHiAndVersion() { @@ -193,7 +176,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeLow */ public function testGetTimeLow() { @@ -202,7 +184,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeMid */ public function testGetTimeMid() { @@ -211,7 +192,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimestamp */ public function testGetTimestamp() { @@ -225,8 +205,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimestamp - * @covers Rhumsaa\Uuid\Exception\UnsupportedOperationException * @expectedException Rhumsaa\Uuid\Exception\UnsupportedOperationException * @expectedExceptionMessage Not a time-based UUID */ @@ -238,7 +216,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getUrn */ public function testGetUrn() { @@ -247,7 +224,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForReservedNcs() { @@ -277,7 +253,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForRfc4122() { @@ -295,7 +270,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForReservedMicrosoft() { @@ -307,7 +281,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForReservedFuture() { @@ -319,7 +292,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion1() { @@ -328,7 +300,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion2() { @@ -337,7 +308,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion3() { @@ -346,7 +316,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion4() { @@ -355,7 +324,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion5() { @@ -364,8 +332,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::toString - * @covers Rhumsaa\Uuid\Uuid::__toString */ public function testToString() { @@ -381,8 +347,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 - * @covers Rhumsaa\Uuid\Uuid::getNodeFromSystem */ public function testUuid1() { @@ -394,7 +358,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 */ public function testUuid1WithNodeAndClockSequence() { @@ -409,11 +372,10 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 */ public function testUuid1WithRandomNode() { - Uuid::$ignoreSystemNode = true; + UuidFactory::$ignoreSystemNode = true; $uuid = Uuid::uuid1(); $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); @@ -427,8 +389,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase * library generates a matching UUID for the same name. * @see http://docs.python.org/library/uuid.html * - * @covers Rhumsaa\Uuid\Uuid::uuid3 - * @covers Rhumsaa\Uuid\Uuid::uuidFromHashedName */ public function testUuid3WithNamespaceAsUuidObject() { @@ -444,8 +404,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase * library generates a matching UUID for the same name. * @see http://docs.python.org/library/uuid.html * - * @covers Rhumsaa\Uuid\Uuid::uuid3 - * @covers Rhumsaa\Uuid\Uuid::uuidFromHashedName */ public function testUuid3WithNamespaceAsUuidString() { @@ -456,8 +414,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid4 - * @covers Rhumsaa\Uuid\Uuid::uuidFromHashedName */ public function testUuid4() { @@ -472,8 +428,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase * library generates a matching UUID for the same name. * @see http://docs.python.org/library/uuid.html * - * @covers Rhumsaa\Uuid\Uuid::uuid5 - * @covers Rhumsaa\Uuid\Uuid::uuidFromHashedName */ public function testUuid5WithNamespaceAsUuidObject() { @@ -489,8 +443,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase * library generates a matching UUID for the same name. * @see http://docs.python.org/library/uuid.html * - * @covers Rhumsaa\Uuid\Uuid::uuid5 - * @covers Rhumsaa\Uuid\Uuid::uuidFromHashedName */ public function testUuid5WithNamespaceAsUuidString() { @@ -501,7 +453,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::compareTo */ public function testCompareTo() { @@ -530,7 +481,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::equals */ public function testEquals() { diff --git a/tests/UuidFactoryTest.php b/tests/UuidFactoryTest.php new file mode 100644 index 0000000..c53d757 --- /dev/null +++ b/tests/UuidFactoryTest.php @@ -0,0 +1,24 @@ +fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); + + $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); + } + + public function testParsesGuidCorrectly() + { + $factory = new UuidFactory(); + + $uuid = $factory->fromGuidString('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 a601b20..c7e8f2e 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -1,20 +1,21 @@ skipIfNoMoontoastMath(); - Uuid::$force32Bit = true; + UuidFactory::$force32Bit = true; // Check a recent date $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); @@ -188,21 +176,22 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getDateTime * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetDateTimeThrownException() { - Uuid::$force32Bit = true; - Uuid::$forceNoBigNumber = true; + UuidFactory::$force32Bit = true; + UuidFactory::$forceNoBigNumber = true; $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); + + $this->assertInstanceOf('Rhumsaa\Uuid\SmallIntUuid', $uuid); + $this->assertInstanceOf('Rhumsaa\Uuid\UnsatisfiedNumberConverter', $uuid->getConverter()); + $date = $uuid->getDateTime(); } /** - * @covers Rhumsaa\Uuid\Uuid::getDateTime - * @covers Rhumsaa\Uuid\Exception\UnsupportedOperationException * @expectedException Rhumsaa\Uuid\Exception\UnsupportedOperationException * @expectedExceptionMessage Not a time-based UUID */ @@ -214,7 +203,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getFields */ public function testGetFields() { @@ -235,18 +223,16 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getFields * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetFields32Bit() { - Uuid::$force32Bit = true; + UuidFactory::$force32Bit = true; $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $fields = $uuid->getFields(); } /** - * @covers Rhumsaa\Uuid\Uuid::getFieldsHex */ public function testGetFieldsHex() { @@ -265,7 +251,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getLeastSignificantBits */ public function testGetLeastSignificantBits() { @@ -277,18 +262,16 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getLeastSignificantBits * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetLeastSignificantBitsException() { - Uuid::$forceNoBigNumber = true; + UuidFactory::$forceNoBigNumber = true; $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $bn = $uuid->getLeastSignificantBits(); } /** - * @covers Rhumsaa\Uuid\Uuid::getLeastSignificantBitsHex */ public function testGetLeastSignificantBitsHex() { @@ -297,7 +280,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getMostSignificantBits */ public function testGetMostSignificantBits() { @@ -309,18 +291,16 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getMostSignificantBits * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetMostSignificantBitsException() { - Uuid::$forceNoBigNumber = true; + UuidFactory::$forceNoBigNumber = true; $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $bn = $uuid->getMostSignificantBits(); } /** - * @covers Rhumsaa\Uuid\Uuid::getMostSignificantBitsHex */ public function testGetMostSignificantBitsHex() { @@ -329,7 +309,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getNode */ public function testGetNode() { @@ -340,18 +319,16 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getNode * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetNode32Bit() { - Uuid::$force32Bit = true; + UuidFactory::$force32Bit = true; $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $node = $uuid->getNode(); } /** - * @covers Rhumsaa\Uuid\Uuid::getNodeHex */ public function testGetNodeHex() { @@ -360,7 +337,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeHiAndVersion */ public function testGetTimeHiAndVersion() { @@ -369,7 +345,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeHiAndVersionHex */ public function testGetTimeHiAndVersionHex() { @@ -378,7 +353,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeLow */ public function testGetTimeLow() { @@ -389,18 +363,16 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeLow * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetTimeLow32Bit() { - Uuid::$force32Bit = true; + UuidFactory::$force32Bit = true; $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $timeLow = $uuid->getTimeLow(); } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeLowHex */ public function testGetTimeLowHex() { @@ -409,7 +381,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeMid */ public function testGetTimeMid() { @@ -418,7 +389,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeMidHex */ public function testGetTimeMidHex() { @@ -427,7 +397,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimestamp */ public function testGetTimestamp() { @@ -443,7 +412,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimestampHex */ public function testGetTimestampHex() { @@ -457,8 +425,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimestamp - * @covers Rhumsaa\Uuid\Exception\UnsupportedOperationException * @expectedException Rhumsaa\Uuid\Exception\UnsupportedOperationException * @expectedExceptionMessage Not a time-based UUID */ @@ -470,8 +436,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimestampHex - * @covers Rhumsaa\Uuid\Exception\UnsupportedOperationException * @expectedException Rhumsaa\Uuid\Exception\UnsupportedOperationException * @expectedExceptionMessage Not a time-based UUID */ @@ -483,18 +447,16 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimestamp * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetTimestamp32Bit() { - Uuid::$force32Bit = true; + UuidFactory::$force32Bit = true; $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $ts = $uuid->getTimestamp(); } /** - * @covers Rhumsaa\Uuid\Uuid::getUrn */ public function testGetUrn() { @@ -503,7 +465,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForReservedNcs() { @@ -533,7 +494,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForRfc4122() { @@ -551,7 +511,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForReservedMicrosoft() { @@ -563,7 +522,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForReservedFuture() { @@ -575,7 +533,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion1() { @@ -584,7 +541,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion2() { @@ -593,7 +549,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion3() { @@ -602,7 +557,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion4() { @@ -611,7 +565,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion5() { @@ -620,8 +573,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::toString - * @covers Rhumsaa\Uuid\Uuid::__toString */ public function testToString() { @@ -637,8 +588,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 - * @covers Rhumsaa\Uuid\Uuid::getNodeFromSystem */ public function testUuid1() { @@ -650,7 +599,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 */ public function testUuid1WithNodeAndClockSequence() { @@ -667,7 +615,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 */ public function testUuid1WithHexadecimalNode() { @@ -685,7 +632,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 */ public function testUuid1WithMixedCaseHexadecimalNode() { @@ -703,7 +649,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 */ public function testUuid1WithNodeAndClockSequence32Bit() { @@ -722,7 +667,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 * @expectedException InvalidArgumentException * @expectedExceptionMessage Invalid node value */ @@ -732,7 +676,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 * @expectedException InvalidArgumentException * @expectedExceptionMessage Invalid node value */ @@ -742,7 +685,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 * @expectedException InvalidArgumentException * @expectedExceptionMessage Invalid node value */ @@ -751,12 +693,9 @@ class UuidTest extends TestCase $uuid = Uuid::uuid1('db77e160355ef'); } - /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 - */ public function testUuid1WithRandomNode() { - Uuid::$ignoreSystemNode = true; + UuidFactory::$ignoreSystemNode = true; $uuid = Uuid::uuid1(); $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); @@ -770,8 +709,6 @@ class UuidTest extends TestCase * library generates a matching UUID for the same name. * @see http://docs.python.org/library/uuid.html * - * @covers Rhumsaa\Uuid\Uuid::uuid3 - * @covers Rhumsaa\Uuid\Uuid::uuidFromHashedName */ public function testUuid3WithNamespaceAsUuidObject() { @@ -787,8 +724,6 @@ class UuidTest extends TestCase * library generates a matching UUID for the same name. * @see http://docs.python.org/library/uuid.html * - * @covers Rhumsaa\Uuid\Uuid::uuid3 - * @covers Rhumsaa\Uuid\Uuid::uuidFromHashedName */ public function testUuid3WithNamespaceAsUuidString() { @@ -804,7 +739,6 @@ class UuidTest extends TestCase * Taken from the Python UUID tests in * http://hg.python.org/cpython/file/2f4c4db9aee5/Lib/test/test_uuid.py * - * @covers Rhumsaa\Uuid\Uuid::uuid3 */ public function testUuid3WithKnownUuids() { @@ -824,9 +758,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid4 - * @covers Rhumsaa\Uuid\Uuid::generateBytes - * @covers Rhumsaa\Uuid\Uuid::uuidFromHashedName */ public function testUuid4() { @@ -837,13 +768,10 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid4 - * @covers Rhumsaa\Uuid\Uuid::generateBytes - * @covers Rhumsaa\Uuid\Uuid::uuidFromHashedName */ public function testUuid4WithoutOpensslRandomPseudoBytes() { - Uuid::$forceNoOpensslRandomPseudoBytes = true; + RandomGeneratorFactory::$forceNoOpensslRandomPseudoBytes = true; $uuid = Uuid::uuid4(); $this->assertInstanceOf('Rhumsaa\Uuid\Uuid', $uuid); $this->assertEquals(2, $uuid->getVariant()); @@ -855,8 +783,6 @@ class UuidTest extends TestCase * library generates a matching UUID for the same name. * @see http://docs.python.org/library/uuid.html * - * @covers Rhumsaa\Uuid\Uuid::uuid5 - * @covers Rhumsaa\Uuid\Uuid::uuidFromHashedName */ public function testUuid5WithNamespaceAsUuidObject() { @@ -872,8 +798,6 @@ class UuidTest extends TestCase * library generates a matching UUID for the same name. * @see http://docs.python.org/library/uuid.html * - * @covers Rhumsaa\Uuid\Uuid::uuid5 - * @covers Rhumsaa\Uuid\Uuid::uuidFromHashedName */ public function testUuid5WithNamespaceAsUuidString() { @@ -889,7 +813,6 @@ class UuidTest extends TestCase * Taken from the Python UUID tests in * http://hg.python.org/cpython/file/2f4c4db9aee5/Lib/test/test_uuid.py * - * @covers Rhumsaa\Uuid\Uuid::uuid5 */ public function testUuid5WithKnownUuids() { @@ -909,7 +832,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::compareTo */ public function testCompareTo() { @@ -938,7 +860,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::equals */ public function testEquals() { @@ -953,8 +874,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 - * @covers Rhumsaa\Uuid\Uuid::calculateUuidTime */ public function testCalculateUuidTime() { @@ -966,7 +885,7 @@ class UuidTest extends TestCase ); // For usec = 277885 - Uuid::$timeOfDayTest = $timeOfDay; + UuidFactory::$timeOfDayTest = $timeOfDay; $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c4dbe7e2-097f-11e2-9669-00007ffffffe', (string) $uuidA); @@ -975,7 +894,7 @@ class UuidTest extends TestCase $this->assertEquals('11e2', $uuidA->getTimeHiAndVersionHex()); // For usec = 0 - Uuid::$timeOfDayTest['usec'] = 0; + UuidFactory::$timeOfDayTest['usec'] = 0; $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c4b18100-097f-11e2-9669-00007ffffffe', (string) $uuidB); @@ -984,7 +903,7 @@ class UuidTest extends TestCase $this->assertEquals('11e2', $uuidB->getTimeHiAndVersionHex()); // For usec = 999999 - Uuid::$timeOfDayTest['usec'] = 999999; + UuidFactory::$timeOfDayTest['usec'] = 999999; $uuidC = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c54a1776-097f-11e2-9669-00007ffffffe', (string) $uuidC); @@ -994,13 +913,11 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 - * @covers Rhumsaa\Uuid\Uuid::calculateUuidTime */ public function testCalculateUuidTimeForce32BitPath() { $this->skipIfNoMoontoastMath(); - Uuid::$force32Bit = true; + UuidFactory::$force32Bit = true; $timeOfDay = array( 'sec' => 1348845514, @@ -1010,7 +927,7 @@ class UuidTest extends TestCase ); // For usec = 277885 - Uuid::$timeOfDayTest = $timeOfDay; + UuidFactory::$timeOfDayTest = $timeOfDay; $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c4dbe7e2-097f-11e2-9669-00007ffffffe', (string) $uuidA); @@ -1019,7 +936,7 @@ class UuidTest extends TestCase $this->assertEquals('11e2', $uuidA->getTimeHiAndVersionHex()); // For usec = 0 - Uuid::$timeOfDayTest['usec'] = 0; + UuidFactory::$timeOfDayTest['usec'] = 0; $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c4b18100-097f-11e2-9669-00007ffffffe', (string) $uuidB); @@ -1028,7 +945,7 @@ class UuidTest extends TestCase $this->assertEquals('11e2', $uuidB->getTimeHiAndVersionHex()); // For usec = 999999 - Uuid::$timeOfDayTest['usec'] = 999999; + UuidFactory::$timeOfDayTest['usec'] = 999999; $uuidC = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c54a1776-097f-11e2-9669-00007ffffffe', (string) $uuidC); @@ -1038,8 +955,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 - * @covers Rhumsaa\Uuid\Uuid::calculateUuidTime */ public function testCalculateUuidTimeUpperLowerBounds64Bit() { @@ -1053,7 +968,7 @@ class UuidTest extends TestCase 'dsttime' => 0, ); - Uuid::$timeOfDayTest = $timeOfDay; + UuidFactory::$timeOfDayTest = $timeOfDay; $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('ff9785f6-ffff-1fff-9669-00007ffffffe', (string) $uuidA); @@ -1069,7 +984,7 @@ class UuidTest extends TestCase 'dsttime' => 0, ); - Uuid::$timeOfDayTest = $timeOfDay; + UuidFactory::$timeOfDayTest = $timeOfDay; $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('00000000-0000-1000-9669-00007ffffffe', (string) $uuidB); @@ -1082,15 +997,13 @@ class UuidTest extends TestCase * This test ensures that the UUIDs generated by the 32-bit path match * those generated by the 64-bit path, given the same 64-bit time values. * - * @covers Rhumsaa\Uuid\Uuid::uuid1 - * @covers Rhumsaa\Uuid\Uuid::calculateUuidTime */ public function testCalculateUuidTimeUpperLowerBounds64BitThrough32BitPath() { $this->skipIfNoMoontoastMath(); $this->skip64BitTest(); - Uuid::$force32Bit = true; + UuidFactory::$force32Bit = true; // 5235-03-31T21:20:59+00:00 $timeOfDay = array( @@ -1100,7 +1013,7 @@ class UuidTest extends TestCase 'dsttime' => 0, ); - Uuid::$timeOfDayTest = $timeOfDay; + UuidFactory::$timeOfDayTest = $timeOfDay; $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('ff9785f6-ffff-1fff-9669-00007ffffffe', (string) $uuidA); @@ -1116,7 +1029,7 @@ class UuidTest extends TestCase 'dsttime' => 0, ); - Uuid::$timeOfDayTest = $timeOfDay; + UuidFactory::$timeOfDayTest = $timeOfDay; $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('00000000-0000-1000-9669-00007ffffffe', (string) $uuidB); @@ -1126,13 +1039,11 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 - * @covers Rhumsaa\Uuid\Uuid::calculateUuidTime */ public function testCalculateUuidTimeUpperLowerBounds32Bit() { $this->skipIfNoMoontoastMath(); - Uuid::$force32Bit = true; + UuidFactory::$force32Bit = true; // 2038-01-19T03:14:07+00:00 $timeOfDay = array( @@ -1142,7 +1053,7 @@ class UuidTest extends TestCase 'dsttime' => 0, ); - Uuid::$timeOfDayTest = $timeOfDay; + UuidFactory::$timeOfDayTest = $timeOfDay; $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('13813ff6-6912-11fe-9669-00007ffffffe', (string) $uuidA); @@ -1158,7 +1069,7 @@ class UuidTest extends TestCase 'dsttime' => 0, ); - Uuid::$timeOfDayTest = $timeOfDay; + UuidFactory::$timeOfDayTest = $timeOfDay; $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('1419d680-d292-1165-9669-00007ffffffe', (string) $uuidB); @@ -1171,8 +1082,6 @@ class UuidTest extends TestCase * This test ensures that the UUIDs generated by the 64-bit path match * those generated by the 32-bit path, given the same 32-bit time values. * - * @covers Rhumsaa\Uuid\Uuid::uuid1 - * @covers Rhumsaa\Uuid\Uuid::calculateUuidTime */ public function testCalculateUuidTimeUpperLowerBounds32BitThrough64BitPath() { @@ -1186,7 +1095,7 @@ class UuidTest extends TestCase 'dsttime' => 0, ); - Uuid::$timeOfDayTest = $timeOfDay; + UuidFactory::$timeOfDayTest = $timeOfDay; $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('13813ff6-6912-11fe-9669-00007ffffffe', (string) $uuidA); @@ -1202,7 +1111,7 @@ class UuidTest extends TestCase 'dsttime' => 0, ); - Uuid::$timeOfDayTest = $timeOfDay; + UuidFactory::$timeOfDayTest = $timeOfDay; $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('1419d680-d292-1165-9669-00007ffffffe', (string) $uuidB); @@ -1234,12 +1143,12 @@ class UuidTest extends TestCase 'dsttime' => 0, ); - Uuid::$timeOfDayTest = $timeOfDay; + UuidFactory::$timeOfDayTest = $timeOfDay; - Uuid::$force32Bit = true; + UuidFactory::$force32Bit = true; $uuid32 = Uuid::uuid1(0x00007ffffffe, 0x1669); - Uuid::$force32Bit = false; + UuidFactory::$force32Bit = false; $uuid64 = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertTrue( @@ -1258,79 +1167,17 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::calculateUuidTime * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException */ public function testCalculateUuidTimeThrownException() { - Uuid::$force32Bit = true; - Uuid::$forceNoBigNumber = true; + UuidFactory::$force32Bit = true; + UuidFactory::$forceNoBigNumber = true; $uuid = Uuid::uuid1(0x00007ffffffe, 0x1669); } /** - * @covers Rhumsaa\Uuid\Uuid::hasBigNumber - */ - public function testHasBigNumber() - { - $this->skipIfNoMoontoastMath(); - - $hasBigNumber = new \ReflectionMethod( - 'Rhumsaa\Uuid\Uuid', 'hasBigNumber' - ); - $hasBigNumber->setAccessible(true); - - $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - - $this->assertTrue($hasBigNumber->invoke($uuid)); - - Uuid::$forceNoBigNumber = true; - $this->assertFalse($hasBigNumber->invoke($uuid)); - } - - /** - * @covers Rhumsaa\Uuid\Uuid::hasOpensslRandomPseudoBytes - */ - public function testHasOpensslRandomPseudoBytes() - { - $hasOpensslRandomPseudoBytes = new \ReflectionMethod( - 'Rhumsaa\Uuid\Uuid', 'hasOpensslRandomPseudoBytes' - ); - $hasOpensslRandomPseudoBytes->setAccessible(true); - - $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - - $this->assertTrue($hasOpensslRandomPseudoBytes->invoke($uuid)); - - Uuid::$forceNoOpensslRandomPseudoBytes = true; - $this->assertFalse($hasOpensslRandomPseudoBytes->invoke($uuid)); - } - - /** - * @covers Rhumsaa\Uuid\Uuid::is64BitSystem - */ - public function testIs64BitSystem() - { - $is64BitSystem = new \ReflectionMethod( - 'Rhumsaa\Uuid\Uuid', 'is64BitSystem' - ); - $is64BitSystem->setAccessible(true); - - $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - - if (PHP_INT_SIZE == 8) { - $this->assertTrue($is64BitSystem->invoke($uuid)); - } else { - $this->assertFalse($is64BitSystem->invoke($uuid)); - } - - Uuid::$force32Bit = true; - $this->assertFalse($is64BitSystem->invoke($uuid)); - } - - /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidGoodVersion1() { @@ -1339,7 +1186,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidGoodVersion2() { @@ -1348,7 +1194,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidGoodVersion3() { @@ -1357,7 +1202,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidGoodVersion4() { @@ -1366,7 +1210,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidGoodVersion5() { @@ -1375,7 +1218,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidGoodUpperCase() { @@ -1384,7 +1226,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidBadHex() { @@ -1393,7 +1234,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidTooShort1() { @@ -1402,7 +1242,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidTooShort2() { @@ -1411,7 +1250,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidNoDashes() { @@ -1420,7 +1258,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidTooLong() { @@ -1429,7 +1266,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testUsingNilAsValidUuid() { @@ -1438,7 +1274,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::fromBytes */ public function testFromBytes() { @@ -1471,7 +1306,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::fromBytes * @expectedException InvalidArgumentException */ public function testFromBytesArgumentTooShort() @@ -1480,7 +1314,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::fromBytes * @expectedException InvalidArgumentException */ public function testFromBytesArgumentTooLong() @@ -1522,25 +1355,6 @@ class UuidTest extends TestCase * Taken from the Python UUID tests in * http://hg.python.org/cpython/file/2f4c4db9aee5/Lib/test/test_uuid.py * - * @covers Rhumsaa\Uuid\Uuid::fromString - * @covers Rhumsaa\Uuid\Uuid::fromBytes - * @covers Rhumsaa\Uuid\Uuid::fromInteger - * @covers Rhumsaa\Uuid\Uuid::toString - * @covers Rhumsaa\Uuid\Uuid::getBytes - * @covers Rhumsaa\Uuid\Uuid::getFieldsHex - * @covers Rhumsaa\Uuid\Uuid::getHex - * @covers Rhumsaa\Uuid\Uuid::getInteger - * @covers Rhumsaa\Uuid\Uuid::getTimeLowHex - * @covers Rhumsaa\Uuid\Uuid::getTimeMidHex - * @covers Rhumsaa\Uuid\Uuid::getTimeHiAndVersionHex - * @covers Rhumsaa\Uuid\Uuid::getClockSeqHiAndReservedHex - * @covers Rhumsaa\Uuid\Uuid::getClockSeqLowHex - * @covers Rhumsaa\Uuid\Uuid::getNodeHex - * @covers Rhumsaa\Uuid\Uuid::getUrn - * @covers Rhumsaa\Uuid\Uuid::getTimestampHex - * @covers Rhumsaa\Uuid\Uuid::getClockSequenceHex - * @covers Rhumsaa\Uuid\Uuid::getVariant - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testUuidPassesPythonTests() { @@ -1863,13 +1677,12 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getInteger * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException - * @expectedExceptionMessage Cannot call Rhumsaa\Uuid\Uuid::getInteger without support for large integers + * @expectedExceptionMessage Cannot call Rhumsaa\Uuid\UnsatisfiedNumberConverter::fromHex without support for large integers */ public function testGetInteger() { - Uuid::$forceNoBigNumber = true; + UuidFactory::$forceNoBigNumber = true; $uuid = Uuid::uuid1(); $uuid->getInteger(); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 50e981f..7c57d53 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -17,3 +17,9 @@ $loader = include realpath(dirname(__FILE__) . '/../vendor/autoload.php'); $loader->add("Doctrine\Tests\DBAL", __DIR__."/../vendor/doctrine/dbal/tests"); $loader->addPsr4('Rhumsaa\\Uuid\\', __DIR__); + +register_shutdown_function(function() { + if ($error = error_get_last()) { + var_dump($error); + } +});