packages/ztd-query-core/tests/Unit/Shadow/Mutation/ConflictSearchTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Shadow\Mutation;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use ZtdQuery\Schema\Key\CandidateKeyConflict;
11use ZtdQuery\Schema\Key\CandidateKeyMatch;
12use ZtdQuery\Schema\Key\CandidateKeySet;
13use ZtdQuery\Shadow\Mutation\ConflictSearch;
14use ZtdQuery\Shadow\Mutation\Upsert\UpsertOperator;
15use ZtdQuery\Shadow\Mutation\UpsertColumnSource;
16use ZtdQuery\Shadow\Mutation\UpsertExpression;
17use ZtdQuery\Shadow\Mutation\UpsertExpressionKind;
18
19#[CoversClass(ConflictSearch::class)]
20#[UsesClass(CandidateKeySet::class)]
21#[UsesClass(CandidateKeyMatch::class)]
22#[UsesClass(CandidateKeyConflict::class)]
23#[UsesClass(UpsertExpression::class)]
24#[UsesClass(\ZtdQuery\Shadow\Mutation\Upsert\UpsertColumn::class)]
25#[UsesClass(\ZtdQuery\Shadow\Mutation\Upsert\UpsertComparison::class)]
26#[UsesClass(\ZtdQuery\Shadow\Mutation\Upsert\UpsertNumber::class)]
27#[UsesClass(\ZtdQuery\Shadow\Mutation\Upsert\UpsertTruth::class)]
28#[UsesClass(UpsertOperator::class)]
29#[UsesClass(\ZtdQuery\Shadow\Mutation\Upsert\UpsertLiteral::class)]
30final class ConflictSearchTest extends TestCase
31{
32 public function testOfAnswersTheRowTheIncomingRowWouldCollideWith(): void
33 {
34 $search = new ConflictSearch(CandidateKeySet::fromSchema(['id']), null, 'users');
35
36 self::assertSame(1, $search->of(['id' => 2], [['id' => 1], ['id' => 2]])?->rowIndex);
37 }
38
39 public function testOfIsNothingWhereNoRowAlreadyThereCarriesTheSameKey(): void
40 {
41 $search = new ConflictSearch(CandidateKeySet::fromSchema(['id']), null, 'users');
42
43 self::assertNull($search->of(['id' => 3], [['id' => 1], ['id' => 2]]));
44 }
45
46 public function testOfIsNothingWhereTheIncomingRowTakesNoPartInTheNarrowedKey(): void
47 {
48 $search = new ConflictSearch(
49 CandidateKeySet::fromSchema(['id']),
50 UpsertExpression::binary(
51 UpsertExpressionKind::Equal,
52 UpsertExpression::column(UpsertColumnSource::Existing, 'active'),
53 UpsertExpression::literal(true),
54 ),
55 'users',
56 );
57
58 self::assertNull($search->of(['id' => 1, 'active' => false], [['id' => 1, 'active' => true]]));
59 }
60
61 public function testOfLeavesOutTheRowsAlreadyThereThatTakeNoPart(): void
62 {
63 $search = new ConflictSearch(
64 CandidateKeySet::fromSchema(['id']),
65 UpsertExpression::binary(
66 UpsertExpressionKind::Equal,
67 UpsertExpression::column(UpsertColumnSource::Existing, 'active'),
68 UpsertExpression::literal(true),
69 ),
70 'users',
71 );
72
73 self::assertNull($search->of(['id' => 1, 'active' => true], [['id' => 1, 'active' => false]]));
74 }
75
76 public function testOfReportsTheRowUnderTheKeyTheCallerKnowsItBy(): void
77 {
78 $search = new ConflictSearch(
79 CandidateKeySet::fromSchema(['id']),
80 UpsertExpression::binary(
81 UpsertExpressionKind::Equal,
82 UpsertExpression::column(UpsertColumnSource::Existing, 'active'),
83 UpsertExpression::literal(true),
84 ),
85 'users',
86 );
87
88 $conflict = $search->of(
89 ['id' => 2, 'active' => true],
90 [['id' => 1, 'active' => false], ['id' => 2, 'active' => true]],
91 );
92
93 self::assertSame(1, $conflict?->rowIndex);
94 }
95}
96