From c7daee6c6a582110a1d60bb482a9644202d3c7a2 Mon Sep 17 00:00:00 2001 From: Dan van Kley Date: Mon, 7 Apr 2014 11:14:56 -0400 Subject: [PATCH 01/54] Remove "final" keyword to allow extending --- src/Uuid.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Uuid.php b/src/Uuid.php index 40c2587..a08d511 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -29,7 +29,7 @@ use InvalidArgumentException; * @link http://docs.python.org/3/library/uuid.html * @link http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html */ -final class Uuid +class Uuid { /** * When this namespace is specified, the name string is a fully-qualified domain name. From 45c34cd7097bcf6e416932e2fc08ccae96abc465 Mon Sep 17 00:00:00 2001 From: Greg Brown Date: Tue, 22 Jul 2014 23:20:43 -0700 Subject: [PATCH 02/54] require 5.4 and add JsonSerializable --- .gitignore | 1 + composer.json | 2 +- src/Uuid.php | 15 ++++++++++++++- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index de2b378..0a59599 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.idea/ *.phar .DS_Store build diff --git a/composer.json b/composer.json index 8adc973..30de67e 100644 --- a/composer.json +++ b/composer.json @@ -20,7 +20,7 @@ "source": "https://github.com/ramsey/uuid" }, "require": { - "php": ">=5.3.3" + "php": ">=5.4" }, "require-dev": { "moontoast/math": "~1.1", diff --git a/src/Uuid.php b/src/Uuid.php index 40c2587..3f8a349 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -29,7 +29,7 @@ use InvalidArgumentException; * @link http://docs.python.org/3/library/uuid.html * @link http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html */ -final class Uuid +final class Uuid implements \JsonSerializable { /** * When this namespace is specified, the name string is a fully-qualified domain name. @@ -175,6 +175,19 @@ final class Uuid return $this->toString(); } + /** + * Converts this UUID object to a string when the object is serialized + * with json_encode() + * + * @link http://php.net/manual/en/class.jsonserializable.php + * + * @return string + */ + public function jsonSerialize() + { + return $this->toString(); + } + /** * Compares this UUID with the specified UUID. * From f85eb9f69d39cfb03946d794fdc4776ca1187cf1 Mon Sep 17 00:00:00 2001 From: Greg Brown Date: Thu, 24 Jul 2014 22:29:46 -0700 Subject: [PATCH 03/54] require 5.4 and add JsonSerializable -on branch - prep for pr --- .travis.yml | 1 - README.md | 2 +- composer.json | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 40ce721..4ec0096 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,7 +1,6 @@ language: php php: - - 5.3 - 5.4 - 5.5 - 5.6 diff --git a/README.md b/README.md index 776b722..893b025 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ## About -Rhumsaa\Uuid is a PHP 5.3+ library for generating and working with +Rhumsaa\Uuid is a PHP 5.4+ library for generating and working with [RFC 4122][rfc4122] version 1, 3, 4, and 5 universally unique identifiers (UUID). From [Wikipedia](http://en.wikipedia.org/wiki/Universally_unique_identifier): diff --git a/composer.json b/composer.json index 30de67e..9edc26b 100644 --- a/composer.json +++ b/composer.json @@ -1,6 +1,6 @@ { "name": "rhumsaa/uuid", - "description": "A PHP 5.3+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", + "description": "A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", "type": "library", "keywords": ["uuid", "identifier", "guid"], "homepage": "https://github.com/ramsey/uuid", From 6af68ccfa197455ec8ec2880de446efd325b36eb Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Mon, 28 Jul 2014 13:03:11 -0500 Subject: [PATCH 04/54] Set package version to 3.0.x-dev --- composer.json | 2 +- src/Uuid.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 4e2c627..f590cc2 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ }, "extra": { "branch-alias": { - "dev-master": "2.8.x-dev" + "dev-master": "3.0.x-dev" } } } diff --git a/src/Uuid.php b/src/Uuid.php index 107b0ba..29fd08f 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -93,7 +93,7 @@ final class Uuid /** * Version of the Rhumsaa\Uuid package */ - const VERSION = '2.8.x-dev'; + const VERSION = '3.0.x-dev'; /** * For testing, 64-bit system override; if true, treat the system as 32-bit From a0544fe71bc8e19109b981c802f1fecf0bb04022 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Thu, 30 Oct 2014 00:39:01 -0500 Subject: [PATCH 05/54] Updating README to use version 3.0 in Composer install example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 55ef92d..850acd7 100644 --- a/README.md +++ b/README.md @@ -91,7 +91,7 @@ the following command to install the package and add it as a requirement to `composer.json`: ```bash -composer.phar require "rhumsaa/uuid=~2.8" +composer.phar require "rhumsaa/uuid=~3.0" ``` From 750801f4f5bce5373e47fbc01bee3adef7d846a1 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Thu, 30 Oct 2014 01:05:28 -0500 Subject: [PATCH 06/54] Fixing the copyright years to coincide with the first release --- LICENSE | 2 +- bin/uuid | 2 +- src/Console/Application.php | 2 +- src/Console/Command/DecodeCommand.php | 2 +- src/Console/Command/GenerateCommand.php | 2 +- src/Console/Exception.php | 2 +- src/Console/Util/ErrorHandler.php | 2 +- src/Doctrine/UuidType.php | 2 +- src/Exception/UnsatisfiedDependencyException.php | 2 +- src/Exception/UnsupportedOperationException.php | 2 +- src/Uuid.php | 2 +- 11 files changed, 11 insertions(+), 11 deletions(-) diff --git a/LICENSE b/LICENSE index 923e880..fcea456 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013-2014 Ben Ramsey +Copyright (c) 2012-2014 Ben Ramsey Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/bin/uuid b/bin/uuid index ddfdc61..7f8f654 100755 --- a/bin/uuid +++ b/bin/uuid @@ -6,7 +6,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * - * @copyright Copyright (c) 2013-2014 Ben Ramsey + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ diff --git a/src/Console/Application.php b/src/Console/Application.php index ddeff64..2356286 100644 --- a/src/Console/Application.php +++ b/src/Console/Application.php @@ -5,7 +5,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * - * @copyright Copyright (c) 2013-2014 Ben Ramsey + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ diff --git a/src/Console/Command/DecodeCommand.php b/src/Console/Command/DecodeCommand.php index 0c1758f..d0caad1 100644 --- a/src/Console/Command/DecodeCommand.php +++ b/src/Console/Command/DecodeCommand.php @@ -5,7 +5,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * - * @copyright Copyright (c) 2013-2014 Ben Ramsey + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ diff --git a/src/Console/Command/GenerateCommand.php b/src/Console/Command/GenerateCommand.php index a4c6604..4dc20a9 100644 --- a/src/Console/Command/GenerateCommand.php +++ b/src/Console/Command/GenerateCommand.php @@ -5,7 +5,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * - * @copyright Copyright (c) 2013-2014 Ben Ramsey + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ diff --git a/src/Console/Exception.php b/src/Console/Exception.php index aefef0d..2fa6da5 100644 --- a/src/Console/Exception.php +++ b/src/Console/Exception.php @@ -5,7 +5,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * - * @copyright Copyright (c) 2013-2014 Ben Ramsey + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ diff --git a/src/Console/Util/ErrorHandler.php b/src/Console/Util/ErrorHandler.php index fe4d90a..8797a44 100644 --- a/src/Console/Util/ErrorHandler.php +++ b/src/Console/Util/ErrorHandler.php @@ -5,7 +5,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * - * @copyright Copyright (c) 2013-2014 Ben Ramsey + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ diff --git a/src/Doctrine/UuidType.php b/src/Doctrine/UuidType.php index ffecee8..b6b1974 100644 --- a/src/Doctrine/UuidType.php +++ b/src/Doctrine/UuidType.php @@ -5,7 +5,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * - * @copyright Copyright (c) 2013-2014 Ben Ramsey + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ diff --git a/src/Exception/UnsatisfiedDependencyException.php b/src/Exception/UnsatisfiedDependencyException.php index e402837..32985d5 100644 --- a/src/Exception/UnsatisfiedDependencyException.php +++ b/src/Exception/UnsatisfiedDependencyException.php @@ -5,7 +5,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * - * @copyright Copyright (c) 2013-2014 Ben Ramsey + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ diff --git a/src/Exception/UnsupportedOperationException.php b/src/Exception/UnsupportedOperationException.php index e9eed08..493abde 100644 --- a/src/Exception/UnsupportedOperationException.php +++ b/src/Exception/UnsupportedOperationException.php @@ -5,7 +5,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * - * @copyright Copyright (c) 2013-2014 Ben Ramsey + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ diff --git a/src/Uuid.php b/src/Uuid.php index c5a9e52..01976e9 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -5,7 +5,7 @@ * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. * - * @copyright Copyright (c) 2013-2014 Ben Ramsey + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ From b28029fbc7850228d11871708d5117f6980fac04 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Fri, 17 Oct 2014 16:52:56 +0200 Subject: [PATCH 07/54] Add support for MS GUIDs --- src/Uuid.php | 52 +++++++++++++++++++++++++++++++++------------- tests/UuidTest.php | 37 +++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 15 deletions(-) diff --git a/src/Uuid.php b/src/Uuid.php index 01976e9..821b105 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -149,6 +149,12 @@ class Uuid implements \JsonSerializable 'node' => '000000000000', ); + /** + * Whether the first three fields are stored in little endian format (GUID's) + * @var bool + */ + protected $isLittleEndian; + /** * Creates a universally unique identifier (UUID) from an array of fields. * @@ -156,11 +162,13 @@ class Uuid implements \JsonSerializable * UUIDs. * * @param array $fields + * @param bool $littleEndian Whether the first three fields are in little-endian format. * @link Rhumsaa.Uuid.Uuid.html#method_getFields */ - protected function __construct(array $fields) + protected function __construct(array $fields, $littleEndian = false) { $this->fields = $fields; + $this->isLittleEndian = (bool)$littleEndian; } /** @@ -445,7 +453,7 @@ class Uuid implements \JsonSerializable */ public function getHex() { - return str_replace('-', '', $this->toString()); + return str_replace('-', '', $this->toString(true)); } /** @@ -834,11 +842,20 @@ class Uuid implements \JsonSerializable * * @return string */ - public function toString() + public function toString($forceBigEndian = false) { + $fields = array_values($this->fields); + + if ($this->isLittleEndian && $forceBigEndian == false) { + // Swap byte-order on the first three fields + $fields[0] = unpack('H*', pack('V', hexdec($fields[0])))[1]; + $fields[1] = unpack('H*', pack('v', hexdec($fields[1])))[1]; + $fields[2] = unpack('H*', pack('v', hexdec($fields[2])))[1]; + } + return vsprintf( '%08s-%04s-%04s-%02s%02s-%012s', - $this->fields + $fields ); } @@ -849,22 +866,18 @@ class Uuid implements \JsonSerializable * @return Uuid * @throws InvalidArgumentException If the $bytes string does not contain 16 characters */ - public static function fromBytes($bytes) + public static function fromBytes($bytes, $littleEndian = false) { if (strlen($bytes) !== 16) { throw new InvalidArgumentException('$bytes string should contain 16 characters.'); } - $uuid = ''; - foreach (range(0, 15) as $step) { - $uuid .= sprintf('%02x', ord($bytes[$step])); + $hexUuid = unpack('H*', $bytes); - if (in_array($step, array(3, 5, 7, 9))) { - $uuid .= '-'; - } - } + $uuid = Uuid::fromString($hexUuid[1], false); + $uuid->isLittleEndian = $littleEndian; - return Uuid::fromString($uuid); + return $uuid; } /** @@ -872,10 +885,11 @@ class Uuid implements \JsonSerializable * 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 static function fromString($name) + public static function fromString($name, $littleEndian = false) { $nameParsed = str_replace(array('urn:', 'uuid:', '{', '}', '-'), '', $name); @@ -889,6 +903,14 @@ class Uuid implements \JsonSerializable substr($nameParsed, 16, 4), substr($nameParsed, 20), ); + + // Swap byte-order on the first three fields + if ($littleEndian) { + $components[0] = unpack('H*', pack('V', hexdec($components[0])))[1]; + $components[1] = unpack('H*', pack('v', hexdec($components[1])))[1]; + $components[2] = unpack('H*', pack('v', hexdec($components[2])))[1]; + } + $nameParsed = implode('-', $components); if (!self::isValid($nameParsed)) { @@ -904,7 +926,7 @@ class Uuid implements \JsonSerializable 'node' => sprintf('%012s', $components[4]), ); - return new self($fields); + return new self($fields, $littleEndian); } /** diff --git a/tests/UuidTest.php b/tests/UuidTest.php index 8be8b26..fe56804 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -23,6 +23,21 @@ class UuidTest extends TestCase $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); } + /** + * @covers Rhumsaa\Uuid\Uuid::fromString + */ + public function testFromLittleEndianString() + { + $uuid = Uuid::fromString('b08c6fff-7dc5-e111-9b21-0800200c9a66'); + $guid = Uuid::fromString('b08c6fff-7dc5-e111-9b21-0800200c9a66', true); + + $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $guid); + // UUID's and GUID's share the same textual representation + $this->assertEquals($uuid->toString(), $guid->toString()); + // But not the same binary representation + $this->assertNotEquals(bin2hex($uuid->getBytes()), bin2hex($guid->getBytes())); + } + /** * @covers Rhumsaa\Uuid\Uuid::fromString */ @@ -1435,6 +1450,28 @@ class UuidTest extends TestCase $this->assertTrue($uuid->equals($fromBytesUuid)); } + public function testFromLittleEndianBytes() + { + // Check that parsing BE bytes as LE reverses fields + $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); + $bytes = $uuid->getBytes(); + + $guid = Uuid::fromBytes($bytes, true); + + // First three fields should be reversed + $this->assertEquals('b08c6fff-7dc5-e111-9b21-0800200c9a66', $guid->toString()); + // Except if forcing big endian + $this->assertEquals($uuid->toString(), $guid->toString(true)); + + // Check that parsing LE bytes as LE preserves fields + $guid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', true); + $bytes = $guid->getBytes(); + + $parsedGuid = Uuid::fromBytes($bytes, true); + + $this->assertEquals($guid->toString(), $parsedGuid->toString()); + } + /** * @covers Rhumsaa\Uuid\Uuid::fromBytes * @expectedException InvalidArgumentException From 0650b46d0eb61b95a3403e5f8336f1057d5cb531 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Fri, 17 Oct 2014 17:00:21 +0200 Subject: [PATCH 08/54] Remove non PHP 5.3 syntax --- src/Uuid.php | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/Uuid.php b/src/Uuid.php index 821b105..a5bed74 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -848,9 +848,12 @@ class Uuid implements \JsonSerializable if ($this->isLittleEndian && $forceBigEndian == false) { // Swap byte-order on the first three fields - $fields[0] = unpack('H*', pack('V', hexdec($fields[0])))[1]; - $fields[1] = unpack('H*', pack('v', hexdec($fields[1])))[1]; - $fields[2] = unpack('H*', pack('v', hexdec($fields[2])))[1]; + $hex = unpack('H*', pack('V', hexdec($fields[0]))); + $fields[0] = $hex[1]; + $hex = unpack('H*', pack('v', hexdec($fields[1]))); + $fields[1] = $hex[1]; + $hex = unpack('H*', pack('v', hexdec($fields[2]))); + $fields[2] = $hex[1]; } return vsprintf( @@ -906,9 +909,12 @@ class Uuid implements \JsonSerializable // Swap byte-order on the first three fields if ($littleEndian) { - $components[0] = unpack('H*', pack('V', hexdec($components[0])))[1]; - $components[1] = unpack('H*', pack('v', hexdec($components[1])))[1]; - $components[2] = unpack('H*', pack('v', hexdec($components[2])))[1]; + $hex = unpack('H*', pack('V', hexdec($components[0]))); + $components[0] = $hex[1]; + $hex = unpack('H*', pack('v', hexdec($components[1]))); + $components[1] = $hex[1]; + $hex = unpack('H*', pack('v', hexdec($components[2]))); + $components[2] = $hex[1]; } $nameParsed = implode('-', $components); From 65916f292844f27c046ba35c58a49e61f85b598f Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Fri, 17 Oct 2014 17:49:49 +0200 Subject: [PATCH 09/54] Set default timezone in PHPUnit bootstrap to pass HHVM tests --- tests/bootstrap.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 786bef2..72c9c19 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -9,6 +9,11 @@ if (!file_exists(dirname(__DIR__) . '/vendor/autoload.php')) { . "See http://getcomposer.org for help with installing composer\n"); } +var_dump(phpversion()); + +// Set a default timezone for HHVM tests +date_default_timezone_set('UTC'); + // Include the Composer autoloader $loader = include realpath(dirname(__FILE__) . '/../vendor/autoload.php'); From 13b3bf7ed9a4ca026a6ed972a585ba68c33c50b5 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Thu, 30 Oct 2014 09:53:43 +0100 Subject: [PATCH 10/54] Refactor from/toString methods to codecs --- src/Codec.php | 12 ++++ src/Codec/GuidStringCodec.php | 93 +++++++++++++++++++++++++++++ src/Codec/StringCodec.php | 72 ++++++++++++++++++++++ src/Uuid.php | 85 ++++++-------------------- src/UuidInterface.php | 46 ++++++++++++++ tests/Codec/GuidStringCodecTest.php | 18 ++++++ tests/Codec/StringCodecTest.php | 18 ++++++ tests/bootstrap.php | 2 - 8 files changed, 276 insertions(+), 70 deletions(-) create mode 100644 src/Codec.php create mode 100644 src/Codec/GuidStringCodec.php create mode 100644 src/Codec/StringCodec.php create mode 100644 src/UuidInterface.php create mode 100644 tests/Codec/GuidStringCodecTest.php create mode 100644 tests/Codec/StringCodecTest.php diff --git a/src/Codec.php b/src/Codec.php new file mode 100644 index 0000000..0e045c7 --- /dev/null +++ b/src/Codec.php @@ -0,0 +1,12 @@ +getFieldsHex()); + + // Swap byte-order on the first three fields + $hex = unpack('H*', pack('V', hexdec($fields[0]))); + $fields[0] = $hex[1]; + $hex = unpack('H*', pack('v', hexdec($fields[1]))); + $fields[1] = $hex[1]; + $hex = unpack('H*', pack('v', hexdec($fields[2]))); + $fields[2] = $hex[1]; + + return vsprintf( + '%08s-%04s-%04s-%02s%02s-%012s', + $fields + ); + } + + public function decode($encodedUuid) + { + return $this->_decode($encodedUuid, true); + } + + public function decodeBytes($bytes) + { + if (strlen($bytes) !== 16) { + throw new InvalidArgumentException('$bytes string should contain 16 characters.'); + } + + $hexUuid = unpack('H*', $bytes); + + return $this->_decode($hexUuid, false); + } + + private function _decode($hex, $swap) + { + $nameParsed = str_replace(array( + 'urn:', + 'uuid:', + '{', + '}', + '-' + ), '', $hex); + + // We have stripped out the dashes and are breaking up the string using + // substr(). In this way, we can accept a full hex value that doesn't + // contain dashes. + $components = array( + substr($nameParsed, 0, 8), + substr($nameParsed, 8, 4), + substr($nameParsed, 12, 4), + substr($nameParsed, 16, 4), + substr($nameParsed, 20) + ); + + if ($swap) { + $hex = unpack('H*', pack('V', hexdec($components[0]))); + $components[0] = $hex[1]; + $hex = unpack('H*', pack('v', hexdec($components[1]))); + $components[1] = $hex[1]; + $hex = unpack('H*', pack('v', hexdec($components[2]))); + $components[2] = $hex[1]; + $nameParsed = implode('-', $components); + } + + if (! Uuid::isValid($nameParsed)) { + throw new InvalidArgumentException('Invalid UUID string: ' . $name); + } + + $fields = array( + 'time_low' => sprintf('%08s', $components[0]), + 'time_mid' => sprintf('%04s', $components[1]), + 'time_hi_and_version' => sprintf('%04s', $components[2]), + 'clock_seq_hi_and_reserved' => sprintf('%02s', substr($components[3], 0, 2)), + 'clock_seq_low' => sprintf('%02s', substr($components[3], 2)), + 'node' => sprintf('%012s', $components[4]) + ); + + return new Uuid($fields, $this); + } +} diff --git a/src/Codec/StringCodec.php b/src/Codec/StringCodec.php new file mode 100644 index 0000000..a65f108 --- /dev/null +++ b/src/Codec/StringCodec.php @@ -0,0 +1,72 @@ +getFieldsHex()); + + return vsprintf( + '%08s-%04s-%04s-%02s%02s-%012s', + $fields + ); + } + + public function decode($encodedUuid) + { + $nameParsed = str_replace(array( + 'urn:', + 'uuid:', + '{', + '}', + '-' + ), '', $encodedUuid); + + // We have stripped out the dashes and are breaking up the string using + // substr(). In this way, we can accept a full hex value that doesn't + // contain dashes. + $components = array( + substr($nameParsed, 0, 8), + substr($nameParsed, 8, 4), + substr($nameParsed, 12, 4), + substr($nameParsed, 16, 4), + substr($nameParsed, 20) + ); + + $nameParsed = implode('-', $components); + + if (! Uuid::isValid($nameParsed)) { + throw new InvalidArgumentException('Invalid UUID string: ' . $name); + } + + $fields = array( + 'time_low' => sprintf('%08s', $components[0]), + 'time_mid' => sprintf('%04s', $components[1]), + 'time_hi_and_version' => sprintf('%04s', $components[2]), + 'clock_seq_hi_and_reserved' => sprintf('%02s', substr($components[3], 0, 2)), + 'clock_seq_low' => sprintf('%02s', substr($components[3], 2)), + 'node' => sprintf('%012s', $components[4]) + ); + + return new Uuid($fields, $this); + } + + public function decodeBytes($bytes) + { + if (strlen($bytes) !== 16) { + throw new InvalidArgumentException('$bytes string should contain 16 characters.'); + } + + $hexUuid = unpack('H*', $bytes); + + return $this->decode($hexUuid); + } +} diff --git a/src/Uuid.php b/src/Uuid.php index a5bed74..4cdbddc 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -12,6 +12,8 @@ namespace Rhumsaa\Uuid; use InvalidArgumentException; +use Rhumsaa\Uuid\Codec\GuidStringCodec; +use Rhumsaa\Uuid\Codec\StringCodec; /** * Represents a universally unique identifier (UUID), according to RFC 4122 @@ -29,7 +31,8 @@ use InvalidArgumentException; * @link http://docs.python.org/3/library/uuid.html * @link http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html */ -class Uuid implements \JsonSerializable + +final class Uuid implements UuidInterface, \JsonSerializable { /** * When this namespace is specified, the name string is a fully-qualified domain name. @@ -150,10 +153,10 @@ class Uuid implements \JsonSerializable ); /** - * Whether the first three fields are stored in little endian format (GUID's) - * @var bool + * String codec + * @var Codec */ - protected $isLittleEndian; + protected $codec; /** * Creates a universally unique identifier (UUID) from an array of fields. @@ -162,13 +165,13 @@ class Uuid implements \JsonSerializable * UUIDs. * * @param array $fields - * @param bool $littleEndian Whether the first three fields are in little-endian format. + * @param Codec $codec String codec * @link Rhumsaa.Uuid.Uuid.html#method_getFields */ - protected function __construct(array $fields, $littleEndian = false) + public function __construct(array $fields, Codec $codec = null) { $this->fields = $fields; - $this->isLittleEndian = (bool)$littleEndian; + $this->codec = $codec ?: new StringCodec(); } /** @@ -209,7 +212,7 @@ class Uuid implements \JsonSerializable * @param Uuid $uuid UUID to which this UUID is to be compared * @return int -1, 0 or 1 as this UUID is less than, equal to, or greater than $uuid */ - public function compareTo(Uuid $uuid) + public function compareTo(UuidInterface $uuid) { $comparison = null; @@ -844,22 +847,7 @@ class Uuid implements \JsonSerializable */ public function toString($forceBigEndian = false) { - $fields = array_values($this->fields); - - if ($this->isLittleEndian && $forceBigEndian == false) { - // Swap byte-order on the first three fields - $hex = unpack('H*', pack('V', hexdec($fields[0]))); - $fields[0] = $hex[1]; - $hex = unpack('H*', pack('v', hexdec($fields[1]))); - $fields[1] = $hex[1]; - $hex = unpack('H*', pack('v', hexdec($fields[2]))); - $fields[2] = $hex[1]; - } - - return vsprintf( - '%08s-%04s-%04s-%02s%02s-%012s', - $fields - ); + return $this->codec->encode($this); } /** @@ -871,16 +859,11 @@ class Uuid implements \JsonSerializable */ public static function fromBytes($bytes, $littleEndian = false) { - if (strlen($bytes) !== 16) { - throw new InvalidArgumentException('$bytes string should contain 16 characters.'); + if ($littleEndian) { + return (new GuidStringCodec())->decodeBytes($bytes); } - $hexUuid = unpack('H*', $bytes); - - $uuid = Uuid::fromString($hexUuid[1], false); - $uuid->isLittleEndian = $littleEndian; - - return $uuid; + return (new StringCodec())->decodeBytes($bytes); } /** @@ -894,45 +877,11 @@ class Uuid implements \JsonSerializable */ public static function fromString($name, $littleEndian = false) { - $nameParsed = str_replace(array('urn:', 'uuid:', '{', '}', '-'), '', $name); - - // We have stripped out the dashes and are breaking up the string using - // substr(). In this way, we can accept a full hex value that doesn't - // contain dashes. - $components = array( - substr($nameParsed, 0, 8), - substr($nameParsed, 8, 4), - substr($nameParsed, 12, 4), - substr($nameParsed, 16, 4), - substr($nameParsed, 20), - ); - - // Swap byte-order on the first three fields if ($littleEndian) { - $hex = unpack('H*', pack('V', hexdec($components[0]))); - $components[0] = $hex[1]; - $hex = unpack('H*', pack('v', hexdec($components[1]))); - $components[1] = $hex[1]; - $hex = unpack('H*', pack('v', hexdec($components[2]))); - $components[2] = $hex[1]; + return (new GuidStringCodec())->decode($name); } - $nameParsed = implode('-', $components); - - if (!self::isValid($nameParsed)) { - throw new InvalidArgumentException('Invalid UUID string: ' . $name); - } - - $fields = array( - 'time_low' => sprintf('%08s', $components[0]), - 'time_mid' => sprintf('%04s', $components[1]), - 'time_hi_and_version' => sprintf('%04s', $components[2]), - 'clock_seq_hi_and_reserved' => sprintf('%02s', substr($components[3], 0, 2)), - 'clock_seq_low' => sprintf('%02s', substr($components[3], 2)), - 'node' => sprintf('%012s', $components[4]), - ); - - return new self($fields, $littleEndian); + return (new StringCodec())->decode($name); } /** diff --git a/src/UuidInterface.php b/src/UuidInterface.php new file mode 100644 index 0000000..d268ff2 --- /dev/null +++ b/src/UuidInterface.php @@ -0,0 +1,46 @@ +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 new file mode 100644 index 0000000..5426b66 --- /dev/null +++ b/tests/Codec/StringCodecTest.php @@ -0,0 +1,18 @@ +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/bootstrap.php b/tests/bootstrap.php index 72c9c19..50e981f 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -9,8 +9,6 @@ if (!file_exists(dirname(__DIR__) . '/vendor/autoload.php')) { . "See http://getcomposer.org for help with installing composer\n"); } -var_dump(phpversion()); - // Set a default timezone for HHVM tests date_default_timezone_set('UTC'); From 723ef345bf759e4c7ae49a948a1680d51e39b0fa Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Thu, 30 Oct 2014 10:16:22 +0100 Subject: [PATCH 11/54] Refactor factory functions Remove $littleEndian parameter Add fromGuidString/Bytes factory methods for GUIDs No longer possible to output GUIDs as UUIDs and vice-versa Pass tests --- src/Codec.php | 4 +++- src/Codec/GuidStringCodec.php | 14 +++++++++++--- src/Codec/StringCodec.php | 15 +++++++++++++-- src/Uuid.php | 32 ++++++++++++++------------------ src/UuidInterface.php | 2 ++ tests/UuidTest.php | 10 ++++------ 6 files changed, 47 insertions(+), 30 deletions(-) diff --git a/src/Codec.php b/src/Codec.php index 0e045c7..9912851 100644 --- a/src/Codec.php +++ b/src/Codec.php @@ -4,7 +4,9 @@ namespace Rhumsaa\Uuid; interface Codec { - public function encode(UuidInterface $plainUuid); + public function encode(UuidInterface $uuid); + + public function encodeBinary(UuidInterface $uuid); public function decode($encodedUuid); diff --git a/src/Codec/GuidStringCodec.php b/src/Codec/GuidStringCodec.php index a8afb25..1e03e6e 100644 --- a/src/Codec/GuidStringCodec.php +++ b/src/Codec/GuidStringCodec.php @@ -28,6 +28,13 @@ class GuidStringCodec implements Codec ); } + public function encodeBinary(UuidInterface $uuid) + { + $reversed = $this->_decode($this->encode($uuid), false); + + return (new StringCodec())->encodeBinary($reversed); + } + public function decode($encodedUuid) { return $this->_decode($encodedUuid, true); @@ -41,7 +48,7 @@ class GuidStringCodec implements Codec $hexUuid = unpack('H*', $bytes); - return $this->_decode($hexUuid, false); + return $this->_decode($hexUuid[1], false); } private function _decode($hex, $swap) @@ -72,11 +79,12 @@ class GuidStringCodec implements Codec $components[1] = $hex[1]; $hex = unpack('H*', pack('v', hexdec($components[2]))); $components[2] = $hex[1]; - $nameParsed = implode('-', $components); } + $nameParsed = implode('-', $components); + if (! Uuid::isValid($nameParsed)) { - throw new InvalidArgumentException('Invalid UUID string: ' . $name); + throw new InvalidArgumentException('Invalid UUID string: ' . $hex); } $fields = array( diff --git a/src/Codec/StringCodec.php b/src/Codec/StringCodec.php index a65f108..b787a6e 100644 --- a/src/Codec/StringCodec.php +++ b/src/Codec/StringCodec.php @@ -20,6 +20,17 @@ class StringCodec implements Codec ); } + public function encodeBinary(UuidInterface $uuid) + { + $bytes = ''; + + foreach (range(-2, -32, 2) as $step) { + $bytes = chr(hexdec(substr($uuid->getHex(), $step, 2))) . $bytes; + } + + return $bytes; + } + public function decode($encodedUuid) { $nameParsed = str_replace(array( @@ -44,7 +55,7 @@ class StringCodec implements Codec $nameParsed = implode('-', $components); if (! Uuid::isValid($nameParsed)) { - throw new InvalidArgumentException('Invalid UUID string: ' . $name); + throw new InvalidArgumentException('Invalid UUID string: ' . $encodedUuid); } $fields = array( @@ -67,6 +78,6 @@ class StringCodec implements Codec $hexUuid = unpack('H*', $bytes); - return $this->decode($hexUuid); + return $this->decode($hexUuid[1]); } } diff --git a/src/Uuid.php b/src/Uuid.php index 4cdbddc..3cc6d69 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -258,13 +258,7 @@ final class Uuid implements UuidInterface, \JsonSerializable */ public function getBytes() { - $bytes = ''; - - foreach (range(-2, -32, 2) as $step) { - $bytes = chr(hexdec(substr($this->getHex(), $step, 2))) . $bytes; - } - - return $bytes; + return $this->codec->encodeBinary($this); } /** @@ -845,7 +839,7 @@ final class Uuid implements UuidInterface, \JsonSerializable * * @return string */ - public function toString($forceBigEndian = false) + public function toString() { return $this->codec->encode($this); } @@ -857,15 +851,16 @@ final class Uuid implements UuidInterface, \JsonSerializable * @return Uuid * @throws InvalidArgumentException If the $bytes string does not contain 16 characters */ - public static function fromBytes($bytes, $littleEndian = false) + public static function fromBytes($bytes) { - if ($littleEndian) { - return (new GuidStringCodec())->decodeBytes($bytes); - } - return (new StringCodec())->decodeBytes($bytes); } + public static function fromGuidBytes($bytes) + { + return (new GuidStringCodec())->decodeBytes($bytes); + } + /** * Creates a UUID from the string standard representation as described * in the toString() method. @@ -875,15 +870,16 @@ final class Uuid implements UuidInterface, \JsonSerializable * @return Uuid * @throws InvalidArgumentException If the $name isn't a valid UUID */ - public static function fromString($name, $littleEndian = false) + public static function fromString($name) { - if ($littleEndian) { - return (new GuidStringCodec())->decode($name); - } - return (new StringCodec())->decode($name); } + public static function fromGuidString($name) + { + return (new GuidStringCodec())->decode($name); + } + /** * Creates a UUID from either the UUID as a 128-bit integer string or a Moontoast\Math\BigNumber object. * diff --git a/src/UuidInterface.php b/src/UuidInterface.php index d268ff2..f82f161 100644 --- a/src/UuidInterface.php +++ b/src/UuidInterface.php @@ -9,6 +9,8 @@ interface UuidInterface public function equals($other); + public function getHex(); + public function getFieldsHex(); public function getClockSeqHiAndReservedHex(); diff --git a/tests/UuidTest.php b/tests/UuidTest.php index fe56804..a601b20 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -29,7 +29,7 @@ class UuidTest extends TestCase public function testFromLittleEndianString() { $uuid = Uuid::fromString('b08c6fff-7dc5-e111-9b21-0800200c9a66'); - $guid = Uuid::fromString('b08c6fff-7dc5-e111-9b21-0800200c9a66', true); + $guid = Uuid::fromGuidString('b08c6fff-7dc5-e111-9b21-0800200c9a66'); $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $guid); // UUID's and GUID's share the same textual representation @@ -1456,18 +1456,16 @@ class UuidTest extends TestCase $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $bytes = $uuid->getBytes(); - $guid = Uuid::fromBytes($bytes, true); + $guid = Uuid::fromGuidBytes($bytes); // First three fields should be reversed $this->assertEquals('b08c6fff-7dc5-e111-9b21-0800200c9a66', $guid->toString()); - // Except if forcing big endian - $this->assertEquals($uuid->toString(), $guid->toString(true)); // Check that parsing LE bytes as LE preserves fields - $guid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', true); + $guid = Uuid::fromGuidString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $bytes = $guid->getBytes(); - $parsedGuid = Uuid::fromBytes($bytes, true); + $parsedGuid = Uuid::fromGuidBytes($bytes); $this->assertEquals($guid->toString(), $parsedGuid->toString()); } From fead6f3223688c087b3e5e0e4c7456172ee5424b Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Thu, 30 Oct 2014 13:16:19 +0100 Subject: [PATCH 12/54] 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); + } +}); From 053a25f335f8e2ee0fb3cb0b9a84a631fd1f0047 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Thu, 30 Oct 2014 13:41:17 +0100 Subject: [PATCH 13/54] Remove 5.3 build & debug info --- tests/bootstrap.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 7c57d53..50e981f 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -17,9 +17,3 @@ $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); - } -}); From 653349f4907be7b8deb487f45a28f292dc39a5d6 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Thu, 30 Oct 2014 15:26:30 +0100 Subject: [PATCH 14/54] Remove final keyword (rebase error...) --- src/Uuid.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Uuid.php b/src/Uuid.php index 82abc22..1a56aca 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -32,7 +32,7 @@ use Rhumsaa\Uuid\Codec\StringCodec; * @link http://docs.oracle.com/javase/6/docs/api/java/util/UUID.html */ -final class Uuid implements UuidInterface, \JsonSerializable +class Uuid implements UuidInterface, \JsonSerializable { /** * When this namespace is specified, the name string is a fully-qualified domain name. From cd3e58b1f59d156db318ba9937332473ddb17562 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Thu, 30 Oct 2014 16:07:48 +0100 Subject: [PATCH 15/54] Refactor fromInteger method to use factory --- src/BigNumberConverter.php | 9 +++++++++ src/UnsatisfiedNumberConverter.php | 9 +++++++++ src/Uuid.php | 17 +---------------- src/UuidFactory.php | 8 ++++++++ tests/UuidTest.php | 3 --- 5 files changed, 27 insertions(+), 19 deletions(-) diff --git a/src/BigNumberConverter.php b/src/BigNumberConverter.php index 349ea33..0e1b3fd 100644 --- a/src/BigNumberConverter.php +++ b/src/BigNumberConverter.php @@ -10,4 +10,13 @@ class BigNumberConverter return new \Moontoast\Math\BigNumber($number); } + + public function toHex($integer) + { + if (!$integer instanceof \Moontoast\Math\BigNumber) { + $integer = new \Moontoast\Math\BigNumber($integer); + } + + return \Moontoast\Math\BigNumber::baseConvert($integer, 10, 16); + } } diff --git a/src/UnsatisfiedNumberConverter.php b/src/UnsatisfiedNumberConverter.php index e6b7119..cc933b3 100644 --- a/src/UnsatisfiedNumberConverter.php +++ b/src/UnsatisfiedNumberConverter.php @@ -13,4 +13,13 @@ class UnsatisfiedNumberConverter extends BigNumberConverter . '; consider calling an hex based method instead' ); } + + public function toHex($integer) + { + 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. ' + ); + } } diff --git a/src/Uuid.php b/src/Uuid.php index 1a56aca..3a0a614 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -777,22 +777,7 @@ class Uuid implements UuidInterface, \JsonSerializable */ public static function fromInteger($integer) { - 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. ' - ); - } - - if (!$integer instanceof \Moontoast\Math\BigNumber) { - $integer = new \Moontoast\Math\BigNumber($integer); - } - - $hex = \Moontoast\Math\BigNumber::baseConvert($integer, 10, 16); - $hex = str_pad($hex, 32, '0', STR_PAD_LEFT); - - return self::fromString($hex); + return self::getFactory()->fromInteger($integer); } /** diff --git a/src/UuidFactory.php b/src/UuidFactory.php index 44dcba4..f2dd6a5 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -230,6 +230,14 @@ class UuidFactory return $this->guidCodec->decode($this->getConverter(), $name); } + public function fromInteger($integer) + { + $hex = $this->getConverter()->toHex($integer); + $hex = str_pad($hex, 32, '0', STR_PAD_LEFT); + + return $this->fromString($hex); + } + public function getConverter() { $converter = new BigNumberConverter(); diff --git a/tests/UuidTest.php b/tests/UuidTest.php index c7e8f2e..f330690 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -1322,7 +1322,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::fromInteger */ public function testFromIntegerBigNumber() { @@ -1335,7 +1334,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::fromInteger */ public function testFromIntegerString() { @@ -1347,7 +1345,6 @@ class UuidTest extends TestCase $this->assertTrue($uuid->equals($fromIntegerUuid)); } - /** * This test ensures that Rhumsaa\Uuid passes the same test cases * as the Python UUID library. From f97c9e08f993f8bfbe1f2ef9a870e81fa481172b Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Thu, 6 Nov 2014 10:42:02 +0100 Subject: [PATCH 16/54] Rename degraded feature classes with more consistent names --- ...verter.php => DegradedNumberConverter.php} | 2 +- src/{SmallIntUuid.php => DegradedUuid.php} | 2 +- src/UuidFactory.php | 4 +-- tests/DegradedNumberConverterTest.php | 26 +++++++++++++++++++ tests/UnsatisfiedNumberConverterTest.php | 16 ------------ tests/UuidTest.php | 6 ++--- 6 files changed, 33 insertions(+), 23 deletions(-) rename src/{UnsatisfiedNumberConverter.php => DegradedNumberConverter.php} (92%) rename src/{SmallIntUuid.php => DegradedUuid.php} (99%) create mode 100644 tests/DegradedNumberConverterTest.php delete mode 100644 tests/UnsatisfiedNumberConverterTest.php diff --git a/src/UnsatisfiedNumberConverter.php b/src/DegradedNumberConverter.php similarity index 92% rename from src/UnsatisfiedNumberConverter.php rename to src/DegradedNumberConverter.php index cc933b3..7950cca 100644 --- a/src/UnsatisfiedNumberConverter.php +++ b/src/DegradedNumberConverter.php @@ -2,7 +2,7 @@ namespace Rhumsaa\Uuid; -class UnsatisfiedNumberConverter extends BigNumberConverter +class DegradedNumberConverter extends BigNumberConverter { public function fromHex($hex) { diff --git a/src/SmallIntUuid.php b/src/DegradedUuid.php similarity index 99% rename from src/SmallIntUuid.php rename to src/DegradedUuid.php index 17effc7..7f11acc 100644 --- a/src/SmallIntUuid.php +++ b/src/DegradedUuid.php @@ -2,7 +2,7 @@ namespace Rhumsaa\Uuid; -class SmallIntUuid extends Uuid +class DegradedUuid extends Uuid { public function __construct(array $fields, BigNumberConverter $converter, Codec $codec) diff --git a/src/UuidFactory.php b/src/UuidFactory.php index f2dd6a5..e70d0b2 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -243,7 +243,7 @@ class UuidFactory $converter = new BigNumberConverter(); if (! self::hasBigNumber()) { - $converter = new UnsatisfiedNumberConverter(); + $converter = new DegradedNumberConverter(); } return $converter; @@ -384,7 +384,7 @@ class UuidFactory $codec = $codec ?: $this->codec; if (! self::is64BitSystem()) { - return new SmallIntUuid($fields, $this->getConverter(), $codec); + return new DegradedUuid($fields, $this->getConverter(), $codec); } return new Uuid($fields, $this->getConverter(), $codec); diff --git a/tests/DegradedNumberConverterTest.php b/tests/DegradedNumberConverterTest.php new file mode 100644 index 0000000..8f14ceb --- /dev/null +++ b/tests/DegradedNumberConverterTest.php @@ -0,0 +1,26 @@ +fromHex('ffff'); + } + + /** + * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + */ + public function testConvertingToHexThrowsException() + { + $converter = new DegradedNumberConverter(); + + $converter->toHex(0); + } +} diff --git a/tests/UnsatisfiedNumberConverterTest.php b/tests/UnsatisfiedNumberConverterTest.php deleted file mode 100644 index 32f8a52..0000000 --- a/tests/UnsatisfiedNumberConverterTest.php +++ /dev/null @@ -1,16 +0,0 @@ -fromHex('ffff'); - } -} diff --git a/tests/UuidTest.php b/tests/UuidTest.php index f330690..7858abb 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -185,8 +185,8 @@ class UuidTest extends TestCase $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertInstanceOf('Rhumsaa\Uuid\SmallIntUuid', $uuid); - $this->assertInstanceOf('Rhumsaa\Uuid\UnsatisfiedNumberConverter', $uuid->getConverter()); + $this->assertInstanceOf('Rhumsaa\Uuid\DegradedUuid', $uuid); + $this->assertInstanceOf('Rhumsaa\Uuid\DegradedNumberConverter', $uuid->getConverter()); $date = $uuid->getDateTime(); } @@ -1675,7 +1675,7 @@ class UuidTest extends TestCase /** * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException - * @expectedExceptionMessage Cannot call Rhumsaa\Uuid\UnsatisfiedNumberConverter::fromHex without support for large integers + * @expectedExceptionMessage Cannot call Rhumsaa\Uuid\DegradedNumberConverter::fromHex without support for large integers */ public function testGetInteger() { From 84123b206031ec81cd51317502bb991d3533ba02 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sat, 8 Nov 2014 12:41:40 +0100 Subject: [PATCH 17/54] 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(); From c07988fe317b41b2328dcdd78cd4be304e948e67 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sat, 8 Nov 2014 15:00:58 +0100 Subject: [PATCH 18/54] Refactor codecs to remove duplication --- src/Codec/GuidStringCodec.php | 95 +++++++------------------------ src/Codec/StringCodec.php | 60 +++++++++++-------- src/FeatureSet.php | 2 +- src/Node/FallbackNodeProvider.php | 2 +- src/Uuid.php | 1 + src/UuidFactory.php | 11 ++-- tests/UuidTest.php | 13 +++-- 7 files changed, 70 insertions(+), 114 deletions(-) diff --git a/src/Codec/GuidStringCodec.php b/src/Codec/GuidStringCodec.php index e290b03..ec9e5bd 100644 --- a/src/Codec/GuidStringCodec.php +++ b/src/Codec/GuidStringCodec.php @@ -3,112 +3,57 @@ namespace Rhumsaa\Uuid\Codec; use InvalidArgumentException; -use Rhumsaa\Uuid\Codec; use Rhumsaa\Uuid\UuidInterface; use Rhumsaa\Uuid\Uuid; use Rhumsaa\Uuid\BigNumberConverter; use Rhumsaa\Uuid\UuidFactory; use Rhumsaa\Uuid\UuidBuilder; +use Rhumsaa\Uuid\Codec; -class GuidStringCodec implements Codec +class GuidStringCodec extends StringCodec { - private $builder; - - private $uuidCodec; - - public function __construct(UuidBuilder $builder, Codec $uuidCodec) - { - $this->builder = $builder; - $this->uuidCodec = $uuidCodec; - } - public function encode(UuidInterface $uuid) { - $fields = array_values($uuid->getFieldsHex()); + $components = array_values($uuid->getFieldsHex()); // Swap byte-order on the first three fields - $hex = unpack('H*', pack('V', hexdec($fields[0]))); - $fields[0] = $hex[1]; - $hex = unpack('H*', pack('v', hexdec($fields[1]))); - $fields[1] = $hex[1]; - $hex = unpack('H*', pack('v', hexdec($fields[2]))); - $fields[2] = $hex[1]; + $this->swapFields($components); return vsprintf( '%08s-%04s-%04s-%02s%02s-%012s', - $fields + $components ); } public function encodeBinary(UuidInterface $uuid) { - $reversed = $this->_decode($this->encode($uuid), false); + $components = array_values($uuid->getFieldsHex()); - return $this->uuidCodec->encodeBinary($reversed); + return hex2bin(implode('', $components)); } public function decode($encodedUuid) { - return $this->_decode($encodedUuid, true); + $components = $this->extractComponents($encodedUuid); + + $this->swapFields($components); + + return $this->getBuilder()->build($this, $this->getFields($components)); } public function decodeBytes($bytes) { - if (strlen($bytes) !== 16) { - throw new InvalidArgumentException('$bytes string should contain 16 characters.'); - } - - $hexUuid = unpack('H*', $bytes); - - return $this->_decode($hexUuid[1], false); + return parent::decode(bin2hex($bytes)); } - private function _decode($hex, $swap) + protected function swapFields(array & $components) { - $nameParsed = str_replace(array( - 'urn:', - 'uuid:', - '{', - '}', - '-' - ), '', $hex); - - // We have stripped out the dashes and are breaking up the string using - // substr(). In this way, we can accept a full hex value that doesn't - // contain dashes. - $components = array( - substr($nameParsed, 0, 8), - substr($nameParsed, 8, 4), - substr($nameParsed, 12, 4), - substr($nameParsed, 16, 4), - substr($nameParsed, 20) - ); - - if ($swap) { - $hex = unpack('H*', pack('V', hexdec($components[0]))); - $components[0] = $hex[1]; - $hex = unpack('H*', pack('v', hexdec($components[1]))); - $components[1] = $hex[1]; - $hex = unpack('H*', pack('v', hexdec($components[2]))); - $components[2] = $hex[1]; - } - - $nameParsed = implode('-', $components); - - if (! Uuid::isValid($nameParsed)) { - throw new InvalidArgumentException('Invalid UUID string: ' . $hex); - } - - $fields = array( - 'time_low' => sprintf('%08s', $components[0]), - 'time_mid' => sprintf('%04s', $components[1]), - 'time_hi_and_version' => sprintf('%04s', $components[2]), - 'clock_seq_hi_and_reserved' => sprintf('%02s', substr($components[3], 0, 2)), - 'clock_seq_low' => sprintf('%02s', substr($components[3], 2)), - 'node' => sprintf('%012s', $components[4]) - ); - - return $this->builder->build($this, $fields); + $hex = unpack('H*', pack('V', hexdec($components[0]))); + $components[0] = $hex[1]; + $hex = unpack('H*', pack('v', hexdec($components[1]))); + $components[1] = $hex[1]; + $hex = unpack('H*', pack('v', hexdec($components[2]))); + $components[2] = $hex[1]; } } diff --git a/src/Codec/StringCodec.php b/src/Codec/StringCodec.php index ce451de..3147f81 100644 --- a/src/Codec/StringCodec.php +++ b/src/Codec/StringCodec.php @@ -3,12 +3,12 @@ namespace Rhumsaa\Uuid\Codec; use InvalidArgumentException; -use Rhumsaa\Uuid\Codec; -use Rhumsaa\Uuid\UuidInterface; -use Rhumsaa\Uuid\Uuid; use Rhumsaa\Uuid\BigNumberConverter; -use Rhumsaa\Uuid\UuidFactory; +use Rhumsaa\Uuid\Codec; +use Rhumsaa\Uuid\Uuid; use Rhumsaa\Uuid\UuidBuilder; +use Rhumsaa\Uuid\UuidInterface; +use Rhumsaa\Uuid\UuidFactory; class StringCodec implements Codec { @@ -32,16 +32,34 @@ class StringCodec implements Codec public function encodeBinary(UuidInterface $uuid) { - $bytes = ''; - - foreach (range(-2, -32, 2) as $step) { - $bytes = chr(hexdec(substr($uuid->getHex(), $step, 2))) . $bytes; - } - - return $bytes; + return hex2bin($uuid->getHex()); } public function decode($encodedUuid) + { + $components = $this->extractComponents($encodedUuid); + $fields = $this->getFields($components); + + return $this->builder->build($this, $fields); + } + + public function decodeBytes($bytes) + { + if (strlen($bytes) !== 16) { + throw new InvalidArgumentException('$bytes string should contain 16 characters.'); + } + + $hexUuid = unpack('H*', $bytes); + + return $this->decode($hexUuid[1]); + } + + protected function getBuilder() + { + return $this->builder; + } + + protected function extractComponents($encodedUuid) { $nameParsed = str_replace(array( 'urn:', @@ -68,7 +86,12 @@ class StringCodec implements Codec throw new InvalidArgumentException('Invalid UUID string: ' . $encodedUuid); } - $fields = array( + return $components; + } + + protected function getFields(array $components) + { + return array( 'time_low' => sprintf('%08s', $components[0]), 'time_mid' => sprintf('%04s', $components[1]), 'time_hi_and_version' => sprintf('%04s', $components[2]), @@ -76,18 +99,5 @@ class StringCodec implements Codec 'clock_seq_low' => sprintf('%02s', substr($components[3], 2)), 'node' => sprintf('%012s', $components[4]) ); - - return $this->builder->build($this, $fields); - } - - public function decodeBytes($bytes) - { - if (strlen($bytes) !== 16) { - throw new InvalidArgumentException('$bytes string should contain 16 characters.'); - } - - $hexUuid = unpack('H*', $bytes); - - return $this->decode($hexUuid[1]); } } diff --git a/src/FeatureSet.php b/src/FeatureSet.php index 7709ad1..bd6c31e 100644 --- a/src/FeatureSet.php +++ b/src/FeatureSet.php @@ -96,7 +96,7 @@ class FeatureSet protected function buildCodec($useGuids = false) { if ($useGuids) { - return new GuidStringCodec($this->builder, $this->buildCodec(false)); + return new GuidStringCodec($this->builder); } return new StringCodec($this->builder); diff --git a/src/Node/FallbackNodeProvider.php b/src/Node/FallbackNodeProvider.php index 947ca9a..dbfbe30 100644 --- a/src/Node/FallbackNodeProvider.php +++ b/src/Node/FallbackNodeProvider.php @@ -4,7 +4,7 @@ namespace Rhumsaa\Uuid\Node; use Rhumsaa\Uuid\NodeProvider; -class FallbackNodeProvider +class FallbackNodeProvider implements NodeProvider { private $nodeProviders; diff --git a/src/Uuid.php b/src/Uuid.php index b5bf67b..8332c2d 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -787,6 +787,7 @@ class Uuid implements UuidInterface, \JsonSerializable if (!preg_match('/' . self::VALID_PATTERN . '/', $uuid)) { return false; } + return true; } diff --git a/src/UuidFactory.php b/src/UuidFactory.php index 6138e09..2f66f0c 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -21,12 +21,6 @@ class UuidFactory */ private $codec = null; - /** - * - * @var Codec - */ - private $guidCodec = null; - /** * * @var NodeProvider @@ -79,6 +73,11 @@ class UuidFactory $this->uuidBuilder = $features->getBuilder(); } + public function getCodec() + { + return $this->codec; + } + public function setTimeConverter(TimeConverter $converter) { $this->timeConverter = $converter; diff --git a/tests/UuidTest.php b/tests/UuidTest.php index c2f0d6d..05f5744 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -1294,22 +1294,23 @@ class UuidTest extends TestCase public function testFromLittleEndianBytes() { + $uuidFactory = new UuidFactory(new FeatureSet(false)); + $guidFactory = new UuidFactory(new FeatureSet(true)); + // Check that parsing BE bytes as LE reverses fields - $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); + $uuid = $uuidFactory->fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $bytes = $uuid->getBytes(); - Uuid::setFactory(new UuidFactory(new FeatureSet(true))); - - $guid = Uuid::fromBytes($bytes); + $guid = $guidFactory->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::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); + $guid = $guidFactory->fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $bytes = $guid->getBytes(); - $parsedGuid = Uuid::fromBytes($bytes); + $parsedGuid = $guidFactory->fromBytes($bytes); $this->assertEquals($guid->toString(), $parsedGuid->toString()); } From 9df122eb0036ae7d09871347a638220fc1335084 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sat, 8 Nov 2014 15:08:06 +0100 Subject: [PATCH 19/54] Remove duplication in UuidFactory --- src/UuidFactory.php | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/src/UuidFactory.php b/src/UuidFactory.php index 2f66f0c..b1ab8b4 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -217,13 +217,7 @@ class UuidFactory */ public function uuid3($ns, $name) { - if (!($ns instanceof UuidInterface)) { - $ns = $this->codec->decode($ns); - } - - $hash = md5($ns->getBytes() . $name); - - return $this->uuidFromHashedName($hash, 3); + return $this->uuidFromNsAndName($ns, $name, 3, 'md5'); } /** @@ -253,13 +247,7 @@ class UuidFactory */ public function uuid5($ns, $name) { - if (!($ns instanceof Uuid)) { - $ns = $this->codec->decode($ns); - } - - $hash = sha1($ns->getBytes() . $name); - - return $this->uuidFromHashedName($hash, 5); + return $this->uuidFromNsAndName($ns, $name, 5, 'sha1'); } public function uuid(array $fields) @@ -267,6 +255,17 @@ class UuidFactory return $this->uuidBuilder->build($this->codec, $fields); } + protected function uuidFromNsAndName($ns, $name, $version, $hashFunction) + { + if (!($ns instanceof Uuid)) { + $ns = $this->codec->decode($ns); + } + + $hash = call_user_func($hashFunction, ($ns->getBytes() . $name)); + + return $this->uuidFromHashedName($hash, $version); + } + /** * 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) From 04c64d6f4570f488818bdf330c118408dc7d82da Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sat, 8 Nov 2014 15:41:53 +0100 Subject: [PATCH 20/54] Refactor duplicate code --- src/UuidFactory.php | 74 +++++++++++++++++++++++++-------------------- tests/UuidTest.php | 22 ++++++++------ 2 files changed, 54 insertions(+), 42 deletions(-) diff --git a/src/UuidFactory.php b/src/UuidFactory.php index b1ab8b4..a66617f 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -159,20 +159,7 @@ class UuidFactory */ public function uuid1($node = null, $clockSeq = null) { - if ($node === null) { - $node = $this->nodeProvider->getNode(); - } - - // 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) { - throw new \InvalidArgumentException('Invalid node value'); - } - - $node = strtolower(sprintf('%012s', $node)); + $node = $this->getValidNode($node); if ($clockSeq === null) { // Not using "stable storage"; see RFC 4122, Section 4.2.1.1 @@ -184,15 +171,8 @@ class UuidFactory $timeOfDay = $this->timeProvider->currentTime(); $uuidTime = $this->timeConverter->calculateTime($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; + $timeHi = $this->applyVersion($uuidTime['hi'], 1); + $clockSeqHi = $this->applyVariant($clockSeq >> 8); $fields = array( 'time_low' => $uuidTime['low'], @@ -255,6 +235,25 @@ class UuidFactory return $this->uuidBuilder->build($this->codec, $fields); } + protected function applyVariant($clockSeqHi) + { + // Set the variant to RFC 4122 + $clockSeqHi = $clockSeqHi & 0x3f; + $clockSeqHi &= ~(0xc0); + $clockSeqHi |= 0x80; + + return $clockSeqHi; + } + + protected function applyVersion($timeHi, $version) + { + $timeHi = hexdec($timeHi) & 0x0fff; + $timeHi &= ~(0xf000); + $timeHi |= $version << 12; + + return $timeHi; + } + protected function uuidFromNsAndName($ns, $name, $version, $hashFunction) { if (!($ns instanceof Uuid)) { @@ -276,15 +275,8 @@ class UuidFactory */ 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; + $timeHi = $this->applyVersion(substr($hash, 12, 4), $version); + $clockSeqHi = $this->applyVariant(hexdec(substr($hash, 16, 2))); $fields = array( 'time_low' => substr($hash, 0, 8), @@ -297,4 +289,22 @@ class UuidFactory return $this->uuid($fields); } + + protected function getValidNode($node) + { + if ($node === null) { + $node = $this->nodeProvider->getNode(); + } + + // 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) { + throw new \InvalidArgumentException('Invalid node value'); + } + + return strtolower(sprintf('%012s', $node)); + } } diff --git a/tests/UuidTest.php b/tests/UuidTest.php index 05f5744..2372b2c 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -1142,19 +1142,21 @@ class UuidTest extends TestCase $factory = new UuidFactory(); $smallIntFactory = new UuidFactory(new FeatureSet(false, true)); + $timeOfDay = new FixedTimeProvider(array( + 'sec' => $currentTime, + 'usec' => $usec, + 'minuteswest' => 0, + 'dsttime' => 0, + )); + + $factory->setTimeProvider($timeOfDay); + $smallIntFactory->setTimeProvider($timeOfDay); + while ($currentTime <= $endTime) { foreach (array(0, 50000, 250000, 500000, 750000, 999999) as $usec) { - - $timeOfDay = new FixedTimeProvider(array( - 'sec' => $currentTime, - 'usec' => $usec, - 'minuteswest' => 0, - 'dsttime' => 0, - )); - - $factory->setTimeProvider($timeOfDay); - $smallIntFactory->setTimeProvider($timeOfDay); + $timeOfDay->setSec($currentTime); + $timeOfDay->setUsec($usec); $uuid32 = $smallIntFactory->uuid1(0x00007ffffffe, 0x1669); $uuid64 = $factory->uuid1(0x00007ffffffe, 0x1669); From b0192fa9b0e28870b69cd3308216c260f3c807ac Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sat, 8 Nov 2014 15:42:36 +0100 Subject: [PATCH 21/54] Handle unknown versions --- src/Console/Command/DecodeCommand.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Console/Command/DecodeCommand.php b/src/Console/Command/DecodeCommand.php index d0caad1..22c99c3 100644 --- a/src/Console/Command/DecodeCommand.php +++ b/src/Console/Command/DecodeCommand.php @@ -90,6 +90,8 @@ class DecodeCommand extends Command case 5: $version = '5 (name based, SHA-1)'; break; + default: + $version = 'Invalid or unknown UUID version'; } $table->addRows(array( From ed06e0a84e778859abd66293ee6d789cff43ddb0 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sat, 8 Nov 2014 15:50:19 +0100 Subject: [PATCH 22/54] Remove unused code --- src/Uuid.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Uuid.php b/src/Uuid.php index 8332c2d..7ed74ca 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -186,7 +186,7 @@ class Uuid implements UuidInterface, \JsonSerializable */ public function compareTo(UuidInterface $uuid) { - $comparison = null; + $comparison = 0; if ($this->getMostSignificantBitsHex() < $uuid->getMostSignificantBitsHex()) { $comparison = -1; @@ -196,8 +196,6 @@ class Uuid implements UuidInterface, \JsonSerializable $comparison = -1; } elseif ($this->getLeastSignificantBitsHex() > $uuid->getLeastSignificantBitsHex()) { $comparison = 1; - } else { - $comparison = 0; } return $comparison; @@ -396,7 +394,7 @@ class Uuid implements UuidInterface, \JsonSerializable */ public function getHex() { - return str_replace('-', '', $this->toString(true)); + return str_replace('-', '', $this->toString()); } /** From cce58a0b8a1ceb5058022cfa1755deca43654ac1 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sat, 8 Nov 2014 15:57:30 +0100 Subject: [PATCH 23/54] Fix doc comments and remove unneeded usings --- src/BigNumberConverter.php | 3 ++ src/Codec.php | 12 ++++++ src/Codec/GuidStringCodec.php | 4 -- src/Codec/StringCodec.php | 2 - src/Console/Command/DecodeCommand.php | 1 - src/Node/SystemNodeProvider.php | 1 + src/RandomGenerator.php | 5 +++ src/Uuid.php | 7 +--- src/UuidBuilder.php | 3 ++ src/UuidFactory.php | 20 ++++----- src/UuidInterface.php | 60 +++++++++++++++++++++++++++ 11 files changed, 95 insertions(+), 23 deletions(-) diff --git a/src/BigNumberConverter.php b/src/BigNumberConverter.php index 0e1b3fd..97551cf 100644 --- a/src/BigNumberConverter.php +++ b/src/BigNumberConverter.php @@ -4,6 +4,9 @@ namespace Rhumsaa\Uuid; class BigNumberConverter { + /** + * @param string $hex + */ public function fromHex($hex) { $number = \Moontoast\Math\BigNumber::baseConvert($hex, 16, 10); diff --git a/src/Codec.php b/src/Codec.php index 9912851..f32800e 100644 --- a/src/Codec.php +++ b/src/Codec.php @@ -4,11 +4,23 @@ namespace Rhumsaa\Uuid; interface Codec { + /** + * @return string + */ public function encode(UuidInterface $uuid); + /** + * @return string + */ public function encodeBinary(UuidInterface $uuid); + /** + * @return callable + */ public function decode($encodedUuid); + /** + * @param string $bytes + */ public function decodeBytes($bytes); } diff --git a/src/Codec/GuidStringCodec.php b/src/Codec/GuidStringCodec.php index ec9e5bd..53999fb 100644 --- a/src/Codec/GuidStringCodec.php +++ b/src/Codec/GuidStringCodec.php @@ -2,12 +2,8 @@ namespace Rhumsaa\Uuid\Codec; -use InvalidArgumentException; use Rhumsaa\Uuid\UuidInterface; use Rhumsaa\Uuid\Uuid; -use Rhumsaa\Uuid\BigNumberConverter; -use Rhumsaa\Uuid\UuidFactory; -use Rhumsaa\Uuid\UuidBuilder; use Rhumsaa\Uuid\Codec; class GuidStringCodec extends StringCodec diff --git a/src/Codec/StringCodec.php b/src/Codec/StringCodec.php index 3147f81..852116b 100644 --- a/src/Codec/StringCodec.php +++ b/src/Codec/StringCodec.php @@ -3,12 +3,10 @@ namespace Rhumsaa\Uuid\Codec; use InvalidArgumentException; -use Rhumsaa\Uuid\BigNumberConverter; use Rhumsaa\Uuid\Codec; use Rhumsaa\Uuid\Uuid; use Rhumsaa\Uuid\UuidBuilder; use Rhumsaa\Uuid\UuidInterface; -use Rhumsaa\Uuid\UuidFactory; class StringCodec implements Codec { diff --git a/src/Console/Command/DecodeCommand.php b/src/Console/Command/DecodeCommand.php index 22c99c3..ff44bf6 100644 --- a/src/Console/Command/DecodeCommand.php +++ b/src/Console/Command/DecodeCommand.php @@ -15,7 +15,6 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Helper\TableHelper; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Rhumsaa\Uuid\Console\Exception; use Rhumsaa\Uuid\Uuid; diff --git a/src/Node/SystemNodeProvider.php b/src/Node/SystemNodeProvider.php index 819ce9b..dde9753 100644 --- a/src/Node/SystemNodeProvider.php +++ b/src/Node/SystemNodeProvider.php @@ -29,6 +29,7 @@ class SystemNodeProvider implements NodeProvider * @todo Needs evaluation and possibly modification to ensure this works * well across multiple platforms. * @codeCoverageIgnore + * @return string */ protected function getIfconfig() { diff --git a/src/RandomGenerator.php b/src/RandomGenerator.php index 9fac8b9..d703d04 100644 --- a/src/RandomGenerator.php +++ b/src/RandomGenerator.php @@ -4,5 +4,10 @@ namespace Rhumsaa\Uuid; interface RandomGenerator { + /** + * @param integer $length + * + * @return string + */ function generate($length); } diff --git a/src/Uuid.php b/src/Uuid.php index 7ed74ca..ab0c5ca 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -12,8 +12,6 @@ namespace Rhumsaa\Uuid; use InvalidArgumentException; -use Rhumsaa\Uuid\Codec\GuidStringCodec; -use Rhumsaa\Uuid\Codec\StringCodec; /** * Represents a universally unique identifier (UUID), according to RFC 4122 @@ -747,7 +745,6 @@ class Uuid implements UuidInterface, \JsonSerializable * 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 */ @@ -813,7 +810,7 @@ class Uuid implements UuidInterface, \JsonSerializable * 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 $ns The UUID namespace in which to create the named UUID * @param string $name The name to create a UUID for * @return Uuid */ @@ -836,7 +833,7 @@ class Uuid implements UuidInterface, \JsonSerializable * 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 $ns The UUID namespace in which to create the named UUID * @param string $name The name to create a UUID for * @return Uuid */ diff --git a/src/UuidBuilder.php b/src/UuidBuilder.php index 6f777be..b4f490c 100644 --- a/src/UuidBuilder.php +++ b/src/UuidBuilder.php @@ -4,5 +4,8 @@ namespace Rhumsaa\Uuid; interface UuidBuilder { + /** + * @return Uuid + */ public function build(Codec $codec, array $fields); } diff --git a/src/UuidFactory.php b/src/UuidFactory.php index a66617f..5df3116 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -2,16 +2,6 @@ namespace Rhumsaa\Uuid; -use Rhumsaa\Uuid\Codec\StringCodec; -use Rhumsaa\Uuid\Codec\GuidStringCodec; -use Rhumsaa\Uuid\Time\PhpTimeConverter; -use Rhumsaa\Uuid\Time\BigNumberTimeConverter; -use Rhumsaa\Uuid\Time\DegradedTimeConverter; -use Rhumsaa\Uuid\Time\SystemTimeProvider; -use Rhumsaa\Uuid\Node\FallbackNodeProvider; -use Rhumsaa\Uuid\Node\SystemNodeProvider; -use Rhumsaa\Uuid\Node\RandomNodeProvider; - class UuidFactory { @@ -125,7 +115,6 @@ class UuidFactory * 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 */ @@ -245,6 +234,10 @@ class UuidFactory return $clockSeqHi; } + /** + * @param string $timeHi + * @param integer $version + */ protected function applyVersion($timeHi, $version) { $timeHi = hexdec($timeHi) & 0x0fff; @@ -254,6 +247,11 @@ class UuidFactory return $timeHi; } + /** + * @param string $name + * @param integer $version + * @param string $hashFunction + */ protected function uuidFromNsAndName($ns, $name, $version, $hashFunction) { if (!($ns instanceof Uuid)) { diff --git a/src/UuidInterface.php b/src/UuidInterface.php index 7858fee..4e852e2 100644 --- a/src/UuidInterface.php +++ b/src/UuidInterface.php @@ -5,46 +5,106 @@ namespace Rhumsaa\Uuid; interface UuidInterface { + /** + * @return integer + */ public function compareTo(UuidInterface $other); + /** + * @return boolean + */ public function equals($other); + /** + * @return BigNumberConverter + */ public function getConverter(); + /** + * @return string + */ public function getHex(); public function getFieldsHex(); + /** + * @return string + */ public function getClockSeqHiAndReservedHex(); + /** + * @return string + */ public function getClockSeqLowHex(); + /** + * @return string + */ public function getClockSequenceHex(); + /** + * @return \DateTime + */ public function getDateTime(); + /** + * @return \Moontoast\Math\BigNumber + */ public function getInteger(); + /** + * @return string + */ public function getLeastSignificantBitsHex(); + /** + * @return string + */ public function getMostSignificantBitsHex(); + /** + * @return string + */ public function getNodeHex(); + /** + * @return string + */ public function getTimeHiAndVersionHex(); + /** + * @return string + */ public function getTimeLowHex(); + /** + * @return string + */ public function getTimeMidHex(); + /** + * @return string + */ public function getTimestampHex(); + /** + * @return string + */ public function getUrn(); + /** + * @return integer + */ public function getVariant(); + /** + * @return integer|null + */ public function getVersion(); + /** + * @return string + */ public function toString(); } From 260063c1b5593fe6c231fa1d3a68c80ce0c20ca6 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sat, 8 Nov 2014 16:01:48 +0100 Subject: [PATCH 24/54] Fix incorrect return type --- src/Codec.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Codec.php b/src/Codec.php index f32800e..7ac628f 100644 --- a/src/Codec.php +++ b/src/Codec.php @@ -15,12 +15,13 @@ interface Codec public function encodeBinary(UuidInterface $uuid); /** - * @return callable + * @return UuidInterface */ public function decode($encodedUuid); /** * @param string $bytes + * @return UuidInterface */ public function decodeBytes($bytes); } From 6ef25d304065da14b153692bdf47763f5d4919db Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sat, 8 Nov 2014 16:13:49 +0100 Subject: [PATCH 25/54] Refactor long method --- src/Console/Command/DecodeCommand.php | 59 ++++++++++++++------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/src/Console/Command/DecodeCommand.php b/src/Console/Command/DecodeCommand.php index ff44bf6..e52f341 100644 --- a/src/Console/Command/DecodeCommand.php +++ b/src/Console/Command/DecodeCommand.php @@ -63,34 +63,55 @@ class DecodeCommand extends Command )); if ($uuid->getVariant() != Uuid::RFC_4122) { - $table->addRows(array( array('decode:', 'variant:', 'Not an RFC 4122 UUID'), )); - - $table->render($output); - - return; } + else { + $this->dumpUuid($table, $uuid); + } + + $table->render($output); + } + + protected function dumpUuid($table, $uuid) + { + $content = null; + $version = 'Invalid or unknown UUID version'; switch ($uuid->getVersion()) { case 1: $version = '1 (time and node based)'; + $content = array( + array('', 'content:', 'time: ' . $uuid->getDateTime()->format('c')), + array('', '', 'clock: ' . $uuid->getClockSequence() . ' (usually random)'), + array('', '', 'node: ' . substr(chunk_split($uuid->getNodeHex(), 2, ':'), 0, -1)), + ); break; case 2: $version = '2 (DCE security based)'; break; case 3: $version = '3 (name based, MD5)'; + $content = array( + array('', 'content:', substr(chunk_split($uuid->getHex(), 2, ':'), 0, -1)), + array('', '', '(not decipherable: SHA1 message digest only)'), + ); break; case 4: $version = '4 (random data based)'; + $content = array( + array('', 'content:', substr(chunk_split($uuid->getHex(), 2, ':'), 0, -1)), + array('', '', '(no semantics: random data only)'), + ); break; case 5: $version = '5 (name based, SHA-1)'; + $content = array( + array('', 'content:', substr(chunk_split($uuid->getHex(), 2, ':'), 0, -1)), + array('', '', '(not decipherable: SHA1 message digest only)'), + ); break; - default: - $version = 'Invalid or unknown UUID version'; } $table->addRows(array( @@ -98,28 +119,8 @@ class DecodeCommand extends Command array('', 'version:', $version), )); - if ($uuid->getVersion() == 1) { - $table->addRows(array( - array('', 'content:', 'time: ' . $uuid->getDateTime()->format('c')), - array('', '', 'clock: ' . $uuid->getClockSequence() . ' (usually random)'), - array('', '', 'node: ' . substr(chunk_split($uuid->getNodeHex(), 2, ':'), 0, -1)), - )); + if ($content) { + $table->addRows($content); } - - if ($uuid->getVersion() == 4) { - $table->addRows(array( - array('', 'content:', substr(chunk_split($uuid->getHex(), 2, ':'), 0, -1)), - array('', '', '(no semantics: random data only)'), - )); - } - - if ($uuid->getVersion() == 3 || $uuid->getVersion() == 5) { - $table->addRows(array( - array('', 'content:', substr(chunk_split($uuid->getHex(), 2, ':'), 0, -1)), - array('', '', '(not decipherable: MD5 message digest only)'), - )); - } - - $table->render($output); } } From 61ba69785348f0273b0d3b8c44707cf778ce4548 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sat, 8 Nov 2014 16:28:19 +0100 Subject: [PATCH 26/54] Fix decode output for v5 (incorrect hash algo name) --- src/Console/Command/DecodeCommand.php | 2 +- tests/console-mocks/testExecuteForVersion5Uuid.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Console/Command/DecodeCommand.php b/src/Console/Command/DecodeCommand.php index e52f341..e557310 100644 --- a/src/Console/Command/DecodeCommand.php +++ b/src/Console/Command/DecodeCommand.php @@ -95,7 +95,7 @@ class DecodeCommand extends Command $version = '3 (name based, MD5)'; $content = array( array('', 'content:', substr(chunk_split($uuid->getHex(), 2, ':'), 0, -1)), - array('', '', '(not decipherable: SHA1 message digest only)'), + array('', '', '(not decipherable: MD5 message digest only)'), ); break; case 4: diff --git a/tests/console-mocks/testExecuteForVersion5Uuid.txt b/tests/console-mocks/testExecuteForVersion5Uuid.txt index e564146..2498622 100644 --- a/tests/console-mocks/testExecuteForVersion5Uuid.txt +++ b/tests/console-mocks/testExecuteForVersion5Uuid.txt @@ -4,5 +4,5 @@ decode: variant: RFC 4122 version: 5 (name based, SHA-1) content: 88:63:13:e1:3b:8a:53:72:9b:90:0c:9a:ee:19:9e:5d - (not decipherable: MD5 message digest only) + (not decipherable: SHA1 message digest only) ========= ========== ================================================= From cd2d09c356841de7a7cb7a91da5c9c48d910502d Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Sat, 8 Nov 2014 14:43:09 -0500 Subject: [PATCH 27/54] Introduce Converter namespace and move Number and Time classes into it --- src/Builder/DefaultUuidBuilder.php | 4 ++-- src/Builder/DegradedUuidBuilder.php | 4 ++-- src/{ => Converter/Number}/BigNumberConverter.php | 6 ++++-- .../Number}/DegradedNumberConverter.php | 11 +++++++---- src/Converter/NumberConverterInterface.php | 10 ++++++++++ src/{ => Converter}/Time/BigNumberTimeConverter.php | 6 +++--- src/{ => Converter}/Time/DegradedTimeConverter.php | 6 +++--- src/{ => Converter}/Time/PhpTimeConverter.php | 6 +++--- .../TimeConverterInterface.php} | 4 ++-- src/DegradedUuid.php | 4 +++- src/FeatureSet.php | 8 +++++--- src/Uuid.php | 5 +++-- src/UuidFactory.php | 12 ++++++++---- src/UuidInterface.php | 6 ++++-- .../Number}/DegradedNumberConverterTest.php | 4 +++- tests/UuidTest.php | 4 ++-- 16 files changed, 64 insertions(+), 36 deletions(-) rename src/{ => Converter/Number}/BigNumberConverter.php (75%) rename src/{ => Converter/Number}/DegradedNumberConverter.php (63%) create mode 100644 src/Converter/NumberConverterInterface.php rename src/{ => Converter}/Time/BigNumberTimeConverter.php (81%) rename src/{ => Converter}/Time/DegradedTimeConverter.php (71%) rename src/{ => Converter}/Time/PhpTimeConverter.php (79%) rename src/{TimeConverter.php => Converter/TimeConverterInterface.php} (81%) rename tests/{ => Converter/Number}/DegradedNumberConverterTest.php (89%) diff --git a/src/Builder/DefaultUuidBuilder.php b/src/Builder/DefaultUuidBuilder.php index 449e68b..b8892e7 100644 --- a/src/Builder/DefaultUuidBuilder.php +++ b/src/Builder/DefaultUuidBuilder.php @@ -2,7 +2,7 @@ namespace Rhumsaa\Uuid\Builder; -use Rhumsaa\Uuid\BigNumberConverter; +use Rhumsaa\Uuid\Converter\NumberConverterInterface; use Rhumsaa\Uuid\Codec; use Rhumsaa\Uuid\Uuid; use Rhumsaa\Uuid\UuidBuilder; @@ -12,7 +12,7 @@ class DefaultUuidBuilder implements UuidBuilder private $converter; - public function __construct(BigNumberConverter $converter) + public function __construct(NumberConverterInterface $converter) { $this->converter = $converter; } diff --git a/src/Builder/DegradedUuidBuilder.php b/src/Builder/DegradedUuidBuilder.php index 8de0218..d5a345e 100644 --- a/src/Builder/DegradedUuidBuilder.php +++ b/src/Builder/DegradedUuidBuilder.php @@ -5,14 +5,14 @@ namespace Rhumsaa\Uuid\Builder; use Rhumsaa\Uuid\UuidBuilder; use Rhumsaa\Uuid\Codec; use Rhumsaa\Uuid\DegradedUuid; -use Rhumsaa\Uuid\BigNumberConverter; +use Rhumsaa\Uuid\Converter\NumberConverterInterface; class DegradedUuidBuilder implements UuidBuilder { private $converter; - public function __construct(BigNumberConverter $converter) + public function __construct(NumberConverterInterface $converter) { $this->converter = $converter; } diff --git a/src/BigNumberConverter.php b/src/Converter/Number/BigNumberConverter.php similarity index 75% rename from src/BigNumberConverter.php rename to src/Converter/Number/BigNumberConverter.php index 97551cf..31189be 100644 --- a/src/BigNumberConverter.php +++ b/src/Converter/Number/BigNumberConverter.php @@ -1,8 +1,10 @@ fields = $fields; $this->codec = $codec; @@ -303,7 +304,7 @@ class Uuid implements UuidInterface, \JsonSerializable return sprintf('%04x', $this->getClockSequence()); } - public function getConverter() + public function getNumberConverter() { return $this->converter; } diff --git a/src/UuidFactory.php b/src/UuidFactory.php index 5df3116..511260b 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -2,6 +2,10 @@ namespace Rhumsaa\Uuid; +use InvalidArgumentException; +use Rhumsaa\Uuid\Converter\NumberConverterInterface; +use Rhumsaa\Uuid\Converter\TimeConverterInterface; + class UuidFactory { @@ -19,7 +23,7 @@ class UuidFactory /** * - * @var BigNumberConverter + * @var NumberConverterInterface */ private $numberConverter = null; @@ -30,7 +34,7 @@ class UuidFactory /** * - * @var TimeConverter + * @var TimeConverterInterface */ private $timeConverter = null; @@ -68,7 +72,7 @@ class UuidFactory return $this->codec; } - public function setTimeConverter(TimeConverter $converter) + public function setTimeConverter(TimeConverterInterface $converter) { $this->timeConverter = $converter; } @@ -88,7 +92,7 @@ class UuidFactory $this->nodeProvider = $provider; } - public function setNumberConverter(BigNumberConverter $converter) + public function setNumberConverter(NumberConverterInterface $converter) { $this->numberConverter = $converter; } diff --git a/src/UuidInterface.php b/src/UuidInterface.php index 4e852e2..20ba807 100644 --- a/src/UuidInterface.php +++ b/src/UuidInterface.php @@ -2,6 +2,8 @@ namespace Rhumsaa\Uuid; +use Rhumsaa\Uuid\Converter\NumberConverterInterface; + interface UuidInterface { @@ -16,9 +18,9 @@ interface UuidInterface public function equals($other); /** - * @return BigNumberConverter + * @return NumberConverterInterface */ - public function getConverter(); + public function getNumberConverter(); /** * @return string diff --git a/tests/DegradedNumberConverterTest.php b/tests/Converter/Number/DegradedNumberConverterTest.php similarity index 89% rename from tests/DegradedNumberConverterTest.php rename to tests/Converter/Number/DegradedNumberConverterTest.php index 8f14ceb..0ebef84 100644 --- a/tests/DegradedNumberConverterTest.php +++ b/tests/Converter/Number/DegradedNumberConverterTest.php @@ -1,6 +1,8 @@ assertInstanceOf('Rhumsaa\Uuid\DegradedUuid', $uuid); - $this->assertInstanceOf('Rhumsaa\Uuid\DegradedNumberConverter', $uuid->getConverter()); + $this->assertInstanceOf('Rhumsaa\Uuid\Converter\Number\DegradedNumberConverter', $uuid->getNumberConverter()); $date = $uuid->getDateTime(); } @@ -1687,7 +1687,7 @@ class UuidTest extends TestCase /** * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException - * @expectedExceptionMessage Cannot call Rhumsaa\Uuid\DegradedNumberConverter::fromHex without support for large integers + * @expectedExceptionMessage Cannot call Rhumsaa\Uuid\Converter\Number\DegradedNumberConverter::fromHex without support for large integers */ public function testGetInteger() { From 90fd1531d00338660f66bebfaa2fd23f39f4a8d8 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Sat, 8 Nov 2014 14:53:12 -0500 Subject: [PATCH 28/54] Fixing PSR2 standards violations reported by PHP_CodeSniffer --- composer.json | 1 + phpcs.xml | 15 +++++++++++++++ src/Console/Command/DecodeCommand.php | 3 +-- src/Console/Command/GenerateCommand.php | 6 ++++-- src/Converter/NumberConverterInterface.php | 2 +- src/DegradedUuid.php | 9 +++++---- src/FeatureSet.php | 11 +++++++---- src/RandomGenerator.php | 2 +- src/Uuid.php | 3 ++- src/UuidInterface.php | 1 - 10 files changed, 37 insertions(+), 16 deletions(-) create mode 100644 phpcs.xml diff --git a/composer.json b/composer.json index 41c32a4..b57eaf8 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "symfony/console": "~2.3", "doctrine/dbal": ">=2.3", "phpunit/phpunit": "~4.1", + "squizlabs/php_codesniffer": "2.0.0RC4", "satooshi/php-coveralls": "~0.6" }, "bin": ["bin/uuid"], diff --git a/phpcs.xml b/phpcs.xml new file mode 100644 index 0000000..6aa2b59 --- /dev/null +++ b/phpcs.xml @@ -0,0 +1,15 @@ + + + + Coding standard rules for Rhumsaa\Uuid + + */build/* + */tests/* + */vendor/* + + + + + + + diff --git a/src/Console/Command/DecodeCommand.php b/src/Console/Command/DecodeCommand.php index e557310..f1ed843 100644 --- a/src/Console/Command/DecodeCommand.php +++ b/src/Console/Command/DecodeCommand.php @@ -66,8 +66,7 @@ class DecodeCommand extends Command $table->addRows(array( array('decode:', 'variant:', 'Not an RFC 4122 UUID'), )); - } - else { + } else { $this->dumpUuid($table, $uuid); } diff --git a/src/Console/Command/GenerateCommand.php b/src/Console/Command/GenerateCommand.php index 4dc20a9..78a1669 100644 --- a/src/Console/Command/GenerateCommand.php +++ b/src/Console/Command/GenerateCommand.php @@ -159,9 +159,11 @@ class GenerateCommand extends Command return $namespace; } - throw new Exception('Invalid namespace. ' + throw new Exception( + 'Invalid namespace. ' . 'May be either a UUID in string representation or an identifier ' . 'for internally pre-defined namespace UUIDs (currently known ' - . 'are "ns:DNS", "ns:URL", "ns:OID", and "ns:X500").'); + . 'are "ns:DNS", "ns:URL", "ns:OID", and "ns:X500").' + ); } } diff --git a/src/Converter/NumberConverterInterface.php b/src/Converter/NumberConverterInterface.php index 5a3ae89..b111a8f 100644 --- a/src/Converter/NumberConverterInterface.php +++ b/src/Converter/NumberConverterInterface.php @@ -7,4 +7,4 @@ interface NumberConverterInterface public function fromHex($hex); public function toHex($integer); -} \ No newline at end of file +} diff --git a/src/DegradedUuid.php b/src/DegradedUuid.php index 9c9ff80..df7a841 100644 --- a/src/DegradedUuid.php +++ b/src/DegradedUuid.php @@ -22,7 +22,8 @@ class DegradedUuid extends Uuid * * @return \DateTime A PHP DateTime representation of the date * @throws Exception\UnsupportedOperationException If this UUID is not a version 1 UUID - * @throws Exception\UnsatisfiedDependencyException if called on a 32-bit system and Moontoast\Math\BigNumber is not present + * @throws Exception\UnsatisfiedDependencyException if called on a 32-bit system and + * Moontoast\Math\BigNumber is not present */ public function getDateTime() { @@ -63,9 +64,9 @@ class DegradedUuid extends Uuid 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' + 'Cannot call ' . __METHOD__ . ' on a 32-bit system, since some ' + . 'values overflow the system max integer value' + . '; consider calling getFieldsHex instead' ); } diff --git a/src/FeatureSet.php b/src/FeatureSet.php index cfbc8ba..4a29f88 100644 --- a/src/FeatureSet.php +++ b/src/FeatureSet.php @@ -45,8 +45,12 @@ class FeatureSet private $timeProvider; - public function __construct($useGuids = false, $force32Bit = false, $forceNoBigNumber = false, $ignoreSystemNode = false) - { + public function __construct( + $useGuids = false, + $force32Bit = false, + $forceNoBigNumber = false, + $ignoreSystemNode = false + ) { $this->disableBigNumber = $forceNoBigNumber; $this->disable64Bit = $force32Bit; $this->ignoreSystemNode = $ignoreSystemNode; @@ -134,8 +138,7 @@ class FeatureSet { if ($this->is64BitSystem()) { return new PhpTimeConverter(); - } - elseif ($this->hasBigNumber()) { + } elseif ($this->hasBigNumber()) { return new BigNumberTimeConverter(); } diff --git a/src/RandomGenerator.php b/src/RandomGenerator.php index d703d04..5f7521c 100644 --- a/src/RandomGenerator.php +++ b/src/RandomGenerator.php @@ -9,5 +9,5 @@ interface RandomGenerator * * @return string */ - function generate($length); + public function generate($length); } diff --git a/src/Uuid.php b/src/Uuid.php index 75acb84..88b18eb 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -319,7 +319,8 @@ class Uuid implements UuidInterface, \JsonSerializable * * @return \DateTime A PHP DateTime representation of the date * @throws Exception\UnsupportedOperationException If this UUID is not a version 1 UUID - * @throws Exception\UnsatisfiedDependencyException if called on a 32-bit system and Moontoast\Math\BigNumber is not present + * @throws Exception\UnsatisfiedDependencyException if called on a 32-bit system and + * Moontoast\Math\BigNumber is not present */ public function getDateTime() { diff --git a/src/UuidInterface.php b/src/UuidInterface.php index 20ba807..4670e7e 100644 --- a/src/UuidInterface.php +++ b/src/UuidInterface.php @@ -108,5 +108,4 @@ interface UuidInterface * @return string */ public function toString(); - } From 958643e7b654247865390a41de2481107c05c478 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Sat, 8 Nov 2014 16:16:44 -0500 Subject: [PATCH 29/54] Introduce Provider namespace and move Node and Time classes into it --- src/FeatureSet.php | 8 ++++---- src/NodeProvider.php | 8 -------- src/{ => Provider}/Node/FallbackNodeProvider.php | 6 +++--- src/{ => Provider}/Node/RandomNodeProvider.php | 6 +++--- src/{ => Provider}/Node/SystemNodeProvider.php | 6 +++--- src/Provider/NodeProviderInterface.php | 8 ++++++++ src/{ => Provider}/Time/FixedTimeProvider.php | 6 +++--- src/Provider/Time/SystemTimeProvider.php | 13 +++++++++++++ .../TimeProviderInterface.php} | 4 ++-- src/Time/SystemTimeProvider.php | 13 ------------- src/UuidFactory.php | 10 ++++++---- tests/UuidTest.php | 4 ++-- 12 files changed, 47 insertions(+), 45 deletions(-) delete mode 100644 src/NodeProvider.php rename src/{ => Provider}/Node/FallbackNodeProvider.php (71%) rename src/{ => Provider}/Node/RandomNodeProvider.php (65%) rename src/{ => Provider}/Node/SystemNodeProvider.php (89%) create mode 100644 src/Provider/NodeProviderInterface.php rename src/{ => Provider}/Time/FixedTimeProvider.php (80%) create mode 100644 src/Provider/Time/SystemTimeProvider.php rename src/{TimeProvider.php => Provider/TimeProviderInterface.php} (71%) delete mode 100644 src/Time/SystemTimeProvider.php diff --git a/src/FeatureSet.php b/src/FeatureSet.php index 4a29f88..50f855d 100644 --- a/src/FeatureSet.php +++ b/src/FeatureSet.php @@ -2,15 +2,15 @@ namespace Rhumsaa\Uuid; -use Rhumsaa\Uuid\Node\FallbackNodeProvider; -use Rhumsaa\Uuid\Node\RandomNodeProvider; -use Rhumsaa\Uuid\Node\SystemNodeProvider; +use Rhumsaa\Uuid\Provider\Node\FallbackNodeProvider; +use Rhumsaa\Uuid\Provider\Node\RandomNodeProvider; +use Rhumsaa\Uuid\Provider\Node\SystemNodeProvider; use Rhumsaa\Uuid\Converter\Number\BigNumberConverter; use Rhumsaa\Uuid\Converter\Number\DegradedNumberConverter; use Rhumsaa\Uuid\Converter\Time\BigNumberTimeConverter; use Rhumsaa\Uuid\Converter\Time\DegradedTimeConverter; use Rhumsaa\Uuid\Converter\Time\PhpTimeConverter; -use Rhumsaa\Uuid\Time\SystemTimeProvider; +use Rhumsaa\Uuid\Provider\Time\SystemTimeProvider; use Rhumsaa\Uuid\Builder\DefaultUuidBuilder; use Rhumsaa\Uuid\Codec\StringCodec; use Rhumsaa\Uuid\Codec\GuidStringCodec; diff --git a/src/NodeProvider.php b/src/NodeProvider.php deleted file mode 100644 index 70f58d2..0000000 --- a/src/NodeProvider.php +++ /dev/null @@ -1,8 +0,0 @@ -timeConverter = $converter; } - public function setTimeProvider(TimeProvider $provider) + public function setTimeProvider(TimeProviderInterface $provider) { $this->timeProvider = $provider; } @@ -87,7 +89,7 @@ class UuidFactory $this->randomGenerator = $generator; } - public function setNodeProvider(NodeProvider $provider) + public function setNodeProvider(NodeProviderInterface $provider) { $this->nodeProvider = $provider; } diff --git a/tests/UuidTest.php b/tests/UuidTest.php index eb6e410..8d609fe 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -2,8 +2,8 @@ namespace Rhumsaa\Uuid; -use Rhumsaa\Uuid\Time\SystemTimeProvider; -use Rhumsaa\Uuid\Time\FixedTimeProvider; +use Rhumsaa\Uuid\Provider\Time\SystemTimeProvider; +use Rhumsaa\Uuid\Provider\Time\FixedTimeProvider; class UuidTest extends TestCase { From ebea9b969bc5c761fc199f8f23a566418d293623 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Sat, 8 Nov 2014 16:24:22 -0500 Subject: [PATCH 30/54] Add ircmaxell-RandomLib to the dev dependencies --- composer.json | 2 ++ src/Generator/RandomLibAdapter.php | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index b57eaf8..c8737ec 100644 --- a/composer.json +++ b/composer.json @@ -24,6 +24,7 @@ }, "require-dev": { "moontoast/math": "~1.1", + "ircmaxell/random-lib": "~1.0", "symfony/console": "~2.3", "doctrine/dbal": ">=2.3", "phpunit/phpunit": "~4.1", @@ -33,6 +34,7 @@ "bin": ["bin/uuid"], "suggest": { "moontoast/math": "Support for converting UUID to 128-bit integer (in string form).", + "ircmaxell/random-lib": "Provides RandomLib to use with the RandomLibAdapter", "symfony/console": "Support for use of the bin/uuid command line tool.", "doctrine/dbal": "Allow the use of a UUID as doctrine field type." }, diff --git a/src/Generator/RandomLibAdapter.php b/src/Generator/RandomLibAdapter.php index 8dac106..4bab073 100644 --- a/src/Generator/RandomLibAdapter.php +++ b/src/Generator/RandomLibAdapter.php @@ -1,9 +1,10 @@ Date: Sat, 8 Nov 2014 16:27:20 -0500 Subject: [PATCH 31/54] Interfaces should have the suffix "Interface" in their names --- src/Builder/DefaultUuidBuilder.php | 4 ++-- src/Builder/DegradedUuidBuilder.php | 4 ++-- src/Codec/GuidStringCodec.php | 2 +- src/Codec/StringCodec.php | 4 ++-- src/{Codec.php => CodecInterface.php} | 2 +- src/DegradedUuid.php | 2 +- src/Generator/MtRandGenerator.php | 4 ++-- src/Generator/OpenSslGenerator.php | 4 ++-- src/Generator/RandomLibAdapter.php | 4 ++-- src/{RandomGenerator.php => RandomGeneratorInterface.php} | 2 +- src/Uuid.php | 6 +++--- src/UuidBuilder.php | 2 +- src/UuidFactory.php | 6 +++--- 13 files changed, 23 insertions(+), 23 deletions(-) rename src/{Codec.php => CodecInterface.php} (94%) rename src/{RandomGenerator.php => RandomGeneratorInterface.php} (81%) diff --git a/src/Builder/DefaultUuidBuilder.php b/src/Builder/DefaultUuidBuilder.php index b8892e7..0cf6720 100644 --- a/src/Builder/DefaultUuidBuilder.php +++ b/src/Builder/DefaultUuidBuilder.php @@ -3,7 +3,7 @@ namespace Rhumsaa\Uuid\Builder; use Rhumsaa\Uuid\Converter\NumberConverterInterface; -use Rhumsaa\Uuid\Codec; +use Rhumsaa\Uuid\CodecInterface; use Rhumsaa\Uuid\Uuid; use Rhumsaa\Uuid\UuidBuilder; @@ -17,7 +17,7 @@ class DefaultUuidBuilder implements UuidBuilder $this->converter = $converter; } - public function build(Codec $codec, array $fields) + public function build(CodecInterface $codec, array $fields) { return new Uuid($fields, $this->converter, $codec); } diff --git a/src/Builder/DegradedUuidBuilder.php b/src/Builder/DegradedUuidBuilder.php index d5a345e..21751ab 100644 --- a/src/Builder/DegradedUuidBuilder.php +++ b/src/Builder/DegradedUuidBuilder.php @@ -3,7 +3,7 @@ namespace Rhumsaa\Uuid\Builder; use Rhumsaa\Uuid\UuidBuilder; -use Rhumsaa\Uuid\Codec; +use Rhumsaa\Uuid\CodecInterface; use Rhumsaa\Uuid\DegradedUuid; use Rhumsaa\Uuid\Converter\NumberConverterInterface; @@ -17,7 +17,7 @@ class DegradedUuidBuilder implements UuidBuilder $this->converter = $converter; } - public function build(Codec $codec, array $fields) + public function build(CodecInterface $codec, array $fields) { return new DegradedUuid($fields, $this->converter, $codec); } diff --git a/src/Codec/GuidStringCodec.php b/src/Codec/GuidStringCodec.php index 53999fb..023a896 100644 --- a/src/Codec/GuidStringCodec.php +++ b/src/Codec/GuidStringCodec.php @@ -4,7 +4,7 @@ namespace Rhumsaa\Uuid\Codec; use Rhumsaa\Uuid\UuidInterface; use Rhumsaa\Uuid\Uuid; -use Rhumsaa\Uuid\Codec; +use Rhumsaa\Uuid\CodecInterface; class GuidStringCodec extends StringCodec { diff --git a/src/Codec/StringCodec.php b/src/Codec/StringCodec.php index 852116b..d9eb62d 100644 --- a/src/Codec/StringCodec.php +++ b/src/Codec/StringCodec.php @@ -3,12 +3,12 @@ namespace Rhumsaa\Uuid\Codec; use InvalidArgumentException; -use Rhumsaa\Uuid\Codec; +use Rhumsaa\Uuid\CodecInterface; use Rhumsaa\Uuid\Uuid; use Rhumsaa\Uuid\UuidBuilder; use Rhumsaa\Uuid\UuidInterface; -class StringCodec implements Codec +class StringCodec implements CodecInterface { private $builder; diff --git a/src/Codec.php b/src/CodecInterface.php similarity index 94% rename from src/Codec.php rename to src/CodecInterface.php index 7ac628f..cb934ec 100644 --- a/src/Codec.php +++ b/src/CodecInterface.php @@ -2,7 +2,7 @@ namespace Rhumsaa\Uuid; -interface Codec +interface CodecInterface { /** * @return string diff --git a/src/DegradedUuid.php b/src/DegradedUuid.php index df7a841..e19e57e 100644 --- a/src/DegradedUuid.php +++ b/src/DegradedUuid.php @@ -7,7 +7,7 @@ use Rhumsaa\Uuid\Converter\NumberConverterInterface; class DegradedUuid extends Uuid { - public function __construct(array $fields, NumberConverterInterface $converter, Codec $codec) + public function __construct(array $fields, NumberConverterInterface $converter, CodecInterface $codec) { parent::__construct($fields, $converter, $codec); } diff --git a/src/Generator/MtRandGenerator.php b/src/Generator/MtRandGenerator.php index af24dcc..c5e7c03 100644 --- a/src/Generator/MtRandGenerator.php +++ b/src/Generator/MtRandGenerator.php @@ -2,9 +2,9 @@ namespace Rhumsaa\Uuid\Generator; -use Rhumsaa\Uuid\RandomGenerator; +use Rhumsaa\Uuid\RandomGeneratorInterface; -class MtRandGenerator implements RandomGenerator +class MtRandGenerator implements RandomGeneratorInterface { public function generate($length) { diff --git a/src/Generator/OpenSslGenerator.php b/src/Generator/OpenSslGenerator.php index 200f8c0..8211d6f 100644 --- a/src/Generator/OpenSslGenerator.php +++ b/src/Generator/OpenSslGenerator.php @@ -2,9 +2,9 @@ namespace Rhumsaa\Uuid\Generator; -use Rhumsaa\Uuid\RandomGenerator; +use Rhumsaa\Uuid\RandomGeneratorInterface; -class OpenSslGenerator implements RandomGenerator +class OpenSslGenerator implements RandomGeneratorInterface { public function generate($length) diff --git a/src/Generator/RandomLibAdapter.php b/src/Generator/RandomLibAdapter.php index 4bab073..710a400 100644 --- a/src/Generator/RandomLibAdapter.php +++ b/src/Generator/RandomLibAdapter.php @@ -4,9 +4,9 @@ namespace Rhumsaa\Uuid\Generator; use RandomLib\Generator; use RandomLib\Factory; -use Rhumsaa\Uuid\RandomGenerator; +use Rhumsaa\Uuid\RandomGeneratorInterface; -class RandomLibAdapter implements RandomGenerator +class RandomLibAdapter implements RandomGeneratorInterface { private $generator; diff --git a/src/RandomGenerator.php b/src/RandomGeneratorInterface.php similarity index 81% rename from src/RandomGenerator.php rename to src/RandomGeneratorInterface.php index 5f7521c..3a1e529 100644 --- a/src/RandomGenerator.php +++ b/src/RandomGeneratorInterface.php @@ -2,7 +2,7 @@ namespace Rhumsaa\Uuid; -interface RandomGenerator +interface RandomGeneratorInterface { /** * @param integer $length diff --git a/src/Uuid.php b/src/Uuid.php index 88b18eb..0da5200 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -105,7 +105,7 @@ class Uuid implements UuidInterface, \JsonSerializable /** * String codec - * @var Codec + * @var CodecInterface */ protected $codec; @@ -135,10 +135,10 @@ class Uuid implements UuidInterface, \JsonSerializable * UUIDs. * * @param array $fields - * @param Codec $codec String codec + * @param CodecInterface $codec String codec * @link Rhumsaa.Uuid.Uuid.html#method_getFields */ - public function __construct(array $fields, NumberConverterInterface $converter, Codec $codec) + public function __construct(array $fields, NumberConverterInterface $converter, CodecInterface $codec) { $this->fields = $fields; $this->codec = $codec; diff --git a/src/UuidBuilder.php b/src/UuidBuilder.php index b4f490c..29b253b 100644 --- a/src/UuidBuilder.php +++ b/src/UuidBuilder.php @@ -7,5 +7,5 @@ interface UuidBuilder /** * @return Uuid */ - public function build(Codec $codec, array $fields); + public function build(CodecInterface $codec, array $fields); } diff --git a/src/UuidFactory.php b/src/UuidFactory.php index 74bcc75..5919968 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -13,7 +13,7 @@ class UuidFactory /** * - * @var Codec + * @var CodecInterface */ private $codec = null; @@ -30,7 +30,7 @@ class UuidFactory private $numberConverter = null; /** - * @var RandomGenerator + * @var RandomGeneratorInterface */ private $randomGenerator = null; @@ -84,7 +84,7 @@ class UuidFactory $this->timeProvider = $provider; } - public function setRandomGenerator(RandomGenerator $generator) + public function setRandomGenerator(RandomGeneratorInterface $generator) { $this->randomGenerator = $generator; } From 39c98bb652a48b91d1b060068df581873b22239c Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Sat, 8 Nov 2014 16:50:04 -0500 Subject: [PATCH 32/54] Add phpcs.xml to the .gitattributes ignore list --- .gitattributes | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitattributes b/.gitattributes index bc2c43f..60c2a77 100644 --- a/.gitattributes +++ b/.gitattributes @@ -3,4 +3,5 @@ /.travis.yml export-ignore /tests export-ignore /phpunit.xml.dist export-ignore +/phpcs.xml export-ignore /apigen.neon export-ignore From 2069071f667d77a28991d1afc96ff1b3a8df9507 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sun, 9 Nov 2014 11:03:09 +0100 Subject: [PATCH 33/54] Remove unneeded parent class --- src/Converter/Number/DegradedNumberConverter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Converter/Number/DegradedNumberConverter.php b/src/Converter/Number/DegradedNumberConverter.php index 9e6da9f..043fc7c 100644 --- a/src/Converter/Number/DegradedNumberConverter.php +++ b/src/Converter/Number/DegradedNumberConverter.php @@ -5,7 +5,7 @@ namespace Rhumsaa\Uuid\Converter\Number; use Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException; use Rhumsaa\Uuid\Converter\NumberConverterInterface; -class DegradedNumberConverter extends BigNumberConverter implements NumberConverterInterface +class DegradedNumberConverter implements NumberConverterInterface { public function fromHex($hex) { From 463aa47338ff749fdfd6c248a6c2658680f6f7a6 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sun, 9 Nov 2014 11:31:08 +0100 Subject: [PATCH 34/54] Extract classes for CLI rendering --- src/Console/Command/DecodeCommand.php | 65 +------------- src/Console/Util/Formatter/V1Formatter.php | 19 ++++ src/Console/Util/Formatter/V2Formatter.php | 15 ++++ src/Console/Util/Formatter/V3Formatter.php | 18 ++++ src/Console/Util/Formatter/V4Formatter.php | 18 ++++ src/Console/Util/Formatter/V5Formatter.php | 18 ++++ .../Util/UuidContentFormatterInterface.php | 10 +++ src/Console/Util/UuidFormatter.php | 88 +++++++++++++++++++ 8 files changed, 189 insertions(+), 62 deletions(-) create mode 100644 src/Console/Util/Formatter/V1Formatter.php create mode 100644 src/Console/Util/Formatter/V2Formatter.php create mode 100644 src/Console/Util/Formatter/V3Formatter.php create mode 100644 src/Console/Util/Formatter/V4Formatter.php create mode 100644 src/Console/Util/Formatter/V5Formatter.php create mode 100644 src/Console/Util/UuidContentFormatterInterface.php create mode 100644 src/Console/Util/UuidFormatter.php diff --git a/src/Console/Command/DecodeCommand.php b/src/Console/Command/DecodeCommand.php index f1ed843..3cd0f26 100644 --- a/src/Console/Command/DecodeCommand.php +++ b/src/Console/Command/DecodeCommand.php @@ -18,6 +18,8 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Rhumsaa\Uuid\Console\Exception; use Rhumsaa\Uuid\Uuid; +use Rhumsaa\Uuid\Console\Util\UuidFormatter; +use Symfony\Component\Console\Helper\Table; /** * Provides the console command to decode UUIDs and dump information about them @@ -57,69 +59,8 @@ class DecodeCommand extends Command $table = $this->getHelperSet()->get('table'); $table->setLayout(TableHelper::LAYOUT_BORDERLESS); - $table->addRows(array( - array('encode:', 'STR:', (string) $uuid), - array('', 'INT:', (string) $uuid->getInteger()), - )); - - if ($uuid->getVariant() != Uuid::RFC_4122) { - $table->addRows(array( - array('decode:', 'variant:', 'Not an RFC 4122 UUID'), - )); - } else { - $this->dumpUuid($table, $uuid); - } + (new UuidFormatter())->write($table, $uuid); $table->render($output); } - - protected function dumpUuid($table, $uuid) - { - $content = null; - $version = 'Invalid or unknown UUID version'; - - switch ($uuid->getVersion()) { - case 1: - $version = '1 (time and node based)'; - $content = array( - array('', 'content:', 'time: ' . $uuid->getDateTime()->format('c')), - array('', '', 'clock: ' . $uuid->getClockSequence() . ' (usually random)'), - array('', '', 'node: ' . substr(chunk_split($uuid->getNodeHex(), 2, ':'), 0, -1)), - ); - break; - case 2: - $version = '2 (DCE security based)'; - break; - case 3: - $version = '3 (name based, MD5)'; - $content = array( - array('', 'content:', substr(chunk_split($uuid->getHex(), 2, ':'), 0, -1)), - array('', '', '(not decipherable: MD5 message digest only)'), - ); - break; - case 4: - $version = '4 (random data based)'; - $content = array( - array('', 'content:', substr(chunk_split($uuid->getHex(), 2, ':'), 0, -1)), - array('', '', '(no semantics: random data only)'), - ); - break; - case 5: - $version = '5 (name based, SHA-1)'; - $content = array( - array('', 'content:', substr(chunk_split($uuid->getHex(), 2, ':'), 0, -1)), - array('', '', '(not decipherable: SHA1 message digest only)'), - ); - break; - } - - $table->addRows(array( - array('decode:', 'variant:', 'RFC 4122'), - array('', 'version:', $version), - )); - - if ($content) { - $table->addRows($content); - } - } } diff --git a/src/Console/Util/Formatter/V1Formatter.php b/src/Console/Util/Formatter/V1Formatter.php new file mode 100644 index 0000000..4c27c00 --- /dev/null +++ b/src/Console/Util/Formatter/V1Formatter.php @@ -0,0 +1,19 @@ +getDateTime()->format('c')), + array('', '', 'clock: ' . $uuid->getClockSequence() . ' (usually random)'), + array('', '', 'node: ' . substr(chunk_split($uuid->getNodeHex(), 2, ':'), 0, -1)), + ); + } +} diff --git a/src/Console/Util/Formatter/V2Formatter.php b/src/Console/Util/Formatter/V2Formatter.php new file mode 100644 index 0000000..3362028 --- /dev/null +++ b/src/Console/Util/Formatter/V2Formatter.php @@ -0,0 +1,15 @@ +getHex(), 2, ':'), 0, -1)), + array('', '', '(not decipherable: MD5 message digest only)'), + ); + } +} diff --git a/src/Console/Util/Formatter/V4Formatter.php b/src/Console/Util/Formatter/V4Formatter.php new file mode 100644 index 0000000..4bce8ca --- /dev/null +++ b/src/Console/Util/Formatter/V4Formatter.php @@ -0,0 +1,18 @@ +getHex(), 2, ':'), 0, -1)), + array('', '', '(no semantics: random data only)'), + ); + } +} diff --git a/src/Console/Util/Formatter/V5Formatter.php b/src/Console/Util/Formatter/V5Formatter.php new file mode 100644 index 0000000..bf99c78 --- /dev/null +++ b/src/Console/Util/Formatter/V5Formatter.php @@ -0,0 +1,18 @@ +getHex(), 2, ':'), 0, -1)), + array('', '', '(not decipherable: SHA1 message digest only)'), + ); + } +} diff --git a/src/Console/Util/UuidContentFormatterInterface.php b/src/Console/Util/UuidContentFormatterInterface.php new file mode 100644 index 0000000..ae74ca6 --- /dev/null +++ b/src/Console/Util/UuidContentFormatterInterface.php @@ -0,0 +1,10 @@ + '1 (time and node based)', + 2 => '2 (DCE security based)', + 3 => '3 (name based, MD5)', + 4 => '4 (random data based)', + 5 => '5 (name based, SHA-1)' + ]; + + private static $variantMap = [ + Uuid::RESERVED_NCS => 'Reserved', + Uuid::RFC_4122 => 'RFC 4122', + Uuid::RESERVED_MICROSOFT => 'Reserved for Microsoft use.', + Uuid::RESERVED_FUTURE => 'Reserved for future use.' + ]; + + private static $formatters; + + public function __construct() + { + if (self::$formatters == null) { + self::$formatters = [ + 1 => new V1Formatter(), + 2 => new V2Formatter(), + 3 => new V3Formatter(), + 4 => new V4Formatter(), + 5 => new V5Formatter() + ]; + } + } + + public function write(TableHelper $table, UuidInterface $uuid) + { + $table->addRows(array( + array('encode:', 'STR:', (string) $uuid), + array('', 'INT:', (string) $uuid->getInteger()), + )); + + if ($uuid->getVariant() == Uuid::RFC_4122) { + $table->addRows(array( + array('decode:', 'variant:',$this->getFormattedVariant($uuid)), + array('', 'version:', $this->getFormattedVersion($uuid)), + )); + + $table->addRows($this->getContent($uuid)); + } + else { + $table->addRows(array( + array('decode:', 'variant:', 'Not an RFC 4122 UUID'), + )); + } + } + + public function getFormattedVersion(UuidInterface $uuid) + { + return self::$versionMap[$uuid->getVersion()]; + } + + public function getFormattedVariant(UuidInterface $uuid) + { + return self::$variantMap[$uuid->getVariant()]; + } + + /** + * Returns content as an array of rows, each row being an array containing column values. + */ + public function getContent(UuidInterface $uuid) + { + $formatter = self::$formatters[$uuid->getVersion()]; + + return $formatter->getContent($uuid); + } +} From 3ca7eaa0702fcd68733e6c00a9bbbdbe37571ee1 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sun, 9 Nov 2014 11:34:28 +0100 Subject: [PATCH 35/54] Fix PHPCS violation --- src/Console/Util/UuidFormatter.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Console/Util/UuidFormatter.php b/src/Console/Util/UuidFormatter.php index 9a5795a..785e41d 100644 --- a/src/Console/Util/UuidFormatter.php +++ b/src/Console/Util/UuidFormatter.php @@ -58,8 +58,7 @@ class UuidFormatter )); $table->addRows($this->getContent($uuid)); - } - else { + } else { $table->addRows(array( array('decode:', 'variant:', 'Not an RFC 4122 UUID'), )); From 7e036c44021c8c0b15604027d5bafe9837956911 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sun, 9 Nov 2014 11:37:50 +0100 Subject: [PATCH 36/54] Add PHPCS to build config --- .travis.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4ec0096..7dba238 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,6 +10,8 @@ before_script: - composer self-update - composer install --dev --prefer-source -script: ./vendor/bin/phpunit --coverage-text --coverage-clover ./build/logs/clover.xml +script: + - ./vendor/bin/phpunit --coverage-text --coverage-clover ./build/logs/clover.xml + - ./vendor/bin/phpcs --standard=phpcs.xml ./ after_script: php vendor/bin/coveralls From b8fe2e4a918cbb072efea4e435f53006bfb577ee Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Wed, 17 Dec 2014 01:30:45 +0100 Subject: [PATCH 37/54] Extract factory interface & add basic pecl impl --- src/PeclUuidFactory.php | 74 ++++++++++++++++++++++++++++++++++++ src/UuidFactory.php | 2 +- src/UuidFactoryInterface.php | 21 ++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 src/PeclUuidFactory.php create mode 100644 src/UuidFactoryInterface.php diff --git a/src/PeclUuidFactory.php b/src/PeclUuidFactory.php new file mode 100644 index 0000000..9cf881c --- /dev/null +++ b/src/PeclUuidFactory.php @@ -0,0 +1,74 @@ +factory = $factory; + } + + /* + * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::uuid1() + */ + public function uuid1($node = null, $clockSeq = null) + { + $uuid = uuid_create(UUID_TYPE_TIME); + + return $this->fromString($uuid); + } + + /* + * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::uuid3() + */ + public function uuid3($ns, $name) + { + return $this->factory->uuid3($ns, $name); + } + + /* + * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::uuid4() + */ + public function uuid4() + { + $uuid = uuid_create(UUID_TYPE_RANDOM); + + return $this->fromString($uuid); + } + + /* + * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::uuid5() + */ + public function uuid5($ns, $name) + { + return $this->factory->uuid5($ns, $name); + } + + /* + * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::fromBytes() + */ + public function fromBytes($bytes) + { + return $this->factory->fromBytes($bytes); + } + + /* + * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::fromString() + */ + public function fromString($name) + { + return $this->factory->fromString($name); + } + + /* + * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::fromInteger() + */ + public function fromInteger($integer) + { + return $this->factory->fromInteger($integer); + } +} \ No newline at end of file diff --git a/src/UuidFactory.php b/src/UuidFactory.php index 5919968..9885742 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -8,7 +8,7 @@ use Rhumsaa\Uuid\Converter\TimeConverterInterface; use Rhumsaa\Uuid\Provider\NodeProviderInterface; use Rhumsaa\Uuid\Provider\TimeProviderInterface; -class UuidFactory +class UuidFactory implements UuidFactoryInterface { /** diff --git a/src/UuidFactoryInterface.php b/src/UuidFactoryInterface.php new file mode 100644 index 0000000..99a743e --- /dev/null +++ b/src/UuidFactoryInterface.php @@ -0,0 +1,21 @@ + Date: Wed, 17 Dec 2014 01:40:10 +0100 Subject: [PATCH 38/54] Add tests for Pecl factory --- src/Uuid.php | 4 ++-- tests/PeclUuidTest.php | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 tests/PeclUuidTest.php diff --git a/src/Uuid.php b/src/Uuid.php index 0da5200..74a3d5a 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -99,7 +99,7 @@ class Uuid implements UuidInterface, \JsonSerializable /** * - * @var UuidFactory + * @var UuidFactoryInterface */ private static $factory = null; @@ -725,7 +725,7 @@ class Uuid implements UuidInterface, \JsonSerializable return self::$factory; } - public static function setFactory(UuidFactory $factory) + public static function setFactory(UuidFactoryInterface $factory) { self::$factory = $factory; } diff --git a/tests/PeclUuidTest.php b/tests/PeclUuidTest.php new file mode 100644 index 0000000..a5cf9f0 --- /dev/null +++ b/tests/PeclUuidTest.php @@ -0,0 +1,17 @@ + Date: Wed, 17 Dec 2014 02:39:03 +0100 Subject: [PATCH 39/54] Add more unit tests for Pecl-based factory Do not try to install UUID ext in HHVM run --- .travis.yml | 1 + src/PeclUuidFactory.php | 49 ++++++++++++---- src/Uuid.php | 2 +- tests/PeclUuidTest.php | 124 +++++++++++++++++++++++++++++++++++++--- 4 files changed, 156 insertions(+), 20 deletions(-) diff --git a/.travis.yml b/.travis.yml index 7dba238..69f5091 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,6 +9,7 @@ php: before_script: - composer self-update - composer install --dev --prefer-source + - sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then pecl install uuid; fi;' script: - ./vendor/bin/phpunit --coverage-text --coverage-clover ./build/logs/clover.xml diff --git a/src/PeclUuidFactory.php b/src/PeclUuidFactory.php index 9cf881c..35c9a11 100644 --- a/src/PeclUuidFactory.php +++ b/src/PeclUuidFactory.php @@ -2,27 +2,50 @@ namespace Rhumsaa\Uuid; +/** + * Factory relying on PECL UUID library whenever possible, otherwise defaulting + * to pure PHP factory. + * @author thibaud + * + */ class PeclUuidFactory implements UuidFactoryInterface { - + /** + * + * @var UuidFactoryInterface + */ private $factory; + /** + * + * @var boolean + */ + private $hasExt = false; + + /** + * + * @param UuidFactoryInterface $factory + */ public function __construct(UuidFactoryInterface $factory) { + $this->hasExt = extension_loaded('uuid'); $this->factory = $factory; } - /* + /** * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::uuid1() */ public function uuid1($node = null, $clockSeq = null) { - $uuid = uuid_create(UUID_TYPE_TIME); + if (! $this->hasExt || $node !== null || $clockSeq !== null) { + // If either param is not null, we cannot use PECL without breaking LSP. + return $this->factory->uuid1($node, $clockSeq); + } - return $this->fromString($uuid); + return $this->fromString(uuid_create(UUID_TYPE_TIME)); } - /* + /** * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::uuid3() */ public function uuid3($ns, $name) @@ -30,17 +53,19 @@ class PeclUuidFactory implements UuidFactoryInterface return $this->factory->uuid3($ns, $name); } - /* + /** * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::uuid4() */ public function uuid4() { - $uuid = uuid_create(UUID_TYPE_RANDOM); + if (! $this->hasExt) { + return $this->factory->uuid4(); + } - return $this->fromString($uuid); + return $this->fromString(uuid_create(UUID_TYPE_RANDOM)); } - /* + /** * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::uuid5() */ public function uuid5($ns, $name) @@ -48,7 +73,7 @@ class PeclUuidFactory implements UuidFactoryInterface return $this->factory->uuid5($ns, $name); } - /* + /** * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::fromBytes() */ public function fromBytes($bytes) @@ -56,7 +81,7 @@ class PeclUuidFactory implements UuidFactoryInterface return $this->factory->fromBytes($bytes); } - /* + /** * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::fromString() */ public function fromString($name) @@ -64,7 +89,7 @@ class PeclUuidFactory implements UuidFactoryInterface return $this->factory->fromString($name); } - /* + /** * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::fromInteger() */ public function fromInteger($integer) diff --git a/src/Uuid.php b/src/Uuid.php index 74a3d5a..30589ff 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -719,7 +719,7 @@ class Uuid implements UuidInterface, \JsonSerializable public static function getFactory() { if (! self::$factory) { - self::$factory = new UuidFactory(); + self::$factory = new PeclUuidFactory(new UuidFactory()); } return self::$factory; diff --git a/tests/PeclUuidTest.php b/tests/PeclUuidTest.php index a5cf9f0..4ee7966 100644 --- a/tests/PeclUuidTest.php +++ b/tests/PeclUuidTest.php @@ -2,16 +2,126 @@ namespace Rhumsaa\Uuid; -use Rhumsaa\Uuid\Provider\Time\SystemTimeProvider; -use Rhumsaa\Uuid\Provider\Time\FixedTimeProvider; -use Rhumsaa\Uuid\Generator\CombGenerator; - -class PeclUuidTest extends UuidTest +class PeclUuidTest extends \PHPUnit_Framework_TestCase { + private $mockFactory; + + public static $mockNoExt = false; + protected function setUp() + { + $this->mockFactory = $this->getMock('Rhumsaa\Uuid\UuidFactoryInterface'); + + if (! function_exists('\Rhumsaa\Uuid\extension_loaded')) { + // Hackish, but allows mocking extension not avail without + // breaking the function if tests are loaded accidently in non test env. + eval('namespace Rhumsaa\Uuid { function extension_loaded($name) { + return ! PeclUuidTest::$mockNoExt; + } }'); + } + + Uuid::setFactory(new PeclUuidFactory($this->mockFactory)); + } + + public function getUuid1Params() + { + return [ + [ true, null ], + [ null, true ], + [ true, true ] + ]; + } + + /** + * @dataProvider getUuid1Params + */ + public function testUuid1WithParametersIsDelegated($node, $clockSeq) + { + $node = true; + $clockSeq = null; + + $this->mockFactory->expects($this->once()) + ->method('uuid1') + ->with($node, $clockSeq); + + Uuid::uuid1($node, $clockSeq); + } + + public function testUuid1WithoutParametersIsNotDelegated() + { + $this->mockFactory->expects($this->never()) + ->method('uuid1'); + + Uuid::uuid1(); + } + + public function testUuid1WithoutExtensionIsDelegated() + { + self::$mockNoExt = true; + + Uuid::setFactory(new PeclUuidFactory($this->mockFactory)); + + $this->mockFactory->expects($this->once()) + ->method('uuid1'); + + Uuid::uuid1(); + + self::$mockNoExt = false; + } + + public function testUuid1Version() { Uuid::setFactory(new PeclUuidFactory(new UuidFactory())); - RandomGeneratorFactory::$forceNoOpensslRandomPseudoBytes = false; + $uuid = Uuid::uuid1(); + + $this->assertEquals(1, $uuid->getVersion()); } -} + + public function testUuid3IsDelegated() + { + $this->mockFactory->expects($this->once()) + ->method('uuid3'); + + Uuid::uuid3(Uuid::NAMESPACE_DNS, str_replace('\\', '.', __NAMESPACE__)); + } + + public function testUuid4WithoutExtensionIsDelegated() + { + self::$mockNoExt = true; + + Uuid::setFactory(new PeclUuidFactory($this->mockFactory)); + + $this->mockFactory->expects($this->once()) + ->method('uuid4'); + + Uuid::uuid4(); + + self::$mockNoExt = false; + } + + public function testUuid4WithParametersIsNeverDelegated() + { + $this->mockFactory->expects($this->never()) + ->method('uuid4'); + + Uuid::uuid4(); + } + + public function testUuid4Version() + { + Uuid::setFactory(new PeclUuidFactory(new UuidFactory())); + + $uuid = Uuid::uuid4(); + + $this->assertEquals(4, $uuid->getVersion()); + } + + public function testUuid5IsDelegated() + { + $this->mockFactory->expects($this->once()) + ->method('uuid5'); + + Uuid::uuid5(Uuid::NAMESPACE_DNS, str_replace('\\', '.', __NAMESPACE__)); + } +} \ No newline at end of file From 82c57cac9936d16bb06dc8c358b01f7fb295e30f Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Wed, 17 Dec 2014 03:17:14 +0100 Subject: [PATCH 40/54] Add UUID system library to build Use sudo to install UUID lib --- .travis.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 69f5091..bde7bb3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,10 +6,13 @@ php: - 5.6 - hhvm +before_install: + - sudo apt-get update && sudo apt-get install uuid-dev + before_script: - composer self-update - composer install --dev --prefer-source - - sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then pecl install uuid; fi;' + - sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then printf "\n" | pecl install uuid; fi;' script: - ./vendor/bin/phpunit --coverage-text --coverage-clover ./build/logs/clover.xml From 6047058adcb58a6ebd4bafc79b6ae224543252aa Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Wed, 17 Dec 2014 16:02:42 +0100 Subject: [PATCH 41/54] Enable extension Enable extension Debug for Travis build Run PECL tests only WIP --- .travis.yml | 3 ++- tests/PeclUuidTest.php | 3 --- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index bde7bb3..f87070b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,9 +13,10 @@ before_script: - composer self-update - composer install --dev --prefer-source - sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then printf "\n" | pecl install uuid; fi;' + - phpenv rehash script: - - ./vendor/bin/phpunit --coverage-text --coverage-clover ./build/logs/clover.xml + - ./vendor/bin/phpunit --coverage-text --coverage-clover ./build/logs/clover.xml tests/PeclUuidTest.php - ./vendor/bin/phpcs --standard=phpcs.xml ./ after_script: php vendor/bin/coveralls diff --git a/tests/PeclUuidTest.php b/tests/PeclUuidTest.php index 4ee7966..bec3df5 100644 --- a/tests/PeclUuidTest.php +++ b/tests/PeclUuidTest.php @@ -37,9 +37,6 @@ class PeclUuidTest extends \PHPUnit_Framework_TestCase */ public function testUuid1WithParametersIsDelegated($node, $clockSeq) { - $node = true; - $clockSeq = null; - $this->mockFactory->expects($this->once()) ->method('uuid1') ->with($node, $clockSeq); From d6205aaf475504c9bb81ff03b5072f7757a431c4 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Mon, 29 Dec 2014 21:57:42 +0100 Subject: [PATCH 42/54] Remove hackish extension_loaded mock --- src/PeclUuidFactory.php | 8 ++++++++ tests/PeclUuidTest.php | 24 ++++++------------------ 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/PeclUuidFactory.php b/src/PeclUuidFactory.php index 35c9a11..5436ece 100644 --- a/src/PeclUuidFactory.php +++ b/src/PeclUuidFactory.php @@ -32,6 +32,14 @@ class PeclUuidFactory implements UuidFactoryInterface $this->factory = $factory; } + /** + * Forces factory to act as if PECL extension is not available + */ + public function disablePecl() + { + $this->hasExt = false; + } + /** * (non-PHPdoc) @see \Rhumsaa\Uuid\UuidFactoryInterface::uuid1() */ diff --git a/tests/PeclUuidTest.php b/tests/PeclUuidTest.php index bec3df5..6d0d327 100644 --- a/tests/PeclUuidTest.php +++ b/tests/PeclUuidTest.php @@ -6,20 +6,10 @@ class PeclUuidTest extends \PHPUnit_Framework_TestCase { private $mockFactory; - public static $mockNoExt = false; - protected function setUp() { $this->mockFactory = $this->getMock('Rhumsaa\Uuid\UuidFactoryInterface'); - if (! function_exists('\Rhumsaa\Uuid\extension_loaded')) { - // Hackish, but allows mocking extension not avail without - // breaking the function if tests are loaded accidently in non test env. - eval('namespace Rhumsaa\Uuid { function extension_loaded($name) { - return ! PeclUuidTest::$mockNoExt; - } }'); - } - Uuid::setFactory(new PeclUuidFactory($this->mockFactory)); } @@ -54,16 +44,15 @@ class PeclUuidTest extends \PHPUnit_Framework_TestCase public function testUuid1WithoutExtensionIsDelegated() { - self::$mockNoExt = true; + $factory = new PeclUuidFactory($this->mockFactory); + $factory->disablePecl(); - Uuid::setFactory(new PeclUuidFactory($this->mockFactory)); + Uuid::setFactory($factory); $this->mockFactory->expects($this->once()) ->method('uuid1'); Uuid::uuid1(); - - self::$mockNoExt = false; } public function testUuid1Version() @@ -85,16 +74,15 @@ class PeclUuidTest extends \PHPUnit_Framework_TestCase public function testUuid4WithoutExtensionIsDelegated() { - self::$mockNoExt = true; + $factory = new PeclUuidFactory($this->mockFactory); + $factory->disablePecl(); - Uuid::setFactory(new PeclUuidFactory($this->mockFactory)); + Uuid::setFactory($factory); $this->mockFactory->expects($this->once()) ->method('uuid4'); Uuid::uuid4(); - - self::$mockNoExt = false; } public function testUuid4WithParametersIsNeverDelegated() From ace0db770777859dc9e8645676e2e7c1328cbc84 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Mon, 29 Dec 2014 22:06:06 +0100 Subject: [PATCH 43/54] Skip tests that cannot succeed with HHVM --- tests/PeclUuidTest.php | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/PeclUuidTest.php b/tests/PeclUuidTest.php index 6d0d327..a19024f 100644 --- a/tests/PeclUuidTest.php +++ b/tests/PeclUuidTest.php @@ -36,6 +36,10 @@ class PeclUuidTest extends \PHPUnit_Framework_TestCase public function testUuid1WithoutParametersIsNotDelegated() { + if (defined('HHVM_VERSION')) { + $this->markTestSkipped('PECL Uuid extension not available in HHVM'); + } + $this->mockFactory->expects($this->never()) ->method('uuid1'); @@ -87,6 +91,10 @@ class PeclUuidTest extends \PHPUnit_Framework_TestCase public function testUuid4WithParametersIsNeverDelegated() { + if (defined('HHVM_VERSION')) { + $this->markTestSkipped('PECL Uuid extension not available in HHVM'); + } + $this->mockFactory->expects($this->never()) ->method('uuid4'); From 01b2b0b72e9658b35f5c66e97e9139937996e0d9 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Mon, 29 Dec 2014 22:09:34 +0100 Subject: [PATCH 44/54] Run all tests --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index f87070b..b54bbf0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ before_script: - phpenv rehash script: - - ./vendor/bin/phpunit --coverage-text --coverage-clover ./build/logs/clover.xml tests/PeclUuidTest.php + - ./vendor/bin/phpunit --coverage-text --coverage-clover ./build/logs/clover.xml - ./vendor/bin/phpcs --standard=phpcs.xml ./ after_script: php vendor/bin/coveralls From cc23f64d589996a5e714814e8a71426e4d022390 Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Tue, 16 Dec 2014 23:23:35 +0100 Subject: [PATCH 45/54] Add COMB generator for use with UUID4 --- src/Generator/CombGenerator.php | 68 +++++++++++++++++++++++++++++++++ src/UuidFactory.php | 10 +++++ tests/UuidTest.php | 45 ++++++++++++++++++++++ 3 files changed, 123 insertions(+) create mode 100644 src/Generator/CombGenerator.php diff --git a/src/Generator/CombGenerator.php b/src/Generator/CombGenerator.php new file mode 100644 index 0000000..24e3428 --- /dev/null +++ b/src/Generator/CombGenerator.php @@ -0,0 +1,68 @@ +converter = $numberConverter; + $this->randomGenerator = $generator; + $this->timestampBytes = 6; + } + + /** + * (non-PHPdoc) @see \Rhumsaa\Uuid\RandomGeneratorInterface::generate() + */ + public function generate($length) + { + if ($length < $this->timestampBytes || $length < 0) { + throw new \InvalidArgumentException('Length must be a positive integer.'); + } + + $hash = ''; + + if ($this->timestampBytes > 0 && $length > $this->timestampBytes) { + $hash = $this->randomGenerator->generate($length - $this->timestampBytes); + } + + $lsbTime = str_pad($this->converter->toHex($this->timestamp()), $this->timestampBytes * 2, '0', STR_PAD_LEFT); + + if ($this->timestampBytes > 0 && strlen($lsbTime) > $this->timestampBytes * 2) { + $lsbTime = substr($lsbTime, 0 - ($this->timestampBytes * 2)); + } + + return hex2bin(str_pad(bin2hex($hash), $length - $this->timestampBytes, '0')) . hex2bin($lsbTime); + } + + /** + * Returns current timestamp as integer, precise to 0.00001 seconds + * @return number + */ + private function timestamp() + { + $time = explode(' ', microtime(false)); + + return $time[1] . substr($time[0], 2, 5); + } +} \ No newline at end of file diff --git a/src/UuidFactory.php b/src/UuidFactory.php index 9885742..052feaf 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -74,6 +74,16 @@ class UuidFactory implements UuidFactoryInterface return $this->codec; } + public function getNumberConverter() + { + return $this->numberConverter; + } + + public function getTimeConverter() + { + return $this->timeConverter; + } + public function setTimeConverter(TimeConverterInterface $converter) { $this->timeConverter = $converter; diff --git a/tests/UuidTest.php b/tests/UuidTest.php index 8d609fe..d43f1f2 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -4,6 +4,7 @@ namespace Rhumsaa\Uuid; use Rhumsaa\Uuid\Provider\Time\SystemTimeProvider; use Rhumsaa\Uuid\Provider\Time\FixedTimeProvider; +use Rhumsaa\Uuid\Generator\CombGenerator; class UuidTest extends TestCase { @@ -785,6 +786,50 @@ class UuidTest extends TestCase $this->assertEquals(4, $uuid->getVersion()); } + /** + * Tests that generated UUID's using COMB are sequential + * @return string + */ + public function testUuid4Comb() + { + $mock = $this->getMock('Rhumsaa\Uuid\RandomGeneratorInterface'); + $mock->expects($this->any()) + ->method('generate') + ->willReturnCallback(function ($length) + { + // Makes first fields of UUIDs equal + return str_pad('', $length, '0'); + }); + + $factory = new UuidFactory(); + $generator = new CombGenerator($mock, $factory->getNumberConverter()); + $factory->setRandomGenerator($generator); + + $previous = $factory->uuid4(); + + for ($i = 0; $i < 1000; $i ++) { + $uuid = $factory->uuid4(); + $this->assertGreaterThan($previous->toString(), $uuid->toString()); + + $previous = $uuid; + } + } + + /** + * Test that COMB UUID's have a version 4 flag + */ + public function testUuid4CombVersion() + { + $factory = new UuidFactory(); + $generator = new CombGenerator(RandomGeneratorFactory::getGenerator(), $factory->getNumberConverter()); + + $factory->setRandomGenerator($generator); + + $uuid = $factory->uuid4(); + + $this->assertEquals(4, $uuid->getVersion()); + } + /** * The "python.org" UUID is a known entity, so we're testing that this * library generates a matching UUID for the same name. From 8bece7c95bf000c4595fc22c271ba6e0a2465d6a Mon Sep 17 00:00:00 2001 From: Thibaud Fabre Date: Sat, 7 Feb 2015 13:12:50 +0100 Subject: [PATCH 46/54] Add COMB and GUID options to command line --- src/Console/Command/GenerateCommand.php | 31 +++++++++++++++++++++++++ src/UuidFactory.php | 5 ++++ 2 files changed, 36 insertions(+) diff --git a/src/Console/Command/GenerateCommand.php b/src/Console/Command/GenerateCommand.php index 78a1669..09ff88d 100644 --- a/src/Console/Command/GenerateCommand.php +++ b/src/Console/Command/GenerateCommand.php @@ -18,6 +18,10 @@ use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Rhumsaa\Uuid\Console\Exception; use Rhumsaa\Uuid\Uuid; +use Rhumsaa\Uuid\Generator\CombGenerator; +use Rhumsaa\Uuid\Codec\GuidStringCodec; +use Rhumsaa\Uuid\FeatureSet; +use Rhumsaa\Uuid\UuidFactory; /** * Provides the console command to generate UUIDs @@ -60,6 +64,18 @@ class GenerateCommand extends Command InputOption::VALUE_REQUIRED, 'Generate count UUIDs instead of just a single one.', 1 + ) + ->addOption( + 'comb', + null, + InputOption::VALUE_NONE, + 'For version 4 UUIDs, uses the COMB strategy to generate the random data.' + ) + ->addOption( + 'guid', + 'g', + InputOption::VALUE_NONE, + 'Returns a GUID formatted UUID.' ); } @@ -82,6 +98,21 @@ class GenerateCommand extends Command ) ); + if (((bool) $input->getOption('guid')) == true) { + $features = new FeatureSet(true); + + Uuid::setFactory(new UuidFactory($features)); + } + + if (((bool) $input->getOption('comb')) === true) { + Uuid::getFactory()->setRandomGenerator( + new CombGenerator( + Uuid::getFactory()->getRandomGenerator(), + Uuid::getFactory()->getNumberConverter() + ) + ); + } + for ($i = 0; $i < $count; $i++) { $uuids[] = $this->createUuid( $input->getArgument('version'), diff --git a/src/UuidFactory.php b/src/UuidFactory.php index 052feaf..632cb4d 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -74,6 +74,11 @@ class UuidFactory implements UuidFactoryInterface return $this->codec; } + public function getRandomGenerator() + { + return $this->randomGenerator; + } + public function getNumberConverter() { return $this->numberConverter; From b61689126b440489c8746cb378cca7f698bbeec8 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Sat, 21 Mar 2015 20:14:26 +0000 Subject: [PATCH 47/54] Updating the build tools --- .travis.yml | 14 +++++++++----- composer.json | 7 ++++--- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/.travis.yml b/.travis.yml index b54bbf0..fbc19fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,19 +4,23 @@ php: - 5.4 - 5.5 - 5.6 + - 7.0 - hhvm before_install: - sudo apt-get update && sudo apt-get install uuid-dev before_script: - - composer self-update - - composer install --dev --prefer-source + - travis_retry composer self-update + - travis_retry composer install --no-interaction --prefer-source - sh -c 'if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then printf "\n" | pecl install uuid; fi;' - phpenv rehash script: - - ./vendor/bin/phpunit --coverage-text --coverage-clover ./build/logs/clover.xml - - ./vendor/bin/phpcs --standard=phpcs.xml ./ + - mkdir -p build/logs + - ./vendor/bin/parallel-lint src tests + - ./vendor/bin/phpunit --coverage-text + - ./vendor/bin/phpcs src --standard=psr2 -sp -after_script: php vendor/bin/coveralls +after_script: + - php vendor/bin/coveralls diff --git a/composer.json b/composer.json index c8737ec..14c38c2 100644 --- a/composer.json +++ b/composer.json @@ -27,9 +27,10 @@ "ircmaxell/random-lib": "~1.0", "symfony/console": "~2.3", "doctrine/dbal": ">=2.3", - "phpunit/phpunit": "~4.1", - "squizlabs/php_codesniffer": "2.0.0RC4", - "satooshi/php-coveralls": "~0.6" + "phpunit/phpunit": "~4.5", + "squizlabs/php_codesniffer": "~2.2", + "jakub-onderka/php-parallel-lint": "0.8.*", + "satooshi/php-coveralls": "0.6.*" }, "bin": ["bin/uuid"], "suggest": { From 2fd86e2cf914488201f2d15783f463dd58de94df Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Sat, 21 Mar 2015 20:14:43 +0000 Subject: [PATCH 48/54] Coding standards fixes --- src/Generator/CombGenerator.php | 4 ++-- src/PeclUuidFactory.php | 2 +- src/UuidFactoryInterface.php | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/Generator/CombGenerator.php b/src/Generator/CombGenerator.php index 24e3428..9a0c021 100644 --- a/src/Generator/CombGenerator.php +++ b/src/Generator/CombGenerator.php @@ -42,7 +42,7 @@ class CombGenerator implements RandomGeneratorInterface $hash = ''; - if ($this->timestampBytes > 0 && $length > $this->timestampBytes) { + if ($this->timestampBytes > 0 && $length > $this->timestampBytes) { $hash = $this->randomGenerator->generate($length - $this->timestampBytes); } @@ -65,4 +65,4 @@ class CombGenerator implements RandomGeneratorInterface return $time[1] . substr($time[0], 2, 5); } -} \ No newline at end of file +} diff --git a/src/PeclUuidFactory.php b/src/PeclUuidFactory.php index 5436ece..4ceea8f 100644 --- a/src/PeclUuidFactory.php +++ b/src/PeclUuidFactory.php @@ -104,4 +104,4 @@ class PeclUuidFactory implements UuidFactoryInterface { return $this->factory->fromInteger($integer); } -} \ No newline at end of file +} diff --git a/src/UuidFactoryInterface.php b/src/UuidFactoryInterface.php index 99a743e..ea589a7 100644 --- a/src/UuidFactoryInterface.php +++ b/src/UuidFactoryInterface.php @@ -17,5 +17,4 @@ interface UuidFactoryInterface public function fromString($name); public function fromInteger($integer); - -} \ No newline at end of file +} From ff1f55a05b9e6d5afe5721a12f878b5ea68a090f Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Sat, 21 Mar 2015 20:17:28 +0000 Subject: [PATCH 49/54] Remove the PHP CodeSniffer rules file --- phpcs.xml | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 phpcs.xml diff --git a/phpcs.xml b/phpcs.xml deleted file mode 100644 index 6aa2b59..0000000 --- a/phpcs.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - Coding standard rules for Rhumsaa\Uuid - - */build/* - */tests/* - */vendor/* - - - - - - - From 2c1c525d705d6707d6f984020fba461ec9db3e8f Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Sat, 21 Mar 2015 20:24:15 +0000 Subject: [PATCH 50/54] Updating README badges [ci skip] --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 850acd7..2e068b3 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,11 @@ # Rhumsaa\Uuid for PHP -[![Build Status](https://travis-ci.org/ramsey/uuid.png?branch=master)](https://travis-ci.org/ramsey/uuid) -[![Coverage Status](https://coveralls.io/repos/ramsey/uuid/badge.png)](https://coveralls.io/r/ramsey/uuid) -[![Latest Stable Version](https://poser.pugx.org/rhumsaa/uuid/v/stable.png)](https://packagist.org/packages/rhumsaa/uuid) -[![Latest Unstable Version](https://poser.pugx.org/rhumsaa/uuid/v/unstable.png)](https://packagist.org/packages/rhumsaa/uuid) -[![Total Downloads](https://poser.pugx.org/rhumsaa/uuid/downloads.png)](https://packagist.org/packages/rhumsaa/uuid) -[![HHVM Status](http://hhvm.h4cc.de/badge/rhumsaa/uuid.png)](http://hhvm.h4cc.de/package/rhumsaa/uuid) +[![Build Status](https://travis-ci.org/ramsey/uuid.svg?branch=master)](https://travis-ci.org/ramsey/uuid) +[![Coverage Status](https://coveralls.io/repos/ramsey/uuid/badge.svg?branch=master)](https://coveralls.io/r/ramsey/uuid) +[![Latest Stable Version](https://poser.pugx.org/rhumsaa/uuid/v/stable.svg)](https://packagist.org/packages/rhumsaa/uuid) +[![Total Downloads](https://poser.pugx.org/rhumsaa/uuid/downloads.svg)](https://packagist.org/packages/rhumsaa/uuid) +[![Latest Unstable Version](https://poser.pugx.org/rhumsaa/uuid/v/unstable.svg)](https://packagist.org/packages/rhumsaa/uuid) +[![License](https://poser.pugx.org/rhumsaa/uuid/license.svg)](https://packagist.org/packages/rhumsaa/uuid) ## About From 6cfb4fc4c45b15421d4a7810456301dc9daa95b2 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Sat, 21 Mar 2015 20:42:32 +0000 Subject: [PATCH 51/54] PECL UUID extension does not yet work in PHP 7 --- tests/PeclUuidTest.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/tests/PeclUuidTest.php b/tests/PeclUuidTest.php index a19024f..21c484e 100644 --- a/tests/PeclUuidTest.php +++ b/tests/PeclUuidTest.php @@ -40,6 +40,10 @@ class PeclUuidTest extends \PHPUnit_Framework_TestCase $this->markTestSkipped('PECL Uuid extension not available in HHVM'); } + if (version_compare(PHP_VERSION, '7.0.0-dev', '>=')) { + $this->markTestSkipped('PECL Uuid extension does not yet work in PHP 7'); + } + $this->mockFactory->expects($this->never()) ->method('uuid1'); @@ -95,6 +99,10 @@ class PeclUuidTest extends \PHPUnit_Framework_TestCase $this->markTestSkipped('PECL Uuid extension not available in HHVM'); } + if (version_compare(PHP_VERSION, '7.0.0-dev', '>=')) { + $this->markTestSkipped('PECL Uuid extension does not yet work in PHP 7'); + } + $this->mockFactory->expects($this->never()) ->method('uuid4'); @@ -117,4 +125,4 @@ class PeclUuidTest extends \PHPUnit_Framework_TestCase Uuid::uuid5(Uuid::NAMESPACE_DNS, str_replace('\\', '.', __NAMESPACE__)); } -} \ No newline at end of file +} From 7513255743751a1b0feb0c649a7348e54d4b5188 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Sun, 22 Mar 2015 20:44:30 +0000 Subject: [PATCH 52/54] Using extension_loaded() to check whether UUID ext is present --- tests/PeclUuidTest.php | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/tests/PeclUuidTest.php b/tests/PeclUuidTest.php index 21c484e..bf8529e 100644 --- a/tests/PeclUuidTest.php +++ b/tests/PeclUuidTest.php @@ -36,12 +36,8 @@ class PeclUuidTest extends \PHPUnit_Framework_TestCase public function testUuid1WithoutParametersIsNotDelegated() { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('PECL Uuid extension not available in HHVM'); - } - - if (version_compare(PHP_VERSION, '7.0.0-dev', '>=')) { - $this->markTestSkipped('PECL Uuid extension does not yet work in PHP 7'); + if (!extension_loaded('uuid')) { + $this->markTestSkipped('PECL UUID extension not loaded'); } $this->mockFactory->expects($this->never()) @@ -95,12 +91,8 @@ class PeclUuidTest extends \PHPUnit_Framework_TestCase public function testUuid4WithParametersIsNeverDelegated() { - if (defined('HHVM_VERSION')) { - $this->markTestSkipped('PECL Uuid extension not available in HHVM'); - } - - if (version_compare(PHP_VERSION, '7.0.0-dev', '>=')) { - $this->markTestSkipped('PECL Uuid extension does not yet work in PHP 7'); + if (!extension_loaded('uuid')) { + $this->markTestSkipped('PECL UUID extension not loaded'); } $this->mockFactory->expects($this->never()) From 2ae6adc891e805a898e5636f444726673812dc6c Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Tue, 21 Apr 2015 08:14:34 -0500 Subject: [PATCH 53/54] Updating Badge Poser badges [ci skip] --- README.md | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 2e068b3..f044ea3 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,9 @@ [![Build Status](https://travis-ci.org/ramsey/uuid.svg?branch=master)](https://travis-ci.org/ramsey/uuid) [![Coverage Status](https://coveralls.io/repos/ramsey/uuid/badge.svg?branch=master)](https://coveralls.io/r/ramsey/uuid) -[![Latest Stable Version](https://poser.pugx.org/rhumsaa/uuid/v/stable.svg)](https://packagist.org/packages/rhumsaa/uuid) -[![Total Downloads](https://poser.pugx.org/rhumsaa/uuid/downloads.svg)](https://packagist.org/packages/rhumsaa/uuid) -[![Latest Unstable Version](https://poser.pugx.org/rhumsaa/uuid/v/unstable.svg)](https://packagist.org/packages/rhumsaa/uuid) -[![License](https://poser.pugx.org/rhumsaa/uuid/license.svg)](https://packagist.org/packages/rhumsaa/uuid) +[![Latest Stable Version](https://poser.pugx.org/rhumsaa/uuid/v/stable)](https://packagist.org/packages/rhumsaa/uuid) +[![Total Downloads](https://poser.pugx.org/rhumsaa/uuid/downloads)](https://packagist.org/packages/rhumsaa/uuid) +[![Latest Unstable Version](https://poser.pugx.org/rhumsaa/uuid/v/unstable)](https://packagist.org/packages/rhumsaa/uuid) [![License](https://poser.pugx.org/rhumsaa/uuid/license)](https://packagist.org/packages/rhumsaa/uuid) ## About From d67c3490a8c9a3c71b8b7e69a2af83a0de04c4b2 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Sat, 25 Apr 2015 12:11:37 -0500 Subject: [PATCH 54/54] Change namespace to "Ramsey"; closes #48 --- CHANGELOG.md | 2 +- README.md | 14 +- apigen.neon | 4 +- bin/uuid | 6 +- composer.json | 4 +- phpunit.xml.dist | 2 +- src/Builder/DefaultUuidBuilder.php | 10 +- src/Builder/DegradedUuidBuilder.php | 10 +- src/Codec/GuidStringCodec.php | 8 +- src/Codec/StringCodec.php | 10 +- src/CodecInterface.php | 2 +- src/Console/Application.php | 8 +- src/Console/Command/DecodeCommand.php | 10 +- src/Console/Command/GenerateCommand.php | 16 +- src/Console/Exception.php | 4 +- src/Console/Util/ErrorHandler.php | 4 +- src/Console/Util/Formatter/V1Formatter.php | 8 +- src/Console/Util/Formatter/V2Formatter.php | 8 +- src/Console/Util/Formatter/V3Formatter.php | 8 +- src/Console/Util/Formatter/V4Formatter.php | 8 +- src/Console/Util/Formatter/V5Formatter.php | 8 +- .../Util/UuidContentFormatterInterface.php | 4 +- src/Console/Util/UuidFormatter.php | 16 +- src/Converter/Number/BigNumberConverter.php | 4 +- .../Number/DegradedNumberConverter.php | 6 +- src/Converter/NumberConverterInterface.php | 2 +- src/Converter/Time/BigNumberTimeConverter.php | 4 +- src/Converter/Time/DegradedTimeConverter.php | 6 +- src/Converter/Time/PhpTimeConverter.php | 4 +- src/Converter/TimeConverterInterface.php | 2 +- src/DegradedUuid.php | 4 +- src/Doctrine/UuidType.php | 6 +- .../UnsatisfiedDependencyException.php | 4 +- .../UnsupportedOperationException.php | 4 +- src/FeatureSet.php | 28 ++-- src/Generator/CombGenerator.php | 8 +- src/Generator/MtRandGenerator.php | 4 +- src/Generator/OpenSslGenerator.php | 4 +- src/Generator/RandomLibAdapter.php | 4 +- src/PeclUuidFactory.php | 16 +- src/Provider/Node/FallbackNodeProvider.php | 4 +- src/Provider/Node/RandomNodeProvider.php | 4 +- src/Provider/Node/SystemNodeProvider.php | 4 +- src/Provider/NodeProviderInterface.php | 2 +- src/Provider/Time/FixedTimeProvider.php | 4 +- src/Provider/Time/SystemTimeProvider.php | 4 +- src/Provider/TimeProviderInterface.php | 2 +- src/RandomGeneratorFactory.php | 6 +- src/RandomGeneratorInterface.php | 2 +- src/Uuid.php | 14 +- src/UuidBuilder.php | 2 +- src/UuidFactory.php | 10 +- src/UuidFactoryInterface.php | 2 +- src/UuidInterface.php | 4 +- tests/Console/ApplicationTest.php | 8 +- tests/Console/Command/DecodeCommandTest.php | 32 ++-- tests/Console/Command/GenerateCommandTest.php | 146 +++++++++--------- tests/Console/TestCase.php | 4 +- tests/Console/Util/BufferedOutput.php | 2 +- tests/Console/Util/ErrorHandlerTest.php | 12 +- tests/Console/Util/TestOutput.php | 2 +- .../Number/DegradedNumberConverterTest.php | 8 +- tests/Doctrine/UuidTypeTest.php | 26 ++-- tests/PeclUuidTest.php | 4 +- tests/RandomGeneratorFactoryTest.php | 6 +- tests/TestCase.php | 2 +- tests/UuidBcTag1_1_2Test.php | 22 +-- tests/UuidFactoryTest.php | 2 +- tests/UuidTest.php | 70 ++++----- tests/bootstrap.php | 2 +- 70 files changed, 348 insertions(+), 348 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e4a9b58..7f50688 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# Rhumsaa\Uuid Changelog +# Ramsey\Uuid Changelog ## 2.8.0 diff --git a/README.md b/README.md index f044ea3..e0b9b23 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Rhumsaa\Uuid for PHP +# Ramsey\Uuid for PHP [![Build Status](https://travis-ci.org/ramsey/uuid.svg?branch=master)](https://travis-ci.org/ramsey/uuid) [![Coverage Status](https://coveralls.io/repos/ramsey/uuid/badge.svg?branch=master)](https://coveralls.io/r/ramsey/uuid) @@ -8,7 +8,7 @@ ## About -Rhumsaa\Uuid is a PHP 5.4+ library for generating and working with +Ramsey\Uuid is a PHP 5.4+ library for generating and working with [RFC 4122][rfc4122] version 1, 3, 4, and 5 universally unique identifiers (UUID). From [Wikipedia](http://en.wikipedia.org/wiki/Universally_unique_identifier): @@ -43,7 +43,7 @@ library are recommended. However, this library is designed to work on 32-bit builds of PHP without Moontoast\Math, with some degraded functionality. Please check the API documentation for more information. -If a particular requirement is not present, then a `Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException` +If a particular requirement is not present, then a `Ramsey\Uuid\Exception\UnsatisfiedDependencyException` is thrown, allowing one to catch a bad call in an environment where the call is not supported and gracefully degrade. @@ -53,8 +53,8 @@ not supported and gracefully degrade. add(new Command\GenerateCommand()); diff --git a/composer.json b/composer.json index 14c38c2..5427177 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "rhumsaa/uuid", + "name": "ramsey/uuid", "description": "A PHP 5.4+ library for generating RFC 4122 version 1, 3, 4, and 5 universally unique identifiers (UUID).", "type": "library", "keywords": ["uuid", "identifier", "guid"], @@ -40,7 +40,7 @@ "doctrine/dbal": "Allow the use of a UUID as doctrine field type." }, "autoload": { - "psr-4": {"Rhumsaa\\Uuid\\": "src/"} + "psr-4": {"Ramsey\\Uuid\\": "src/"} }, "extra": { "branch-alias": { diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c8ee44a..dc63149 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -11,7 +11,7 @@ - diff --git a/src/Builder/DefaultUuidBuilder.php b/src/Builder/DefaultUuidBuilder.php index 0cf6720..b6e2282 100644 --- a/src/Builder/DefaultUuidBuilder.php +++ b/src/Builder/DefaultUuidBuilder.php @@ -1,11 +1,11 @@ '00000000', @@ -136,7 +136,7 @@ class Uuid implements UuidInterface, \JsonSerializable * * @param array $fields * @param CodecInterface $codec String codec - * @link Rhumsaa.Uuid.Uuid.html#method_getFields + * @link Ramsey.Uuid.Uuid.html#method_getFields */ public function __construct(array $fields, NumberConverterInterface $converter, CodecInterface $codec) { @@ -760,7 +760,7 @@ class Uuid implements UuidInterface, \JsonSerializable * * @param string|\Moontoast\Math\BigNumber $integer String/BigNumber representation of UUID integer * @throws Exception\UnsatisfiedDependencyException If Moontoast\Math\BigNumber is not present - * @return \Rhumsaa\Uuid\Uuid + * @return \Ramsey\Uuid\Uuid */ public static function fromInteger($integer) { diff --git a/src/UuidBuilder.php b/src/UuidBuilder.php index 29b253b..ec99e70 100644 --- a/src/UuidBuilder.php +++ b/src/UuidBuilder.php @@ -1,6 +1,6 @@ assertInstanceOf('Rhumsaa\\Uuid\\Console\\Application', $app); + $this->assertInstanceOf('Ramsey\\Uuid\\Console\\Application', $app); $this->assertEquals('uuid', $app->getName()); - $this->assertEquals(\Rhumsaa\Uuid\Uuid::VERSION, $app->getVersion()); + $this->assertEquals(\Ramsey\Uuid\Uuid::VERSION, $app->getVersion()); } } diff --git a/tests/Console/Command/DecodeCommandTest.php b/tests/Console/Command/DecodeCommandTest.php index fc70b64..d32de49 100644 --- a/tests/Console/Command/DecodeCommandTest.php +++ b/tests/Console/Command/DecodeCommandTest.php @@ -1,10 +1,10 @@ execute = new \ReflectionMethod('Rhumsaa\\Uuid\\Console\\Command\\DecodeCommand', 'execute'); + $this->execute = new \ReflectionMethod('Ramsey\\Uuid\\Console\\Command\\DecodeCommand', 'execute'); $this->execute->setAccessible(true); $this->decode = new DecodeCommand(); - $this->decode->setApplication(new \Rhumsaa\Uuid\Console\Application()); + $this->decode->setApplication(new \Ramsey\Uuid\Console\Application()); } /** - * @covers Rhumsaa\Uuid\Console\Command\DecodeCommand::configure + * @covers Ramsey\Uuid\Console\Command\DecodeCommand::configure */ public function testConfigure() { @@ -35,8 +35,8 @@ class DecodeCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\DecodeCommand::execute - * @expectedException Rhumsaa\Uuid\Console\Exception + * @covers Ramsey\Uuid\Console\Command\DecodeCommand::execute + * @expectedException Ramsey\Uuid\Console\Exception * @expectedExceptionMessage Invalid UUID */ public function testExecuteForInvalidUuid() @@ -52,7 +52,7 @@ class DecodeCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\DecodeCommand::execute + * @covers Ramsey\Uuid\Console\Command\DecodeCommand::execute */ public function testExecuteForNonRFC4122Uuid() { @@ -71,7 +71,7 @@ class DecodeCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\DecodeCommand::execute + * @covers Ramsey\Uuid\Console\Command\DecodeCommand::execute */ public function testExecuteForVersion1Uuid() { @@ -90,7 +90,7 @@ class DecodeCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\DecodeCommand::execute + * @covers Ramsey\Uuid\Console\Command\DecodeCommand::execute */ public function testExecuteForVersion2Uuid() { @@ -109,7 +109,7 @@ class DecodeCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\DecodeCommand::execute + * @covers Ramsey\Uuid\Console\Command\DecodeCommand::execute */ public function testExecuteForVersion3Uuid() { @@ -128,7 +128,7 @@ class DecodeCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\DecodeCommand::execute + * @covers Ramsey\Uuid\Console\Command\DecodeCommand::execute */ public function testExecuteForVersion4Uuid() { @@ -147,7 +147,7 @@ class DecodeCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\DecodeCommand::execute + * @covers Ramsey\Uuid\Console\Command\DecodeCommand::execute */ public function testExecuteForVersion5Uuid() { diff --git a/tests/Console/Command/GenerateCommandTest.php b/tests/Console/Command/GenerateCommandTest.php index 93f9f1b..3f7c203 100644 --- a/tests/Console/Command/GenerateCommandTest.php +++ b/tests/Console/Command/GenerateCommandTest.php @@ -1,9 +1,9 @@ execute = new \ReflectionMethod('Rhumsaa\\Uuid\\Console\\Command\\GenerateCommand', 'execute'); + $this->execute = new \ReflectionMethod('Ramsey\\Uuid\\Console\\Command\\GenerateCommand', 'execute'); $this->execute->setAccessible(true); } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::configure + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::configure */ public function testConfigure() { @@ -32,8 +32,8 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid */ public function testExecuteForUuidDefault() { @@ -54,8 +54,8 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid */ public function testExecuteForUuidDefaultWithCount() { @@ -101,8 +101,8 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid */ public function testExecuteForUuidSpecifyVersion1() { @@ -123,8 +123,8 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid */ public function testExecuteForUuidSpecifyVersion1WithCount() { @@ -170,8 +170,8 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid */ public function testExecuteForUuidSpecifyVersion4() { @@ -192,8 +192,8 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid */ public function testExecuteForUuidSpecifyVersion4WithCount() { @@ -239,9 +239,9 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace */ public function testExecuteForUuidSpecifyVersion3WithDnsNs() { @@ -263,9 +263,9 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace */ public function testExecuteForUuidSpecifyVersion3WithUrlNs() { @@ -287,9 +287,9 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace */ public function testExecuteForUuidSpecifyVersion3WithOidNs() { @@ -311,9 +311,9 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace */ public function testExecuteForUuidSpecifyVersion3WithX500Ns() { @@ -335,9 +335,9 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace */ public function testExecuteForUuidSpecifyVersion3WithOtherNs() { @@ -359,10 +359,10 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace - * @expectedException Rhumsaa\Uuid\Console\Exception + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace + * @expectedException Ramsey\Uuid\Console\Exception * @expectedExceptionMessage May be either a UUID in string representation or an identifier */ public function testExecuteForUuidSpecifyVersion3WithInvalidNs() @@ -380,9 +380,9 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace */ public function testExecuteForUuidSpecifyVersion3WithCount() { @@ -407,10 +407,10 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace - * @expectedException Rhumsaa\Uuid\Console\Exception + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace + * @expectedException Ramsey\Uuid\Console\Exception * @expectedExceptionMessage The name argument is required for version 3 or 5 UUIDs */ public function testExecuteForUuidSpecifyVersion3WithoutName() @@ -428,9 +428,9 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace */ public function testExecuteForUuidSpecifyVersion5WithDnsNs() { @@ -452,9 +452,9 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace */ public function testExecuteForUuidSpecifyVersion5WithUrlNs() { @@ -476,9 +476,9 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace */ public function testExecuteForUuidSpecifyVersion5WithOidNs() { @@ -500,9 +500,9 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace */ public function testExecuteForUuidSpecifyVersion5WithX500Ns() { @@ -524,9 +524,9 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace */ public function testExecuteForUuidSpecifyVersion5WithOtherNs() { @@ -548,10 +548,10 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace - * @expectedException Rhumsaa\Uuid\Console\Exception + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace + * @expectedException Ramsey\Uuid\Console\Exception * @expectedExceptionMessage May be either a UUID in string representation or an identifier */ public function testExecuteForUuidSpecifyVersion5WithInvalidNs() @@ -569,9 +569,9 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace */ public function testExecuteForUuidSpecifyVersion5WithCount() { @@ -596,10 +596,10 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::validateNamespace - * @expectedException Rhumsaa\Uuid\Console\Exception + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::validateNamespace + * @expectedException Ramsey\Uuid\Console\Exception * @expectedExceptionMessage The name argument is required for version 3 or 5 UUIDs */ public function testExecuteForUuidSpecifyVersion5WithoutName() @@ -617,9 +617,9 @@ class GenerateCommandTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::execute - * @covers Rhumsaa\Uuid\Console\Command\GenerateCommand::createUuid - * @expectedException Rhumsaa\Uuid\Console\Exception + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::execute + * @covers Ramsey\Uuid\Console\Command\GenerateCommand::createUuid + * @expectedException Ramsey\Uuid\Console\Exception * @expectedExceptionMessage Invalid UUID version. Supported are version "1", "3", "4", and "5". */ public function testExecuteForUuidSpecifyInvalidVersion() diff --git a/tests/Console/TestCase.php b/tests/Console/TestCase.php index 19f4695..727b9c1 100644 --- a/tests/Console/TestCase.php +++ b/tests/Console/TestCase.php @@ -1,7 +1,7 @@ type->convertToPHPValue('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $this->platform); - $this->assertInstanceOf('Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('Ramsey\Uuid\Uuid', $uuid); $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); } /** - * @covers Rhumsaa\Uuid\Doctrine\UuidType::convertToPHPValue + * @covers Ramsey\Uuid\Doctrine\UuidType::convertToPHPValue */ public function testInvalidUuidConversionForPHPValue() { @@ -80,7 +80,7 @@ class UuidTypeTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Doctrine\UuidType::convertToPHPValue + * @covers Ramsey\Uuid\Doctrine\UuidType::convertToPHPValue */ public function testNullConversionForPHPValue() { @@ -88,7 +88,7 @@ class UuidTypeTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Doctrine\UuidType::getName + * @covers Ramsey\Uuid\Doctrine\UuidType::getName */ public function testGetName() { @@ -96,7 +96,7 @@ class UuidTypeTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Doctrine\UuidType::getSqlDeclaration + * @covers Ramsey\Uuid\Doctrine\UuidType::getSqlDeclaration */ public function testGetGuidTypeDeclarationSQL() { @@ -104,7 +104,7 @@ class UuidTypeTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Doctrine\UuidType::requiresSQLCommentHint + * @covers Ramsey\Uuid\Doctrine\UuidType::requiresSQLCommentHint */ public function testRequiresSQLCommentHint() { diff --git a/tests/PeclUuidTest.php b/tests/PeclUuidTest.php index bf8529e..3b368db 100644 --- a/tests/PeclUuidTest.php +++ b/tests/PeclUuidTest.php @@ -1,6 +1,6 @@ mockFactory = $this->getMock('Rhumsaa\Uuid\UuidFactoryInterface'); + $this->mockFactory = $this->getMock('Ramsey\Uuid\UuidFactoryInterface'); Uuid::setFactory(new PeclUuidFactory($this->mockFactory)); } diff --git a/tests/RandomGeneratorFactoryTest.php b/tests/RandomGeneratorFactoryTest.php index 130b7eb..590a7b4 100644 --- a/tests/RandomGeneratorFactoryTest.php +++ b/tests/RandomGeneratorFactoryTest.php @@ -1,6 +1,6 @@ assertNotInstanceOf('\Rhumsaa\Uuid\Generator\OpenSslGenerator', $generator); + $this->assertNotInstanceOf('\Ramsey\Uuid\Generator\OpenSslGenerator', $generator); } public function testFactoryReturnsOpenSslGeneratorIfAvailable() @@ -19,6 +19,6 @@ class RandomGeneratorFactoryTest extends TestCase $generator = RandomGeneratorFactory::getGenerator(); - $this->assertInstanceOf('\Rhumsaa\Uuid\Generator\OpenSslGenerator', $generator); + $this->assertInstanceOf('\Ramsey\Uuid\Generator\OpenSslGenerator', $generator); } } diff --git a/tests/TestCase.php b/tests/TestCase.php index 7427eb7..b8e12ef 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -1,5 +1,5 @@ assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); } @@ -36,7 +36,7 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase public function testFromStringWithCurlyBraces() { $uuid = Uuid::fromString('{ff6f8cb0-c57d-11e1-9b21-0800200c9a66}'); - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); } @@ -54,7 +54,7 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase public function testFromStringWithUrn() { $uuid = Uuid::fromString('urn:uuid:ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); } @@ -106,7 +106,7 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @expectedException Rhumsaa\Uuid\Exception\UnsupportedOperationException + * @expectedException Ramsey\Uuid\Exception\UnsupportedOperationException * @expectedExceptionMessage Not a time-based UUID */ public function testGetDateTimeFromNonVersion1Uuid() @@ -207,7 +207,7 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @expectedException Rhumsaa\Uuid\Exception\UnsupportedOperationException + * @expectedException Ramsey\Uuid\Exception\UnsupportedOperationException * @expectedExceptionMessage Not a time-based UUID */ public function testGetTimestampFromNonVersion1Uuid() @@ -353,7 +353,7 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase public function testUuid1() { $uuid = Uuid::uuid1(); - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $this->assertInstanceOf('\DateTime', $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -364,7 +364,7 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase public function testUuid1WithNodeAndClockSequence() { $uuid = Uuid::uuid1(0x0800200c9a66, 0x1669); - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $this->assertInstanceOf('\DateTime', $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -380,7 +380,7 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase Uuid::setFactory(new UuidFactory(new FeatureSet(false, false, false, true))); $uuid = Uuid::uuid1(); - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $this->assertInstanceOf('\DateTime', $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -420,7 +420,7 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase public function testUuid4() { $uuid = Uuid::uuid4(); - $this->assertInstanceOf('Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('Ramsey\Uuid\Uuid', $uuid); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(4, $uuid->getVersion()); } diff --git a/tests/UuidFactoryTest.php b/tests/UuidFactoryTest.php index b5ca218..62ac35b 100644 --- a/tests/UuidFactoryTest.php +++ b/tests/UuidFactoryTest.php @@ -1,6 +1,6 @@ assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); } @@ -34,7 +34,7 @@ class UuidTest extends TestCase $guid = Uuid::fromString('b08c6fff-7dc5-e111-9b21-0800200c9a66'); - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $guid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $guid); // UUID's and GUID's share the same textual representation $this->assertEquals($uuid->toString(), $guid->toString()); // But not the same binary representation @@ -46,7 +46,7 @@ class UuidTest extends TestCase public function testFromStringWithCurlyBraces() { $uuid = Uuid::fromString('{ff6f8cb0-c57d-11e1-9b21-0800200c9a66}'); - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); } @@ -64,7 +64,7 @@ class UuidTest extends TestCase public function testFromStringWithUrn() { $uuid = Uuid::fromString('urn:uuid:ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); } @@ -179,7 +179,7 @@ class UuidTest extends TestCase } /** - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetDateTimeThrownException() { @@ -187,14 +187,14 @@ class UuidTest extends TestCase $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertInstanceOf('Rhumsaa\Uuid\DegradedUuid', $uuid); - $this->assertInstanceOf('Rhumsaa\Uuid\Converter\Number\DegradedNumberConverter', $uuid->getNumberConverter()); + $this->assertInstanceOf('Ramsey\Uuid\DegradedUuid', $uuid); + $this->assertInstanceOf('Ramsey\Uuid\Converter\Number\DegradedNumberConverter', $uuid->getNumberConverter()); $date = $uuid->getDateTime(); } /** - * @expectedException Rhumsaa\Uuid\Exception\UnsupportedOperationException + * @expectedException Ramsey\Uuid\Exception\UnsupportedOperationException * @expectedExceptionMessage Not a time-based UUID */ public function testGetDateTimeFromNonVersion1Uuid() @@ -225,7 +225,7 @@ class UuidTest extends TestCase } /** - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetFields32Bit() { @@ -265,7 +265,7 @@ class UuidTest extends TestCase } /** - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetLeastSignificantBitsException() { @@ -295,7 +295,7 @@ class UuidTest extends TestCase } /** - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetMostSignificantBitsException() { @@ -324,7 +324,7 @@ class UuidTest extends TestCase } /** - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetNode32Bit() { @@ -369,7 +369,7 @@ class UuidTest extends TestCase } /** - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetTimeLow32Bit() { @@ -432,7 +432,7 @@ class UuidTest extends TestCase } /** - * @expectedException Rhumsaa\Uuid\Exception\UnsupportedOperationException + * @expectedException Ramsey\Uuid\Exception\UnsupportedOperationException * @expectedExceptionMessage Not a time-based UUID */ public function testGetTimestampFromNonVersion1Uuid() @@ -443,7 +443,7 @@ class UuidTest extends TestCase } /** - * @expectedException Rhumsaa\Uuid\Exception\UnsupportedOperationException + * @expectedException Ramsey\Uuid\Exception\UnsupportedOperationException * @expectedExceptionMessage Not a time-based UUID */ public function testGetTimestampHexFromNonVersion1Uuid() @@ -454,7 +454,7 @@ class UuidTest extends TestCase } /** - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetTimestamp32Bit() { @@ -600,7 +600,7 @@ class UuidTest extends TestCase public function testUuid1() { $uuid = Uuid::uuid1(); - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $this->assertInstanceOf('\DateTime', $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -613,7 +613,7 @@ class UuidTest extends TestCase $this->skip64BitTest(); $uuid = Uuid::uuid1(0x0800200c9a66, 0x1669); - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $this->assertInstanceOf('\DateTime', $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -628,7 +628,7 @@ class UuidTest extends TestCase { $uuid = Uuid::uuid1('7160355e'); - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $this->assertInstanceOf('\DateTime', $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -645,7 +645,7 @@ class UuidTest extends TestCase { $uuid = Uuid::uuid1('71B0aD5e'); - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $this->assertInstanceOf('\DateTime', $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -661,7 +661,7 @@ class UuidTest extends TestCase public function testUuid1WithNodeAndClockSequence32Bit() { $uuid = Uuid::uuid1(0x7fffffff, 0x1669); - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $this->assertInstanceOf('\DateTime', $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -706,7 +706,7 @@ class UuidTest extends TestCase Uuid::setFactory(new UuidFactory(new FeatureSet(false, false, false, true))); $uuid = Uuid::uuid1(); - $this->assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $this->assertInstanceOf('\DateTime', $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -770,7 +770,7 @@ class UuidTest extends TestCase public function testUuid4() { $uuid = Uuid::uuid4(); - $this->assertInstanceOf('Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('Ramsey\Uuid\Uuid', $uuid); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(4, $uuid->getVersion()); } @@ -781,7 +781,7 @@ class UuidTest extends TestCase { RandomGeneratorFactory::$forceNoOpensslRandomPseudoBytes = true; $uuid = Uuid::uuid4(); - $this->assertInstanceOf('Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('Ramsey\Uuid\Uuid', $uuid); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(4, $uuid->getVersion()); } @@ -792,7 +792,7 @@ class UuidTest extends TestCase */ public function testUuid4Comb() { - $mock = $this->getMock('Rhumsaa\Uuid\RandomGeneratorInterface'); + $mock = $this->getMock('Ramsey\Uuid\RandomGeneratorInterface'); $mock->expects($this->any()) ->method('generate') ->willReturnCallback(function ($length) @@ -1222,7 +1222,7 @@ class UuidTest extends TestCase } /** - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testCalculateUuidTimeThrownException() { @@ -1323,8 +1323,8 @@ class UuidTest extends TestCase */ public function testUsingNilAsValidUuid() { - $this->assertInstanceOf('Rhumsaa\Uuid\Uuid', Uuid::uuid3(Uuid::NIL, 'randomtext')); - $this->assertInstanceOf('Rhumsaa\Uuid\Uuid', Uuid::uuid5(Uuid::NIL, 'randomtext')); + $this->assertInstanceOf('Ramsey\Uuid\Uuid', Uuid::uuid3(Uuid::NIL, 'randomtext')); + $this->assertInstanceOf('Ramsey\Uuid\Uuid', Uuid::uuid5(Uuid::NIL, 'randomtext')); } /** @@ -1403,7 +1403,7 @@ class UuidTest extends TestCase } /** - * This test ensures that Rhumsaa\Uuid passes the same test cases + * This test ensures that Ramsey\Uuid passes the same test cases * as the Python UUID library. * * Taken from the Python UUID tests in @@ -1731,8 +1731,8 @@ class UuidTest extends TestCase } /** - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException - * @expectedExceptionMessage Cannot call Rhumsaa\Uuid\Converter\Number\DegradedNumberConverter::fromHex without support for large integers + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException + * @expectedExceptionMessage Cannot call Ramsey\Uuid\Converter\Number\DegradedNumberConverter::fromHex without support for large integers */ public function testGetInteger() { diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 50e981f..b1857f4 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -16,4 +16,4 @@ date_default_timezone_set('UTC'); $loader = include realpath(dirname(__FILE__) . '/../vendor/autoload.php'); $loader->add("Doctrine\Tests\DBAL", __DIR__."/../vendor/doctrine/dbal/tests"); -$loader->addPsr4('Rhumsaa\\Uuid\\', __DIR__); +$loader->addPsr4('Ramsey\\Uuid\\', __DIR__);