Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
78 / 78
n/a
0 / 0
CRAP
n/a
0 / 0
1<?php
2
3// ╔════════════════════════════════════════════════════════════╗
4// ║ MIT Licence (#Expat) - https://opensource.org/licenses/MIT ║
5// ║ Copyright 2026 Frederic Poeydomenge <dyno@phexium.com>     ║
6// ╚════════════════════════════════════════════════════════════╝
7
8declare(strict_types=1);
9
10use Phexium\Domain\Id\Ulid;
11use Phexium\Plugin\IdGenerator\Adapter\UlidGenerator;
12
13test('Generator returns a Ulid object', function (): void {
14    $generator = new UlidGenerator();
15
16    $result = $generator->generate();
17
18    expect($result)->toBeInstanceOf(Ulid::class);
19});
20
21test('Generator returns a Ulid object from a Base32 string', function (): void {
22    $generator = new UlidGenerator();
23    $validUlid = '01GCZ05N3JFRKBRWKNGCQZGP44';
24
25    $result = $generator->from($validUlid);
26
27    expect($result)->toBeInstanceOf(Ulid::class)
28        ->and($result->getValue())->toBe($validUlid)
29    ;
30});
31
32test('Generator returns a Ulid object from a UUID string', function (): void {
33    $generator = new UlidGenerator();
34    $validUuid = '018e89e8-86e0-7a6c-a982-3b4e8e8d8e8e';
35
36    $result = $generator->from($validUuid);
37
38    expect($result)->toBeInstanceOf(Ulid::class)
39        ->and($result->getValue())->toMatch('/^[0-9A-Z]{26}$/')
40    ;
41});
42
43test('Generated ULID is in Base32 format with 26 characters', function (): void {
44    $generator = new UlidGenerator();
45
46    $result = $generator->generate();
47
48    expect($result)->toBeInstanceOf(Ulid::class)
49        ->and($result->getValue())->toMatch('/^[0-9A-Z]{26}$/')
50    ;
51});
52
53it('generator throws exception when creating from int', function (): void {
54    $generator = new UlidGenerator();
55
56    expect(fn (): Ulid => $generator->from(123))
57        ->toThrow(LogicException::class, 'Ulid generator cannot create ULIDs from integers')
58    ;
59});
60
61it('Ulid throws exception when creating from int', function (): void {
62    expect(fn (): Ulid => Ulid::from(123))
63        ->toThrow(LogicException::class, 'Ulid cannot be created from an integer')
64    ;
65});
66
67it('Ulid throws exception with invalid string', function (): void {
68    expect(fn (): Ulid => Ulid::from('invalid-ulid'))
69        ->toThrow(InvalidArgumentException::class, 'Invalid ULID: invalid-ulid')
70    ;
71});
72
73test('Ulid equality', function (): void {
74    $ulid = '01GCZ05N3JFRKBRWKNGCQZGP44';
75    $id1 = Ulid::from($ulid);
76
77    expect($id1->equals($id1))->toBeTrue();
78
79    $anotherUlid = '01GCZ05N3JFRKBRWKNGCQZGP45';
80    $id2 = Ulid::from($anotherUlid);
81
82    expect($id1->equals($id2))->toBeFalse();
83});
84
85test('Ulid can be converted to string in Base32 format', function (): void {
86    $ulid = '01GCZ05N3JFRKBRWKNGCQZGP44';
87    $id = Ulid::from($ulid);
88
89    expect((string) $id)->toBeString()
90        ->toBe($ulid)
91        ->and($id->getValue())->toBe($ulid)
92        ->and(strlen($id->getValue()))->toBe(26)
93    ;
94});
95
96test('Generated ULIDs are different', function (): void {
97    $generator = new UlidGenerator();
98
99    $id1 = $generator->generate();
100    $id2 = $generator->generate();
101
102    expect($id1->equals($id2))->toBeFalse()
103        ->and($id1->getValue())->not->toBe($id2->getValue())
104    ;
105});
106
107test('Ulid Crockford mode normalizes ambiguous characters I L O', function (): void {
108    $normalizationTests = [
109        '01GCZ05N3JFRKBRWKNGCQZGP4I' => '01GCZ05N3JFRKBRWKNGCQZGP41',
110        '01GCZ05N3JFRKBRWKNGCQZGP4L' => '01GCZ05N3JFRKBRWKNGCQZGP41',
111        '01GCZ05N3JFRKBRWKNGCQZGP4O' => '01GCZ05N3JFRKBRWKNGCQZGP40',
112    ];
113
114    foreach ($normalizationTests as $input => $expected) {
115        $ulid = Ulid::from($input);
116        $normalized = $ulid->getValue();
117
118        expect($normalized)->toBe(
119            $expected,
120            sprintf('ULID %s should normalize to %s but got %s', $input, $expected, $normalized)
121        );
122    }
123});