From 1944a1536bd4b28067d948fe3b2d2e460558cefe Mon Sep 17 00:00:00 2001 From: Andrew Mitchell Date: Sat, 9 May 2020 18:33:33 -0400 Subject: [PATCH 01/22] Remove phpstan/phpdoc-parser from dev dependencies --- composer.json | 1 - 1 file changed, 1 deletion(-) diff --git a/composer.json b/composer.json index 5d34375..2e12048 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,6 @@ "php-mock/php-mock-phpunit": "^2.5", "php-parallel-lint/php-parallel-lint": "^1.1", "phpstan/extension-installer": "^1.0", - "phpstan/phpdoc-parser": "0.4.4", "phpstan/phpstan": "^0.12", "phpstan/phpstan-mockery": "^0.12", "phpstan/phpstan-phpunit": "^0.12", From fcbe5731cef867d13da9a290859f9e58ccc9d5da Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Thu, 25 Jun 2020 17:59:03 +0000 Subject: [PATCH 02/22] Update dealerdirect/phpcodesniffer-composer-installer requirement || ^0.7.0 Updates the requirements on dealerdirect/phpcodesniffer-composer-installer to permit the latest version. Signed-off-by: dependabot-preview[bot] --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 2e12048..a8bbe80 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ }, "require-dev": { "codeception/aspect-mock": "^3", - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2", + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7.0", "doctrine/annotations": "^1.8", "goaop/framework": "^2", "mockery/mockery": "^1.3", From 22ee596348c02a5f2d6cc4ce4b7cc59264a54194 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Wed, 8 Jul 2020 15:27:19 -0500 Subject: [PATCH 03/22] Make `serialize(UuidInterface)` more compact Resolves #318 --- src/Fields/SerializableFieldsTrait.php | 10 +++++++--- src/Uuid.php | 12 +++++++++--- tests/Rfc4122/FieldsTest.php | 10 ++++++++++ tests/UuidTest.php | 10 ++++++++++ 4 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/Fields/SerializableFieldsTrait.php b/src/Fields/SerializableFieldsTrait.php index 90f1d49..4ae90be 100644 --- a/src/Fields/SerializableFieldsTrait.php +++ b/src/Fields/SerializableFieldsTrait.php @@ -15,7 +15,7 @@ declare(strict_types=1); namespace Ramsey\Uuid\Fields; use function base64_decode; -use function base64_encode; +use function strlen; /** * Provides common serialization functionality to fields @@ -39,7 +39,7 @@ trait SerializableFieldsTrait */ public function serialize(): string { - return base64_encode($this->getBytes()); + return $this->getBytes(); } /** @@ -51,6 +51,10 @@ trait SerializableFieldsTrait */ public function unserialize($serialized): void { - $this->__construct(base64_decode($serialized)); + if (strlen($serialized) === 16) { + $this->__construct($serialized); + } else { + $this->__construct(base64_decode($serialized)); + } } } diff --git a/src/Uuid.php b/src/Uuid.php index 0f86cdd..f38e375 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -273,7 +273,7 @@ class Uuid implements UuidInterface */ public function serialize(): string { - return $this->toString(); + return $this->getBytes(); } /** @@ -286,8 +286,14 @@ class Uuid implements UuidInterface */ public function unserialize($serialized): void { - /** @var \Ramsey\Uuid\Uuid $uuid */ - $uuid = self::fromString($serialized); + if (strlen($serialized) === 16) { + /** @var Uuid $uuid */ + $uuid = self::fromBytes($serialized); + } else { + /** @var Uuid $uuid */ + $uuid = self::fromString($serialized); + } + $this->codec = $uuid->codec; $this->numberConverter = $uuid->numberConverter; $this->fields = $uuid->fields; diff --git a/tests/Rfc4122/FieldsTest.php b/tests/Rfc4122/FieldsTest.php index 40282a6..7f4b217 100644 --- a/tests/Rfc4122/FieldsTest.php +++ b/tests/Rfc4122/FieldsTest.php @@ -212,4 +212,14 @@ class FieldsTest extends TestCase $this->assertEquals($fields, $unserializedFields); } + + public function testSerializingFieldsWithOldFormat(): void + { + $fields = new Fields("\xb3\xcd\x58\x6a\xe3\xca\x44\xf3\x98\x8c\xf4\xd6\x66\xc1\xbf\x4d"); + + $serializedFields = 'C:26:"Ramsey\Uuid\Rfc4122\Fields":24:{s81YauPKRPOYjPTWZsG/TQ==}'; + $unserializedFields = unserialize($serializedFields); + + $this->assertEquals($fields, $unserializedFields); + } } diff --git a/tests/UuidTest.php b/tests/UuidTest.php index a77108f..5cbf6c7 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -1538,6 +1538,16 @@ class UuidTest extends TestCase $this->assertTrue($uuid->equals($unserializedUuid)); } + public function testSerializeWithOldStringFormat(): void + { + $serialized = 'C:26:"Ramsey\Uuid\Rfc4122\UuidV4":36:{b3cd586a-e3ca-44f3-988c-f4d666c1bf4d}'; + + /** @var UuidInterface $unserializedUuid */ + $unserializedUuid = unserialize($serialized); + + $this->assertSame('b3cd586a-e3ca-44f3-988c-f4d666c1bf4d', $unserializedUuid->toString()); + } + public function testUuid3WithEmptyNamespace(): void { $this->expectException(InvalidArgumentException::class); From 8d42044a99cfa35fed8e954634d4882be10a711f Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 30 Jun 2020 12:21:44 +0200 Subject: [PATCH 04/22] Minimal benchmarks around `Uuid::fromString()`, `Uuid::fromBytes()`, `Uuid#toString()`, `Uuid#getBytes()` This is mostly to store an initial state, before we go on and start manipulating the UUID library internals. --- .gitattributes | 1 + composer.json | 1 + phpbench.json | 10 + tests/benchmark/UuidStringConversionBench.php | 261 ++++++++++++++++++ 4 files changed, 273 insertions(+) create mode 100644 phpbench.json create mode 100644 tests/benchmark/UuidStringConversionBench.php diff --git a/.gitattributes b/.gitattributes index 5d184e3..2ee8814 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4,6 +4,7 @@ .readthedocs.yml export-ignore .travis.yml export-ignore docs/ export-ignore +phpbench.json export-ignore phpcs.xml.dist export-ignore phpunit.xml.dist export-ignore resources/ export-ignore diff --git a/composer.json b/composer.json index a8bbe80..414598b 100644 --- a/composer.json +++ b/composer.json @@ -27,6 +27,7 @@ "php-mock/php-mock-mockery": "^1.3", "php-mock/php-mock-phpunit": "^2.5", "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^0.17.1", "phpstan/extension-installer": "^1.0", "phpstan/phpstan": "^0.12", "phpstan/phpstan-mockery": "^0.12", diff --git a/phpbench.json b/phpbench.json new file mode 100644 index 0000000..f1150d0 --- /dev/null +++ b/phpbench.json @@ -0,0 +1,10 @@ +{ + "bootstrap": "vendor/autoload.php", + "path": "tests/benchmark", + "retry_threshold": 5, + "reports": { + "report": { + "extends": "aggregate" + } + } +} diff --git a/tests/benchmark/UuidStringConversionBench.php b/tests/benchmark/UuidStringConversionBench.php new file mode 100644 index 0000000..ca05de6 --- /dev/null +++ b/tests/benchmark/UuidStringConversionBench.php @@ -0,0 +1,261 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Benchmark; + +use Ramsey\Uuid\Uuid; +use Ramsey\Uuid\UuidInterface; +use function array_map; + +final class UuidStringConversionBench +{ + private const TINY_UUID = '00000000-0000-0000-0000-000000000001'; + private const HUGE_UUID = 'ffffffff-ffff-ffff-ffff-ffffffffffff'; + private const UUIDS_TO_BE_SHORTENED = [ + '0ae0cac5-2a40-465c-99ed-3d331b7cf72a', + '5759b9ce-07b5-4e89-b33a-f864317a2951', + '20c8664e-81a8-498d-9e98-444973ef3122', + '16fcbcf3-bb47-4227-90bd-3485d60510c3', + 'fa83ae94-38e0-4903-bc6a-0a3eca6e9ef5', + '51c9e011-0429-4d77-a753-702bd67dcd84', + '1bd8857a-d6d7-4bd6-8734-b3dfedbcda7b', + '7aa38b71-37c3-4561-9b2e-ca227f1c9c55', + 'e6b8854c-435c-4bb1-b6ad-1800b5d3e6bb', + '4e2b0031-8b09-46e2-8244-3814c46a2f53', + 'bedd0850-da1a-4808-95c4-25fef0abbaa7', + '516b9052-d6fb-4828-bfc1-dffdef2d56d2', + '5d60a7e7-9139-4779-9f28-e6316b9fe3b7', + '65aa3d74-c1fb-4bdd-9a00-ce88a5270c57', + '27c2e339-74ed-49a7-a3c4-1a0172e9f945', + 'e89b7727-4847-41ab-98d7-4148216eea8c', + 'd79efaf3-b5dc-43a0-b3a5-c492155a7e0d', + 'ee9ee6e7-5b7d-4e18-ab88-ce03d569305f', + 'fe90c911-c13b-4103-bf33-16757aa87ff5', + '4d7ff67a-0074-4195-95d7-cf8b84eba079', + 'abe5d378-d021-4905-93f4-0e76a7848365', + '19d21907-d121-4d85-8a34-a65d04ce8977', + 'c421b8ad-33a4-42aa-b0cc-8f5f94b2cff7', + 'f3dbbe55-3c80-453e-ab39-a6fe5001a7fc', + 'f48d3eb2-6060-458f-809f-b5e887f9a17f', + 'd189e406-de29-4889-8470-7bfa0d020c0c', + '71627018-9f21-4034-aafe-4c8b17151217', + '0c6a9278-0963-4460-9cae-6dc6f5420f4f', + 'c833ac35-cce0-4315-8df3-3ed76656a548', + '78e94126-1d0a-472a-9b99-37840784318f', + '6e684707-ce4b-42df-8a77-71e57b54b581', + '811df139-e7a3-4cd8-b778-c81494d239ee', + 'c263c5d8-c166-4599-9219-3e975e506f45', + 'b31e7c5d-95ba-41d4-bc29-e6357c96f005', + '16ae2983-7f8f-4eee-9afb-6d4617836a01', + 'ecbbfac7-f92a-4b41-996e-3e4724aa0e23', + '2c6b3db9-a5ee-4425-a837-8880a86faaa0', + '3d67a99a-b39a-4295-b7f8-0bf71ead5b2d', + 'ca421bb7-ad73-41ea-9648-70073862ad5a', + '5ba156fa-853d-460f-a884-ca8dd3a27314', + '42a4359a-1df2-4086-b454-7477dbb726ff', + '7db9517b-f6ba-4bcf-ae26-6a88a7dbb034', + 'bc758bd6-eb50-425b-ada1-07e6bb312032', + '254cf6d0-696d-4ff0-b579-ac3b633f03c0', + 'f8f34b37-4c71-4177-bac5-6b99bb1929af', + 'b0cc6179-f2b1-4ddf-8fe2-2251c3d935a3', + '333ad834-fa3b-4cf4-b9ba-fdb1c481c497', + '011fc3bc-a97d-4535-8cb0-81766e361e78', + 'acf2262b-4ccf-4f1d-b5c1-5e44641884c6', + '6bf661b1-2f85-4277-8dba-6552141e7e42', + 'a76df66b-8c50-488f-b4e7-4f4d3c05afff', + 'b5c5df47-f939-4536-a340-442bf00bd70d', + 'd4914d41-0011-49fb-a1c2-fe69108e4983', + 'efd5fa37-b0de-43b0-9fe7-1b7a7a6523f8', + '6048f863-7faa-43f2-8202-4b349ae34810', + '659a0024-fa05-4068-aed0-e61239554b6d', + '6ec80af3-0415-429e-91e9-8491ab5745c0', + '0e6f754c-0533-4336-b4f0-e2e35518efa1', + '47469672-7e55-4316-b5d4-c458e43d2404', + '0c5ad756-a823-4a3f-8449-840fac080f45', + '8f8345da-1dd9-499b-bda5-57100bb305d5', + '4a31d059-e375-4571-9d28-ea0de51740e7', + 'ed7fb50c-1b3a-4594-920b-9a461abce57c', + '3d8fe6f6-e603-44c0-b550-3568523c3224', + '809259bc-7912-427a-a975-7298ee5626db', + 'ec88d77e-5612-466c-b269-ad146abd70d0', + 'bd308a10-8073-45ae-9bfb-9a663ad5dd10', + '83a6a4cc-3079-46d8-9263-8f57af4fd4c7', + '557f0041-7e7f-447c-988c-eafa6e396915', + '6ad0fa1c-7425-41e9-9b74-19c4935750a2', + 'a9193e21-e529-43cf-9421-6ed09b59d86e', + '2a09f6e6-4fb2-4da0-97bf-6f32858ba977', + 'd66e0940-087f-4e71-8292-fc38e306d9f7', + '0dfc58b3-d591-40be-803d-e17a52e5d262', + 'a46c6902-de10-45cc-8dac-600d68860532', + '5200f9dc-b967-4d1e-ab01-51c726c152ba', + 'acd8498b-ee8b-4d58-b0ef-c353fb1b5a45', + '36adf355-cccc-406f-a814-6333ec4e31bf', + 'd6d64c6f-8388-4de3-9db1-de07f02071b6', + 'daf3fde9-41d0-422f-a0e3-8c7a93a77091', + '160f4fac-a229-4169-893e-4e9e6864c098', + '170c4be9-1fe6-4838-8a77-dee364ae9a95', + '2864fed0-868c-4bd1-a3fa-ae3bb3de20f4', + '8ea6639c-36dc-463c-8299-8f9a12b10898', + '626bef95-2f24-47c2-a792-f06e8f13a11e', + 'ede75c44-5a1d-484c-942d-87407f27db23', + '966ec42b-0bf7-4923-9672-7a41fee377bc', + '399d7ce6-b28f-4751-ac50-73e31b079f22', + 'ab2b4086-e181-4f02-aee1-a94afed40b50', + '3cfc33a6-73f7-49f7-9c01-fbcf84e604d0', + '40cf06c6-74ca-4016-b388-17dc0334770d', + '58f9ecd3-14ab-4100-b32a-cc2622f06c81', + 'a5c35e34-5d05-4724-bb6c-613b5d306a18', + '5133ae3e-e38b-47fa-a3dc-965c738be792', + '594acd2f-7100-4b2b-8b8a-6097cb1cec3d', + '08b3da92-6b32-43d8-9fdd-53eaa996d649', + '93dcdc27-ab2c-4828-9074-4876ee7ab257', + '8260a154-23cc-4510-a5df-cc5119f457fb', + '732a6571-9729-4935-92be-1a74b3242636', + 'c15f5581-e047-45b7-a36f-dfef4e7ba4bb', + ]; + /** @var UuidInterface */ + private $tinyUuid; + /** @var UuidInterface */ + private $hugeUuid; + /** @var UuidInterface */ + private $uuid; + /** + * @var UuidInterface + * + * @psalm-var non-empty-list + */ + private $promiscuousUuids; + /** + * @var string + * + * @psalm-var non-empty-string + */ + private $tinyUuidBytes; + /** + * @var string + * + * @psalm-var non-empty-string + */ + private $hugeUuidBytes; + /** + * @var string + * + * @psalm-var non-empty-string + */ + private $uuidBytes; + /** + * @var string + * + * @psalm-var non-empty-list + */ + private $promiscuousUuidsBytes; + + public function __construct() + { + $this->tinyUuid = Uuid::fromString(self::TINY_UUID); + $this->hugeUuid = Uuid::fromString(self::HUGE_UUID); + $this->uuid = Uuid::fromString(self::UUIDS_TO_BE_SHORTENED[0]); + $this->promiscuousUuids = array_map([Uuid::class, 'fromString'], self::UUIDS_TO_BE_SHORTENED); + $this->tinyUuidBytes = $this->tinyUuid->getBytes(); + $this->hugeUuidBytes = $this->hugeUuid->getBytes(); + $this->uuidBytes = $this->uuid->getBytes(); + $this->promiscuousUuidsBytes = array_map(static function (UuidInterface $uuid): string { + return $uuid->getBytes(); + }, $this->promiscuousUuids); + } + + public function benchCreationOfTinyUuidFromString(): void + { + Uuid::fromString(self::TINY_UUID); + } + + public function benchCreationOfHugeUuidFromString(): void + { + Uuid::fromString(self::HUGE_UUID); + } + + public function benchCreationOfUuidFromString(): void + { + Uuid::fromString(self::UUIDS_TO_BE_SHORTENED[0]); + } + + public function benchCreationOfPromiscuousUuidsFromString(): void + { + array_map([Uuid::class, 'fromString'], self::UUIDS_TO_BE_SHORTENED); + } + + public function benchCreationOfTinyUuidFromBytes(): void + { + Uuid::fromBytes($this->tinyUuidBytes); + } + + public function benchCreationOfHugeUuidFromBytes(): void + { + Uuid::fromBytes($this->hugeUuidBytes); + } + + public function benchCreationOfUuidFromBytes(): void + { + Uuid::fromBytes($this->uuidBytes); + } + + public function benchCreationOfPromiscuousUuidsFromBytes(): void + { + array_map([Uuid::class, 'fromBytes'], $this->promiscuousUuidsBytes); + } + + public function benchStringConversionOfTinyUuid(): void + { + $this->tinyUuid->toString(); + } + + public function benchStringConversionOfHugeUuid(): void + { + $this->hugeUuid->toString(); + } + + public function benchStringConversionOfUuid(): void + { + $this->uuid->toString(); + } + + public function benchStringConversionOfPromiscuousUuids(): void + { + array_map(static function (UuidInterface $uuid): string { + return $uuid->toString(); + }, $this->promiscuousUuids); + } + + public function benchBytesConversionOfTinyUuid(): void + { + $this->tinyUuid->getBytes(); + } + + public function benchBytesConversionOfHugeUuid(): void + { + $this->hugeUuid->getBytes(); + } + + public function benchBytesConversionOfUuid(): void + { + $this->uuid->getBytes(); + } + + public function benchBytesConversionOfPromiscuousUuids(): void + { + array_map(static function (UuidInterface $uuid): string { + return $uuid->getBytes(); + }, $this->promiscuousUuids); + } +} From 569e93ac4e82410102d3431815cb65e701bef26a Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 30 Jun 2020 14:38:04 +0200 Subject: [PATCH 05/22] Re-implemented `Uuid::fromString()` so it produces a `LazyUuidFromString` when possible This should speed up `Uuid::fromString()` massively, leading to much shallower execution paths when `toString()` and similar simplistic API is required. --- src/Lazy/LazyUuidFromString.php | 409 +++++++++++++++++++++++ src/Rfc4122/Validator.php | 6 +- src/Uuid.php | 23 +- src/Validator/GenericValidator.php | 4 +- tests/Nonstandard/UuidV6Test.php | 7 +- tests/Rfc4122/ValidatorTest.php | 16 +- tests/UuidTest.php | 40 +-- tests/Validator/GenericValidatorTest.php | 14 +- 8 files changed, 482 insertions(+), 37 deletions(-) create mode 100644 src/Lazy/LazyUuidFromString.php diff --git a/src/Lazy/LazyUuidFromString.php b/src/Lazy/LazyUuidFromString.php new file mode 100644 index 0000000..031f0c9 --- /dev/null +++ b/src/Lazy/LazyUuidFromString.php @@ -0,0 +1,409 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Lazy; + +use DateTimeInterface; +use Ramsey\Uuid\Converter\NumberConverterInterface; +use Ramsey\Uuid\Exception\UnsupportedOperationException; +use Ramsey\Uuid\Fields\FieldsInterface; +use Ramsey\Uuid\Nonstandard\UuidV6; +use Ramsey\Uuid\Rfc4122\UuidV1; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer as IntegerObject; +use Ramsey\Uuid\Uuid; +use Ramsey\Uuid\UuidInterface; +use function hex2bin; +use function str_replace; + +/** + * Lazy version of a UUID: its format has not been determined yet, so it is mostly only usable for string/bytes + * conversion. This object optimizes instantiation, serialization and string conversion time, at the cost of + * increased overhead for more advanced UUID operations. + * + * @psalm-immutable + * + * @internal this type is used internally for performance reasons, and is not supposed to be directly referenced + * in consumer libraries. + */ +final class LazyUuidFromString implements UuidInterface +{ + public const VALID_PATTERN = '/\A[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}\z/ms'; + + /** @var non-empty-string */ + private $uuid; + + /** @var non-empty-string */ + public function __construct(string $uuid) + { + $this->uuid = $uuid; + } + + public function serialize(): string + { + return $this->uuid; + } + + public function unserialize($serialized): void + { + $this->uuid = $serialized; + } + + public function getNumberConverter(): NumberConverterInterface + { + return $this->unwrap() + ->getNumberConverter(); + } + + public function getFieldsHex(): array + { + return $this->unwrap() + ->getFieldsHex(); + } + + public function getClockSeqHiAndReservedHex(): string + { + return $this->unwrap() + ->getClockSeqHiAndReservedHex(); + } + + public function getClockSeqLowHex(): string + { + return $this->unwrap() + ->getClockSeqLowHex(); + } + + public function getClockSequenceHex(): string + { + return $this->unwrap() + ->getClockSequenceHex(); + } + + public function getDateTime(): DateTimeInterface + { + return $this->unwrap() + ->getDateTime(); + } + + public function getLeastSignificantBitsHex(): string + { + return $this->unwrap() + ->getLeastSignificantBitsHex(); + } + + public function getMostSignificantBitsHex(): string + { + return $this->unwrap() + ->getMostSignificantBitsHex(); + } + + public function getNodeHex(): string + { + return $this->unwrap() + ->getNodeHex(); + } + + public function getTimeHiAndVersionHex(): string + { + return $this->unwrap() + ->getTimeHiAndVersionHex(); + } + + public function getTimeLowHex(): string + { + return $this->unwrap() + ->getTimeLowHex(); + } + + public function getTimeMidHex(): string + { + return $this->unwrap() + ->getTimeMidHex(); + } + + public function getTimestampHex(): string + { + return $this->unwrap() + ->getTimestampHex(); + } + + public function getUrn(): string + { + return $this->unwrap() + ->getUrn(); + } + + public function getVariant(): ?int + { + return $this->unwrap() + ->getVariant(); + } + + public function getVersion(): ?int + { + return $this->unwrap() + ->getVersion(); + } + + public function compareTo(UuidInterface $other): int + { + return $this->unwrap() + ->compareTo($other); + } + + public function equals(?object $other): bool + { + if (! $other instanceof UuidInterface) { + return false; + } + + return $this->uuid === $other->toString(); + } + + public function getBytes(): string + { + return hex2bin(str_replace('-', '', $this->uuid)); + } + + public function getFields(): FieldsInterface + { + return $this->unwrap() + ->getFields(); + } + + public function getHex(): Hexadecimal + { + return $this->unwrap() + ->getHex(); + } + + public function getInteger(): IntegerObject + { + return $this->unwrap() + ->getInteger(); + } + + public function toString(): string + { + return $this->uuid; + } + + public function __toString(): string + { + return $this->uuid; + } + + public function jsonSerialize(): string + { + return $this->uuid; + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqHiAndReserved()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getClockSeqHiAndReserved(): string + { + $instance = $this->unwrap(); + + return $instance->getNumberConverter() + ->fromHex( + $instance->getFields() + ->getClockSeqHiAndReserved() + ->toString() + ); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqLow()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getClockSeqLow(): string + { + $instance = $this->unwrap(); + + return $instance->getNumberConverter() + ->fromHex( + $instance->getFields() + ->getClockSeqLow() + ->toString() + ); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getClockSeq()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getClockSequence(): string + { + $instance = $this->unwrap(); + + return $instance->getNumberConverter() + ->fromHex( + $instance->getFields() + ->getClockSeq() + ->toString() + ); + } + + /** + * @deprecated This method will be removed in 5.0.0. There is no direct + * alternative, but the same information may be obtained by splitting + * in half the value returned by {@see UuidInterface::getHex()}. + */ + public function getLeastSignificantBits(): string + { + $instance = $this->unwrap(); + + return $instance->getNumberConverter() + ->fromHex(substr($instance->getHex()->toString(), 16)); + } + + /** + * @deprecated This method will be removed in 5.0.0. There is no direct + * alternative, but the same information may be obtained by splitting + * in half the value returned by {@see UuidInterface::getHex()}. + */ + public function getMostSignificantBits(): string + { + $instance = $this->unwrap(); + + return $instance->getNumberConverter() + ->fromHex(substr($instance->getHex()->toString(), 0, 16)); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getNode()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getNode(): string + { + $instance = $this->unwrap(); + + return $instance->getNumberConverter() + ->fromHex( + $instance->getFields() + ->getNode() + ->toString() + ); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimeHiAndVersion()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getTimeHiAndVersion(): string + { + $instance = $this->unwrap(); + + return $instance->getNumberConverter() + ->fromHex( + $instance->getFields() + ->getTimeHiAndVersion() + ->toString() + ); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimeLow()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getTimeLow(): string + { + $instance = $this->unwrap(); + + return $instance->getNumberConverter() + ->fromHex( + $instance->getFields() + ->getTimeLow() + ->toString() + ); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimeMid()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getTimeMid(): string + { + $instance = $this->unwrap(); + + return $instance->getNumberConverter() + ->fromHex( + $instance->getFields() + ->getTimeMid() + ->toString() + ); + } + + /** + * @deprecated Use {@see UuidInterface::getFields()} to get a + * {@see FieldsInterface} instance. If it is a {@see Rfc4122FieldsInterface} + * instance, you may call {@see Rfc4122FieldsInterface::getTimestamp()} + * and use the arbitrary-precision math library of your choice to + * convert it to a string integer. + */ + public function getTimestamp(): string + { + $instance = $this->unwrap(); + $fields = $instance->getFields(); + + if ($fields->getVersion() !== 1) { + throw new UnsupportedOperationException('Not a time-based UUID'); + } + + return $instance->getNumberConverter() + ->fromHex($fields->getTimestamp()->toString()); + } + + public function toUuidV1(): UuidV1 + { + $instance = $this->unwrap(); + + if ($instance instanceof UuidV1) { + return $instance; + } + + assert($instance instanceof UuidV6); + + return $instance->toUuidV1(); + } + + private function unwrap(): UuidInterface + { + return Uuid::getFactory() + ->fromString($this->uuid); + } +} diff --git a/src/Rfc4122/Validator.php b/src/Rfc4122/Validator.php index 7dcf078..ed43c98 100644 --- a/src/Rfc4122/Validator.php +++ b/src/Rfc4122/Validator.php @@ -27,8 +27,8 @@ use function str_replace; */ final class Validator implements ValidatorInterface { - private const VALID_PATTERN = '^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-' - . '[1-5]{1}[0-9A-Fa-f]{3}-[ABab89]{1}[0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}$'; + private const VALID_PATTERN = '\A[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-' + . '[1-5]{1}[0-9A-Fa-f]{3}-[ABab89]{1}[0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}\z'; /** * @psalm-return non-empty-string @@ -44,6 +44,6 @@ final class Validator implements ValidatorInterface { $uuid = str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}'], '', $uuid); - return $uuid === Uuid::NIL || preg_match('/' . self::VALID_PATTERN . '/D', $uuid); + return $uuid === Uuid::NIL || preg_match('/' . self::VALID_PATTERN . '/Dms', $uuid); } } diff --git a/src/Uuid.php b/src/Uuid.php index f38e375..091348b 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -19,12 +19,16 @@ use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Fields\FieldsInterface; +use Ramsey\Uuid\Lazy\LazyUuidFromString; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; +use function bin2hex; +use function preg_match; use function str_replace; use function strcmp; +use function strtolower; /** * Uuid provides constants and static methods for working with and generating UUIDs @@ -194,6 +198,12 @@ class Uuid implements UuidInterface */ private static $factory = null; + /** + * @var bool flag to detect if the UUID factory was replaced internally, which disables all optimizations + * for the default/happy path internal scenarios + */ + private static $factoryReplaced = false; + /** * @var CodecInterface */ @@ -288,10 +298,10 @@ class Uuid implements UuidInterface { if (strlen($serialized) === 16) { /** @var Uuid $uuid */ - $uuid = self::fromBytes($serialized); + $uuid = self::getFactory()->fromBytes($serialized); } else { /** @var Uuid $uuid */ - $uuid = self::fromString($serialized); + $uuid = self::getFactory()->fromString($serialized); } $this->codec = $uuid->codec; @@ -375,6 +385,10 @@ class Uuid implements UuidInterface */ public static function setFactory(UuidFactoryInterface $factory): void { + // Note: non-string equality is intentional here. If the factory is configured differently, every assumption + // around purity is broken, and we have to internally decide everything differently. + self::$factoryReplaced = ($factory != new UuidFactory()); + self::$factory = $factory; } @@ -391,6 +405,7 @@ class Uuid implements UuidInterface */ public static function fromBytes(string $bytes): UuidInterface { + // @TODO optimize this endpoint too return self::getFactory()->fromBytes($bytes); } @@ -407,6 +422,10 @@ class Uuid implements UuidInterface */ public static function fromString(string $uuid): UuidInterface { + if (! self::$factoryReplaced && preg_match(LazyUuidFromString::VALID_PATTERN, $uuid) === 1) { + return new LazyUuidFromString(strtolower($uuid)); + } + return self::getFactory()->fromString($uuid); } diff --git a/src/Validator/GenericValidator.php b/src/Validator/GenericValidator.php index f6a6010..fd60955 100644 --- a/src/Validator/GenericValidator.php +++ b/src/Validator/GenericValidator.php @@ -29,7 +29,7 @@ final class GenericValidator implements ValidatorInterface /** * Regular expression pattern for matching a UUID of any variant. */ - private 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}$'; + private const VALID_PATTERN = '\A[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}\z'; /** * @psalm-return non-empty-string @@ -45,6 +45,6 @@ final class GenericValidator implements ValidatorInterface { $uuid = str_replace(['urn:', 'uuid:', 'URN:', 'UUID:', '{', '}'], '', $uuid); - return $uuid === Uuid::NIL || preg_match('/' . self::VALID_PATTERN . '/D', $uuid); + return $uuid === Uuid::NIL || preg_match('/' . self::VALID_PATTERN . '/Dms', $uuid); } } diff --git a/tests/Nonstandard/UuidV6Test.php b/tests/Nonstandard/UuidV6Test.php index 3c0300e..899f032 100644 --- a/tests/Nonstandard/UuidV6Test.php +++ b/tests/Nonstandard/UuidV6Test.php @@ -11,9 +11,9 @@ use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\DateTimeException; use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Lazy\LazyUuidFromString; use Ramsey\Uuid\Nonstandard\UuidV6; use Ramsey\Uuid\Rfc4122\FieldsInterface; -use Ramsey\Uuid\Rfc4122\UuidV1; use Ramsey\Uuid\Test\TestCase; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Time; @@ -123,8 +123,9 @@ class UuidV6Test extends TestCase */ public function testFromUuidV1(string $uuidv6, string $uuidv1): void { - /** @var UuidV1 $uuid1 */ - $uuid1 = Uuid::fromString($uuidv1); + /** @var LazyUuidFromString $uuid */ + $uuid = Uuid::fromString($uuidv1); + $uuid1 = $uuid->toUuidV1(); $uuid6 = UuidV6::fromUuidV1($uuid1); $this->assertSame($uuidv1, $uuid1->toString()); diff --git a/tests/Rfc4122/ValidatorTest.php b/tests/Rfc4122/ValidatorTest.php index 415e20f..e8b9770 100644 --- a/tests/Rfc4122/ValidatorTest.php +++ b/tests/Rfc4122/ValidatorTest.php @@ -75,13 +75,25 @@ class ValidatorTest extends TestCase 'value' => 'ff6f8cb0-c57da-51e1-9b21-0800200c9a66', 'expected' => false, ], + [ + 'value' => "ff6f8cb0-c57d-11e1-1b21-0800200c9a66\n", + 'expected' => false, + ], + [ + 'value' => "\nff6f8cb0-c57d-11e1-1b21-0800200c9a66", + 'expected' => false, + ], + [ + 'value' => "\nff6f8cb0-c57d-11e1-1b21-0800200c9a66\n", + 'expected' => false, + ], ]); } public function testGetPattern(): void { - $expectedPattern = '^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-' - . '[1-5]{1}[0-9A-Fa-f]{3}-[ABab89]{1}[0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}$'; + $expectedPattern = '\A[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-' + . '[1-5]{1}[0-9A-Fa-f]{3}-[ABab89]{1}[0-9A-Fa-f]{3}-[0-9A-Fa-f]{12}\z'; $validator = new Validator(); diff --git a/tests/UuidTest.php b/tests/UuidTest.php index 5cbf6c7..7e8551b 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -68,9 +68,11 @@ class UuidTest extends TestCase public function testFromString(): void { - $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertInstanceOf(Uuid::class, $uuid); - $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); + $this->assertEquals( + 'ff6f8cb0-c57d-11e1-9b21-0800200c9a66', + Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66') + ->toString() + ); } /** @@ -109,6 +111,14 @@ class UuidTest extends TestCase Uuid::fromString('ff6f8cb0-c57d-11e1-9b21'); } + public function testFromStringWithLeadingNewLine(): void + { + $this->expectException(InvalidUuidStringException::class); + $this->expectExceptionMessage('Invalid UUID string:'); + + Uuid::fromString("\nd0d5f586-21d1-470c-8088-55c8857728dc"); + } + public function testFromStringWithTrailingNewLine(): void { $this->expectException(InvalidUuidStringException::class); @@ -713,8 +723,7 @@ class UuidTest extends TestCase $this->assertEquals(2, $uobj1->getVariant()); $this->assertEquals(3, $uobj1->getVersion()); - $this->assertEquals(Uuid::fromString($uuid), $uobj1); - $this->assertEquals((string) $uobj1, $uuid); + $this->assertEquals(Uuid::fromString($uuid)->toString(), $uobj1->toString()); $this->assertTrue($uobj1->equals($uobj2)); } @@ -848,8 +857,7 @@ class UuidTest extends TestCase $this->assertEquals(2, $uobj1->getVariant()); $this->assertEquals(5, $uobj1->getVersion()); - $this->assertEquals(Uuid::fromString($uuid), $uobj1); - $this->assertEquals((string) $uobj1, $uuid); + $this->assertEquals(Uuid::fromString($uuid)->toString(), $uobj1->toString()); $this->assertTrue($uobj1->equals($uobj2)); } @@ -1177,8 +1185,7 @@ class UuidTest extends TestCase string $time, string $clockSeq, int $variant, - ?int $version, - string $class + ?int $version ): void { $uuids = [ Uuid::fromString($string), @@ -1209,7 +1216,6 @@ class UuidTest extends TestCase $this->assertSame($clockSeq, $uuid->getClockSequenceHex()); $this->assertSame($variant, $uuid->getVariant()); $this->assertSame($version, $uuid->getVersion()); - $this->assertInstanceOf($class, $uuid); } } @@ -1242,7 +1248,6 @@ class UuidTest extends TestCase 'clock_seq' => '0000', 'variant' => Uuid::RESERVED_NCS, 'version' => null, - 'class' => NilUuid::class, ], [ 'string' => '00010203-0405-0607-0809-0a0b0c0d0e0f', @@ -1263,7 +1268,6 @@ class UuidTest extends TestCase 'clock_seq' => '0809', 'variant' => Uuid::RESERVED_NCS, 'version' => null, - 'class' => NonstandardUuid::class, ], [ 'string' => '02d9e6d5-9467-382e-8f9b-9300a64ac3cd', @@ -1284,7 +1288,6 @@ class UuidTest extends TestCase 'clock_seq' => '0f9b', 'variant' => Uuid::RFC_4122, 'version' => Uuid::UUID_TYPE_HASH_MD5, - 'class' => UuidV3::class, ], [ 'string' => '12345678-1234-5678-1234-567812345678', @@ -1305,7 +1308,6 @@ class UuidTest extends TestCase 'clock_seq' => '1234', 'variant' => Uuid::RESERVED_NCS, 'version' => null, - 'class' => NonstandardUuid::class, ], [ 'string' => '6ba7b810-9dad-11d1-80b4-00c04fd430c8', @@ -1326,7 +1328,6 @@ class UuidTest extends TestCase 'clock_seq' => '00b4', 'variant' => Uuid::RFC_4122, 'version' => Uuid::UUID_TYPE_TIME, - 'class' => UuidV1::class, ], [ 'string' => '6ba7b811-9dad-11d1-80b4-00c04fd430c8', @@ -1347,7 +1348,6 @@ class UuidTest extends TestCase 'clock_seq' => '00b4', 'variant' => Uuid::RFC_4122, 'version' => Uuid::UUID_TYPE_TIME, - 'class' => UuidV1::class, ], [ 'string' => '6ba7b812-9dad-11d1-80b4-00c04fd430c8', @@ -1368,7 +1368,6 @@ class UuidTest extends TestCase 'clock_seq' => '00b4', 'variant' => Uuid::RFC_4122, 'version' => Uuid::UUID_TYPE_TIME, - 'class' => UuidV1::class, ], [ 'string' => '6ba7b814-9dad-11d1-80b4-00c04fd430c8', @@ -1389,7 +1388,6 @@ class UuidTest extends TestCase 'clock_seq' => '00b4', 'variant' => Uuid::RFC_4122, 'version' => Uuid::UUID_TYPE_TIME, - 'class' => UuidV1::class, ], [ 'string' => '7d444840-9dc0-11d1-b245-5ffdce74fad2', @@ -1410,7 +1408,6 @@ class UuidTest extends TestCase 'clock_seq' => '3245', 'variant' => Uuid::RFC_4122, 'version' => Uuid::UUID_TYPE_TIME, - 'class' => UuidV1::class, ], [ 'string' => 'e902893a-9d22-3c7e-a7b8-d6e313b71d9f', @@ -1431,7 +1428,6 @@ class UuidTest extends TestCase 'clock_seq' => '27b8', 'variant' => Uuid::RFC_4122, 'version' => Uuid::UUID_TYPE_HASH_MD5, - 'class' => UuidV3::class, ], [ 'string' => 'eb424026-6f54-4ef8-a4d0-bb658a1fc6cf', @@ -1452,7 +1448,6 @@ class UuidTest extends TestCase 'clock_seq' => '24d0', 'variant' => Uuid::RFC_4122, 'version' => Uuid::UUID_TYPE_RANDOM, - 'class' => UuidV4::class, ], [ 'string' => 'f81d4fae-7dec-11d0-a765-00a0c91e6bf6', @@ -1473,7 +1468,6 @@ class UuidTest extends TestCase 'clock_seq' => '2765', 'variant' => Uuid::RFC_4122, 'version' => Uuid::UUID_TYPE_TIME, - 'class' => UuidV1::class, ], [ 'string' => 'fffefdfc-fffe-fffe-fffe-fffefdfcfbfa', @@ -1494,7 +1488,6 @@ class UuidTest extends TestCase 'clock_seq' => '3ffe', 'variant' => Uuid::RESERVED_FUTURE, 'version' => null, - 'class' => NonstandardUuid::class, ], [ 'string' => 'ffffffff-ffff-ffff-ffff-ffffffffffff', @@ -1515,7 +1508,6 @@ class UuidTest extends TestCase 'clock_seq' => '3fff', 'variant' => Uuid::RESERVED_FUTURE, 'version' => null, - 'class' => NonstandardUuid::class, ], ]; } diff --git a/tests/Validator/GenericValidatorTest.php b/tests/Validator/GenericValidatorTest.php index 5a8699b..4a41330 100644 --- a/tests/Validator/GenericValidatorTest.php +++ b/tests/Validator/GenericValidatorTest.php @@ -72,12 +72,24 @@ class GenericValidatorTest extends TestCase 'value' => 'ff6f8cb0-c57da-51e1-9b21-0800200c9a66', 'expected' => false, ], + [ + 'value' => "ff6f8cb0-c57d-11e1-1b21-0800200c9a66\n", + 'expected' => false, + ], + [ + 'value' => "\nff6f8cb0-c57d-11e1-1b21-0800200c9a66", + 'expected' => false, + ], + [ + 'value' => "\nff6f8cb0-c57d-11e1-1b21-0800200c9a66\n", + 'expected' => false, + ], ]); } public function testGetPattern(): void { - $expectedPattern = '^[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}$'; + $expectedPattern = '\A[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}\z'; $validator = new GenericValidator(); From 0f68910bf2f50b243da7b381db809076b534ca2e Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 30 Jun 2020 15:01:41 +0200 Subject: [PATCH 06/22] Optimized `Uuid::fromBytes()` de-serialization to use `LazyUuidFromString` where possible --- src/Lazy/LazyUuidFromString.php | 12 +++++++++++- src/Nonstandard/UuidV6.php | 9 +++++---- src/Uuid.php | 21 +++++++++++++++++++-- 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/Lazy/LazyUuidFromString.php b/src/Lazy/LazyUuidFromString.php index 031f0c9..fd15b14 100644 --- a/src/Lazy/LazyUuidFromString.php +++ b/src/Lazy/LazyUuidFromString.php @@ -24,6 +24,7 @@ use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; +use function assert; use function hex2bin; use function str_replace; @@ -39,7 +40,7 @@ use function str_replace; */ final class LazyUuidFromString implements UuidInterface { - public const VALID_PATTERN = '/\A[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}\z/ms'; + public const VALID_REGEX = '/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/ms'; /** @var non-empty-string */ private $uuid; @@ -401,6 +402,15 @@ final class LazyUuidFromString implements UuidInterface return $instance->toUuidV1(); } + public function toUuidV6(): UuidV6 + { + $instance = $this->unwrap(); + + assert($instance instanceof UuidV6); + + return $instance; + } + private function unwrap(): UuidInterface { return Uuid::getFactory() diff --git a/src/Nonstandard/UuidV6.php b/src/Nonstandard/UuidV6.php index 454d04c..05586b3 100644 --- a/src/Nonstandard/UuidV6.php +++ b/src/Nonstandard/UuidV6.php @@ -21,6 +21,7 @@ use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Exception\DateTimeException; use Ramsey\Uuid\Exception\InvalidArgumentException; +use Ramsey\Uuid\Lazy\LazyUuidFromString; use Ramsey\Uuid\Rfc4122\FieldsInterface as Rfc4122FieldsInterface; use Ramsey\Uuid\Rfc4122\UuidInterface; use Ramsey\Uuid\Rfc4122\UuidV1; @@ -106,10 +107,10 @@ final class UuidV6 extends Uuid implements UuidInterface . '1' . substr($hex, 0, 3) . substr($hex, 16); - /** @var UuidV1 $uuid */ + /** @var LazyUuidFromString $uuid */ $uuid = Uuid::fromBytes((string) hex2bin($hex)); - return $uuid; + return $uuid->toUuidV1(); } /** @@ -124,9 +125,9 @@ final class UuidV6 extends Uuid implements UuidInterface . '6' . substr($hex, 5, 3) . substr($hex, 16); - /** @var UuidV6 $uuid */ + /** @var LazyUuidFromString $uuid */ $uuid = Uuid::fromBytes((string) hex2bin($hex)); - return $uuid; + return $uuid->toUuidV6(); } } diff --git a/src/Uuid.php b/src/Uuid.php index 091348b..3742caf 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -28,7 +28,9 @@ use function bin2hex; use function preg_match; use function str_replace; use function strcmp; +use function strlen; use function strtolower; +use function substr; /** * Uuid provides constants and static methods for working with and generating UUIDs @@ -405,7 +407,22 @@ class Uuid implements UuidInterface */ public static function fromBytes(string $bytes): UuidInterface { - // @TODO optimize this endpoint too + if (! self::$factoryReplaced && strlen($bytes) === 16) { + $base16Uuid = bin2hex($bytes); + + return self::fromString( + substr($base16Uuid,0, 8) + . '-' + . substr($base16Uuid, 8, 4) + . '-' + . substr($base16Uuid, 12, 4) + . '-' + . substr($base16Uuid, 16, 4) + . '-' + . substr($base16Uuid, 20, 12) + ); + } + return self::getFactory()->fromBytes($bytes); } @@ -422,7 +439,7 @@ class Uuid implements UuidInterface */ public static function fromString(string $uuid): UuidInterface { - if (! self::$factoryReplaced && preg_match(LazyUuidFromString::VALID_PATTERN, $uuid) === 1) { + if (! self::$factoryReplaced && preg_match(LazyUuidFromString::VALID_REGEX, $uuid) === 1) { return new LazyUuidFromString(strtolower($uuid)); } From c01872212e4fdc2d12b1a7922026a5a25eb737a4 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 30 Jun 2020 15:13:11 +0200 Subject: [PATCH 07/22] Add phpbench to CI run to ensure that we don't accidentally break benchmarks This is not indicative of performance, but just guarantees that the benchmarks still run, and that we didn't break them during an upgrade or code change. --- .travis.yml | 1 + composer.json | 2 ++ 2 files changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 5ba1e69..5aa0eca 100644 --- a/.travis.yml +++ b/.travis.yml @@ -62,6 +62,7 @@ script: - ./resources/scripts/cmd-proxy.sh composer phpcs - ./resources/scripts/cmd-proxy.sh composer phpstan - ./resources/scripts/cmd-proxy.sh composer psalm + - ./resources/scripts/cmd-proxy.sh composer phpbench - travis_wait 30 ./resources/scripts/cmd-proxy.sh ./vendor/bin/phpunit --verbose --coverage-clover build/logs/clover.xml after_success: diff --git a/composer.json b/composer.json index 414598b..7a20ee2 100644 --- a/composer.json +++ b/composer.json @@ -73,6 +73,7 @@ }, "scripts": { "lint": "parallel-lint src tests", + "phpbench": "phpbench run", "phpcbf": "phpcbf -vpw --cache=build/cache/phpcs.cache", "phpcs": "phpcs --cache=build/cache/phpcs.cache", "phpstan": [ @@ -84,6 +85,7 @@ "phpunit-coverage": "phpunit --verbose --colors=always --coverage-html build/coverage", "test": [ "@lint", + "@phpbench", "@phpcs", "@phpstan", "@psalm", From 1ce3f556733cbcb677c8a5d9613eac7c29d049fc Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 30 Jun 2020 15:19:15 +0200 Subject: [PATCH 08/22] Applied automated CS fixes according to project CS settings --- src/Lazy/LazyUuidFromString.php | 7 +++++-- src/Uuid.php | 3 ++- tests/UuidTest.php | 2 -- tests/benchmark/UuidStringConversionBench.php | 6 +----- 4 files changed, 8 insertions(+), 10 deletions(-) diff --git a/src/Lazy/LazyUuidFromString.php b/src/Lazy/LazyUuidFromString.php index fd15b14..0ea9b19 100644 --- a/src/Lazy/LazyUuidFromString.php +++ b/src/Lazy/LazyUuidFromString.php @@ -24,6 +24,7 @@ use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; + use function assert; use function hex2bin; use function str_replace; @@ -33,10 +34,10 @@ use function str_replace; * conversion. This object optimizes instantiation, serialization and string conversion time, at the cost of * increased overhead for more advanced UUID operations. * - * @psalm-immutable - * * @internal this type is used internally for performance reasons, and is not supposed to be directly referenced * in consumer libraries. + * + * @psalm-immutable */ final class LazyUuidFromString implements UuidInterface { @@ -56,6 +57,7 @@ final class LazyUuidFromString implements UuidInterface return $this->uuid; } + /** {@inheritDoc} */ public function unserialize($serialized): void { $this->uuid = $serialized; @@ -67,6 +69,7 @@ final class LazyUuidFromString implements UuidInterface ->getNumberConverter(); } + /** {@inheritDoc} */ public function getFieldsHex(): array { return $this->unwrap() diff --git a/src/Uuid.php b/src/Uuid.php index 3742caf..d7c70ea 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -389,6 +389,7 @@ class Uuid implements UuidInterface { // Note: non-string equality is intentional here. If the factory is configured differently, every assumption // around purity is broken, and we have to internally decide everything differently. + // phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedNotEqualOperator self::$factoryReplaced = ($factory != new UuidFactory()); self::$factory = $factory; @@ -411,7 +412,7 @@ class Uuid implements UuidInterface $base16Uuid = bin2hex($bytes); return self::fromString( - substr($base16Uuid,0, 8) + substr($base16Uuid, 0, 8) . '-' . substr($base16Uuid, 8, 4) . '-' diff --git a/tests/UuidTest.php b/tests/UuidTest.php index 7e8551b..ef46a3a 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -24,12 +24,10 @@ use Ramsey\Uuid\Generator\CombGenerator; use Ramsey\Uuid\Generator\RandomGeneratorFactory; use Ramsey\Uuid\Generator\RandomGeneratorInterface; use Ramsey\Uuid\Guid\Guid; -use Ramsey\Uuid\Nonstandard\Uuid as NonstandardUuid; use Ramsey\Uuid\Nonstandard\UuidV6; use Ramsey\Uuid\Provider\Node\RandomNodeProvider; use Ramsey\Uuid\Provider\Time\FixedTimeProvider; use Ramsey\Uuid\Rfc4122\FieldsInterface; -use Ramsey\Uuid\Rfc4122\NilUuid; use Ramsey\Uuid\Rfc4122\UuidV1; use Ramsey\Uuid\Rfc4122\UuidV2; use Ramsey\Uuid\Rfc4122\UuidV3; diff --git a/tests/benchmark/UuidStringConversionBench.php b/tests/benchmark/UuidStringConversionBench.php index ca05de6..8703550 100644 --- a/tests/benchmark/UuidStringConversionBench.php +++ b/tests/benchmark/UuidStringConversionBench.php @@ -16,6 +16,7 @@ namespace Ramsey\Uuid\Benchmark; use Ramsey\Uuid\Uuid; use Ramsey\Uuid\UuidInterface; + use function array_map; final class UuidStringConversionBench @@ -132,31 +133,26 @@ final class UuidStringConversionBench private $uuid; /** * @var UuidInterface - * * @psalm-var non-empty-list */ private $promiscuousUuids; /** * @var string - * * @psalm-var non-empty-string */ private $tinyUuidBytes; /** * @var string - * * @psalm-var non-empty-string */ private $hugeUuidBytes; /** * @var string - * * @psalm-var non-empty-string */ private $uuidBytes; /** * @var string - * * @psalm-var non-empty-list */ private $promiscuousUuidsBytes; From 1f0cd71d93d435afe1d461a388ba387e85fceb48 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Tue, 30 Jun 2020 15:49:29 +0200 Subject: [PATCH 09/22] Applied fixes and suppressions (sadly) to match psalm/phpstan code quality guidelines We have a lot of deprecated API in here which shouldn't exist in first place, but that will luckily disappear with v5.0.0 :-) --- composer.json | 1 + src/Lazy/LazyUuidFromString.php | 116 ++++++++++++++++-- src/Uuid.php | 15 +++ tests/UuidTest.php | 1 - tests/benchmark/UuidStringConversionBench.php | 4 +- tests/phpstan.neon | 5 + 6 files changed, 131 insertions(+), 11 deletions(-) diff --git a/composer.json b/composer.json index 7a20ee2..0f6dd38 100644 --- a/composer.json +++ b/composer.json @@ -67,6 +67,7 @@ }, "autoload-dev": { "psr-4": { + "Ramsey\\Uuid\\Benchmark\\": "tests/benchmark/", "Ramsey\\Uuid\\StaticAnalysis\\": "tests/static-analysis/", "Ramsey\\Uuid\\Test\\": "tests/" } diff --git a/src/Lazy/LazyUuidFromString.php b/src/Lazy/LazyUuidFromString.php index 0ea9b19..bad46fb 100644 --- a/src/Lazy/LazyUuidFromString.php +++ b/src/Lazy/LazyUuidFromString.php @@ -22,7 +22,7 @@ use Ramsey\Uuid\Nonstandard\UuidV6; use Ramsey\Uuid\Rfc4122\UuidV1; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Integer as IntegerObject; -use Ramsey\Uuid\Uuid; +use Ramsey\Uuid\UuidFactory; use Ramsey\Uuid\UuidInterface; use function assert; @@ -38,15 +38,26 @@ use function str_replace; * in consumer libraries. * * @psalm-immutable + * + * Note: the {@see FieldsInterface} does not declare methods that deprecated API + * relies upon: the API has been ported from the {@see \Ramsey\Uuid\Uuid} definition, + * and is deprecated anyway. + * Note: the deprecated API from {@see \Ramsey\Uuid\Uuid} is in use here (on purpose): it will be removed + * once the deprecated API is gone from this class too. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod */ final class LazyUuidFromString implements UuidInterface { public const VALID_REGEX = '/\A[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\z/ms'; - - /** @var non-empty-string */ + /** + * @var string + * @psalm-var non-empty-string + */ private $uuid; - /** @var non-empty-string */ + /** @psalm-param non-empty-string $uuid */ public function __construct(string $uuid) { $this->uuid = $uuid; @@ -57,103 +68,128 @@ final class LazyUuidFromString implements UuidInterface return $this->uuid; } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + * + * @param string $serialized + * + * @psalm-param non-empty-string $serialized + */ public function unserialize($serialized): void { $this->uuid = $serialized; } + /** @psalm-suppress DeprecatedMethod */ public function getNumberConverter(): NumberConverterInterface { return $this->unwrap() ->getNumberConverter(); } - /** {@inheritDoc} */ + /** + * {@inheritDoc} + * + * @psalm-suppress DeprecatedMethod + */ public function getFieldsHex(): array { return $this->unwrap() ->getFieldsHex(); } + /** @psalm-suppress DeprecatedMethod */ public function getClockSeqHiAndReservedHex(): string { return $this->unwrap() ->getClockSeqHiAndReservedHex(); } + /** @psalm-suppress DeprecatedMethod */ public function getClockSeqLowHex(): string { return $this->unwrap() ->getClockSeqLowHex(); } + /** @psalm-suppress DeprecatedMethod */ public function getClockSequenceHex(): string { return $this->unwrap() ->getClockSequenceHex(); } + /** @psalm-suppress DeprecatedMethod */ public function getDateTime(): DateTimeInterface { return $this->unwrap() ->getDateTime(); } + /** @psalm-suppress DeprecatedMethod */ public function getLeastSignificantBitsHex(): string { return $this->unwrap() ->getLeastSignificantBitsHex(); } + /** @psalm-suppress DeprecatedMethod */ public function getMostSignificantBitsHex(): string { return $this->unwrap() ->getMostSignificantBitsHex(); } + /** @psalm-suppress DeprecatedMethod */ public function getNodeHex(): string { return $this->unwrap() ->getNodeHex(); } + /** @psalm-suppress DeprecatedMethod */ public function getTimeHiAndVersionHex(): string { return $this->unwrap() ->getTimeHiAndVersionHex(); } + /** @psalm-suppress DeprecatedMethod */ public function getTimeLowHex(): string { return $this->unwrap() ->getTimeLowHex(); } + /** @psalm-suppress DeprecatedMethod */ public function getTimeMidHex(): string { return $this->unwrap() ->getTimeMidHex(); } + /** @psalm-suppress DeprecatedMethod */ public function getTimestampHex(): string { return $this->unwrap() ->getTimestampHex(); } + /** @psalm-suppress DeprecatedMethod */ public function getUrn(): string { return $this->unwrap() ->getUrn(); } + /** @psalm-suppress DeprecatedMethod */ public function getVariant(): ?int { return $this->unwrap() ->getVariant(); } + /** @psalm-suppress DeprecatedMethod */ public function getVersion(): ?int { return $this->unwrap() @@ -175,9 +211,16 @@ final class LazyUuidFromString implements UuidInterface return $this->uuid === $other->toString(); } + /** + * {@inheritDoc} + * + * @psalm-suppress MoreSpecificReturnType + * @psalm-suppress LessSpecificReturnStatement we know that {@see self::$uuid} is a non-empty string, so + * we know that {@see hex2bin} will retrieve a non-empty string too. + */ public function getBytes(): string { - return hex2bin(str_replace('-', '', $this->uuid)); + return (string) hex2bin(str_replace('-', '', $this->uuid)); } public function getFields(): FieldsInterface @@ -219,6 +262,11 @@ final class LazyUuidFromString implements UuidInterface * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqHiAndReserved()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall */ public function getClockSeqHiAndReserved(): string { @@ -238,6 +286,11 @@ final class LazyUuidFromString implements UuidInterface * instance, you may call {@see Rfc4122FieldsInterface::getClockSeqLow()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall */ public function getClockSeqLow(): string { @@ -257,6 +310,11 @@ final class LazyUuidFromString implements UuidInterface * instance, you may call {@see Rfc4122FieldsInterface::getClockSeq()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall */ public function getClockSequence(): string { @@ -274,6 +332,11 @@ final class LazyUuidFromString implements UuidInterface * @deprecated This method will be removed in 5.0.0. There is no direct * alternative, but the same information may be obtained by splitting * in half the value returned by {@see UuidInterface::getHex()}. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall */ public function getLeastSignificantBits(): string { @@ -287,6 +350,11 @@ final class LazyUuidFromString implements UuidInterface * @deprecated This method will be removed in 5.0.0. There is no direct * alternative, but the same information may be obtained by splitting * in half the value returned by {@see UuidInterface::getHex()}. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall */ public function getMostSignificantBits(): string { @@ -302,6 +370,11 @@ final class LazyUuidFromString implements UuidInterface * instance, you may call {@see Rfc4122FieldsInterface::getNode()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall */ public function getNode(): string { @@ -321,6 +394,11 @@ final class LazyUuidFromString implements UuidInterface * instance, you may call {@see Rfc4122FieldsInterface::getTimeHiAndVersion()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall */ public function getTimeHiAndVersion(): string { @@ -340,6 +418,11 @@ final class LazyUuidFromString implements UuidInterface * instance, you may call {@see Rfc4122FieldsInterface::getTimeLow()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall */ public function getTimeLow(): string { @@ -359,6 +442,11 @@ final class LazyUuidFromString implements UuidInterface * instance, you may call {@see Rfc4122FieldsInterface::getTimeMid()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall */ public function getTimeMid(): string { @@ -378,6 +466,11 @@ final class LazyUuidFromString implements UuidInterface * instance, you may call {@see Rfc4122FieldsInterface::getTimestamp()} * and use the arbitrary-precision math library of your choice to * convert it to a string integer. + * + * @psalm-suppress UndefinedInterfaceMethod + * @psalm-suppress DeprecatedMethod + * @psalm-suppress MixedArgument + * @psalm-suppress MixedMethodCall */ public function getTimestamp(): string { @@ -414,9 +507,16 @@ final class LazyUuidFromString implements UuidInterface return $instance; } + /** + * @psalm-suppress ImpureMethodCall the retrieval of the factory is a clear violation of purity here: this is a + * known pitfall of the design of this library, where a value object contains + * a mutable reference to a factory. We use a fixed factory here, so the violation + * will not have real-world effects, as this object is only instantiated with the + * default factory settings/features. + */ private function unwrap(): UuidInterface { - return Uuid::getFactory() + return (new UuidFactory()) ->fromString($this->uuid); } } diff --git a/src/Uuid.php b/src/Uuid.php index d7c70ea..d0859a3 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -405,6 +405,11 @@ class Uuid implements UuidInterface * * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, * but under constant factory setups, this method operates in functionally pure manners + * + * @psalm-suppress ImpureStaticProperty we know that the factory being replaced can lead to massive + * havoc across all consumers: that should never happen, and + * is generally to be discouraged. Until the factory is kept + * un-replaced, this method is effectively pure. */ public static function fromBytes(string $bytes): UuidInterface { @@ -437,6 +442,11 @@ class Uuid implements UuidInterface * * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, * but under constant factory setups, this method operates in functionally pure manners + * + * @psalm-suppress ImpureStaticProperty we know that the factory being replaced can lead to massive + * havoc across all consumers: that should never happen, and + * is generally to be discouraged. Until the factory is kept + * un-replaced, this method is effectively pure. */ public static function fromString(string $uuid): UuidInterface { @@ -588,6 +598,11 @@ class Uuid implements UuidInterface * * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, * but under constant factory setups, this method operates in functionally pure manners + * + * @psalm-suppress ImpureMethodCall we know that the factory being replaced can lead to massive + * havoc across all consumers: that should never happen, and + * is generally to be discouraged. Until the factory is kept + * un-replaced, this method is effectively pure. */ public static function uuid5($ns, string $name): UuidInterface { diff --git a/tests/UuidTest.php b/tests/UuidTest.php index ef46a3a..cef8511 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -1168,7 +1168,6 @@ class UuidTest extends TestCase * as the Python UUID library. * * @param string[] $fields - * @param class-string $class * * @dataProvider providePythonTests */ diff --git a/tests/benchmark/UuidStringConversionBench.php b/tests/benchmark/UuidStringConversionBench.php index 8703550..a15b804 100644 --- a/tests/benchmark/UuidStringConversionBench.php +++ b/tests/benchmark/UuidStringConversionBench.php @@ -132,7 +132,7 @@ final class UuidStringConversionBench /** @var UuidInterface */ private $uuid; /** - * @var UuidInterface + * @var UuidInterface[] * @psalm-var non-empty-list */ private $promiscuousUuids; @@ -152,7 +152,7 @@ final class UuidStringConversionBench */ private $uuidBytes; /** - * @var string + * @var string[] * @psalm-var non-empty-list */ private $promiscuousUuidsBytes; diff --git a/tests/phpstan.neon b/tests/phpstan.neon index 0d3c590..405d2d8 100644 --- a/tests/phpstan.neon +++ b/tests/phpstan.neon @@ -24,3 +24,8 @@ parameters: message: '#^Comparison operation ">" between 6 and 0 is always true\.$#' count: 1 path: ../src/Generator/CombGenerator.php + - + # Legacy methods of `Ramsey\Uuid` use interface methods that are NOT defined on `FieldsInterface` + message: '#^Call to an undefined method Ramsey\\Uuid\\Fields\\FieldsInterface::get.*$#' + count: 9 + path: ../src/Lazy/LazyUuidFromString.php From 910e3e459c7d301f10f2ce212bc598292e51812f Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Wed, 1 Jul 2020 12:07:50 +0200 Subject: [PATCH 10/22] Adjusted comment wording: s/string/strict (typo) Co-authored-by: Jacob Dreesen --- src/Uuid.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Uuid.php b/src/Uuid.php index d0859a3..d7c08b4 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -387,7 +387,7 @@ class Uuid implements UuidInterface */ public static function setFactory(UuidFactoryInterface $factory): void { - // Note: non-string equality is intentional here. If the factory is configured differently, every assumption + // Note: non-strict equality is intentional here. If the factory is configured differently, every assumption // around purity is broken, and we have to internally decide everything differently. // phpcs:ignore SlevomatCodingStandard.Operators.DisallowEqualOperators.DisallowedNotEqualOperator self::$factoryReplaced = ($factory != new UuidFactory()); From 2421b79841501a87311513821de16ca31275fcd4 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 3 Jul 2020 13:01:43 +0200 Subject: [PATCH 11/22] Added benchmark for UUID generation logic --- tests/benchmark/UuidGenerationBench.php | 101 ++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 tests/benchmark/UuidGenerationBench.php diff --git a/tests/benchmark/UuidGenerationBench.php b/tests/benchmark/UuidGenerationBench.php new file mode 100644 index 0000000..21c7fb9 --- /dev/null +++ b/tests/benchmark/UuidGenerationBench.php @@ -0,0 +1,101 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Benchmark; + +use Ramsey\Uuid\Provider\Node\StaticNodeProvider; +use Ramsey\Uuid\Type\Hexadecimal; +use Ramsey\Uuid\Type\Integer; +use Ramsey\Uuid\Uuid; + +final class UuidGenerationBench +{ + /** @var Hexadecimal */ + private $node; + /** @var int */ + private $clockSequence; + /** @var Integer */ + private $localIdentifier; + /** @var \Ramsey\Uuid\UuidInterface */ + private $namespace; + + public function __construct() + { + $this->node = (new StaticNodeProvider(new Hexadecimal('121212121212'))) + ->getNode(); + $this->clockSequence = 16383; + $this->localIdentifier = new Integer(5); + $this->namespace = Uuid::fromString('c485840e-9389-4548-a276-aeecd9730e50'); + } + + public function benchUuid1GenerationWithoutParameters(): void + { + Uuid::uuid1(); + } + + public function benchUuid1GenerationWithNode(): void + { + Uuid::uuid1($this->node); + } + + public function benchUuid1GenerationWithNodeAndClockSequence(): void + { + Uuid::uuid1($this->node, $this->clockSequence); + } + + public function benchUuid2GenerationWithDomainAndLocalIdentifier(): void + { + Uuid::uuid2(Uuid::DCE_DOMAIN_ORG, $this->localIdentifier); + } + + public function benchUuid2GenerationWithDomainAndLocalIdentifierAndNode(): void + { + Uuid::uuid2(Uuid::DCE_DOMAIN_ORG, $this->localIdentifier, $this->node); + } + + public function benchUuid2GenerationWithDomainAndLocalIdentifierAndNodeAndClockSequence(): void + { + Uuid::uuid2(Uuid::DCE_DOMAIN_ORG, $this->localIdentifier, $this->node, 63); + } + + public function benchUuid3Generation(): void + { + Uuid::uuid3($this->namespace, 'name'); + } + + public function benchUuid4Generation(): void + { + Uuid::uuid4(); + } + + public function benchUuid5Generation(): void + { + Uuid::uuid5($this->namespace, 'name'); + } + + public function benchUuid6GenerationWithoutParameters(): void + { + Uuid::uuid6(); + } + + public function benchUuid6GenerationWithNode(): void + { + Uuid::uuid6($this->node); + } + + public function benchUuid6GenerationWithNodeAndClockSequence(): void + { + Uuid::uuid6($this->node, $this->clockSequence); + } +} From b805572537800d84865d49f5e9e5db04e22ff65d Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Fri, 3 Jul 2020 14:18:24 +0200 Subject: [PATCH 12/22] Ensure that `Uuid::uuidX()` generators produce instances equivalent to `Uuid::fromString()` and `Uuid::fromBytes()` With this change, `Uuid::uuid1()`, `Uuid::uuid2()` and so forth now produce a `LazyUuidFromString` instance, which is both more memory efficient and comparable to `Uuid::fromString()` instances in other tools, such as within PHPUnit's `Assertion::assertEqual()`, which would reject any two objects not matching each other's types. Before this patch, `Assertion::assertEquals(Uuid::uuid5(...), Uuid::fromString(...))` would always fail due to different subtypes produced by the two factory methods. --- src/Lazy/LazyUuidFromString.php | 20 ++++++ src/Uuid.php | 1 + src/UuidFactory.php | 26 ++++++++ tests/Builder/FallbackBuilderTest.php | 2 - tests/UuidFactoryTest.php | 3 - tests/UuidTest.php | 85 +++++++++++++++---------- tests/benchmark/UuidGenerationBench.php | 6 +- 7 files changed, 101 insertions(+), 42 deletions(-) diff --git a/src/Lazy/LazyUuidFromString.php b/src/Lazy/LazyUuidFromString.php index bad46fb..519d4db 100644 --- a/src/Lazy/LazyUuidFromString.php +++ b/src/Lazy/LazyUuidFromString.php @@ -26,8 +26,10 @@ use Ramsey\Uuid\UuidFactory; use Ramsey\Uuid\UuidInterface; use function assert; +use function bin2hex; use function hex2bin; use function str_replace; +use function substr; /** * Lazy version of a UUID: its format has not been determined yet, so it is mostly only usable for string/bytes @@ -63,6 +65,24 @@ final class LazyUuidFromString implements UuidInterface $this->uuid = $uuid; } + /** @psalm-pure */ + public static function fromBytes(string $bytes): self + { + $base16Uuid = bin2hex($bytes); + + return new self( + substr($base16Uuid, 0, 8) + . '-' + . substr($base16Uuid, 8, 4) + . '-' + . substr($base16Uuid, 12, 4) + . '-' + . substr($base16Uuid, 16, 4) + . '-' + . substr($base16Uuid, 20, 12) + ); + } + public function serialize(): string { return $this->uuid; diff --git a/src/Uuid.php b/src/Uuid.php index d7c08b4..1d67d3e 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -416,6 +416,7 @@ class Uuid implements UuidInterface if (! self::$factoryReplaced && strlen($bytes) === 16) { $base16Uuid = bin2hex($bytes); + // Note: we are calling `fromString` internally because we don't know if the given `$bytes` is a valid UUID return self::fromString( substr($base16Uuid, 0, 8) . '-' diff --git a/src/UuidFactory.php b/src/UuidFactory.php index 2d8b3a1..feddef8 100644 --- a/src/UuidFactory.php +++ b/src/UuidFactory.php @@ -24,6 +24,7 @@ use Ramsey\Uuid\Generator\DefaultTimeGenerator; use Ramsey\Uuid\Generator\NameGeneratorInterface; use Ramsey\Uuid\Generator\RandomGeneratorInterface; use Ramsey\Uuid\Generator\TimeGeneratorInterface; +use Ramsey\Uuid\Lazy\LazyUuidFromString; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Provider\Time\FixedTimeProvider; use Ramsey\Uuid\Type\Hexadecimal; @@ -94,11 +95,16 @@ class UuidFactory implements UuidFactoryInterface */ private $validator; + /** @var bool whether the feature set was provided from outside, or we can operate under "default" assumptions */ + private $isDefaultFeatureSet; + /** * @param FeatureSet $features A set of available features in the current environment */ public function __construct(?FeatureSet $features = null) { + $this->isDefaultFeatureSet = $features === null; + $features = $features ?: new FeatureSet(); $this->codec = $features->getCodec(); @@ -128,6 +134,8 @@ class UuidFactory implements UuidFactoryInterface */ public function setCodec(CodecInterface $codec): void { + $this->isDefaultFeatureSet = false; + $this->codec = $codec; } @@ -147,6 +155,8 @@ class UuidFactory implements UuidFactoryInterface */ public function setNameGenerator(NameGeneratorInterface $nameGenerator): void { + $this->isDefaultFeatureSet = false; + $this->nameGenerator = $nameGenerator; } @@ -182,6 +192,8 @@ class UuidFactory implements UuidFactoryInterface */ public function setTimeGenerator(TimeGeneratorInterface $generator): void { + $this->isDefaultFeatureSet = false; + $this->timeGenerator = $generator; } @@ -201,6 +213,8 @@ class UuidFactory implements UuidFactoryInterface */ public function setDceSecurityGenerator(DceSecurityGeneratorInterface $generator): void { + $this->isDefaultFeatureSet = false; + $this->dceSecurityGenerator = $generator; } @@ -220,6 +234,8 @@ class UuidFactory implements UuidFactoryInterface */ public function setRandomGenerator(RandomGeneratorInterface $generator): void { + $this->isDefaultFeatureSet = false; + $this->randomGenerator = $generator; } @@ -231,6 +247,8 @@ class UuidFactory implements UuidFactoryInterface */ public function setNumberConverter(NumberConverterInterface $converter): void { + $this->isDefaultFeatureSet = false; + $this->numberConverter = $converter; } @@ -250,6 +268,8 @@ class UuidFactory implements UuidFactoryInterface */ public function setUuidBuilder(UuidBuilderInterface $builder): void { + $this->isDefaultFeatureSet = false; + $this->uuidBuilder = $builder; } @@ -269,6 +289,8 @@ class UuidFactory implements UuidFactoryInterface */ public function setValidator(ValidatorInterface $validator): void { + $this->isDefaultFeatureSet = false; + $this->validator = $validator; } @@ -458,6 +480,10 @@ class UuidFactory implements UuidFactoryInterface $bytes = substr_replace($bytes, $timeHiAndVersion, 6, 2); $bytes = substr_replace($bytes, $clockSeqHiAndReserved, 8, 2); + if ($this->isDefaultFeatureSet) { + return LazyUuidFromString::fromBytes($bytes); + } + return $this->uuid($bytes); } } diff --git a/tests/Builder/FallbackBuilderTest.php b/tests/Builder/FallbackBuilderTest.php index b9f55b1..7b63b6c 100644 --- a/tests/Builder/FallbackBuilderTest.php +++ b/tests/Builder/FallbackBuilderTest.php @@ -24,7 +24,6 @@ use Ramsey\Uuid\Rfc4122\UuidBuilder as Rfc4122UuidBuilder; use Ramsey\Uuid\Rfc4122\UuidV1; use Ramsey\Uuid\Rfc4122\UuidV2; use Ramsey\Uuid\Test\TestCase; -use Ramsey\Uuid\UuidInterface; use Ramsey\Uuid\Validator\GenericValidator; class FallbackBuilderTest extends TestCase @@ -112,7 +111,6 @@ class FallbackBuilderTest extends TestCase try { $uuid = $builder->build($codec, $bytes); - $this->assertInstanceOf(UuidInterface::class, $uuid); if (($uuid instanceof UuidV1) || ($uuid instanceof UuidV2) || ($uuid instanceof UuidV6)) { $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); diff --git a/tests/UuidFactoryTest.php b/tests/UuidFactoryTest.php index 0ca2540..43a4244 100644 --- a/tests/UuidFactoryTest.php +++ b/tests/UuidFactoryTest.php @@ -20,7 +20,6 @@ use Ramsey\Uuid\Generator\NameGeneratorInterface; use Ramsey\Uuid\Generator\RandomGeneratorInterface; use Ramsey\Uuid\Generator\TimeGeneratorInterface; use Ramsey\Uuid\Provider\NodeProviderInterface; -use Ramsey\Uuid\Rfc4122\UuidV1; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\UuidFactory; use Ramsey\Uuid\Validator\ValidatorInterface; @@ -150,10 +149,8 @@ class UuidFactoryTest extends TestCase ): void { $factory = new UuidFactory(); - /** @var UuidV1 $uuid */ $uuid = $factory->fromDateTime($dateTime, $node, $clockSeq); - $this->assertInstanceOf(UuidV1::class, $uuid); $this->assertStringMatchesFormat($expectedUuidFormat, $uuid->toString()); $this->assertSame($expectedTime, $uuid->getDateTime()->format('U.u')); } diff --git a/tests/UuidTest.php b/tests/UuidTest.php index cef8511..b0a78c2 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -24,15 +24,11 @@ use Ramsey\Uuid\Generator\CombGenerator; use Ramsey\Uuid\Generator\RandomGeneratorFactory; use Ramsey\Uuid\Generator\RandomGeneratorInterface; use Ramsey\Uuid\Guid\Guid; -use Ramsey\Uuid\Nonstandard\UuidV6; +use Ramsey\Uuid\Lazy\LazyUuidFromString; use Ramsey\Uuid\Provider\Node\RandomNodeProvider; use Ramsey\Uuid\Provider\Time\FixedTimeProvider; use Ramsey\Uuid\Rfc4122\FieldsInterface; use Ramsey\Uuid\Rfc4122\UuidV1; -use Ramsey\Uuid\Rfc4122\UuidV2; -use Ramsey\Uuid\Rfc4122\UuidV3; -use Ramsey\Uuid\Rfc4122\UuidV4; -use Ramsey\Uuid\Rfc4122\UuidV5; use Ramsey\Uuid\Type\Hexadecimal; use Ramsey\Uuid\Type\Time; use Ramsey\Uuid\Uuid; @@ -85,8 +81,6 @@ class UuidTest extends TestCase $guid = Guid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertInstanceOf(Uuid::class, $guid); - // UUID's and GUID's share the same textual representation. $this->assertSame($uuid->toString(), $guid->toString()); @@ -97,7 +91,6 @@ class UuidTest extends TestCase public function testFromStringWithCurlyBraces(): void { $uuid = Uuid::fromString('{ff6f8cb0-c57d-11e1-9b21-0800200c9a66}'); - $this->assertInstanceOf(Uuid::class, $uuid); $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); } @@ -128,7 +121,6 @@ class UuidTest extends TestCase public function testFromStringWithUrn(): void { $uuid = Uuid::fromString('urn:uuid:ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertInstanceOf(Uuid::class, $uuid); $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); } @@ -512,7 +504,6 @@ class UuidTest extends TestCase public function testUuid1(): void { $uuid = Uuid::uuid1(); - $this->assertInstanceOf(Uuid::class, $uuid); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -522,7 +513,6 @@ class UuidTest extends TestCase { /** @var Uuid $uuid */ $uuid = Uuid::uuid1('0800200c9a66', 0x1669); - $this->assertInstanceOf(Uuid::class, $uuid); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -535,7 +525,6 @@ class UuidTest extends TestCase { /** @var Uuid $uuid */ $uuid = Uuid::uuid1(new Hexadecimal('0800200c9a66'), 0x1669); - $this->assertInstanceOf(Uuid::class, $uuid); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -549,7 +538,6 @@ class UuidTest extends TestCase /** @var Uuid $uuid */ $uuid = Uuid::uuid1('7160355e'); - $this->assertInstanceOf(Uuid::class, $uuid); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -562,7 +550,6 @@ class UuidTest extends TestCase /** @var Uuid $uuid */ $uuid = Uuid::uuid1(new Hexadecimal('7160355e')); - $this->assertInstanceOf(Uuid::class, $uuid); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -575,7 +562,6 @@ class UuidTest extends TestCase /** @var Uuid $uuid */ $uuid = Uuid::uuid1('71B0aD5e'); - $this->assertInstanceOf(Uuid::class, $uuid); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -612,7 +598,6 @@ class UuidTest extends TestCase Uuid::setFactory(new UuidFactory(new FeatureSet(false, false, false, true))); $uuid = Uuid::uuid1(); - $this->assertInstanceOf(Uuid::class, $uuid); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -621,7 +606,6 @@ class UuidTest extends TestCase public function testUuid1WithUserGeneratedRandomNode(): void { $uuid = Uuid::uuid1(new Hexadecimal((string) (new RandomNodeProvider())->getNode())); - $this->assertInstanceOf(Uuid::class, $uuid); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(1, $uuid->getVersion()); @@ -630,7 +614,6 @@ class UuidTest extends TestCase public function testUuid6(): void { $uuid = Uuid::uuid6(); - $this->assertInstanceOf(UuidV6::class, $uuid); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(6, $uuid->getVersion()); @@ -639,7 +622,6 @@ class UuidTest extends TestCase public function testUuid6WithNodeAndClockSequence(): void { $uuid = Uuid::uuid6(new Hexadecimal('0800200c9a66'), 0x1669); - $this->assertInstanceOf(UuidV6::class, $uuid); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); $this->assertSame(2, $uuid->getVariant()); $this->assertSame(6, $uuid->getVersion()); @@ -652,7 +634,6 @@ class UuidTest extends TestCase { $uuid = Uuid::uuid6(new Hexadecimal('7160355e')); - $this->assertInstanceOf(UuidV6::class, $uuid); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); $this->assertSame(2, $uuid->getVariant()); $this->assertSame(6, $uuid->getVersion()); @@ -663,7 +644,6 @@ class UuidTest extends TestCase { $uuid = Uuid::uuid6(new Hexadecimal('71B0aD5e')); - $this->assertInstanceOf(Uuid::class, $uuid); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); $this->assertSame(2, $uuid->getVariant()); $this->assertSame(6, $uuid->getVersion()); @@ -691,7 +671,6 @@ class UuidTest extends TestCase Uuid::setFactory(new UuidFactory(new FeatureSet(false, false, false, true))); $uuid = Uuid::uuid6(); - $this->assertInstanceOf(UuidV6::class, $uuid); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(6, $uuid->getVersion()); @@ -700,7 +679,6 @@ class UuidTest extends TestCase public function testUuid6WithUserGeneratedRandomNode(): void { $uuid = Uuid::uuid6(new Hexadecimal((string) (new RandomNodeProvider())->getNode())); - $this->assertInstanceOf(UuidV6::class, $uuid); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(6, $uuid->getVersion()); @@ -757,7 +735,6 @@ class UuidTest extends TestCase public function testUuid4(): void { $uuid = Uuid::uuid4(); - $this->assertInstanceOf(Uuid::class, $uuid); $this->assertEquals(2, $uuid->getVariant()); $this->assertEquals(4, $uuid->getVersion()); } @@ -1081,8 +1058,16 @@ class UuidTest extends TestCase public function testUsingNilAsValidUuid(): void { - $this->assertInstanceOf(Uuid::class, Uuid::uuid3(Uuid::NIL, 'randomtext')); - $this->assertInstanceOf(Uuid::class, Uuid::uuid5(Uuid::NIL, 'randomtext')); + self::assertSame( + '0cb17687-6ec7-324b-833a-f1d101a7edb7', + Uuid::uuid3(Uuid::NIL, 'randomtext') + ->toString() + ); + self::assertSame( + '3b24c15b-1273-5628-ade4-fc67c6ede500', + Uuid::uuid5(Uuid::NIL, 'randomtext') + ->toString() + ); } public function testFromBytes(): void @@ -1660,17 +1645,49 @@ class UuidTest extends TestCase } /** - * @param class-string $expectedClass * @param mixed[] $args * * @dataProvider provideStaticMethods */ public function testStaticCreationMethodsReturnSpecificUuidInstances( - string $expectedClass, string $staticMethod, array $args = [] ): void { - $this->assertInstanceOf($expectedClass, Uuid::$staticMethod(...$args)); + $this->assertInstanceOf(LazyUuidFromString::class, Uuid::$staticMethod(...$args)); + } + + /** + * @param mixed[] $args + * + * @dataProvider provideStaticMethods + */ + public function testUuidInstancesBuiltFromStringAreEquivalentToTheirGeneratedCounterparts( + string $staticMethod, + array $args = [] + ): void { + $generated = Uuid::$staticMethod(...$args); + + self::assertEquals( + $generated, + Uuid::fromString($generated->toString()) + ); + } + + /** + * @param mixed[] $args + * + * @dataProvider provideStaticMethods + */ + public function testUuidInstancesBuiltFromBytesAreEquivalentToTheirGeneratedCounterparts( + string $staticMethod, + array $args = [] + ): void { + $generated = Uuid::$staticMethod(...$args); + + self::assertEquals( + $generated, + Uuid::fromBytes($generated->getBytes()) + ); } /** @@ -1679,11 +1696,11 @@ class UuidTest extends TestCase public function provideStaticMethods(): array { return [ - [UuidV1::class, 'uuid1'], - [UuidV2::class, 'uuid2', [Uuid::DCE_DOMAIN_PERSON]], - [UuidV3::class, 'uuid3', [Uuid::NIL, 'foobar']], - [UuidV4::class, 'uuid4'], - [UuidV5::class, 'uuid5', [Uuid::NIL, 'foobar']], + ['uuid1'], + ['uuid2', [Uuid::DCE_DOMAIN_PERSON]], + ['uuid3', [Uuid::NIL, 'foobar']], + ['uuid4'], + ['uuid5', [Uuid::NIL, 'foobar']], ]; } } diff --git a/tests/benchmark/UuidGenerationBench.php b/tests/benchmark/UuidGenerationBench.php index 21c7fb9..6c6b5ca 100644 --- a/tests/benchmark/UuidGenerationBench.php +++ b/tests/benchmark/UuidGenerationBench.php @@ -16,7 +16,7 @@ namespace Ramsey\Uuid\Benchmark; use Ramsey\Uuid\Provider\Node\StaticNodeProvider; use Ramsey\Uuid\Type\Hexadecimal; -use Ramsey\Uuid\Type\Integer; +use Ramsey\Uuid\Type\Integer as IntegerIdentifier; use Ramsey\Uuid\Uuid; final class UuidGenerationBench @@ -25,7 +25,7 @@ final class UuidGenerationBench private $node; /** @var int */ private $clockSequence; - /** @var Integer */ + /** @var IntegerIdentifier */ private $localIdentifier; /** @var \Ramsey\Uuid\UuidInterface */ private $namespace; @@ -35,7 +35,7 @@ final class UuidGenerationBench $this->node = (new StaticNodeProvider(new Hexadecimal('121212121212'))) ->getNode(); $this->clockSequence = 16383; - $this->localIdentifier = new Integer(5); + $this->localIdentifier = new IntegerIdentifier(5); $this->namespace = Uuid::fromString('c485840e-9389-4548-a276-aeecd9730e50'); } From a621ca9e819f3db85416c91353da083f8b60aeb8 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 9 Jul 2020 14:04:20 +0200 Subject: [PATCH 13/22] `Uuid::uuid3()` uses impure `Uuid::getFactory()` API - suppressing it from purity static analysis checks --- src/Uuid.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Uuid.php b/src/Uuid.php index 1d67d3e..762dfdb 100644 --- a/src/Uuid.php +++ b/src/Uuid.php @@ -568,6 +568,11 @@ class Uuid implements UuidInterface * @return UuidInterface A UuidInterface instance that represents a * version 3 UUID * + * @psalm-suppress ImpureMethodCall we know that the factory being replaced can lead to massive + * havoc across all consumers: that should never happen, and + * is generally to be discouraged. Until the factory is kept + * un-replaced, this method is effectively pure. + * * @psalm-pure note: changing the internal factory is an edge case not covered by purity invariants, * but under constant factory setups, this method operates in functionally pure manners */ From 6339cd9fbc68e3ca24fa6254476b515f73e8648f Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 9 Jul 2020 14:15:05 +0200 Subject: [PATCH 14/22] Added UUID serialization benchmark --- tests/benchmark/UuidSerializationBench.php | 206 +++++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 tests/benchmark/UuidSerializationBench.php diff --git a/tests/benchmark/UuidSerializationBench.php b/tests/benchmark/UuidSerializationBench.php new file mode 100644 index 0000000..719f32a --- /dev/null +++ b/tests/benchmark/UuidSerializationBench.php @@ -0,0 +1,206 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Benchmark; + +use Ramsey\Uuid\Uuid; +use Ramsey\Uuid\UuidInterface; + +use function array_map; +use function serialize; + +final class UuidSerializationBench +{ + private const TINY_UUID = '00000000-0000-0000-0000-000000000001'; + private const HUGE_UUID = 'ffffffff-ffff-ffff-ffff-ffffffffffff'; + private const UUIDS_TO_BE_SHORTENED = [ + '0ae0cac5-2a40-465c-99ed-3d331b7cf72a', + '5759b9ce-07b5-4e89-b33a-f864317a2951', + '20c8664e-81a8-498d-9e98-444973ef3122', + '16fcbcf3-bb47-4227-90bd-3485d60510c3', + 'fa83ae94-38e0-4903-bc6a-0a3eca6e9ef5', + '51c9e011-0429-4d77-a753-702bd67dcd84', + '1bd8857a-d6d7-4bd6-8734-b3dfedbcda7b', + '7aa38b71-37c3-4561-9b2e-ca227f1c9c55', + 'e6b8854c-435c-4bb1-b6ad-1800b5d3e6bb', + '4e2b0031-8b09-46e2-8244-3814c46a2f53', + 'bedd0850-da1a-4808-95c4-25fef0abbaa7', + '516b9052-d6fb-4828-bfc1-dffdef2d56d2', + '5d60a7e7-9139-4779-9f28-e6316b9fe3b7', + '65aa3d74-c1fb-4bdd-9a00-ce88a5270c57', + '27c2e339-74ed-49a7-a3c4-1a0172e9f945', + 'e89b7727-4847-41ab-98d7-4148216eea8c', + 'd79efaf3-b5dc-43a0-b3a5-c492155a7e0d', + 'ee9ee6e7-5b7d-4e18-ab88-ce03d569305f', + 'fe90c911-c13b-4103-bf33-16757aa87ff5', + '4d7ff67a-0074-4195-95d7-cf8b84eba079', + 'abe5d378-d021-4905-93f4-0e76a7848365', + '19d21907-d121-4d85-8a34-a65d04ce8977', + 'c421b8ad-33a4-42aa-b0cc-8f5f94b2cff7', + 'f3dbbe55-3c80-453e-ab39-a6fe5001a7fc', + 'f48d3eb2-6060-458f-809f-b5e887f9a17f', + 'd189e406-de29-4889-8470-7bfa0d020c0c', + '71627018-9f21-4034-aafe-4c8b17151217', + '0c6a9278-0963-4460-9cae-6dc6f5420f4f', + 'c833ac35-cce0-4315-8df3-3ed76656a548', + '78e94126-1d0a-472a-9b99-37840784318f', + '6e684707-ce4b-42df-8a77-71e57b54b581', + '811df139-e7a3-4cd8-b778-c81494d239ee', + 'c263c5d8-c166-4599-9219-3e975e506f45', + 'b31e7c5d-95ba-41d4-bc29-e6357c96f005', + '16ae2983-7f8f-4eee-9afb-6d4617836a01', + 'ecbbfac7-f92a-4b41-996e-3e4724aa0e23', + '2c6b3db9-a5ee-4425-a837-8880a86faaa0', + '3d67a99a-b39a-4295-b7f8-0bf71ead5b2d', + 'ca421bb7-ad73-41ea-9648-70073862ad5a', + '5ba156fa-853d-460f-a884-ca8dd3a27314', + '42a4359a-1df2-4086-b454-7477dbb726ff', + '7db9517b-f6ba-4bcf-ae26-6a88a7dbb034', + 'bc758bd6-eb50-425b-ada1-07e6bb312032', + '254cf6d0-696d-4ff0-b579-ac3b633f03c0', + 'f8f34b37-4c71-4177-bac5-6b99bb1929af', + 'b0cc6179-f2b1-4ddf-8fe2-2251c3d935a3', + '333ad834-fa3b-4cf4-b9ba-fdb1c481c497', + '011fc3bc-a97d-4535-8cb0-81766e361e78', + 'acf2262b-4ccf-4f1d-b5c1-5e44641884c6', + '6bf661b1-2f85-4277-8dba-6552141e7e42', + 'a76df66b-8c50-488f-b4e7-4f4d3c05afff', + 'b5c5df47-f939-4536-a340-442bf00bd70d', + 'd4914d41-0011-49fb-a1c2-fe69108e4983', + 'efd5fa37-b0de-43b0-9fe7-1b7a7a6523f8', + '6048f863-7faa-43f2-8202-4b349ae34810', + '659a0024-fa05-4068-aed0-e61239554b6d', + '6ec80af3-0415-429e-91e9-8491ab5745c0', + '0e6f754c-0533-4336-b4f0-e2e35518efa1', + '47469672-7e55-4316-b5d4-c458e43d2404', + '0c5ad756-a823-4a3f-8449-840fac080f45', + '8f8345da-1dd9-499b-bda5-57100bb305d5', + '4a31d059-e375-4571-9d28-ea0de51740e7', + 'ed7fb50c-1b3a-4594-920b-9a461abce57c', + '3d8fe6f6-e603-44c0-b550-3568523c3224', + '809259bc-7912-427a-a975-7298ee5626db', + 'ec88d77e-5612-466c-b269-ad146abd70d0', + 'bd308a10-8073-45ae-9bfb-9a663ad5dd10', + '83a6a4cc-3079-46d8-9263-8f57af4fd4c7', + '557f0041-7e7f-447c-988c-eafa6e396915', + '6ad0fa1c-7425-41e9-9b74-19c4935750a2', + 'a9193e21-e529-43cf-9421-6ed09b59d86e', + '2a09f6e6-4fb2-4da0-97bf-6f32858ba977', + 'd66e0940-087f-4e71-8292-fc38e306d9f7', + '0dfc58b3-d591-40be-803d-e17a52e5d262', + 'a46c6902-de10-45cc-8dac-600d68860532', + '5200f9dc-b967-4d1e-ab01-51c726c152ba', + 'acd8498b-ee8b-4d58-b0ef-c353fb1b5a45', + '36adf355-cccc-406f-a814-6333ec4e31bf', + 'd6d64c6f-8388-4de3-9db1-de07f02071b6', + 'daf3fde9-41d0-422f-a0e3-8c7a93a77091', + '160f4fac-a229-4169-893e-4e9e6864c098', + '170c4be9-1fe6-4838-8a77-dee364ae9a95', + '2864fed0-868c-4bd1-a3fa-ae3bb3de20f4', + '8ea6639c-36dc-463c-8299-8f9a12b10898', + '626bef95-2f24-47c2-a792-f06e8f13a11e', + 'ede75c44-5a1d-484c-942d-87407f27db23', + '966ec42b-0bf7-4923-9672-7a41fee377bc', + '399d7ce6-b28f-4751-ac50-73e31b079f22', + 'ab2b4086-e181-4f02-aee1-a94afed40b50', + '3cfc33a6-73f7-49f7-9c01-fbcf84e604d0', + '40cf06c6-74ca-4016-b388-17dc0334770d', + '58f9ecd3-14ab-4100-b32a-cc2622f06c81', + 'a5c35e34-5d05-4724-bb6c-613b5d306a18', + '5133ae3e-e38b-47fa-a3dc-965c738be792', + '594acd2f-7100-4b2b-8b8a-6097cb1cec3d', + '08b3da92-6b32-43d8-9fdd-53eaa996d649', + '93dcdc27-ab2c-4828-9074-4876ee7ab257', + '8260a154-23cc-4510-a5df-cc5119f457fb', + '732a6571-9729-4935-92be-1a74b3242636', + 'c15f5581-e047-45b7-a36f-dfef4e7ba4bb', + ]; + /** @var UuidInterface */ + private $tinyUuid; + /** @var UuidInterface */ + private $hugeUuid; + /** @var UuidInterface */ + private $uuid; + /** + * @var UuidInterface[] + * @psalm-var non-empty-list + */ + private $promiscuousUuids; + /** @var string */ + private $serializedTinyUuid; + /** @var string */ + private $serializedHugeUuid; + /** @var string */ + private $serializedUuid; + /** + * @var string[] + * @psalm-var non-empty-list + */ + private $serializedPromiscuousUuids; + + public function __construct() + { + $this->tinyUuid = Uuid::fromString(self::TINY_UUID); + $this->hugeUuid = Uuid::fromString(self::HUGE_UUID); + $this->uuid = Uuid::fromString(self::UUIDS_TO_BE_SHORTENED[0]); + $this->promiscuousUuids = array_map([Uuid::class, 'fromString'], self::UUIDS_TO_BE_SHORTENED); + $this->serializedTinyUuid = serialize(Uuid::fromString(self::TINY_UUID)); + $this->serializedHugeUuid = serialize(Uuid::fromString(self::HUGE_UUID)); + $this->serializedUuid = serialize(Uuid::fromString(self::UUIDS_TO_BE_SHORTENED[0])); + $this->serializedPromiscuousUuids = array_map( + 'serialize', + array_map([Uuid::class, 'fromString'], self::UUIDS_TO_BE_SHORTENED) + ); + } + + public function benchSerializationOfTinyUuid(): void + { + serialize($this->tinyUuid); + } + + public function benchSerializationOfHugeUuid(): void + { + serialize($this->hugeUuid); + } + + public function benchSerializationOfUuid(): void + { + serialize($this->uuid); + } + + public function benchSerializationOfPromiscuousUuids(): void + { + array_map('serialize', $this->promiscuousUuids); + } + + public function benchDeSerializationOfTinyUuid(): void + { + unserialize($this->serializedTinyUuid); + } + + public function benchDeSerializationOfHugeUuid(): void + { + unserialize($this->serializedHugeUuid); + } + + public function benchDeSerializationOfUuid(): void + { + unserialize($this->serializedUuid); + } + + public function benchDeSerializationOfPromiscuousUuids(): void + { + array_map('unserialize', $this->serializedPromiscuousUuids); + } +} From fa14d042312e3dc247564d471e572bc0c572a819 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 9 Jul 2020 14:23:49 +0200 Subject: [PATCH 15/22] Added benchmark about extracting UUID field details --- tests/benchmark/UuidFieldExtractionBench.php | 86 ++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 tests/benchmark/UuidFieldExtractionBench.php diff --git a/tests/benchmark/UuidFieldExtractionBench.php b/tests/benchmark/UuidFieldExtractionBench.php new file mode 100644 index 0000000..10bdb8a --- /dev/null +++ b/tests/benchmark/UuidFieldExtractionBench.php @@ -0,0 +1,86 @@ + + * @license http://opensource.org/licenses/MIT MIT + */ + +declare(strict_types=1); + +namespace Ramsey\Uuid\Benchmark; + +use Ramsey\Uuid\Uuid; +use Ramsey\Uuid\UuidInterface; + +final class UuidFieldExtractionBench +{ + /** @var UuidInterface */ + private $uuid; + + public function __construct() + { + $this->uuid = Uuid::fromString('0ae0cac5-2a40-465c-99ed-3d331b7cf72a'); + } + + public function benchGetFields(): void + { + $this->uuid->getFields(); + } + + public function benchGetFields10Times(): void + { + $this->uuid->getFields(); + $this->uuid->getFields(); + $this->uuid->getFields(); + $this->uuid->getFields(); + $this->uuid->getFields(); + $this->uuid->getFields(); + $this->uuid->getFields(); + $this->uuid->getFields(); + $this->uuid->getFields(); + $this->uuid->getFields(); + } + + public function benchGetHex(): void + { + $this->uuid->getHex(); + } + + public function benchGetHex10Times(): void + { + $this->uuid->getHex(); + $this->uuid->getHex(); + $this->uuid->getHex(); + $this->uuid->getHex(); + $this->uuid->getHex(); + $this->uuid->getHex(); + $this->uuid->getHex(); + $this->uuid->getHex(); + $this->uuid->getHex(); + $this->uuid->getHex(); + } + + public function benchGetInteger(): void + { + $this->uuid->getInteger(); + } + + public function benchGetInteger10Times(): void + { + $this->uuid->getInteger(); + $this->uuid->getInteger(); + $this->uuid->getInteger(); + $this->uuid->getInteger(); + $this->uuid->getInteger(); + $this->uuid->getInteger(); + $this->uuid->getInteger(); + $this->uuid->getInteger(); + $this->uuid->getInteger(); + $this->uuid->getInteger(); + } +} From 0c2b4074d2a3f0c9f0051e326305a172eba94627 Mon Sep 17 00:00:00 2001 From: Marco Pivetta Date: Thu, 9 Jul 2020 14:39:36 +0200 Subject: [PATCH 16/22] Minor performance optimization: `LazyUuidFromString#unwrap()` now uses an internal instance cache for unwrapped instances --- src/Lazy/LazyUuidFromString.php | 70 +++++++++++++++++---------------- 1 file changed, 37 insertions(+), 33 deletions(-) diff --git a/src/Lazy/LazyUuidFromString.php b/src/Lazy/LazyUuidFromString.php index 519d4db..3d4ddcb 100644 --- a/src/Lazy/LazyUuidFromString.php +++ b/src/Lazy/LazyUuidFromString.php @@ -58,6 +58,8 @@ final class LazyUuidFromString implements UuidInterface * @psalm-var non-empty-string */ private $uuid; + /** @var UuidInterface|null */ + private $unwrapped; /** @psalm-param non-empty-string $uuid */ public function __construct(string $uuid) @@ -103,7 +105,7 @@ final class LazyUuidFromString implements UuidInterface /** @psalm-suppress DeprecatedMethod */ public function getNumberConverter(): NumberConverterInterface { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getNumberConverter(); } @@ -114,111 +116,111 @@ final class LazyUuidFromString implements UuidInterface */ public function getFieldsHex(): array { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getFieldsHex(); } /** @psalm-suppress DeprecatedMethod */ public function getClockSeqHiAndReservedHex(): string { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getClockSeqHiAndReservedHex(); } /** @psalm-suppress DeprecatedMethod */ public function getClockSeqLowHex(): string { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getClockSeqLowHex(); } /** @psalm-suppress DeprecatedMethod */ public function getClockSequenceHex(): string { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getClockSequenceHex(); } /** @psalm-suppress DeprecatedMethod */ public function getDateTime(): DateTimeInterface { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getDateTime(); } /** @psalm-suppress DeprecatedMethod */ public function getLeastSignificantBitsHex(): string { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getLeastSignificantBitsHex(); } /** @psalm-suppress DeprecatedMethod */ public function getMostSignificantBitsHex(): string { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getMostSignificantBitsHex(); } /** @psalm-suppress DeprecatedMethod */ public function getNodeHex(): string { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getNodeHex(); } /** @psalm-suppress DeprecatedMethod */ public function getTimeHiAndVersionHex(): string { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getTimeHiAndVersionHex(); } /** @psalm-suppress DeprecatedMethod */ public function getTimeLowHex(): string { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getTimeLowHex(); } /** @psalm-suppress DeprecatedMethod */ public function getTimeMidHex(): string { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getTimeMidHex(); } /** @psalm-suppress DeprecatedMethod */ public function getTimestampHex(): string { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getTimestampHex(); } /** @psalm-suppress DeprecatedMethod */ public function getUrn(): string { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getUrn(); } /** @psalm-suppress DeprecatedMethod */ public function getVariant(): ?int { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getVariant(); } /** @psalm-suppress DeprecatedMethod */ public function getVersion(): ?int { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getVersion(); } public function compareTo(UuidInterface $other): int { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->compareTo($other); } @@ -245,19 +247,19 @@ final class LazyUuidFromString implements UuidInterface public function getFields(): FieldsInterface { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getFields(); } public function getHex(): Hexadecimal { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getHex(); } public function getInteger(): IntegerObject { - return $this->unwrap() + return ($this->unwrapped ?? $this->unwrap()) ->getInteger(); } @@ -290,7 +292,7 @@ final class LazyUuidFromString implements UuidInterface */ public function getClockSeqHiAndReserved(): string { - $instance = $this->unwrap(); + $instance = ($this->unwrapped ?? $this->unwrap()); return $instance->getNumberConverter() ->fromHex( @@ -314,7 +316,7 @@ final class LazyUuidFromString implements UuidInterface */ public function getClockSeqLow(): string { - $instance = $this->unwrap(); + $instance = ($this->unwrapped ?? $this->unwrap()); return $instance->getNumberConverter() ->fromHex( @@ -338,7 +340,7 @@ final class LazyUuidFromString implements UuidInterface */ public function getClockSequence(): string { - $instance = $this->unwrap(); + $instance = ($this->unwrapped ?? $this->unwrap()); return $instance->getNumberConverter() ->fromHex( @@ -360,7 +362,7 @@ final class LazyUuidFromString implements UuidInterface */ public function getLeastSignificantBits(): string { - $instance = $this->unwrap(); + $instance = ($this->unwrapped ?? $this->unwrap()); return $instance->getNumberConverter() ->fromHex(substr($instance->getHex()->toString(), 16)); @@ -378,7 +380,7 @@ final class LazyUuidFromString implements UuidInterface */ public function getMostSignificantBits(): string { - $instance = $this->unwrap(); + $instance = ($this->unwrapped ?? $this->unwrap()); return $instance->getNumberConverter() ->fromHex(substr($instance->getHex()->toString(), 0, 16)); @@ -398,7 +400,7 @@ final class LazyUuidFromString implements UuidInterface */ public function getNode(): string { - $instance = $this->unwrap(); + $instance = ($this->unwrapped ?? $this->unwrap()); return $instance->getNumberConverter() ->fromHex( @@ -422,7 +424,7 @@ final class LazyUuidFromString implements UuidInterface */ public function getTimeHiAndVersion(): string { - $instance = $this->unwrap(); + $instance = ($this->unwrapped ?? $this->unwrap()); return $instance->getNumberConverter() ->fromHex( @@ -446,7 +448,7 @@ final class LazyUuidFromString implements UuidInterface */ public function getTimeLow(): string { - $instance = $this->unwrap(); + $instance = ($this->unwrapped ?? $this->unwrap()); return $instance->getNumberConverter() ->fromHex( @@ -470,7 +472,7 @@ final class LazyUuidFromString implements UuidInterface */ public function getTimeMid(): string { - $instance = $this->unwrap(); + $instance = ($this->unwrapped ?? $this->unwrap()); return $instance->getNumberConverter() ->fromHex( @@ -494,7 +496,7 @@ final class LazyUuidFromString implements UuidInterface */ public function getTimestamp(): string { - $instance = $this->unwrap(); + $instance = ($this->unwrapped ?? $this->unwrap()); $fields = $instance->getFields(); if ($fields->getVersion() !== 1) { @@ -507,7 +509,7 @@ final class LazyUuidFromString implements UuidInterface public function toUuidV1(): UuidV1 { - $instance = $this->unwrap(); + $instance = ($this->unwrapped ?? $this->unwrap()); if ($instance instanceof UuidV1) { return $instance; @@ -520,7 +522,7 @@ final class LazyUuidFromString implements UuidInterface public function toUuidV6(): UuidV6 { - $instance = $this->unwrap(); + $instance = ($this->unwrapped ?? $this->unwrap()); assert($instance instanceof UuidV6); @@ -533,10 +535,12 @@ final class LazyUuidFromString implements UuidInterface * a mutable reference to a factory. We use a fixed factory here, so the violation * will not have real-world effects, as this object is only instantiated with the * default factory settings/features. + * @psalm-suppress InaccessibleProperty property {@see $unwrapped} is used as a cache: we don't expose it to the + * outside world, so we should be fine here. */ private function unwrap(): UuidInterface { - return (new UuidFactory()) + return $this->unwrapped = (new UuidFactory()) ->fromString($this->uuid); } } From 988dbefc7878d0a35f12afb4df1f7dd0bd153c43 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Tue, 28 Jul 2020 11:51:01 -0500 Subject: [PATCH 17/22] Update CHANGELOG for 4.1.0 release --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7e53954..3271bb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,15 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Security +## [4.1.0] - 2020-07-28 + +### Changed + +* Improve performance of `Uuid::fromString()`, `Uuid::fromBytes()`, + `UuidInterface#toString()`, and `UuidInterface#getBytes()`. See PR + [#324](https://github.com/ramsey/uuid/pull/324) for more information. + + ## [4.0.1] - 2020-03-29 ### Fixed From 69b3eb8824546bf2c06211fcf2ef630effa5ec49 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Tue, 28 Jul 2020 11:52:54 -0500 Subject: [PATCH 18/22] Fix links in CHANGELOG --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3271bb3..9844a96 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1191,7 +1191,8 @@ versions leading up to this release.* [ramsey/uuid-doctrine]: https://github.com/ramsey/uuid-doctrine [ramsey/uuid-console]: https://github.com/ramsey/uuid-console -[unreleased]: https://github.com/ramsey/uuid/compare/4.0.1...HEAD +[unreleased]: https://github.com/ramsey/uuid/compare/4.1.0...HEAD +[4.1.0]: https://github.com/ramsey/uuid/compare/4.0.1...4.1.0 [4.0.1]: https://github.com/ramsey/uuid/compare/4.0.0...4.0.1 [4.0.0]: https://github.com/ramsey/uuid/compare/4.0.0-beta2...4.0.0 [4.0.0-beta2]: https://github.com/ramsey/uuid/compare/4.0.0-beta1...4.0.0-beta2 From 17638f627cf8f8ef3f9f77b9f090c33e95227250 Mon Sep 17 00:00:00 2001 From: Simon Podlipsky Date: Tue, 18 Aug 2020 14:40:28 +0200 Subject: [PATCH 19/22] Add support for brick/math ^0.9 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 0f6dd38..41d500b 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ "require": { "php": "^7.2 || ^8", "ext-json": "*", - "brick/math": "^0.8", + "brick/math": "^0.8 || ^0.9", "ramsey/collection": "^1.0", "symfony/polyfill-ctype": "^1.8" }, From cd4032040a750077205918c86049aa0f43d22947 Mon Sep 17 00:00:00 2001 From: Ben Ramsey Date: Tue, 18 Aug 2020 12:17:46 -0500 Subject: [PATCH 20/22] Update CHANGELOG for version 4.1.1 --- CHANGELOG.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9844a96..e659605 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Security +## [4.1.1] - 2020-08-18 + +### Fixed + +* Allow use of brick/math version 0.9 + + ## [4.1.0] - 2020-07-28 ### Changed @@ -1191,7 +1198,8 @@ versions leading up to this release.* [ramsey/uuid-doctrine]: https://github.com/ramsey/uuid-doctrine [ramsey/uuid-console]: https://github.com/ramsey/uuid-console -[unreleased]: https://github.com/ramsey/uuid/compare/4.1.0...HEAD +[unreleased]: https://github.com/ramsey/uuid/compare/4.1.1...HEAD +[4.1.1]: https://github.com/ramsey/uuid/compare/4.1.0...4.1.1 [4.1.0]: https://github.com/ramsey/uuid/compare/4.0.1...4.1.0 [4.0.1]: https://github.com/ramsey/uuid/compare/4.0.0...4.0.1 [4.0.0]: https://github.com/ramsey/uuid/compare/4.0.0-beta2...4.0.0 From 7947413a76e5e5fa427198a3d14d73fbfd61de0a Mon Sep 17 00:00:00 2001 From: Bilge Date: Sun, 23 Aug 2020 13:53:19 +0100 Subject: [PATCH 21/22] Use assertSame instead of assertEquals. --- tests/Codec/GuidStringCodecTest.php | 4 +- tests/Codec/OrderedTimeCodecTest.php | 4 +- tests/Codec/StringCodecTest.php | 6 +- tests/Generator/CombGeneratorTest.php | 2 +- .../Generator/PeclUuidRandomGeneratorTest.php | 4 +- tests/Generator/PeclUuidTimeGeneratorTest.php | 4 +- tests/Generator/RandomBytesGeneratorTest.php | 2 +- tests/Generator/RandomLibAdapterTest.php | 2 +- tests/Guid/FieldsTest.php | 2 +- tests/Nonstandard/FieldsTest.php | 2 +- .../Node/FallbackNodeProviderTest.php | 2 +- .../Provider/Node/SystemNodeProviderTest.php | 16 +- tests/Rfc4122/FieldsTest.php | 4 +- tests/UuidFactoryTest.php | 10 +- tests/UuidTest.php | 232 +++++++++--------- 15 files changed, 148 insertions(+), 148 deletions(-) diff --git a/tests/Codec/GuidStringCodecTest.php b/tests/Codec/GuidStringCodecTest.php index c70d572..4394586 100644 --- a/tests/Codec/GuidStringCodecTest.php +++ b/tests/Codec/GuidStringCodecTest.php @@ -106,7 +106,7 @@ class GuidStringCodecTest extends TestCase $codec = new GuidStringCodec($this->builder); $result = $codec->decode($string); - $this->assertEquals($this->uuid, $result); + $this->assertSame($this->uuid, $result); } public function testDecodeBytesReturnsUuid(): void @@ -117,6 +117,6 @@ class GuidStringCodecTest extends TestCase $this->builder->method('build') ->willReturn($this->uuid); $result = $codec->decodeBytes($bytes); - $this->assertEquals($this->uuid, $result); + $this->assertSame($this->uuid, $result); } } diff --git a/tests/Codec/OrderedTimeCodecTest.php b/tests/Codec/OrderedTimeCodecTest.php index fbdddaf..1cf0d44 100644 --- a/tests/Codec/OrderedTimeCodecTest.php +++ b/tests/Codec/OrderedTimeCodecTest.php @@ -83,7 +83,7 @@ class OrderedTimeCodecTest extends TestCase ->willReturn($this->fields); $codec = new OrderedTimeCodec($this->builder); $result = $codec->encode($this->uuid); - $this->assertEquals($this->uuidString, $result); + $this->assertSame($this->uuidString, $result); } public function testEncodeBinary(): void @@ -121,7 +121,7 @@ class OrderedTimeCodecTest extends TestCase ->willReturn($this->uuid); $codec = new OrderedTimeCodec($this->builder); $result = $codec->decode($string); - $this->assertEquals($this->uuid, $result); + $this->assertSame($this->uuid, $result); } public function testDecodeBytesRearrangesFields(): void diff --git a/tests/Codec/StringCodecTest.php b/tests/Codec/StringCodecTest.php index 3ded53c..7aa71f9 100644 --- a/tests/Codec/StringCodecTest.php +++ b/tests/Codec/StringCodecTest.php @@ -68,7 +68,7 @@ class StringCodecTest extends TestCase ->willReturn($this->fields); $codec = new StringCodec($this->builder); $result = $codec->encode($this->uuid); - $this->assertEquals($this->uuidString, $result); + $this->assertSame($this->uuidString, $result); } public function testEncodeBinaryReturnsBinaryString(): void @@ -123,7 +123,7 @@ class StringCodecTest extends TestCase ->willReturn($this->uuid); $codec = new StringCodec($this->builder); $result = $codec->decode($string); - $this->assertEquals($this->uuid, $result); + $this->assertSame($this->uuid, $result); } public function testDecodeBytesThrowsExceptionWhenBytesStringNotSixteenCharacters(): void @@ -145,6 +145,6 @@ class StringCodecTest extends TestCase $this->builder->method('build') ->willReturn($this->uuid); $result = $codec->decodeBytes($bytes); - $this->assertEquals($this->uuid, $result); + $this->assertSame($this->uuid, $result); } } diff --git a/tests/Generator/CombGeneratorTest.php b/tests/Generator/CombGeneratorTest.php index ee0de3f..6649b49 100644 --- a/tests/Generator/CombGeneratorTest.php +++ b/tests/Generator/CombGeneratorTest.php @@ -84,7 +84,7 @@ class CombGeneratorTest extends TestCase $generator = new CombGenerator($randomGenerator, $converter); $returned = $generator->generate($length); $this->assertIsString($returned); - $this->assertEquals($expected, $returned); + $this->assertSame($expected, $returned); } /** diff --git a/tests/Generator/PeclUuidRandomGeneratorTest.php b/tests/Generator/PeclUuidRandomGeneratorTest.php index 3a8e133..aaa5d2e 100644 --- a/tests/Generator/PeclUuidRandomGeneratorTest.php +++ b/tests/Generator/PeclUuidRandomGeneratorTest.php @@ -28,7 +28,7 @@ class PeclUuidRandomGeneratorTest extends PeclUuidTestCase $generator = new PeclUuidRandomGenerator(); $uuid = $generator->generate($this->length); - $this->assertEquals($this->uuidBinary, $uuid); + $this->assertSame($this->uuidBinary, $uuid); $create->verifyInvoked([UUID_TYPE_RANDOM]); $parse->verifyInvoked([$this->uuidString]); } @@ -44,7 +44,7 @@ class PeclUuidRandomGeneratorTest extends PeclUuidTestCase $generator = new PeclUuidRandomGenerator(); $uuid = $generator->generate($this->length); - $this->assertEquals($this->uuidBinary, $uuid); + $this->assertSame($this->uuidBinary, $uuid); $create->verifyInvoked([UUID_TYPE_RANDOM]); $parse->verifyInvoked([$this->uuidString]); } diff --git a/tests/Generator/PeclUuidTimeGeneratorTest.php b/tests/Generator/PeclUuidTimeGeneratorTest.php index 61fe8ac..b404e5f 100644 --- a/tests/Generator/PeclUuidTimeGeneratorTest.php +++ b/tests/Generator/PeclUuidTimeGeneratorTest.php @@ -23,7 +23,7 @@ class PeclUuidTimeGeneratorTest extends PeclUuidTestCase $generator = new PeclUuidTimeGenerator(); $uuid = $generator->generate(); - $this->assertEquals($this->uuidBinary, $uuid); + $this->assertSame($this->uuidBinary, $uuid); $create->verifyInvoked([UUID_TYPE_TIME]); $parse->verifyInvoked([$this->uuidString]); } @@ -39,7 +39,7 @@ class PeclUuidTimeGeneratorTest extends PeclUuidTestCase $generator = new PeclUuidTimeGenerator(); $uuid = $generator->generate(); - $this->assertEquals($this->uuidBinary, $uuid); + $this->assertSame($this->uuidBinary, $uuid); $create->verifyInvoked([UUID_TYPE_TIME]); $parse->verifyInvoked([$this->uuidString]); } diff --git a/tests/Generator/RandomBytesGeneratorTest.php b/tests/Generator/RandomBytesGeneratorTest.php index 83b8fbc..dca6618 100644 --- a/tests/Generator/RandomBytesGeneratorTest.php +++ b/tests/Generator/RandomBytesGeneratorTest.php @@ -55,7 +55,7 @@ class RandomBytesGeneratorTest extends TestCase $bytes = hex2bin($hex); AspectMock::func('Ramsey\Uuid\Generator', 'random_bytes', $bytes); $generator = new RandomBytesGenerator(); - $this->assertEquals($bytes, $generator->generate($length)); + $this->assertSame($bytes, $generator->generate($length)); } /** diff --git a/tests/Generator/RandomLibAdapterTest.php b/tests/Generator/RandomLibAdapterTest.php index 55a8924..438f6f1 100644 --- a/tests/Generator/RandomLibAdapterTest.php +++ b/tests/Generator/RandomLibAdapterTest.php @@ -66,6 +66,6 @@ class RandomLibAdapterTest extends TestCase $adapter = new RandomLibAdapter($generator); $result = $adapter->generate(1); - $this->assertEquals('random-string', $result); + $this->assertSame('random-string', $result); } } diff --git a/tests/Guid/FieldsTest.php b/tests/Guid/FieldsTest.php index 2df25f6..d55f4b1 100644 --- a/tests/Guid/FieldsTest.php +++ b/tests/Guid/FieldsTest.php @@ -199,6 +199,6 @@ class FieldsTest extends TestCase $serializedFields = serialize($fields); $unserializedFields = unserialize($serializedFields); - $this->assertEquals($fields, $unserializedFields); + $this->assertSame($fields->getBytes(), $unserializedFields->getBytes()); } } diff --git a/tests/Nonstandard/FieldsTest.php b/tests/Nonstandard/FieldsTest.php index 842cd8a..119196a 100644 --- a/tests/Nonstandard/FieldsTest.php +++ b/tests/Nonstandard/FieldsTest.php @@ -75,6 +75,6 @@ class FieldsTest extends TestCase $serializedFields = serialize($fields); $unserializedFields = unserialize($serializedFields); - $this->assertEquals($fields, $unserializedFields); + $this->assertSame($fields->getBytes(), $unserializedFields->getBytes()); } } diff --git a/tests/Provider/Node/FallbackNodeProviderTest.php b/tests/Provider/Node/FallbackNodeProviderTest.php index a2b8baf..e8aa13a 100644 --- a/tests/Provider/Node/FallbackNodeProviderTest.php +++ b/tests/Provider/Node/FallbackNodeProviderTest.php @@ -50,7 +50,7 @@ class FallbackNodeProviderTest extends TestCase )); $node = $provider->getNode(); - $this->assertEquals('57764a07f756', $node); + $this->assertSame('57764a07f756', $node->toString()); } public function testGetNodeThrowsExceptionWhenNoNodesFound(): void diff --git a/tests/Provider/Node/SystemNodeProviderTest.php b/tests/Provider/Node/SystemNodeProviderTest.php index bc27d1d..4e98e78 100644 --- a/tests/Provider/Node/SystemNodeProviderTest.php +++ b/tests/Provider/Node/SystemNodeProviderTest.php @@ -151,7 +151,7 @@ class SystemNodeProviderTest extends TestCase /* Assert */ $this->assertMockFunctions(null, null, ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions']); - $this->assertEquals($expected, $node->toString()); + $this->assertSame($expected, $node->toString()); } /** @@ -211,7 +211,7 @@ class SystemNodeProviderTest extends TestCase /* Assert */ $this->assertMockFunctions(null, null, ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions']); - $this->assertEquals('aabbccddeeff', $node->toString()); + $this->assertSame('aabbccddeeff', $node->toString()); } /** @@ -359,7 +359,7 @@ class SystemNodeProviderTest extends TestCase /* Assert */ $this->assertMockFunctions(null, null, ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions']); - $this->assertEquals($node->toString(), $node2->toString()); + $this->assertSame($node->toString(), $node2->toString()); } /** @@ -387,7 +387,7 @@ class SystemNodeProviderTest extends TestCase /* Assert */ $this->assertMockFunctions(null, null, ['netstat -ie 2>&1'], ['PHP_OS'], ['disable_functions']); - $this->assertEquals($node->toString(), $node2->toString()); + $this->assertSame($node->toString(), $node2->toString()); } /** @@ -442,7 +442,7 @@ class SystemNodeProviderTest extends TestCase $isReadableAssert ); - $this->assertEquals('010203040506', $node->toString()); + $this->assertSame('010203040506', $node->toString()); } /** @@ -475,7 +475,7 @@ class SystemNodeProviderTest extends TestCase ['disable_functions'] ); - $this->assertEquals('010203040506', $node->toString()); + $this->assertSame('010203040506', $node->toString()); } /** @@ -508,7 +508,7 @@ class SystemNodeProviderTest extends TestCase ['disable_functions'] ); - $this->assertEquals('010203040506', $node->toString()); + $this->assertSame('010203040506', $node->toString()); } /** @@ -543,7 +543,7 @@ class SystemNodeProviderTest extends TestCase ['mock address path 1', 'mock address path 2'] ); - $this->assertEquals('010203040506', $node->toString()); + $this->assertSame('010203040506', $node->toString()); } /** diff --git a/tests/Rfc4122/FieldsTest.php b/tests/Rfc4122/FieldsTest.php index 7f4b217..39b36eb 100644 --- a/tests/Rfc4122/FieldsTest.php +++ b/tests/Rfc4122/FieldsTest.php @@ -210,7 +210,7 @@ class FieldsTest extends TestCase $serializedFields = serialize($fields); $unserializedFields = unserialize($serializedFields); - $this->assertEquals($fields, $unserializedFields); + $this->assertSame($fields->getBytes(), $unserializedFields->getBytes()); } public function testSerializingFieldsWithOldFormat(): void @@ -220,6 +220,6 @@ class FieldsTest extends TestCase $serializedFields = 'C:26:"Ramsey\Uuid\Rfc4122\Fields":24:{s81YauPKRPOYjPTWZsG/TQ==}'; $unserializedFields = unserialize($serializedFields); - $this->assertEquals($fields, $unserializedFields); + $this->assertSame($fields->getBytes(), $unserializedFields->getBytes()); } } diff --git a/tests/UuidFactoryTest.php b/tests/UuidFactoryTest.php index 43a4244..0102b18 100644 --- a/tests/UuidFactoryTest.php +++ b/tests/UuidFactoryTest.php @@ -57,7 +57,7 @@ class UuidFactoryTest extends TestCase $uuid = $factory->fromString($uuidUpper); - $this->assertEquals($uuidString, $uuid->toString()); + $this->assertSame($uuidString, $uuid->toString()); } public function testGettersReturnValueFromFeatureSet(): void @@ -119,22 +119,22 @@ class UuidFactoryTest extends TestCase /** @var MockObject & CodecInterface $codec */ $codec = $this->getMockBuilder(CodecInterface::class)->getMock(); $uuidFactory->setCodec($codec); - $this->assertEquals($codec, $uuidFactory->getCodec()); + $this->assertSame($codec, $uuidFactory->getCodec()); /** @var MockObject & TimeGeneratorInterface $timeGenerator */ $timeGenerator = $this->getMockBuilder(TimeGeneratorInterface::class)->getMock(); $uuidFactory->setTimeGenerator($timeGenerator); - $this->assertEquals($timeGenerator, $uuidFactory->getTimeGenerator()); + $this->assertSame($timeGenerator, $uuidFactory->getTimeGenerator()); /** @var MockObject & NumberConverterInterface $numberConverter */ $numberConverter = $this->getMockBuilder(NumberConverterInterface::class)->getMock(); $uuidFactory->setNumberConverter($numberConverter); - $this->assertEquals($numberConverter, $uuidFactory->getNumberConverter()); + $this->assertSame($numberConverter, $uuidFactory->getNumberConverter()); /** @var MockObject & UuidBuilderInterface $uuidBuilder */ $uuidBuilder = $this->getMockBuilder(UuidBuilderInterface::class)->getMock(); $uuidFactory->setUuidBuilder($uuidBuilder); - $this->assertEquals($uuidBuilder, $uuidFactory->getUuidBuilder()); + $this->assertSame($uuidBuilder, $uuidFactory->getUuidBuilder()); } /** diff --git a/tests/UuidTest.php b/tests/UuidTest.php index b0a78c2..fccde37 100644 --- a/tests/UuidTest.php +++ b/tests/UuidTest.php @@ -62,7 +62,7 @@ class UuidTest extends TestCase public function testFromString(): void { - $this->assertEquals( + $this->assertSame( 'ff6f8cb0-c57d-11e1-9b21-0800200c9a66', Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66') ->toString() @@ -91,7 +91,7 @@ class UuidTest extends TestCase public function testFromStringWithCurlyBraces(): void { $uuid = Uuid::fromString('{ff6f8cb0-c57d-11e1-9b21-0800200c9a66}'); - $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); + $this->assertSame('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); } public function testFromStringWithInvalidUuidString(): void @@ -121,56 +121,56 @@ class UuidTest extends TestCase public function testFromStringWithUrn(): void { $uuid = Uuid::fromString('urn:uuid:ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); + $this->assertSame('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); } public function testGetBytes(): void { $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals(16, strlen($uuid->getBytes())); - $this->assertEquals('/2+MsMV9EeGbIQgAIAyaZg==', base64_encode($uuid->getBytes())); + $this->assertSame(16, strlen($uuid->getBytes())); + $this->assertSame('/2+MsMV9EeGbIQgAIAyaZg==', base64_encode($uuid->getBytes())); } public function testGetClockSeqHiAndReserved(): void { /** @var Uuid $uuid */ $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals(155, $uuid->getClockSeqHiAndReserved()); + $this->assertSame('155', $uuid->getClockSeqHiAndReserved()); } public function testGetClockSeqHiAndReservedHex(): void { /** @var Uuid $uuid */ $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals('9b', $uuid->getClockSeqHiAndReservedHex()); + $this->assertSame('9b', $uuid->getClockSeqHiAndReservedHex()); } public function testGetClockSeqLow(): void { /** @var Uuid $uuid */ $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals(33, $uuid->getClockSeqLow()); + $this->assertSame('33', $uuid->getClockSeqLow()); } public function testGetClockSeqLowHex(): void { /** @var Uuid $uuid */ $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals('21', $uuid->getClockSeqLowHex()); + $this->assertSame('21', $uuid->getClockSeqLowHex()); } public function testGetClockSequence(): void { /** @var Uuid $uuid */ $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals(6945, $uuid->getClockSequence()); + $this->assertSame('6945', $uuid->getClockSequence()); } public function testGetClockSequenceHex(): void { /** @var Uuid $uuid */ $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals('1b21', $uuid->getClockSequenceHex()); + $this->assertSame('1b21', $uuid->getClockSequenceHex()); } public function testGetDateTime(): void @@ -316,7 +316,7 @@ class UuidTest extends TestCase public function testGetMostSignificantBitsHex(): void { $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals('ff6f8cb0c57d11e1', $uuid->getMostSignificantBitsHex()); + $this->assertSame('ff6f8cb0c57d11e1', $uuid->getMostSignificantBitsHex()); } public function testGetNode(): void @@ -329,20 +329,20 @@ class UuidTest extends TestCase public function testGetNodeHex(): void { $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals('0800200c9a66', $uuid->getNodeHex()); + $this->assertSame('0800200c9a66', $uuid->getNodeHex()); } public function testGetTimeHiAndVersion(): void { /** @var Uuid $uuid */ $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals(4577, $uuid->getTimeHiAndVersion()); + $this->assertSame('4577', $uuid->getTimeHiAndVersion()); } public function testGetTimeHiAndVersionHex(): void { $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals('11e1', $uuid->getTimeHiAndVersionHex()); + $this->assertSame('11e1', $uuid->getTimeHiAndVersionHex()); } public function testGetTimeLow(): void @@ -355,20 +355,20 @@ class UuidTest extends TestCase public function testGetTimeLowHex(): void { $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals('ff6f8cb0', $uuid->getTimeLowHex()); + $this->assertSame('ff6f8cb0', $uuid->getTimeLowHex()); } public function testGetTimeMid(): void { /** @var Uuid $uuid */ $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals(50557, $uuid->getTimeMid()); + $this->assertSame('50557', $uuid->getTimeMid()); } public function testGetTimeMidHex(): void { $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals('c57d', $uuid->getTimeMidHex()); + $this->assertSame('c57d', $uuid->getTimeMidHex()); } public function testGetTimestamp(): void @@ -388,11 +388,11 @@ class UuidTest extends TestCase { // Check for a recent date $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals('1e1c57dff6f8cb0', $uuid->getTimestampHex()); + $this->assertSame('1e1c57dff6f8cb0', $uuid->getTimestampHex()); // Check for an old date $uuid = Uuid::fromString('0901e600-0154-1000-9b21-0800200c9a66'); - $this->assertEquals('00001540901e600', $uuid->getTimestampHex()); + $this->assertSame('00001540901e600', $uuid->getTimestampHex()); } public function testGetTimestampFromNonVersion1Uuid(): void @@ -421,7 +421,7 @@ class UuidTest extends TestCase public function testGetUrn(): void { $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals('urn:uuid:ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->getUrn()); + $this->assertSame('urn:uuid:ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->getUrn()); } /** @@ -461,52 +461,52 @@ class UuidTest extends TestCase public function testGetVersionForVersion1(): void { $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals(1, $uuid->getVersion()); + $this->assertSame(1, $uuid->getVersion()); } public function testGetVersionForVersion2(): void { $uuid = Uuid::fromString('6fa459ea-ee8a-2ca4-894e-db77e160355e'); - $this->assertEquals(2, $uuid->getVersion()); + $this->assertSame(2, $uuid->getVersion()); } public function testGetVersionForVersion3(): void { $uuid = Uuid::fromString('6fa459ea-ee8a-3ca4-894e-db77e160355e'); - $this->assertEquals(3, $uuid->getVersion()); + $this->assertSame(3, $uuid->getVersion()); } public function testGetVersionForVersion4(): void { $uuid = Uuid::fromString('6fabf0bc-603a-42f2-925b-d9f779bd0032'); - $this->assertEquals(4, $uuid->getVersion()); + $this->assertSame(4, $uuid->getVersion()); } public function testGetVersionForVersion5(): void { $uuid = Uuid::fromString('886313e1-3b8a-5372-9b90-0c9aee199e5d'); - $this->assertEquals(5, $uuid->getVersion()); + $this->assertSame(5, $uuid->getVersion()); } public function testToString(): void { // Check with a recent date $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); - $this->assertEquals('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', (string) $uuid); + $this->assertSame('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', $uuid->toString()); + $this->assertSame('ff6f8cb0-c57d-11e1-9b21-0800200c9a66', (string) $uuid); // Check with an old date $uuid = Uuid::fromString('0901e600-0154-1000-9b21-0800200c9a66'); - $this->assertEquals('0901e600-0154-1000-9b21-0800200c9a66', $uuid->toString()); - $this->assertEquals('0901e600-0154-1000-9b21-0800200c9a66', (string) $uuid); + $this->assertSame('0901e600-0154-1000-9b21-0800200c9a66', $uuid->toString()); + $this->assertSame('0901e600-0154-1000-9b21-0800200c9a66', (string) $uuid); } public function testUuid1(): void { $uuid = Uuid::uuid1(); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); - $this->assertEquals(2, $uuid->getVariant()); - $this->assertEquals(1, $uuid->getVersion()); + $this->assertSame(2, $uuid->getVariant()); + $this->assertSame(1, $uuid->getVersion()); } public function testUuid1WithNodeAndClockSequence(): void @@ -514,11 +514,11 @@ class UuidTest extends TestCase /** @var Uuid $uuid */ $uuid = Uuid::uuid1('0800200c9a66', 0x1669); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); - $this->assertEquals(2, $uuid->getVariant()); - $this->assertEquals(1, $uuid->getVersion()); - $this->assertEquals(5737, $uuid->getClockSequence()); + $this->assertSame(2, $uuid->getVariant()); + $this->assertSame(1, $uuid->getVersion()); + $this->assertSame('5737', $uuid->getClockSequence()); $this->assertSame('8796630719078', $uuid->getNode()); - $this->assertEquals('9669-0800200c9a66', substr($uuid->toString(), 19)); + $this->assertSame('9669-0800200c9a66', substr($uuid->toString(), 19)); } public function testUuid1WithHexadecimalObjectNodeAndClockSequence(): void @@ -526,11 +526,11 @@ class UuidTest extends TestCase /** @var Uuid $uuid */ $uuid = Uuid::uuid1(new Hexadecimal('0800200c9a66'), 0x1669); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); - $this->assertEquals(2, $uuid->getVariant()); - $this->assertEquals(1, $uuid->getVersion()); - $this->assertEquals(5737, $uuid->getClockSequence()); + $this->assertSame(2, $uuid->getVariant()); + $this->assertSame(1, $uuid->getVersion()); + $this->assertSame('5737', $uuid->getClockSequence()); $this->assertSame('8796630719078', $uuid->getNode()); - $this->assertEquals('9669-0800200c9a66', substr($uuid->toString(), 19)); + $this->assertSame('9669-0800200c9a66', substr($uuid->toString(), 19)); } public function testUuid1WithHexadecimalNode(): void @@ -539,9 +539,9 @@ class UuidTest extends TestCase $uuid = Uuid::uuid1('7160355e'); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); - $this->assertEquals(2, $uuid->getVariant()); - $this->assertEquals(1, $uuid->getVersion()); - $this->assertEquals('00007160355e', $uuid->getNodeHex()); + $this->assertSame(2, $uuid->getVariant()); + $this->assertSame(1, $uuid->getVersion()); + $this->assertSame('00007160355e', $uuid->getNodeHex()); $this->assertSame('1902130526', $uuid->getNode()); } @@ -551,9 +551,9 @@ class UuidTest extends TestCase $uuid = Uuid::uuid1(new Hexadecimal('7160355e')); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); - $this->assertEquals(2, $uuid->getVariant()); - $this->assertEquals(1, $uuid->getVersion()); - $this->assertEquals('00007160355e', $uuid->getNodeHex()); + $this->assertSame(2, $uuid->getVariant()); + $this->assertSame(1, $uuid->getVersion()); + $this->assertSame('00007160355e', $uuid->getNodeHex()); $this->assertSame('1902130526', $uuid->getNode()); } @@ -563,10 +563,10 @@ class UuidTest extends TestCase $uuid = Uuid::uuid1('71B0aD5e'); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); - $this->assertEquals(2, $uuid->getVariant()); - $this->assertEquals(1, $uuid->getVersion()); - $this->assertEquals('000071b0ad5e', $uuid->getNodeHex()); - $this->assertEquals('1907404126', $uuid->getNode()); + $this->assertSame(2, $uuid->getVariant()); + $this->assertSame(1, $uuid->getVersion()); + $this->assertSame('000071b0ad5e', $uuid->getNodeHex()); + $this->assertSame('1907404126', $uuid->getNode()); } public function testUuid1WithOutOfBoundsNode(): void @@ -599,24 +599,24 @@ class UuidTest extends TestCase $uuid = Uuid::uuid1(); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); - $this->assertEquals(2, $uuid->getVariant()); - $this->assertEquals(1, $uuid->getVersion()); + $this->assertSame(2, $uuid->getVariant()); + $this->assertSame(1, $uuid->getVersion()); } public function testUuid1WithUserGeneratedRandomNode(): void { $uuid = Uuid::uuid1(new Hexadecimal((string) (new RandomNodeProvider())->getNode())); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); - $this->assertEquals(2, $uuid->getVariant()); - $this->assertEquals(1, $uuid->getVersion()); + $this->assertSame(2, $uuid->getVariant()); + $this->assertSame(1, $uuid->getVersion()); } public function testUuid6(): void { $uuid = Uuid::uuid6(); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); - $this->assertEquals(2, $uuid->getVariant()); - $this->assertEquals(6, $uuid->getVersion()); + $this->assertSame(2, $uuid->getVariant()); + $this->assertSame(6, $uuid->getVersion()); } public function testUuid6WithNodeAndClockSequence(): void @@ -672,16 +672,16 @@ class UuidTest extends TestCase $uuid = Uuid::uuid6(); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); - $this->assertEquals(2, $uuid->getVariant()); - $this->assertEquals(6, $uuid->getVersion()); + $this->assertSame(2, $uuid->getVariant()); + $this->assertSame(6, $uuid->getVersion()); } public function testUuid6WithUserGeneratedRandomNode(): void { $uuid = Uuid::uuid6(new Hexadecimal((string) (new RandomNodeProvider())->getNode())); $this->assertInstanceOf(DateTimeInterface::class, $uuid->getDateTime()); - $this->assertEquals(2, $uuid->getVariant()); - $this->assertEquals(6, $uuid->getVersion()); + $this->assertSame(2, $uuid->getVariant()); + $this->assertSame(6, $uuid->getVersion()); } /** @@ -697,9 +697,9 @@ class UuidTest extends TestCase $uobj1 = Uuid::uuid3($ns, $name); $uobj2 = Uuid::uuid3(Uuid::fromString($ns), $name); - $this->assertEquals(2, $uobj1->getVariant()); - $this->assertEquals(3, $uobj1->getVersion()); - $this->assertEquals(Uuid::fromString($uuid)->toString(), $uobj1->toString()); + $this->assertSame(2, $uobj1->getVariant()); + $this->assertSame(3, $uobj1->getVersion()); + $this->assertSame(Uuid::fromString($uuid)->toString(), $uobj1->toString()); $this->assertTrue($uobj1->equals($uobj2)); } @@ -735,8 +735,8 @@ class UuidTest extends TestCase public function testUuid4(): void { $uuid = Uuid::uuid4(); - $this->assertEquals(2, $uuid->getVariant()); - $this->assertEquals(4, $uuid->getVersion()); + $this->assertSame(2, $uuid->getVariant()); + $this->assertSame(4, $uuid->getVersion()); } /** @@ -814,7 +814,7 @@ class UuidTest extends TestCase $uuid = $factory->uuid4(); - $this->assertEquals(4, $uuid->getVersion()); + $this->assertSame(4, $uuid->getVersion()); } /** @@ -830,9 +830,9 @@ class UuidTest extends TestCase $uobj1 = Uuid::uuid5($ns, $name); $uobj2 = Uuid::uuid5(Uuid::fromString($ns), $name); - $this->assertEquals(2, $uobj1->getVariant()); - $this->assertEquals(5, $uobj1->getVersion()); - $this->assertEquals(Uuid::fromString($uuid)->toString(), $uobj1->toString()); + $this->assertSame(2, $uobj1->getVariant()); + $this->assertSame(5, $uobj1->getVersion()); + $this->assertSame(Uuid::fromString($uuid)->toString(), $uobj1->toString()); $this->assertTrue($uobj1->equals($uobj2)); } @@ -883,12 +883,12 @@ class UuidTest extends TestCase // msb are equal to those in $uuid3, lsb are less than in $uuid3 $uuid5 = Uuid::fromString('44cca71e-d13d-11e1-a959-c8bcc8a476f3'); - $this->assertEquals(0, $uuid1->compareTo($uuid2)); - $this->assertEquals(0, $uuid2->compareTo($uuid1)); - $this->assertEquals(-1, $uuid3->compareTo($uuid4)); - $this->assertEquals(1, $uuid4->compareTo($uuid3)); - $this->assertEquals(-1, $uuid5->compareTo($uuid3)); - $this->assertEquals(1, $uuid3->compareTo($uuid5)); + $this->assertSame(0, $uuid1->compareTo($uuid2)); + $this->assertSame(0, $uuid2->compareTo($uuid1)); + $this->assertSame(-1, $uuid3->compareTo($uuid4)); + $this->assertSame(1, $uuid4->compareTo($uuid3)); + $this->assertSame(-1, $uuid5->compareTo($uuid3)); + $this->assertSame(1, $uuid3->compareTo($uuid5)); } public function testCompareToReturnsZeroWhenDifferentCases(): void @@ -898,8 +898,8 @@ class UuidTest extends TestCase $uuid1 = Uuid::fromString($uuidString); $uuid2 = Uuid::fromString(strtoupper($uuidString)); - $this->assertEquals(0, $uuid1->compareTo($uuid2)); - $this->assertEquals(0, $uuid2->compareTo($uuid1)); + $this->assertSame(0, $uuid1->compareTo($uuid2)); + $this->assertSame(0, $uuid2->compareTo($uuid1)); } public function testEqualsReturnsTrueWhenDifferentCases(): void @@ -935,28 +935,28 @@ class UuidTest extends TestCase Uuid::setFactory(new UuidFactory($featureSet)); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); - $this->assertEquals('c4dbe7e2-097f-11e2-9669-00007ffffffe', (string) $uuidA); - $this->assertEquals('c4dbe7e2', $uuidA->getTimeLowHex()); - $this->assertEquals('097f', $uuidA->getTimeMidHex()); - $this->assertEquals('11e2', $uuidA->getTimeHiAndVersionHex()); + $this->assertSame('c4dbe7e2-097f-11e2-9669-00007ffffffe', (string) $uuidA); + $this->assertSame('c4dbe7e2', $uuidA->getTimeLowHex()); + $this->assertSame('097f', $uuidA->getTimeMidHex()); + $this->assertSame('11e2', $uuidA->getTimeHiAndVersionHex()); // For usec = 0 $timeOfDay->setUsec(0); $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); - $this->assertEquals('c4b18100-097f-11e2-9669-00007ffffffe', (string) $uuidB); - $this->assertEquals('c4b18100', $uuidB->getTimeLowHex()); - $this->assertEquals('097f', $uuidB->getTimeMidHex()); - $this->assertEquals('11e2', $uuidB->getTimeHiAndVersionHex()); + $this->assertSame('c4b18100-097f-11e2-9669-00007ffffffe', (string) $uuidB); + $this->assertSame('c4b18100', $uuidB->getTimeLowHex()); + $this->assertSame('097f', $uuidB->getTimeMidHex()); + $this->assertSame('11e2', $uuidB->getTimeHiAndVersionHex()); // For usec = 999999 $timeOfDay->setUsec(999999); $uuidC = Uuid::uuid1(0x00007ffffffe, 0x1669); - $this->assertEquals('c54a1776-097f-11e2-9669-00007ffffffe', (string) $uuidC); - $this->assertEquals('c54a1776', $uuidC->getTimeLowHex()); - $this->assertEquals('097f', $uuidC->getTimeMidHex()); - $this->assertEquals('11e2', $uuidC->getTimeHiAndVersionHex()); + $this->assertSame('c54a1776-097f-11e2-9669-00007ffffffe', (string) $uuidC); + $this->assertSame('c54a1776', $uuidC->getTimeLowHex()); + $this->assertSame('097f', $uuidC->getTimeMidHex()); + $this->assertSame('11e2', $uuidC->getTimeHiAndVersionHex()); } public function testCalculateUuidTimeUpperLowerBounds(): void @@ -970,10 +970,10 @@ class UuidTest extends TestCase Uuid::setFactory(new UuidFactory($featureSet)); $uuidA = Uuid::uuid1(0x00007ffffffe, 0x1669); - $this->assertEquals('ff9785f6-ffff-1fff-9669-00007ffffffe', (string) $uuidA); - $this->assertEquals('ff9785f6', $uuidA->getTimeLowHex()); - $this->assertEquals('ffff', $uuidA->getTimeMidHex()); - $this->assertEquals('1fff', $uuidA->getTimeHiAndVersionHex()); + $this->assertSame('ff9785f6-ffff-1fff-9669-00007ffffffe', (string) $uuidA); + $this->assertSame('ff9785f6', $uuidA->getTimeLowHex()); + $this->assertSame('ffff', $uuidA->getTimeMidHex()); + $this->assertSame('1fff', $uuidA->getTimeHiAndVersionHex()); // 1582-10-15T00:00:00+00:00 $timeOfDay = new FixedTimeProvider(new Time('-12219292800', '0')); @@ -983,10 +983,10 @@ class UuidTest extends TestCase Uuid::setFactory(new UuidFactory($featureSet)); $uuidB = Uuid::uuid1(0x00007ffffffe, 0x1669); - $this->assertEquals('00000000-0000-1000-9669-00007ffffffe', (string) $uuidB); - $this->assertEquals('00000000', $uuidB->getTimeLowHex()); - $this->assertEquals('0000', $uuidB->getTimeMidHex()); - $this->assertEquals('1000', $uuidB->getTimeHiAndVersionHex()); + $this->assertSame('00000000-0000-1000-9669-00007ffffffe', (string) $uuidB); + $this->assertSame('00000000', $uuidB->getTimeLowHex()); + $this->assertSame('0000', $uuidB->getTimeMidHex()); + $this->assertSame('1000', $uuidB->getTimeHiAndVersionHex()); } /** @@ -1027,8 +1027,8 @@ class UuidTest extends TestCase // Assert that the time matches $usecAdd = BigDecimal::of($usec)->dividedBy('1000000', 14, RoundingMode::HALF_UP); $testTime = BigDecimal::of($currentTime)->plus($usecAdd)->toScale(0, RoundingMode::DOWN); - $this->assertEquals((string) $testTime, $uuid64->getDateTime()->getTimestamp()); - $this->assertEquals((string) $testTime, $uuid32->getDateTime()->getTimestamp()); + $this->assertSame((string) $testTime, (string) $uuid64->getDateTime()->getTimestamp()); + $this->assertSame((string) $testTime, (string) $uuid32->getDateTime()->getTimestamp()); } $currentTime++; @@ -1501,7 +1501,7 @@ class UuidTest extends TestCase { $uuid = Uuid::uuid1(); - $this->assertEquals('"' . $uuid->toString() . '"', json_encode($uuid)); + $this->assertSame('"' . $uuid->toString() . '"', json_encode($uuid)); } public function testSerialize(): void @@ -1534,14 +1534,14 @@ class UuidTest extends TestCase { $uuid = Uuid::uuid3(Uuid::NIL, ''); - $this->assertEquals('4ae71336-e44b-39bf-b9d2-752e234818a5', $uuid->toString()); + $this->assertSame('4ae71336-e44b-39bf-b9d2-752e234818a5', $uuid->toString()); } public function testUuid3WithZeroName(): void { $uuid = Uuid::uuid3(Uuid::NIL, '0'); - $this->assertEquals('19826852-5007-3022-a72a-212f66e9fac3', $uuid->toString()); + $this->assertSame('19826852-5007-3022-a72a-212f66e9fac3', $uuid->toString()); } public function testUuid5WithEmptyNamespace(): void @@ -1556,14 +1556,14 @@ class UuidTest extends TestCase { $uuid = Uuid::uuid5(Uuid::NIL, ''); - $this->assertEquals('e129f27c-5103-5c5c-844b-cdf0a15e160d', $uuid->toString()); + $this->assertSame('e129f27c-5103-5c5c-844b-cdf0a15e160d', $uuid->toString()); } public function testUuid5WithZeroName(): void { $uuid = Uuid::uuid5(Uuid::NIL, '0'); - $this->assertEquals('b6c54489-38a0-5f50-a60a-fd8d76219cae', $uuid->toString()); + $this->assertSame('b6c54489-38a0-5f50-a60a-fd8d76219cae', $uuid->toString()); } /** @@ -1572,7 +1572,7 @@ class UuidTest extends TestCase public function testUuidVersionConstantForVersion1(): void { $uuid = Uuid::fromString('ff6f8cb0-c57d-11e1-9b21-0800200c9a66'); - $this->assertEquals($uuid->getVersion(), Uuid::UUID_TYPE_TIME); + $this->assertSame($uuid->getVersion(), Uuid::UUID_TYPE_TIME); } /** @@ -1581,7 +1581,7 @@ class UuidTest extends TestCase public function testUuidVersionConstantForVersion2(): void { $uuid = Uuid::fromString('6fa459ea-ee8a-2ca4-894e-db77e160355e'); - $this->assertEquals($uuid->getVersion(), Uuid::UUID_TYPE_DCE_SECURITY); + $this->assertSame($uuid->getVersion(), Uuid::UUID_TYPE_DCE_SECURITY); } /** @@ -1590,7 +1590,7 @@ class UuidTest extends TestCase public function testUuidVersionConstantForVersion3(): void { $uuid = Uuid::fromString('6fa459ea-ee8a-3ca4-894e-db77e160355e'); - $this->assertEquals($uuid->getVersion(), Uuid::UUID_TYPE_HASH_MD5); + $this->assertSame($uuid->getVersion(), Uuid::UUID_TYPE_HASH_MD5); } /** @@ -1599,7 +1599,7 @@ class UuidTest extends TestCase public function testUuidVersionConstantForVersion4(): void { $uuid = Uuid::fromString('6fabf0bc-603a-42f2-925b-d9f779bd0032'); - $this->assertEquals($uuid->getVersion(), Uuid::UUID_TYPE_RANDOM); + $this->assertSame($uuid->getVersion(), Uuid::UUID_TYPE_RANDOM); } /** @@ -1608,13 +1608,13 @@ class UuidTest extends TestCase public function testUuidVersionConstantForVersion5(): void { $uuid = Uuid::fromString('886313e1-3b8a-5372-9b90-0c9aee199e5d'); - $this->assertEquals($uuid->getVersion(), Uuid::UUID_TYPE_HASH_SHA1); + $this->assertSame($uuid->getVersion(), Uuid::UUID_TYPE_HASH_SHA1); } public function testUuidVersionConstantForVersion6(): void { $uuid = Uuid::fromString('886313e1-3b8a-6372-9b90-0c9aee199e5d'); - $this->assertEquals($uuid->getVersion(), Uuid::UUID_TYPE_PEABODY); + $this->assertSame($uuid->getVersion(), Uuid::UUID_TYPE_PEABODY); } public function testGetDateTimeThrowsExceptionWhenDateTimeCannotParseDate(): void @@ -1667,9 +1667,9 @@ class UuidTest extends TestCase ): void { $generated = Uuid::$staticMethod(...$args); - self::assertEquals( - $generated, - Uuid::fromString($generated->toString()) + self::assertSame( + (string) $generated, + (string) Uuid::fromString($generated->toString()) ); } @@ -1684,9 +1684,9 @@ class UuidTest extends TestCase ): void { $generated = Uuid::$staticMethod(...$args); - self::assertEquals( - $generated, - Uuid::fromBytes($generated->getBytes()) + self::assertSame( + (string) $generated, + (string) Uuid::fromBytes($generated->getBytes()) ); } From 49b772a5e263a111140e73b6e2a825ed6ddeb59c Mon Sep 17 00:00:00 2001 From: Bilge Date: Sun, 23 Aug 2020 19:36:53 +0100 Subject: [PATCH 22/22] Removed redundant interface inheritance. --- src/Builder/BuilderCollection.php | 3 +-- src/Builder/DefaultUuidBuilder.php | 2 +- src/Guid/Guid.php | 3 +-- src/Nonstandard/Uuid.php | 3 +-- src/Provider/Node/NodeProviderCollection.php | 3 +-- 5 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/Builder/BuilderCollection.php b/src/Builder/BuilderCollection.php index b3e5f1d..0997971 100644 --- a/src/Builder/BuilderCollection.php +++ b/src/Builder/BuilderCollection.php @@ -15,7 +15,6 @@ declare(strict_types=1); namespace Ramsey\Uuid\Builder; use Ramsey\Collection\AbstractCollection; -use Ramsey\Collection\CollectionInterface; use Ramsey\Uuid\Converter\Number\GenericNumberConverter; use Ramsey\Uuid\Converter\Time\GenericTimeConverter; use Ramsey\Uuid\Converter\Time\PhpTimeConverter; @@ -28,7 +27,7 @@ use Traversable; /** * A collection of UuidBuilderInterface objects */ -class BuilderCollection extends AbstractCollection implements CollectionInterface +class BuilderCollection extends AbstractCollection { public function getType(): string { diff --git a/src/Builder/DefaultUuidBuilder.php b/src/Builder/DefaultUuidBuilder.php index 2af4e86..7c4a6f8 100644 --- a/src/Builder/DefaultUuidBuilder.php +++ b/src/Builder/DefaultUuidBuilder.php @@ -21,6 +21,6 @@ use Ramsey\Uuid\Rfc4122\UuidBuilder as Rfc4122UuidBuilder; * * @psalm-immutable */ -class DefaultUuidBuilder extends Rfc4122UuidBuilder implements UuidBuilderInterface +class DefaultUuidBuilder extends Rfc4122UuidBuilder { } diff --git a/src/Guid/Guid.php b/src/Guid/Guid.php index 08a0069..b3ed096 100644 --- a/src/Guid/Guid.php +++ b/src/Guid/Guid.php @@ -18,7 +18,6 @@ use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Uuid; -use Ramsey\Uuid\UuidInterface; /** * Guid represents a UUID with "native" (little-endian) byte order @@ -49,7 +48,7 @@ use Ramsey\Uuid\UuidInterface; * * @psalm-immutable */ -final class Guid extends Uuid implements UuidInterface +final class Guid extends Uuid { public function __construct( Fields $fields, diff --git a/src/Nonstandard/Uuid.php b/src/Nonstandard/Uuid.php index 5a7a333..715f825 100644 --- a/src/Nonstandard/Uuid.php +++ b/src/Nonstandard/Uuid.php @@ -18,14 +18,13 @@ use Ramsey\Uuid\Codec\CodecInterface; use Ramsey\Uuid\Converter\NumberConverterInterface; use Ramsey\Uuid\Converter\TimeConverterInterface; use Ramsey\Uuid\Uuid as BaseUuid; -use Ramsey\Uuid\UuidInterface; /** * Nonstandard\Uuid is a UUID that doesn't conform to RFC 4122 * * @psalm-immutable */ -final class Uuid extends BaseUuid implements UuidInterface +final class Uuid extends BaseUuid { public function __construct( Fields $fields, diff --git a/src/Provider/Node/NodeProviderCollection.php b/src/Provider/Node/NodeProviderCollection.php index 89d0917..c49398e 100644 --- a/src/Provider/Node/NodeProviderCollection.php +++ b/src/Provider/Node/NodeProviderCollection.php @@ -15,14 +15,13 @@ declare(strict_types=1); namespace Ramsey\Uuid\Provider\Node; use Ramsey\Collection\AbstractCollection; -use Ramsey\Collection\CollectionInterface; use Ramsey\Uuid\Provider\NodeProviderInterface; use Ramsey\Uuid\Type\Hexadecimal; /** * A collection of NodeProviderInterface objects */ -class NodeProviderCollection extends AbstractCollection implements CollectionInterface +class NodeProviderCollection extends AbstractCollection { public function getType(): string {