packages/ztd-query-core/tests/Unit/Shadow/Mutation/UpsertMutationRowTest.php

1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Shadow\Mutation;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\DataProvider;
9use PHPUnit\Framework\TestCase;
10use ZtdQuery\Shadow\Mutation\UpsertMutationRow;
11
12#[CoversClass(UpsertMutationRow::class)]
13final class UpsertMutationRowTest extends TestCase
14{
15    public function testPredicateColumnAndValueColumnNameWhatTheStatementCarriesAlongsideARow(): void
16    {
17        $codec = new UpsertMutationRow();
18        $row = [
19            'id' => 1,
20            'name' => 'incoming',
21            $codec->valueColumn(-1) => 'before',
22            $codec->valueColumn(0) => 'evaluated',
23            $codec->valueColumn(1) => 'after',
24            $codec->predicateColumn() => 1,
25        ];
26
27        self::assertSame(
28            ['id' => 1, 'name' => 'incoming', '__ztd_upsert_value_-1' => 'before', '__ztd_upsert_value_1' => 'after'],
29            $codec->incomingRow($row, 1),
30        );
31        self::assertSame('__ztd_upsert_value_2', $codec->valueColumn(2));
32        self::assertSame('__ztd_upsert_predicate', $codec->predicateColumn());
33    }
34
35    #[DataProvider('providerPredicateValues')]
36    public function testPredicateMatchesNormalizesDatabasePredicateValues(
37        bool|float|int|string|null $value,
38        bool $expected,
39    ): void {
40        self::assertSame($expected, (new UpsertMutationRow())->predicateMatches($value));
41    }
42
43    /**
44     * @return iterable<string, array{bool|float|int|string|null, bool}>
45     */
46    public static function providerPredicateValues(): iterable
47    {
48        yield 'boolean true' => [true, true];
49        yield 'integer true' => [1, true];
50        yield 'numeric string true' => ['1', true];
51        yield 'PostgreSQL true' => ['t', true];
52        yield 'boolean false' => [false, false];
53        yield 'integer false' => [0, false];
54        yield 'null' => [null, false];
55    }
56    public function testValueColumnNamesOneAssignmentSoNoTableCouldUseTheName(): void
57    {
58        self::assertSame('__ztd_upsert_value_0', (new UpsertMutationRow())->valueColumn(0));
59    }
60
61    public function testIncomingRowLeavesOnlyWhatTheStatementActuallyWrote(): void
62    {
63        $row = [
64            'id' => 1,
65            '__ztd_upsert_value_0' => 'a',
66            '__ztd_upsert_predicate' => 1,
67        ];
68
69        self::assertSame(['id' => 1], (new UpsertMutationRow())->incomingRow($row, 1));
70    }
71
72    public function testIncomingRowLeavesACarriedValueTheClauseNeverDeclared(): void
73    {
74        $row = ['id' => 1, '__ztd_upsert_value_1' => 'a'];
75
76        self::assertSame($row, (new UpsertMutationRow())->incomingRow($row, 1));
77    }
78
79}
80