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