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 diff --git a/.gitignore b/.gitignore index c9d8ead..0a59599 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -.idea +.idea/ *.phar .DS_Store build diff --git a/.travis.yml b/.travis.yml index 40ce721..fbc19fa 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,16 +1,26 @@ language: php php: - - 5.3 - 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 +script: + - 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/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/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/README.md b/README.md index c594b74..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.3+ 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. + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ @@ -48,8 +48,8 @@ if (!class_exists('Symfony\Component\Console\Application') || !class_exists('Moo ); } -use Rhumsaa\Uuid\Console\Application; -use Rhumsaa\Uuid\Console\Command; +use Ramsey\Uuid\Console\Application; +use Ramsey\Uuid\Console\Command; $app = new Application(); $app->add(new Command\GenerateCommand()); diff --git a/composer.json b/composer.json index 4e2c627..5427177 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).", + "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"], "homepage": "https://github.com/ramsey/uuid", @@ -20,27 +20,31 @@ "source": "https://github.com/ramsey/uuid" }, "require": { - "php": ">=5.3.3" + "php": ">=5.4" }, "require-dev": { "moontoast/math": "~1.1", + "ircmaxell/random-lib": "~1.0", "symfony/console": "~2.3", "doctrine/dbal": ">=2.3", - "phpunit/phpunit": "~4.1", - "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": { "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." }, "autoload": { - "psr-4": {"Rhumsaa\\Uuid\\": "src/"} + "psr-4": {"Ramsey\\Uuid\\": "src/"} }, "extra": { "branch-alias": { - "dev-master": "2.8.x-dev" + "dev-master": "3.0.x-dev" } } } 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 new file mode 100644 index 0000000..b6e2282 --- /dev/null +++ b/src/Builder/DefaultUuidBuilder.php @@ -0,0 +1,24 @@ +converter = $converter; + } + + 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 new file mode 100644 index 0000000..610f821 --- /dev/null +++ b/src/Builder/DegradedUuidBuilder.php @@ -0,0 +1,24 @@ +converter = $converter; + } + + 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 new file mode 100644 index 0000000..9619bf1 --- /dev/null +++ b/src/Codec/GuidStringCodec.php @@ -0,0 +1,55 @@ +getFieldsHex()); + + // Swap byte-order on the first three fields + $this->swapFields($components); + + return vsprintf( + '%08s-%04s-%04s-%02s%02s-%012s', + $components + ); + } + + public function encodeBinary(UuidInterface $uuid) + { + $components = array_values($uuid->getFieldsHex()); + + return hex2bin(implode('', $components)); + } + + public function decode($encodedUuid) + { + $components = $this->extractComponents($encodedUuid); + + $this->swapFields($components); + + return $this->getBuilder()->build($this, $this->getFields($components)); + } + + public function decodeBytes($bytes) + { + return parent::decode(bin2hex($bytes)); + } + + protected function swapFields(array & $components) + { + $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 new file mode 100644 index 0000000..26f847b --- /dev/null +++ b/src/Codec/StringCodec.php @@ -0,0 +1,101 @@ +builder = $builder; + } + + public function encode(UuidInterface $uuid) + { + $fields = array_values($uuid->getFieldsHex()); + + return vsprintf( + '%08s-%04s-%04s-%02s%02s-%012s', + $fields + ); + } + + public function encodeBinary(UuidInterface $uuid) + { + 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:', + '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: ' . $encodedUuid); + } + + 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]), + '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]) + ); + } +} diff --git a/src/CodecInterface.php b/src/CodecInterface.php new file mode 100644 index 0000000..ea5de36 --- /dev/null +++ b/src/CodecInterface.php @@ -0,0 +1,27 @@ + + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ -namespace Rhumsaa\Uuid\Console; +namespace Ramsey\Uuid\Console; -use Rhumsaa\Uuid\Console\Util; -use Rhumsaa\Uuid\Uuid; +use Ramsey\Uuid\Console\Util; +use Ramsey\Uuid\Uuid; use Symfony\Component\Console\Application as BaseApplication; /** diff --git a/src/Console/Command/DecodeCommand.php b/src/Console/Command/DecodeCommand.php index 0c1758f..00512cc 100644 --- a/src/Console/Command/DecodeCommand.php +++ b/src/Console/Command/DecodeCommand.php @@ -1,24 +1,25 @@ + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ -namespace Rhumsaa\Uuid\Console\Command; +namespace Ramsey\Uuid\Console\Command; 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; +use Ramsey\Uuid\Console\Exception; +use Ramsey\Uuid\Uuid; +use Ramsey\Uuid\Console\Util\UuidFormatter; +use Symfony\Component\Console\Helper\Table; /** * Provides the console command to decode UUIDs and dump information about them @@ -58,66 +59,7 @@ 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'), - )); - - $table->render($output); - - return; - } - - switch ($uuid->getVersion()) { - case 1: - $version = '1 (time and node based)'; - break; - case 2: - $version = '2 (DCE security based)'; - break; - case 3: - $version = '3 (name based, MD5)'; - break; - case 4: - $version = '4 (random data based)'; - break; - case 5: - $version = '5 (name based, SHA-1)'; - break; - } - - $table->addRows(array( - array('decode:', 'variant:', 'RFC 4122'), - 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 ($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)'), - )); - } + (new UuidFormatter())->write($table, $uuid); $table->render($output); } diff --git a/src/Console/Command/GenerateCommand.php b/src/Console/Command/GenerateCommand.php index a4c6604..6b55f9c 100644 --- a/src/Console/Command/GenerateCommand.php +++ b/src/Console/Command/GenerateCommand.php @@ -1,23 +1,27 @@ + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ -namespace Rhumsaa\Uuid\Console\Command; +namespace Ramsey\Uuid\Console\Command; use Symfony\Component\Console\Command\Command; 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; +use Ramsey\Uuid\Console\Exception; +use Ramsey\Uuid\Uuid; +use Ramsey\Uuid\Generator\CombGenerator; +use Ramsey\Uuid\Codec\GuidStringCodec; +use Ramsey\Uuid\FeatureSet; +use Ramsey\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'), @@ -159,9 +190,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/Console/Exception.php b/src/Console/Exception.php index aefef0d..f8970a9 100644 --- a/src/Console/Exception.php +++ b/src/Console/Exception.php @@ -1,15 +1,15 @@ + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ -namespace Rhumsaa\Uuid\Console; +namespace Ramsey\Uuid\Console; /** * Console exception diff --git a/src/Console/Util/ErrorHandler.php b/src/Console/Util/ErrorHandler.php index fe4d90a..cd0fa23 100644 --- a/src/Console/Util/ErrorHandler.php +++ b/src/Console/Util/ErrorHandler.php @@ -1,15 +1,15 @@ + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ -namespace Rhumsaa\Uuid\Console\Util; +namespace Ramsey\Uuid\Console\Util; /** * Convert PHP errors into exceptions diff --git a/src/Console/Util/Formatter/V1Formatter.php b/src/Console/Util/Formatter/V1Formatter.php new file mode 100644 index 0000000..1486c9b --- /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..df08bcb --- /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..3dd5f8a --- /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..fa41f21 --- /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..aa7b7ef --- /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); + } +} diff --git a/src/Converter/Number/BigNumberConverter.php b/src/Converter/Number/BigNumberConverter.php new file mode 100644 index 0000000..17a76ff --- /dev/null +++ b/src/Converter/Number/BigNumberConverter.php @@ -0,0 +1,27 @@ +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/Converter/Time/DegradedTimeConverter.php b/src/Converter/Time/DegradedTimeConverter.php new file mode 100644 index 0000000..b7a96d7 --- /dev/null +++ b/src/Converter/Time/DegradedTimeConverter.php @@ -0,0 +1,18 @@ + sprintf('%08x', $uuidTime & 0xffffffff), + 'mid' => sprintf('%04x', ($uuidTime >> 32) & 0xffff), + 'hi' => sprintf('%04x', ($uuidTime >> 48) & 0x0fff), + ); + } +} diff --git a/src/Converter/TimeConverterInterface.php b/src/Converter/TimeConverterInterface.php new file mode 100644 index 0000000..ece801e --- /dev/null +++ b/src/Converter/TimeConverterInterface.php @@ -0,0 +1,16 @@ +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/Doctrine/UuidType.php b/src/Doctrine/UuidType.php index ffecee8..078d5b8 100644 --- a/src/Doctrine/UuidType.php +++ b/src/Doctrine/UuidType.php @@ -1,18 +1,18 @@ + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ -namespace Rhumsaa\Uuid\Doctrine; +namespace Ramsey\Uuid\Doctrine; use InvalidArgumentException; -use Rhumsaa\Uuid\Uuid; +use Ramsey\Uuid\Uuid; use Doctrine\DBAL\Types\ConversionException; use Doctrine\DBAL\Types\Type; use Doctrine\DBAL\Platforms\AbstractPlatform; diff --git a/src/Exception/UnsatisfiedDependencyException.php b/src/Exception/UnsatisfiedDependencyException.php index e402837..a681803 100644 --- a/src/Exception/UnsatisfiedDependencyException.php +++ b/src/Exception/UnsatisfiedDependencyException.php @@ -1,15 +1,15 @@ + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ -namespace Rhumsaa\Uuid\Exception; +namespace Ramsey\Uuid\Exception; /** * Thrown to indicate that the requested operation has dependencies that have not diff --git a/src/Exception/UnsupportedOperationException.php b/src/Exception/UnsupportedOperationException.php index e9eed08..ff76dba 100644 --- a/src/Exception/UnsupportedOperationException.php +++ b/src/Exception/UnsupportedOperationException.php @@ -1,15 +1,15 @@ + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ -namespace Rhumsaa\Uuid\Exception; +namespace Ramsey\Uuid\Exception; /** * Thrown to indicate that the requested operation is not supported. diff --git a/src/FeatureSet.php b/src/FeatureSet.php new file mode 100644 index 0000000..4191619 --- /dev/null +++ b/src/FeatureSet.php @@ -0,0 +1,176 @@ +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); + } + + 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/CombGenerator.php b/src/Generator/CombGenerator.php new file mode 100644 index 0000000..cad998d --- /dev/null +++ b/src/Generator/CombGenerator.php @@ -0,0 +1,68 @@ +converter = $numberConverter; + $this->randomGenerator = $generator; + $this->timestampBytes = 6; + } + + /** + * (non-PHPdoc) @see \Ramsey\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); + } +} diff --git a/src/Generator/MtRandGenerator.php b/src/Generator/MtRandGenerator.php new file mode 100644 index 0000000..679a4d9 --- /dev/null +++ b/src/Generator/MtRandGenerator.php @@ -0,0 +1,19 @@ +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/PeclUuidFactory.php b/src/PeclUuidFactory.php new file mode 100644 index 0000000..ff7c115 --- /dev/null +++ b/src/PeclUuidFactory.php @@ -0,0 +1,107 @@ +hasExt = extension_loaded('uuid'); + $this->factory = $factory; + } + + /** + * Forces factory to act as if PECL extension is not available + */ + public function disablePecl() + { + $this->hasExt = false; + } + + /** + * (non-PHPdoc) @see \Ramsey\Uuid\UuidFactoryInterface::uuid1() + */ + public function uuid1($node = null, $clockSeq = null) + { + if (! $this->hasExt || $node !== null || $clockSeq !== null) { + // If either param is not null, we cannot use PECL without breaking LSP. + return $this->factory->uuid1($node, $clockSeq); + } + + return $this->fromString(uuid_create(UUID_TYPE_TIME)); + } + + /** + * (non-PHPdoc) @see \Ramsey\Uuid\UuidFactoryInterface::uuid3() + */ + public function uuid3($ns, $name) + { + return $this->factory->uuid3($ns, $name); + } + + /** + * (non-PHPdoc) @see \Ramsey\Uuid\UuidFactoryInterface::uuid4() + */ + public function uuid4() + { + if (! $this->hasExt) { + return $this->factory->uuid4(); + } + + return $this->fromString(uuid_create(UUID_TYPE_RANDOM)); + } + + /** + * (non-PHPdoc) @see \Ramsey\Uuid\UuidFactoryInterface::uuid5() + */ + public function uuid5($ns, $name) + { + return $this->factory->uuid5($ns, $name); + } + + /** + * (non-PHPdoc) @see \Ramsey\Uuid\UuidFactoryInterface::fromBytes() + */ + public function fromBytes($bytes) + { + return $this->factory->fromBytes($bytes); + } + + /** + * (non-PHPdoc) @see \Ramsey\Uuid\UuidFactoryInterface::fromString() + */ + public function fromString($name) + { + return $this->factory->fromString($name); + } + + /** + * (non-PHPdoc) @see \Ramsey\Uuid\UuidFactoryInterface::fromInteger() + */ + public function fromInteger($integer) + { + return $this->factory->fromInteger($integer); + } +} diff --git a/src/Provider/Node/FallbackNodeProvider.php b/src/Provider/Node/FallbackNodeProvider.php new file mode 100644 index 0000000..6b708d9 --- /dev/null +++ b/src/Provider/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/Provider/Node/RandomNodeProvider.php b/src/Provider/Node/RandomNodeProvider.php new file mode 100644 index 0000000..89ac825 --- /dev/null +++ b/src/Provider/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 + * @return string + */ + 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/Provider/NodeProviderInterface.php b/src/Provider/NodeProviderInterface.php new file mode 100644 index 0000000..a06ea63 --- /dev/null +++ b/src/Provider/NodeProviderInterface.php @@ -0,0 +1,8 @@ +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/Provider/Time/SystemTimeProvider.php b/src/Provider/Time/SystemTimeProvider.php new file mode 100644 index 0000000..fe54e2d --- /dev/null +++ b/src/Provider/Time/SystemTimeProvider.php @@ -0,0 +1,13 @@ + + * @copyright Copyright (c) 2012-2014 Ben Ramsey * @license http://opensource.org/licenses/MIT MIT */ -namespace Rhumsaa\Uuid; +namespace Ramsey\Uuid; use InvalidArgumentException; +use Ramsey\Uuid\Converter\NumberConverterInterface; /** * Represents a universally unique identifier (UUID), according to RFC 4122 @@ -29,7 +30,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 */ -final class Uuid + +class Uuid implements UuidInterface, \JsonSerializable { /** * When this namespace is specified, the name string is a fully-qualified domain name. @@ -91,46 +93,21 @@ final class Uuid const VALID_PATTERN = '^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$'; /** - * Version of the Rhumsaa\Uuid package + * Version of the Ramsey\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 * - * @var bool + * @var UuidFactoryInterface */ - public static $force32Bit = false; + private static $factory = null; /** - * For testing, Moontoast\Math\BigNumber override; if true, treat as if - * BigNumber is not available - * - * @var bool + * String codec + * @var CodecInterface */ - public static $forceNoBigNumber = false; - - /** - * For testing, openssl_random_pseudo_bytes() override; if true, treat as - * if openssl_random_pseudo_bytes() is not available - * - * @var bool - */ - public static $forceNoOpensslRandomPseudoBytes = false; - - /** - * For testing, sets time of day to a static, known value - * - * @var array - */ - public static $timeOfDayTest; - - /** - * For testing, system override to ignore generating node from hardware - * - * @var bool - */ - public static $ignoreSystemNode = false; + protected $codec; /** * The fields that make up this UUID @@ -138,7 +115,7 @@ final class Uuid * This is initialized to the nil value. * * @var array - * @link Rhumsaa.Uuid.Uuid.html#method_getFields + * @link Ramsey.Uuid.Uuid.html#method_getFields */ protected $fields = array( 'time_low' => '00000000', @@ -149,6 +126,8 @@ final class Uuid 'node' => '000000000000', ); + protected $converter; + /** * Creates a universally unique identifier (UUID) from an array of fields. * @@ -156,11 +135,14 @@ final class Uuid * UUIDs. * * @param array $fields - * @link Rhumsaa.Uuid.Uuid.html#method_getFields + * @param CodecInterface $codec String codec + * @link Ramsey.Uuid.Uuid.html#method_getFields */ - protected function __construct(array $fields) + public function __construct(array $fields, NumberConverterInterface $converter, CodecInterface $codec) { $this->fields = $fields; + $this->codec = $codec; + $this->converter = $converter; } /** @@ -175,6 +157,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. * @@ -188,9 +183,9 @@ final class Uuid * @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; + $comparison = 0; if ($this->getMostSignificantBitsHex() < $uuid->getMostSignificantBitsHex()) { $comparison = -1; @@ -200,8 +195,6 @@ final class Uuid $comparison = -1; } elseif ($this->getLeastSignificantBitsHex() > $uuid->getLeastSignificantBitsHex()) { $comparison = 1; - } else { - $comparison = 0; } return $comparison; @@ -234,13 +227,7 @@ final class Uuid */ 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); } /** @@ -317,6 +304,11 @@ final class Uuid return sprintf('%04x', $this->getClockSequence()); } + public function getNumberConverter() + { + return $this->converter; + } + /** * Returns a PHP DateTime object representing the timestamp associated * with this UUID. @@ -327,7 +319,8 @@ final class 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() { @@ -335,31 +328,8 @@ final class Uuid 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}"); } @@ -385,14 +355,6 @@ final class Uuid */ 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(), @@ -443,22 +405,7 @@ final class Uuid */ 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 getHex instead' - ); - } - - $number = \Moontoast\Math\BigNumber::baseConvert( - $this->getHex(), - 16, - 10 - ); - - return new \Moontoast\Math\BigNumber($number); + return $this->converter->fromHex($this->getHex()); } /** @@ -469,22 +416,7 @@ final class Uuid */ 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()); } /** @@ -510,22 +442,7 @@ final class Uuid */ 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()); } /** @@ -570,15 +487,6 @@ final class Uuid */ 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()); } @@ -641,15 +549,6 @@ final class Uuid */ 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()); } @@ -706,15 +605,6 @@ final class Uuid 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()); } @@ -823,10 +713,21 @@ final class Uuid */ public function toString() { - return vsprintf( - '%08s-%04s-%04s-%02s%02s-%012s', - $this->fields - ); + return $this->codec->encode($this); + } + + public static function getFactory() + { + if (! self::$factory) { + self::$factory = new PeclUuidFactory(new UuidFactory()); + } + + return self::$factory; + } + + public static function setFactory(UuidFactoryInterface $factory) + { + self::$factory = $factory; } /** @@ -838,20 +739,7 @@ final class Uuid */ public static function fromBytes($bytes) { - 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])); - - if (in_array($step, array(3, 5, 7, 9))) { - $uuid .= '-'; - } - } - - return Uuid::fromString($uuid); + return self::getFactory()->fromBytes($bytes); } /** @@ -864,34 +752,7 @@ final class Uuid */ public static function fromString($name) { - $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), - ); - $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); + return self::getFactory()->fromString($name); } /** @@ -899,26 +760,11 @@ final class Uuid * * @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) { - 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); } /** @@ -938,6 +784,7 @@ final class Uuid if (!preg_match('/' . self::VALID_PATTERN . '/', $uuid)) { return false; } + return true; } @@ -958,80 +805,20 @@ final class Uuid */ 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); } /** * 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 */ 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); } /** @@ -1041,227 +828,19 @@ final class Uuid */ 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(); } /** * 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 */ 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() - { - ob_start(); - switch (strtoupper(substr(php_uname('a'), 0, 3))) { - case 'WIN': - passthru('ipconfig /all 2>&1'); - break; - case 'DAR': - passthru('ifconfig 2>&1'); - break; - case 'LIN': - default: - passthru('netstat -ie 2>&1'); - break; - } - - return ob_get_clean(); - } - - /** - * 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() - { - static $node = null; - - if($node !== null) { - return $node; - } - - $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/UuidBuilder.php b/src/UuidBuilder.php new file mode 100644 index 0000000..ec99e70 --- /dev/null +++ b/src/UuidBuilder.php @@ -0,0 +1,11 @@ +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(); + } + + public function getCodec() + { + return $this->codec; + } + + public function getRandomGenerator() + { + return $this->randomGenerator; + } + + public function getNumberConverter() + { + return $this->numberConverter; + } + + public function getTimeConverter() + { + return $this->timeConverter; + } + + public function setTimeConverter(TimeConverterInterface $converter) + { + $this->timeConverter = $converter; + } + + public function setTimeProvider(TimeProviderInterface $provider) + { + $this->timeProvider = $provider; + } + + public function setRandomGenerator(RandomGeneratorInterface $generator) + { + $this->randomGenerator = $generator; + } + + public function setNodeProvider(NodeProviderInterface $provider) + { + $this->nodeProvider = $provider; + } + + public function setNumberConverter(NumberConverterInterface $converter) + { + $this->numberConverter = $converter; + } + + public function setUuidBuilder(UuidBuilder $builder) + { + $this->uuidBuilder = $builder; + } + + /** + * 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($bytes); + } + + /** + * Creates a UUID from the string standard representation as described + * in the toString() method. + * + * @param string $name A string that specifies a UUID + * @return Uuid + * @throws InvalidArgumentException If the $name isn't a valid UUID + */ + public function fromString($name) + { + return $this->codec->decode($name); + } + + public function fromInteger($integer) + { + $hex = $this->numberConverter->toHex($integer); + $hex = str_pad($hex, 32, '0', STR_PAD_LEFT); + + return $this->fromString($hex); + } + + /** + * 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) + { + $node = $this->getValidNode($node); + + 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 + $timeOfDay = $this->timeProvider->currentTime(); + $uuidTime = $this->timeConverter->calculateTime($timeOfDay['sec'], $timeOfDay['usec']); + + $timeHi = $this->applyVersion($uuidTime['hi'], 1); + $clockSeqHi = $this->applyVariant($clockSeq >> 8); + + $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) + { + return $this->uuidFromNsAndName($ns, $name, 3, 'md5'); + } + + /** + * Generate a version 4 (random) UUID. + * + * @return Uuid + */ + public function uuid4() + { + $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); + } + + /** + * 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) + { + return $this->uuidFromNsAndName($ns, $name, 5, 'sha1'); + } + + public function uuid(array $fields) + { + 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; + } + + /** + * @param string $timeHi + * @param integer $version + */ + protected function applyVersion($timeHi, $version) + { + $timeHi = hexdec($timeHi) & 0x0fff; + $timeHi &= ~(0xf000); + $timeHi |= $version << 12; + + return $timeHi; + } + + /** + * @param string $name + * @param integer $version + * @param string $hashFunction + */ + 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) + * + * @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) + { + $timeHi = $this->applyVersion(substr($hash, 12, 4), $version); + $clockSeqHi = $this->applyVariant(hexdec(substr($hash, 16, 2))); + + $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); + } + + 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/src/UuidFactoryInterface.php b/src/UuidFactoryInterface.php new file mode 100644 index 0000000..0f1ce8d --- /dev/null +++ b/src/UuidFactoryInterface.php @@ -0,0 +1,20 @@ +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 @@ fromHex('ffff'); + } + + /** + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException + */ + public function testConvertingToHexThrowsException() + { + $converter = new DegradedNumberConverter(); + + $converter->toHex(0); + } +} diff --git a/tests/Doctrine/UuidTypeTest.php b/tests/Doctrine/UuidTypeTest.php index 00356e2..b014c2f 100644 --- a/tests/Doctrine/UuidTypeTest.php +++ b/tests/Doctrine/UuidTypeTest.php @@ -1,9 +1,9 @@ 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 new file mode 100644 index 0000000..3b368db --- /dev/null +++ b/tests/PeclUuidTest.php @@ -0,0 +1,120 @@ +mockFactory = $this->getMock('Ramsey\Uuid\UuidFactoryInterface'); + + Uuid::setFactory(new PeclUuidFactory($this->mockFactory)); + } + + public function getUuid1Params() + { + return [ + [ true, null ], + [ null, true ], + [ true, true ] + ]; + } + + /** + * @dataProvider getUuid1Params + */ + public function testUuid1WithParametersIsDelegated($node, $clockSeq) + { + $this->mockFactory->expects($this->once()) + ->method('uuid1') + ->with($node, $clockSeq); + + Uuid::uuid1($node, $clockSeq); + } + + public function testUuid1WithoutParametersIsNotDelegated() + { + if (!extension_loaded('uuid')) { + $this->markTestSkipped('PECL UUID extension not loaded'); + } + + $this->mockFactory->expects($this->never()) + ->method('uuid1'); + + Uuid::uuid1(); + } + + public function testUuid1WithoutExtensionIsDelegated() + { + $factory = new PeclUuidFactory($this->mockFactory); + $factory->disablePecl(); + + Uuid::setFactory($factory); + + $this->mockFactory->expects($this->once()) + ->method('uuid1'); + + Uuid::uuid1(); + } + + public function testUuid1Version() + { + Uuid::setFactory(new PeclUuidFactory(new UuidFactory())); + + $uuid = Uuid::uuid1(); + + $this->assertEquals(1, $uuid->getVersion()); + } + + public function testUuid3IsDelegated() + { + $this->mockFactory->expects($this->once()) + ->method('uuid3'); + + Uuid::uuid3(Uuid::NAMESPACE_DNS, str_replace('\\', '.', __NAMESPACE__)); + } + + public function testUuid4WithoutExtensionIsDelegated() + { + $factory = new PeclUuidFactory($this->mockFactory); + $factory->disablePecl(); + + Uuid::setFactory($factory); + + $this->mockFactory->expects($this->once()) + ->method('uuid4'); + + Uuid::uuid4(); + } + + public function testUuid4WithParametersIsNeverDelegated() + { + if (!extension_loaded('uuid')) { + $this->markTestSkipped('PECL UUID extension not loaded'); + } + + $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__)); + } +} diff --git a/tests/RandomGeneratorFactoryTest.php b/tests/RandomGeneratorFactoryTest.php new file mode 100644 index 0000000..590a7b4 --- /dev/null +++ b/tests/RandomGeneratorFactoryTest.php @@ -0,0 +1,24 @@ +assertNotInstanceOf('\Ramsey\Uuid\Generator\OpenSslGenerator', $generator); + } + + public function testFactoryReturnsOpenSslGeneratorIfAvailable() + { + RandomGeneratorFactory::$forceNoOpensslRandomPseudoBytes = false; + + $generator = RandomGeneratorFactory::getGenerator(); + + $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 @@ markTestSkipped( @@ -21,28 +23,24 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::fromString - * @covers Rhumsaa\Uuid\Uuid::__construct */ public function testFromString() { $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()); } /** - * @covers Rhumsaa\Uuid\Uuid::fromString */ 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()); } /** - * @covers Rhumsaa\Uuid\Uuid::fromString * @expectedException InvalidArgumentException * @expectedExceptionMessage Invalid UUID string: */ @@ -52,17 +50,15 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::fromString */ 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()); } /** - * @covers Rhumsaa\Uuid\Uuid::getBytes */ public function testGetBytes() { @@ -71,7 +67,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getClockSeqHiAndReserved */ public function testGetClockSeqHiAndReserved() { @@ -80,7 +75,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getClockSeqLow */ public function testGetClockSeqLow() { @@ -89,7 +83,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getClockSequence */ public function testGetClockSequence() { @@ -98,7 +91,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getDateTime */ public function testGetDateTime() { @@ -114,9 +106,7 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getDateTime - * @covers Rhumsaa\Uuid\Exception\UnsupportedOperationException - * @expectedException Rhumsaa\Uuid\Exception\UnsupportedOperationException + * @expectedException Ramsey\Uuid\Exception\UnsupportedOperationException * @expectedExceptionMessage Not a time-based UUID */ public function testGetDateTimeFromNonVersion1Uuid() @@ -127,7 +117,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getFields */ public function testGetFields() { @@ -141,7 +130,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getLeastSignificantBits */ public function testGetLeastSignificantBits() { @@ -158,7 +146,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getMostSignificantBits */ public function testGetMostSignificantBits() { @@ -175,7 +162,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getNode */ public function testGetNode() { @@ -184,7 +170,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeHiAndVersion */ public function testGetTimeHiAndVersion() { @@ -193,7 +178,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeLow */ public function testGetTimeLow() { @@ -202,7 +186,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeMid */ public function testGetTimeMid() { @@ -211,7 +194,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimestamp */ public function testGetTimestamp() { @@ -225,9 +207,7 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimestamp - * @covers Rhumsaa\Uuid\Exception\UnsupportedOperationException - * @expectedException Rhumsaa\Uuid\Exception\UnsupportedOperationException + * @expectedException Ramsey\Uuid\Exception\UnsupportedOperationException * @expectedExceptionMessage Not a time-based UUID */ public function testGetTimestampFromNonVersion1Uuid() @@ -238,7 +218,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getUrn */ public function testGetUrn() { @@ -247,7 +226,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForReservedNcs() { @@ -277,7 +255,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForRfc4122() { @@ -295,7 +272,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForReservedMicrosoft() { @@ -307,7 +283,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForReservedFuture() { @@ -319,7 +294,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion1() { @@ -328,7 +302,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion2() { @@ -337,7 +310,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion3() { @@ -346,7 +318,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion4() { @@ -355,7 +326,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion5() { @@ -364,8 +334,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::toString - * @covers Rhumsaa\Uuid\Uuid::__toString */ public function testToString() { @@ -381,25 +349,22 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 - * @covers Rhumsaa\Uuid\Uuid::getNodeFromSystem */ 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()); } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 */ 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()); @@ -409,14 +374,13 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 */ public function testUuid1WithRandomNode() { - Uuid::$ignoreSystemNode = true; + 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()); @@ -427,8 +391,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 +406,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,13 +416,11 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid4 - * @covers Rhumsaa\Uuid\Uuid::uuidFromHashedName */ 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()); } @@ -472,8 +430,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 +445,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 +455,6 @@ class UuidBcTag1_1_2Test extends \PHPUnit_Framework_TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::compareTo */ public function testCompareTo() { @@ -530,7 +483,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..62ac35b --- /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(new FeatureSet(true)); + + $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 8be8b26..ace9377 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -1,40 +1,56 @@ assertInstanceOf('\Rhumsaa\Uuid\Uuid', $uuid); + $this->assertInstanceOf('\Ramsey\Uuid\Uuid', $uuid); $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'); + + Uuid::setFactory(new UuidFactory(new FeatureSet(true))); + + $guid = Uuid::fromString('b08c6fff-7dc5-e111-9b21-0800200c9a66'); + + $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 + $this->assertNotEquals(bin2hex($uuid->getBytes()), bin2hex($guid->getBytes())); + } + + /** */ 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()); } /** - * @covers Rhumsaa\Uuid\Uuid::fromString * @expectedException InvalidArgumentException * @expectedExceptionMessage Invalid UUID string: */ @@ -44,17 +60,15 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::fromString */ 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()); } /** - * @covers Rhumsaa\Uuid\Uuid::getBytes */ public function testGetBytes() { @@ -64,7 +78,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getClockSeqHiAndReserved */ public function testGetClockSeqHiAndReserved() { @@ -73,7 +86,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getClockSeqHiAndReservedHex */ public function testGetClockSeqHiAndReservedHex() { @@ -82,7 +94,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getClockSeqLow */ public function testGetClockSeqLow() { @@ -91,7 +102,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getClockSeqLowHex */ public function testGetClockSeqLowHex() { @@ -100,7 +110,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getClockSequence */ public function testGetClockSequence() { @@ -109,7 +118,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getClockSequenceHex */ public function testGetClockSequenceHex() { @@ -118,7 +126,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getDateTime */ public function testGetDateTime() { @@ -144,12 +151,11 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getDateTime */ public function testGetDateTime32Bit() { $this->skipIfNoMoontoastMath(); - Uuid::$force32Bit = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); // Check a recent date $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); @@ -173,22 +179,22 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getDateTime - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetDateTimeThrownException() { - Uuid::$force32Bit = true; - Uuid::$forceNoBigNumber = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true, true))); $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); + + $this->assertInstanceOf('Ramsey\Uuid\DegradedUuid', $uuid); + $this->assertInstanceOf('Ramsey\Uuid\Converter\Number\DegradedNumberConverter', $uuid->getNumberConverter()); + $date = $uuid->getDateTime(); } /** - * @covers Rhumsaa\Uuid\Uuid::getDateTime - * @covers Rhumsaa\Uuid\Exception\UnsupportedOperationException - * @expectedException Rhumsaa\Uuid\Exception\UnsupportedOperationException + * @expectedException Ramsey\Uuid\Exception\UnsupportedOperationException * @expectedExceptionMessage Not a time-based UUID */ public function testGetDateTimeFromNonVersion1Uuid() @@ -199,7 +205,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getFields */ public function testGetFields() { @@ -220,18 +225,17 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getFields - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetFields32Bit() { - Uuid::$force32Bit = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); + $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $fields = $uuid->getFields(); } /** - * @covers Rhumsaa\Uuid\Uuid::getFieldsHex */ public function testGetFieldsHex() { @@ -250,7 +254,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getLeastSignificantBits */ public function testGetLeastSignificantBits() { @@ -262,18 +265,17 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getLeastSignificantBits - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetLeastSignificantBitsException() { - Uuid::$forceNoBigNumber = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, false, true))); + $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $bn = $uuid->getLeastSignificantBits(); } /** - * @covers Rhumsaa\Uuid\Uuid::getLeastSignificantBitsHex */ public function testGetLeastSignificantBitsHex() { @@ -282,7 +284,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getMostSignificantBits */ public function testGetMostSignificantBits() { @@ -294,18 +295,17 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getMostSignificantBits - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetMostSignificantBitsException() { - Uuid::$forceNoBigNumber = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, false, true))); + $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $bn = $uuid->getMostSignificantBits(); } /** - * @covers Rhumsaa\Uuid\Uuid::getMostSignificantBitsHex */ public function testGetMostSignificantBitsHex() { @@ -314,7 +314,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getNode */ public function testGetNode() { @@ -325,18 +324,17 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getNode - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetNode32Bit() { - Uuid::$force32Bit = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); + $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $node = $uuid->getNode(); } /** - * @covers Rhumsaa\Uuid\Uuid::getNodeHex */ public function testGetNodeHex() { @@ -345,7 +343,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeHiAndVersion */ public function testGetTimeHiAndVersion() { @@ -354,7 +351,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeHiAndVersionHex */ public function testGetTimeHiAndVersionHex() { @@ -363,7 +359,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeLow */ public function testGetTimeLow() { @@ -374,18 +369,17 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeLow - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetTimeLow32Bit() { - Uuid::$force32Bit = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); + $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $timeLow = $uuid->getTimeLow(); } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeLowHex */ public function testGetTimeLowHex() { @@ -394,7 +388,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeMid */ public function testGetTimeMid() { @@ -403,7 +396,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimeMidHex */ public function testGetTimeMidHex() { @@ -412,7 +404,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimestamp */ public function testGetTimestamp() { @@ -428,7 +419,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimestampHex */ public function testGetTimestampHex() { @@ -442,9 +432,7 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimestamp - * @covers Rhumsaa\Uuid\Exception\UnsupportedOperationException - * @expectedException Rhumsaa\Uuid\Exception\UnsupportedOperationException + * @expectedException Ramsey\Uuid\Exception\UnsupportedOperationException * @expectedExceptionMessage Not a time-based UUID */ public function testGetTimestampFromNonVersion1Uuid() @@ -455,9 +443,7 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimestampHex - * @covers Rhumsaa\Uuid\Exception\UnsupportedOperationException - * @expectedException Rhumsaa\Uuid\Exception\UnsupportedOperationException + * @expectedException Ramsey\Uuid\Exception\UnsupportedOperationException * @expectedExceptionMessage Not a time-based UUID */ public function testGetTimestampHexFromNonVersion1Uuid() @@ -468,18 +454,17 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getTimestamp - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testGetTimestamp32Bit() { - Uuid::$force32Bit = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true))); + $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); $ts = $uuid->getTimestamp(); } /** - * @covers Rhumsaa\Uuid\Uuid::getUrn */ public function testGetUrn() { @@ -488,7 +473,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForReservedNcs() { @@ -518,7 +502,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForRfc4122() { @@ -536,7 +519,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForReservedMicrosoft() { @@ -548,7 +530,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVariant */ public function testGetVariantForReservedFuture() { @@ -560,7 +541,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion1() { @@ -569,7 +549,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion2() { @@ -578,7 +557,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion3() { @@ -587,7 +565,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion4() { @@ -596,7 +573,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::getVersion */ public function testGetVersionForVersion5() { @@ -605,8 +581,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::toString - * @covers Rhumsaa\Uuid\Uuid::__toString */ public function testToString() { @@ -622,27 +596,24 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 - * @covers Rhumsaa\Uuid\Uuid::getNodeFromSystem */ 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()); } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 */ public function testUuid1WithNodeAndClockSequence() { $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()); @@ -652,13 +623,12 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 */ public function testUuid1WithHexadecimalNode() { $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()); @@ -670,13 +640,12 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 */ public function testUuid1WithMixedCaseHexadecimalNode() { $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()); @@ -688,12 +657,11 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 */ 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()); @@ -707,7 +675,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 * @expectedException InvalidArgumentException * @expectedExceptionMessage Invalid node value */ @@ -717,7 +684,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 * @expectedException InvalidArgumentException * @expectedExceptionMessage Invalid node value */ @@ -727,7 +693,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 * @expectedException InvalidArgumentException * @expectedExceptionMessage Invalid node value */ @@ -736,15 +701,12 @@ class UuidTest extends TestCase $uuid = Uuid::uuid1('db77e160355ef'); } - /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 - */ public function testUuid1WithRandomNode() { - Uuid::$ignoreSystemNode = true; + 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()); @@ -755,8 +717,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() { @@ -772,8 +732,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() { @@ -789,7 +747,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() { @@ -809,39 +766,75 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid4 - * @covers Rhumsaa\Uuid\Uuid::generateBytes - * @covers Rhumsaa\Uuid\Uuid::uuidFromHashedName */ 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()); } /** - * @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->assertInstanceOf('Ramsey\Uuid\Uuid', $uuid); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(4, $uuid->getVersion()); } + /** + * Tests that generated UUID's using COMB are sequential + * @return string + */ + public function testUuid4Comb() + { + $mock = $this->getMock('Ramsey\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. * @see http://docs.python.org/library/uuid.html * - * @covers Rhumsaa\Uuid\Uuid::uuid5 - * @covers Rhumsaa\Uuid\Uuid::uuidFromHashedName */ public function testUuid5WithNamespaceAsUuidObject() { @@ -857,8 +850,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() { @@ -874,7 +865,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() { @@ -894,7 +884,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::compareTo */ public function testCompareTo() { @@ -923,7 +912,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::equals */ public function testEquals() { @@ -938,20 +926,18 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 - * @covers Rhumsaa\Uuid\Uuid::calculateUuidTime */ public function testCalculateUuidTime() { - $timeOfDay = array( + $timeOfDay = new FixedTimeProvider(array( 'sec' => 1348845514, 'usec' => 277885, 'minuteswest' => 0, 'dsttime' => 0, - ); + )); // For usec = 277885 - Uuid::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c4dbe7e2-097f-11e2-9669-00007ffffffe', (string) $uuidA); @@ -960,7 +946,7 @@ class UuidTest extends TestCase $this->assertEquals('11e2', $uuidA->getTimeHiAndVersionHex()); // For usec = 0 - Uuid::$timeOfDayTest['usec'] = 0; + $timeOfDay->setUsec(0); $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c4b18100-097f-11e2-9669-00007ffffffe', (string) $uuidB); @@ -969,7 +955,7 @@ class UuidTest extends TestCase $this->assertEquals('11e2', $uuidB->getTimeHiAndVersionHex()); // For usec = 999999 - Uuid::$timeOfDayTest['usec'] = 999999; + $timeOfDay->setUsec(999999); $uuidC = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c54a1776-097f-11e2-9669-00007ffffffe', (string) $uuidC); @@ -979,23 +965,21 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 - * @covers Rhumsaa\Uuid\Uuid::calculateUuidTime */ public function testCalculateUuidTimeForce32BitPath() { $this->skipIfNoMoontoastMath(); - Uuid::$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 - Uuid::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c4dbe7e2-097f-11e2-9669-00007ffffffe', (string) $uuidA); @@ -1004,7 +988,7 @@ class UuidTest extends TestCase $this->assertEquals('11e2', $uuidA->getTimeHiAndVersionHex()); // For usec = 0 - Uuid::$timeOfDayTest['usec'] = 0; + $timeOfDay->setUsec(0); $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c4b18100-097f-11e2-9669-00007ffffffe', (string) $uuidB); @@ -1013,7 +997,7 @@ class UuidTest extends TestCase $this->assertEquals('11e2', $uuidB->getTimeHiAndVersionHex()); // For usec = 999999 - Uuid::$timeOfDayTest['usec'] = 999999; + $timeOfDay->setUsec(999999); $uuidC = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('c54a1776-097f-11e2-9669-00007ffffffe', (string) $uuidC); @@ -1023,22 +1007,20 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 - * @covers Rhumsaa\Uuid\Uuid::calculateUuidTime */ public function testCalculateUuidTimeUpperLowerBounds64Bit() { $this->skip64BitTest(); // 5235-03-31T21:20:59+00:00 - $timeOfDay = array( + $timeOfDay = new FixedTimeProvider(array( 'sec' => 103072857659, 'usec' => 999999, 'minuteswest' => 0, 'dsttime' => 0, - ); + )); - Uuid::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('ff9785f6-ffff-1fff-9669-00007ffffffe', (string) $uuidA); @@ -1047,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, - ); + )); - Uuid::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('00000000-0000-1000-9669-00007ffffffe', (string) $uuidB); @@ -1067,25 +1049,23 @@ 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; + 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, - ); + )); - Uuid::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('ff9785f6-ffff-1fff-9669-00007ffffffe', (string) $uuidA); @@ -1094,14 +1074,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, - ); + )); - Uuid::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('00000000-0000-1000-9669-00007ffffffe', (string) $uuidB); @@ -1111,23 +1091,21 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::uuid1 - * @covers Rhumsaa\Uuid\Uuid::calculateUuidTime */ public function testCalculateUuidTimeUpperLowerBounds32Bit() { $this->skipIfNoMoontoastMath(); - Uuid::$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, - ); + )); - Uuid::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('13813ff6-6912-11fe-9669-00007ffffffe', (string) $uuidA); @@ -1136,14 +1114,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, - ); + )); - Uuid::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('1419d680-d292-1165-9669-00007ffffffe', (string) $uuidB); @@ -1156,22 +1134,20 @@ 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() { $this->skip64BitTest(); // 2038-01-19T03:14:07+00:00 - $timeOfDay = array( + $timeOfDay = new FixedTimeProvider(array( 'sec' => 2147483647, 'usec' => 999999, 'minuteswest' => 0, 'dsttime' => 0, - ); + )); - Uuid::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('13813ff6-6912-11fe-9669-00007ffffffe', (string) $uuidA); @@ -1180,14 +1156,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, - ); + )); - Uuid::$timeOfDayTest = $timeOfDay; + Uuid::getFactory()->setTimeProvider($timeOfDay); $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); $this->assertEquals('1419d680-d292-1165-9669-00007ffffffe', (string) $uuidB); @@ -1208,24 +1184,27 @@ 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)); + + $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->setSec($currentTime); + $timeOfDay->setUsec($usec); - $timeOfDay = array( - 'sec' => $currentTime, - 'usec' => $usec, - 'minuteswest' => 0, - 'dsttime' => 0, - ); - - Uuid::$timeOfDayTest = $timeOfDay; - - Uuid::$force32Bit = true; - $uuid32 = Uuid::uuid1(0x00007ffffffe, 0x1669); - - Uuid::$force32Bit = false; - $uuid64 = Uuid::uuid1(0x00007ffffffe, 0x1669); + $uuid32 = $smallIntFactory->uuid1(0x00007ffffffe, 0x1669); + $uuid64 = $factory->uuid1(0x00007ffffffe, 0x1669); $this->assertTrue( $uuid32->equals($uuid64), @@ -1243,79 +1222,16 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::calculateUuidTime - * @expectedException Rhumsaa\Uuid\Exception\UnsatisfiedDependencyException + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException */ public function testCalculateUuidTimeThrownException() { - Uuid::$force32Bit = true; - Uuid::$forceNoBigNumber = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, true, 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() { @@ -1324,7 +1240,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidGoodVersion2() { @@ -1333,7 +1248,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidGoodVersion3() { @@ -1342,7 +1256,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidGoodVersion4() { @@ -1351,7 +1264,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidGoodVersion5() { @@ -1360,7 +1272,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidGoodUpperCase() { @@ -1369,7 +1280,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidBadHex() { @@ -1378,7 +1288,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidTooShort1() { @@ -1387,7 +1296,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidTooShort2() { @@ -1396,7 +1304,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidNoDashes() { @@ -1405,7 +1312,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ public function testIsValidTooLong() { @@ -1414,16 +1320,14 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::isValid */ 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')); } /** - * @covers Rhumsaa\Uuid\Uuid::fromBytes */ public function testFromBytes() { @@ -1435,8 +1339,30 @@ class UuidTest extends TestCase $this->assertTrue($uuid->equals($fromBytesUuid)); } + 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 = $uuidFactory->fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); + $bytes = $uuid->getBytes(); + + $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 = $guidFactory->fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); + $bytes = $guid->getBytes(); + + $parsedGuid = $guidFactory->fromBytes($bytes); + + $this->assertEquals($guid->toString(), $parsedGuid->toString()); + } + /** - * @covers Rhumsaa\Uuid\Uuid::fromBytes * @expectedException InvalidArgumentException */ public function testFromBytesArgumentTooShort() @@ -1445,7 +1371,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::fromBytes * @expectedException InvalidArgumentException */ public function testFromBytesArgumentTooLong() @@ -1454,7 +1379,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::fromInteger */ public function testFromIntegerBigNumber() { @@ -1467,7 +1391,6 @@ class UuidTest extends TestCase } /** - * @covers Rhumsaa\Uuid\Uuid::fromInteger */ public function testFromIntegerString() { @@ -1479,33 +1402,13 @@ class UuidTest extends TestCase $this->assertTrue($uuid->equals($fromIntegerUuid)); } - /** - * 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 * 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() { @@ -1828,13 +1731,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 + * @expectedException Ramsey\Uuid\Exception\UnsatisfiedDependencyException + * @expectedExceptionMessage Cannot call Ramsey\Uuid\Converter\Number\DegradedNumberConverter::fromHex without support for large integers */ public function testGetInteger() { - Uuid::$forceNoBigNumber = true; + Uuid::setFactory(new UuidFactory(new FeatureSet(false, false, true))); $uuid = Uuid::uuid1(); $uuid->getInteger(); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 786bef2..b1857f4 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -9,8 +9,11 @@ if (!file_exists(dirname(__DIR__) . '/vendor/autoload.php')) { . "See http://getcomposer.org for help with installing composer\n"); } +// Set a default timezone for HHVM tests +date_default_timezone_set('UTC'); + // Include the Composer autoloader $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__); 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) ========= ========== =================================================