packages/sql-faker/tests/Unit/PostgreSql/Generation/Value/QuotedDomainTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\SqlFaker\PostgreSql\Generation\Value;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use SqlFaker\PostgreSql\Generation\Value\QuotedDomain;
10
11#[CoversClass(QuotedDomain::class)]
12final class QuotedDomainTest extends TestCase
13{
14    public function testChooseEscapesDelimitersBackslashesAndUnicodeEscapeMarkersDuringConstruction(): void
15    {
16        self::assertSame("''''", (new QuotedDomain("'", minimum: 1, maximum: 1, alphabet: ["'"]))->choose(static fn (int $count): int => 0));
17        self::assertSame("E'\\\\'", (new QuotedDomain("'", ['E'], true, 1, 1, ['\\']))->choose(static fn (int $count): int => 0));
18        self::assertSame("U&'\\\\'", (new QuotedDomain("'", ['U&'], alphabet: ['\\'], minimum: 1, maximum: 1, unicodeEscapes: true))->choose(static fn (int $count): int => 0));
19        self::assertSame('`a`', (new QuotedDomain('`', minimum: 1, maximum: 1, alphabet: ['a', ' '], trailingSpace: false))->choose(static fn (int $count): int => $count - 1));
20    }
21
22    public function testMatchStopsAtTheFirstUnescapedClosingDelimiter(): void
23    {
24        $domain = new QuotedDomain("'", backslash: true);
25        self::assertSame([7], $domain->match("!'a''b' trailing", 1));
26        self::assertSame([6], $domain->match("'a\\'b'"));
27        self::assertSame([], $domain->match("'unclosed"));
28        self::assertSame([], $domain->match("'a\0b'"));
29        self::assertSame([], $domain->match("'a\\"));
30        self::assertSame([], $domain->match("'a\\\0'"));
31        self::assertSame([], (new QuotedDomain('"', minimum: 1))->match('""'));
32        self::assertSame([3], (new QuotedDomain('[', closing: ']'))->match('[a]b]'));
33        self::assertSame([], (new QuotedDomain("'", ['N']))->match("'text'"));
34    }
35
36    public function testEncodeReturnsCompleteEscapedAtoms(): void
37    {
38        $domain = new QuotedDomain("'", backslash: true);
39        self::assertSame("''", $domain->encode("'"));
40        self::assertSame('\\\\', $domain->encode('\\'));
41        self::assertSame('猫', $domain->encode('猫'));
42    }
43
44    public function testEndReadsTheContentAfterAnOpeningDelimiter(): void
45    {
46        self::assertSame(5, (new QuotedDomain("'"))->end("text'", 1));
47        self::assertNull((new QuotedDomain("'"))->end('unclosed', 0));
48    }
49
50    public function testChooseSpansTheDefaultBodyLengthsFromEmptyToTheScannerMaximum(): void
51    {
52        $domain = new QuotedDomain("'");
53        self::assertSame("''", $domain->choose(static fn (int $count): int => 0));
54        self::assertSame("'" . str_repeat('a', 255) . "'", $domain->choose(static fn (int $count): int => $count === 10 ? 0 : $count - 1));
55    }
56
57    public function testChooseKeepsATrailingSpaceUnlessTheScannerTrimsIt(): void
58    {
59        self::assertSame("' '", (new QuotedDomain("'", minimum: 1, maximum: 1))->choose(static fn (int $count): int => $count === 10 ? 3 : 0));
60        self::assertSame("''''", (new QuotedDomain("'", minimum: 1, maximum: 1, trailingSpace: false))->choose(static fn (int $count): int => $count === 9 ? 3 : 0));
61    }
62
63    public function testChooseClosesWithTheDistinctClosingDelimiterWhenOneIsDeclared(): void
64    {
65        self::assertSame('[a]', (new QuotedDomain('[', minimum: 1, maximum: 1, closing: ']'))->choose(static fn (int $count): int => 0));
66    }
67
68    public function testEncodeLeavesBackslashesAloneUnlessTheScannerReadsEscapes(): void
69    {
70        self::assertSame('\\', (new QuotedDomain("'"))->encode('\\'));
71        self::assertSame('\\\\', (new QuotedDomain("'", unicodeEscapes: true))->encode('\\'));
72    }
73
74    public function testMatchReadsEveryDeclaredPrefixInTurn(): void
75    {
76        $domain = new QuotedDomain("'", ['N', '']);
77        self::assertSame([7], $domain->match("N'text'"));
78        self::assertSame([6], $domain->match("'text'"));
79        self::assertSame([], $domain->match("n'text'"));
80    }
81
82    public function testEndRequiresTheMinimumBodyLength(): void
83    {
84        $domain = new QuotedDomain("'", minimum: 1);
85        self::assertSame(3, $domain->end("'a'", 1));
86        self::assertNull($domain->end("''", 1));
87    }
88}
89