getConstructor(); $constructor->invoke($reflection->newInstanceWithoutConstructor()); // THEN expect(fn (): UuidHelper => $reflection->newInstance()) ->toThrow(\ReflectionException::class); }); it('correctly checks if UUID is v4', function (): void { // GIVEN $uuidV4 = Uuid::uuid4(); $uuidV7 = Uuid::uuid7(); // WHEN & THEN expect(UuidHelper::isV4($uuidV4))->toBeTrue() ->and(UuidHelper::isV4($uuidV7))->toBeFalse(); }); it('correctly checks if UUID is v7', function (): void { // GIVEN $uuidV4 = Uuid::uuid4(); $uuidV7 = Uuid::uuid7(); // WHEN & THEN expect(UuidHelper::isV7($uuidV7))->toBeTrue() ->and(UuidHelper::isV7($uuidV4))->toBeFalse(); }); it('can get the version of an UUID including Guid and Nonstandard Uuid', function (): void { // GIVEN $uuidV4 = Uuid::uuid4(); $uuidV7 = Uuid::uuid7(); $guid = Guid::fromString('00000000-0000-4000-8000-000000000000'); $nonstandard = NonstandardUuid::fromString('00000000-0000-4000-8000-000000000000'); // WHEN $resultV4 = UuidHelper::version($uuidV4); $resultV7 = UuidHelper::version($uuidV7); $resultGuid = UuidHelper::version($guid); $resultNonstandard = UuidHelper::version($nonstandard); // THEN expect($resultV4)->toBe(4) ->and($resultV7)->toBe(7) ->and($resultGuid)->toBe(4) ->and($resultNonstandard)->toBe(4); }); it('falls back to string parsing when fields are not Rfc4122', function (): void { // GIVEN $fields = new class () implements FieldsInterface { public function getBytes(): string { return ''; } public function serialize(): string { return ''; } public function unserialize(string $data): void { // Keep empty. } public function __serialize(): array { return []; } public function __unserialize(array $data): void { // Keep empty. } }; $uuidValid = \Mockery::mock(Uuid::class); $uuidValid->shouldReceive('getFields')->andReturn($fields); $uuidValid->shouldReceive('toString')->andReturn('00000000-0000-7000-8000-000000000000'); $uuidShort = \Mockery::mock(Uuid::class); $uuidShort->shouldReceive('getFields')->andReturn($fields); $uuidShort->shouldReceive('toString')->andReturn('short-uuid'); // WHEN & THEN expect(UuidHelper::version($uuidValid))->toBe(7) ->and(UuidHelper::version($uuidShort))->toBe(0); }); it('extracts DateTimeImmutable from UUIDv7 correctly', function (): void { // GIVEN $uuidV7 = Uuid::uuid7(); // WHEN $dateTime = UuidHelper::toDateTime($uuidV7); // THEN expect($dateTime)->toBeInstanceOf(\DateTimeImmutable::class) ->and($dateTime->getTimezone()->getName())->toBe('UTC') ->and($dateTime->getTimestamp())->toBeLessThanOrEqual(time()) ->and($dateTime->getTimestamp())->toBeGreaterThan(1700000000); }); it('throws InvalidUuidException when extracting DateTime from non-V7 UUID', function (): void { // GIVEN $uuidV4 = Uuid::uuid4(); // WHEN & THEN expect(fn (): \DateTimeImmutable => UuidHelper::toDateTime($uuidV4)) ->toThrow(InvalidUuidException::class, 'Cannot extract datetime from non-V7 UUID'); }); it('is an invalid argument exception', function (): void { // GIVEN / WHEN $exception = InvalidUuidException::forValue('foo'); // THEN expect($exception)->toBeInstanceOf(\InvalidArgumentException::class); }); });