packages/ztd-query-core/tests/Unit/GenericExecuteResultTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\TestCase;
9use Tests\Fake\FakeStatement;
10use ZtdQuery\GenericExecuteResult;
11use ZtdQuery\Rewrite\QueryKind;
12
13#[CoversClass(GenericExecuteResult::class)]
14#[\PHPUnit\Framework\Attributes\UsesClass(\ZtdQuery\Schema\RowSet::class)]
15final class GenericExecuteResultTest extends TestCase
16{
17 public function testPassthroughResult(): void
18 {
19 $result = GenericExecuteResult::passthrough();
20
21 self::assertTrue($result->isPassthrough());
22 self::assertTrue($result->isSuccess());
23 self::assertSame(QueryKind::READ, $result->kind());
24 self::assertTrue($result->hasResultSet());
25 }
26
27 public function testFailureResult(): void
28 {
29 $result = GenericExecuteResult::failure(QueryKind::WRITE_SIMULATED);
30
31 self::assertFalse($result->isPassthrough());
32 self::assertFalse($result->isSuccess());
33 self::assertSame(QueryKind::WRITE_SIMULATED, $result->kind());
34 self::assertFalse($result->hasResultSet());
35 }
36
37 public function testFromBufferedRows(): void
38 {
39 $rows = [
40 ['id' => 1, 'name' => 'Alice'],
41 ['id' => 2, 'name' => 'Bob'],
42 ];
43
44 $result = GenericExecuteResult::fromBufferedRows($rows);
45
46 self::assertFalse($result->isPassthrough());
47 self::assertTrue($result->isSuccess());
48 self::assertSame(QueryKind::WRITE_SIMULATED, $result->kind());
49 self::assertSame(2, $result->rowCount());
50 }
51
52 public function testFetchFromBufferedRows(): void
53 {
54 $rows = [
55 ['id' => 1, 'name' => 'Alice'],
56 ['id' => 2, 'name' => 'Bob'],
57 ];
58
59 $result = GenericExecuteResult::fromBufferedRows($rows);
60
61 self::assertSame(['id' => 1, 'name' => 'Alice'], $result->fetch());
62 self::assertSame(['id' => 2, 'name' => 'Bob'], $result->fetch());
63 self::assertFalse($result->fetch());
64 }
65
66 public function testFetchAllFromBufferedRows(): void
67 {
68 $rows = [
69 ['id' => 1, 'name' => 'Alice'],
70 ['id' => 2, 'name' => 'Bob'],
71 ];
72
73 $result = GenericExecuteResult::fromBufferedRows($rows);
74
75 self::assertSame($rows, $result->fetchAll());
76 }
77
78 public function testFetchAllAfterPartialFetch(): void
79 {
80 $rows = [
81 ['id' => 1, 'name' => 'Alice'],
82 ['id' => 2, 'name' => 'Bob'],
83 ['id' => 3, 'name' => 'Carol'],
84 ];
85
86 $result = GenericExecuteResult::fromBufferedRows($rows);
87 $result->fetch();
88
89 self::assertSame(
90 [['id' => 2, 'name' => 'Bob'], ['id' => 3, 'name' => 'Carol']],
91 $result->fetchAll()
92 );
93 }
94
95 public function testFromStatement(): void
96 {
97 $statement = new FakeStatement([['id' => 1]]);
98 $result = GenericExecuteResult::fromStatement($statement);
99
100 self::assertFalse($result->isPassthrough());
101 self::assertTrue($result->isSuccess());
102 self::assertSame(QueryKind::READ, $result->kind());
103 self::assertTrue($result->hasResultSet());
104 }
105
106 public function testFetchFromStatement(): void
107 {
108 $statement = new FakeStatement([['id' => 1, 'name' => 'Alice']]);
109 $result = GenericExecuteResult::fromStatement($statement);
110
111 self::assertSame(['id' => 1, 'name' => 'Alice'], $result->fetch());
112 }
113
114 public function testFetchFromStatementReturnsSecondRowOnSubsequentCall(): void
115 {
116 $statement = new FakeStatement([
117 ['id' => 1, 'name' => 'Alice'],
118 ['id' => 2, 'name' => 'Bob'],
119 ]);
120 $result = GenericExecuteResult::fromStatement($statement);
121
122 $result->fetch();
123 self::assertSame(['id' => 2, 'name' => 'Bob'], $result->fetch());
124 }
125
126 public function testFetchFromEmptyStatementReturnsFalse(): void
127 {
128 $statement = new FakeStatement([]);
129 $result = GenericExecuteResult::fromStatement($statement);
130
131 self::assertFalse($result->fetch());
132 }
133
134 public function testRowCountFromStatement(): void
135 {
136 $statement = new FakeStatement([['id' => 1]]);
137 $result = GenericExecuteResult::fromStatement($statement);
138
139 self::assertSame(1, $result->rowCount());
140 }
141
142 public function testPassthroughRowCountIsZero(): void
143 {
144 $result = GenericExecuteResult::passthrough();
145
146 self::assertSame(0, $result->rowCount());
147 }
148
149 public function testResetBuffer(): void
150 {
151 $rows = [['id' => 1], ['id' => 2]];
152 $result = GenericExecuteResult::fromBufferedRows($rows);
153 $result->fetch();
154 $result->fetch();
155
156 $result->resetBuffer();
157
158 self::assertSame(['id' => 1], $result->fetch());
159 }
160
161 public function testHasResultSetForWriteIsFalse(): void
162 {
163 $result = GenericExecuteResult::fromBufferedRows([]);
164
165 self::assertFalse($result->hasResultSet());
166 }
167
168 public function testBufferedReturningUsesIndependentAffectedCount(): void
169 {
170 $result = GenericExecuteResult::fromBufferedRows(
171 [['id' => 1]],
172 affectedRowCount: 3,
173 hasResultSet: true,
174 );
175
176 self::assertTrue($result->hasResultSet());
177 self::assertSame(3, $result->rowCount());
178 self::assertSame([['id' => 1]], $result->fetchAll());
179 }
180
181 public function testPassthroughFetchReturnsFalse(): void
182 {
183 $result = GenericExecuteResult::passthrough();
184
185 self::assertFalse($result->fetch());
186 }
187
188 public function testPassthroughFetchAllReturnsEmpty(): void
189 {
190 $result = GenericExecuteResult::passthrough();
191
192 self::assertSame([], $result->fetchAll());
193 }
194
195 public function testFromStatementAndRows(): void
196 {
197 $statement = new FakeStatement([['id' => 1]]);
198 $rows = [['id' => 1, 'name' => 'Alice']];
199
200 $result = GenericExecuteResult::fromStatementAndRows($statement, $rows);
201
202 self::assertFalse($result->isPassthrough());
203 self::assertTrue($result->isSuccess());
204 self::assertSame(1, $result->rowCount());
205 }
206
207 public function testIsPassthroughIsTrueOnlyWhereTheOriginalStatementStillHasToRun(): void
208 {
209 self::assertTrue(GenericExecuteResult::passthrough()->isPassthrough());
210 self::assertFalse(GenericExecuteResult::fromBufferedRows([], QueryKind::READ)->isPassthrough());
211 }
212
213 public function testIsSuccessIsFalseOnlyForAResultThatFailed(): void
214 {
215 self::assertTrue(GenericExecuteResult::fromBufferedRows([], QueryKind::READ)->isSuccess());
216 self::assertFalse(GenericExecuteResult::failure(QueryKind::READ)->isSuccess());
217 }
218
219 public function testKindAnswersWhatWasRun(): void
220 {
221 self::assertSame(
222 QueryKind::DDL_SIMULATED,
223 GenericExecuteResult::fromBufferedRows([], QueryKind::DDL_SIMULATED)->kind(),
224 );
225 }
226}
227