packages/sql-faker/tests/Unit/Generation/Value/ValueChoicesTest.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(ValueChoices::class)]
18#[UsesClass(CharacterDomain::class)]
19#[UsesClass(IntegerDomain::class)]
20#[UsesClass(SequenceDomain::class)]
21#[UsesClass(ChoiceDomain::class)]
22#[UsesClass(ValueDomain::class)]
23final class ValueChoicesTest extends TestCase
24{
25    public function testValueSamplesOncePerOccurrenceAndDefinition(): void
26    {
27        $calls = 0;
28        $choices = new ValueChoices(static function (int $count) use (&$calls): int {
29            ++$calls;
30            return $count - 1;
31        });
32        $domain = new CharacterDomain(['x'], 1, 1);
33        self::assertSame('x', $choices->value(0, 'name', $domain));
34        $afterFirst = $calls;
35        self::assertSame('x', $choices->value(0, 'name', $domain));
36        self::assertSame($afterFirst, $calls);
37        self::assertSame('x', $choices->value(1, 'name', $domain));
38        self::assertGreaterThan($afterFirst, $calls);
39        self::assertNull($choices->value(2, 'no-domain', null));
40        self::assertNull((new ValueChoices(static fn (int $count): ?int => null))->value(0, 'empty-input', $domain));
41    }
42
43    public function testIndexPreservesTheCallerDecisionAndDefaultsExhaustedInput(): void
44    {
45        self::assertSame(2, (new ValueChoices(static fn (int $count): int => $count - 1))->index(3));
46        self::assertSame(0, (new ValueChoices(static fn (int $count): ?int => null))->index(3));
47    }
48}
49