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