packages/ztd-query-core/tests/Unit/Shadow/Row/RowMatchTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Shadow\Row;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use ZtdQuery\Shadow\Row\RowMatch;
10
11#[CoversClass(RowMatch::class)]
12final class RowMatchTest extends TestCase
13{
14 public function testValuesOfReadsTheColumnsInTheOrderTheyWereAskedFor(): void
15 {
16 self::assertSame([2, 1], (new RowMatch())->valuesOf(['a' => 1, 'b' => 2], ['b', 'a']));
17 }
18
19 public function testValuesOfAnswersNothingWhenTheRowLacksAColumn(): void
20 {
21 self::assertNull((new RowMatch())->valuesOf(['a' => 1], ['a', 'b']));
22 }
23
24 public function testValuesOfKeepsANullTheRowActuallyCarries(): void
25 {
26 self::assertSame([null], (new RowMatch())->valuesOf(['a' => null], ['a']));
27 }
28
29 public function testCarriesIsTrueOnlyWhenEveryColumnHoldsTheValuePairedWithIt(): void
30 {
31 self::assertTrue((new RowMatch())->carries(['a' => 1, 'b' => 2], ['a', 'b'], [1, 2]));
32 self::assertFalse((new RowMatch())->carries(['a' => 1, 'b' => 2], ['a', 'b'], [1, 3]));
33 }
34
35 public function testCarriesTellsAStringApartFromTheNumberItLooksLike(): void
36 {
37 self::assertFalse((new RowMatch())->carries(['a' => '1'], ['a'], [1]));
38 }
39
40 public function testCarriesIsFalseWhenTheRowLacksAColumn(): void
41 {
42 self::assertFalse((new RowMatch())->carries(['a' => 1], ['b'], [1]));
43 }
44
45 public function testAgreeOnComparesOnlyTheNamedColumns(): void
46 {
47 self::assertTrue((new RowMatch())->agreeOn(['id' => 1, 'name' => 'a'], ['id' => 1, 'name' => 'b'], ['id']));
48 }
49
50 public function testAgreeOnIsFalseWhenEitherRowLacksAKey(): void
51 {
52 self::assertFalse((new RowMatch())->agreeOn(['id' => 1], ['name' => 'b'], ['id']));
53 self::assertFalse((new RowMatch())->agreeOn(['name' => 'b'], ['id' => 1], ['id']));
54 }
55
56 public function testAgreeOnIsTrueForAnyTwoRowsWhenNoKeyIsNamed(): void
57 {
58 self::assertTrue((new RowMatch())->agreeOn(['id' => 1], ['id' => 2], []));
59 }
60
61 public function testPositionOfSameKeyAnswersWhereTheKeyMatches(): void
62 {
63 $rows = [['id' => 1], ['id' => 2], ['id' => 3]];
64
65 self::assertSame(1, (new RowMatch())->positionOfSameKey($rows, ['id' => 2], ['id'], []));
66 }
67
68 public function testPositionOfSameKeySkipsPositionsAlreadyPairedOff(): void
69 {
70 $rows = [['id' => 1], ['id' => 1]];
71
72 self::assertSame(1, (new RowMatch())->positionOfSameKey($rows, ['id' => 1], ['id'], [0]));
73 }
74
75 public function testPositionOfSameKeyIsNothingWhenNoRowIsLeftToMatch(): void
76 {
77 self::assertNull((new RowMatch())->positionOfSameKey([['id' => 1]], ['id' => 1], ['id'], [0]));
78 }
79
80 public function testPositionOfIdenticalNeedsTheWholeRowToMatch(): void
81 {
82 $rows = [['id' => 1, 'name' => 'a'], ['id' => 1, 'name' => 'b']];
83
84 self::assertSame(1, (new RowMatch())->positionOfIdentical($rows, ['id' => 1, 'name' => 'b'], []));
85 }
86
87 public function testPositionOfIdenticalSkipsPositionsAlreadyPairedOff(): void
88 {
89 $rows = [['id' => 1], ['id' => 1]];
90
91 self::assertSame(1, (new RowMatch())->positionOfIdentical($rows, ['id' => 1], [0]));
92 }
93
94 public function testPositionOfIdenticalIsNothingWhenNoRowIsLeftToMatch(): void
95 {
96 self::assertNull((new RowMatch())->positionOfIdentical([['id' => 2]], ['id' => 1], []));
97 }
98 public function testSameRowReportsTwoRowsCarryingTheSameColumnsAndValues(): void
99 {
100 self::assertTrue((new RowMatch())->sameRow(['a' => 1, 'b' => 2], ['b' => 2, 'a' => 1]));
101 }
102
103 public function testSameRowIsFalseWhereOneCarriesAColumnTheOtherLacks(): void
104 {
105 self::assertFalse((new RowMatch())->sameRow(['a' => 1], ['a' => 1, 'b' => 2]));
106 }
107
108 public function testSameRowIsFalseWhereTheyDifferInAValue(): void
109 {
110 self::assertFalse((new RowMatch())->sameRow(['a' => 1], ['a' => 2]));
111 }
112
113 public function testIdentifiesReportsTwoRowsAgreeingOnTheKeyHoweverElseTheyDiffer(): void
114 {
115 self::assertTrue((new RowMatch())->identifies(['id' => 1, 'n' => 'a'], ['id' => 1, 'n' => 'b'], ['id']));
116 }
117
118 public function testIdentifiesIsFalseWhereTheyDisagreeOnTheKey(): void
119 {
120 self::assertFalse((new RowMatch())->identifies(['id' => 1], ['id' => 2], ['id']));
121 }
122
123 public function testIdentifiesFallsBackToTheWholeRowWhereTheTableDeclaresNoKey(): void
124 {
125 self::assertTrue((new RowMatch())->identifies(['n' => 'a'], ['n' => 'a'], []));
126 }
127
128 public function testIdentifiesTellsTwoRowsApartByEverythingWhereThereIsNoKey(): void
129 {
130 self::assertFalse((new RowMatch())->identifies(['n' => 'a'], ['n' => 'b'], []));
131 }
132
133}
134