packages/sql-faker/tests/Unit/Generation/Value/CharacterDomainTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\Generation\Value;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use SqlFaker\Generation\Value\CharacterDomain;
11use SqlFaker\Generation\Value\ChoiceDomain;
12use SqlFaker\Generation\Value\IntegerDomain;
13use SqlFaker\Generation\Value\SequenceDomain;
14use SqlFaker\Generation\Value\ValueChoices;
15use SqlFaker\Generation\Value\ValueDomain;
16
17#[CoversClass(CharacterDomain::class)]
18#[UsesClass(IntegerDomain::class)]
19#[UsesClass(SequenceDomain::class)]
20#[UsesClass(ChoiceDomain::class)]
21#[UsesClass(ValueChoices::class)]
22#[UsesClass(ValueDomain::class)]
23final class CharacterDomainTest extends TestCase
24{
25 public function testChoosePreservesEncodedAtomsAndEvenDigitLengths(): void
26 {
27 $domain = new CharacterDomain(['0', 'f'], 0, 2, "X'", "'", 2);
28 self::assertSame("X''", $domain->choose(static fn (int $count): int => 0));
29 self::assertSame("X'ffff'", $domain->choose(static fn (int $count): int => $count - 1));
30 self::assertSame("'a''b'", (new CharacterDomain(["a''b"], 1, 1, "'", "'"))->choose(static fn (int $count): int => 0));
31 }
32
33 public function testMatchKeepsAtomsDelimitersAndMultiplesTogether(): void
34 {
35 $domain = new CharacterDomain(['a', 'bb'], 0, 1, "'", "'", 2);
36 self::assertSame([2], $domain->match("''"));
37 self::assertSame([6], $domain->match("!'abb'!", 1));
38 self::assertSame([], $domain->match("'a'"));
39 self::assertSame([], $domain->match("'ab'"));
40 self::assertSame([], $domain->match('abb'));
41 self::assertSame([6], $domain->match("'aaaa'"));
42 }
43
44 public function testChooseSpansTheDefaultLengthsFromEmptyToTheScannerMaximum(): void
45 {
46 $domain = new CharacterDomain(['a']);
47 self::assertSame('', $domain->choose(static fn (int $count): int => 0));
48 self::assertSame(str_repeat('a', 255), $domain->choose(static fn (int $count): int => $count - 1));
49 }
50
51 public function testChooseStaysInsideDeclaredLengthBounds(): void
52 {
53 $domain = new CharacterDomain(['a'], 2, 4);
54 self::assertSame('aa', $domain->choose(static fn (int $count): int => 0));
55 self::assertSame('aaaa', $domain->choose(static fn (int $count): int => $count - 1));
56 }
57
58 public function testChooseAcceptsTheLargestScannerLength(): void
59 {
60 self::assertSame('', (new CharacterDomain(['a'], 0, 65535))->choose(static fn (int $count): int => 0));
61 }
62
63 public function testMatchRequiresTheDeclaredPrefix(): void
64 {
65 self::assertSame([], (new CharacterDomain(['a'], 0, 2, "X'", "'"))->match("'a'"));
66 }
67
68 public function testMatchCountsMultiplesFromTheMinimumLength(): void
69 {
70 self::assertSame([4, 6], (new CharacterDomain(['a'], 2, 3, multiple: 2))->match('aaaaaa'));
71 }
72
73 public function testMatchReportsEachEndOnceWhenAtomsOverlap(): void
74 {
75 self::assertSame([0, 1, 2, 3], (new CharacterDomain(['a', 'aa']))->match('aaa'));
76 }
77}
78