packages/ztd-query-pdo-adapter/tests/Unit/Session/BufferedRowTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Session;
6
7use PDO;
8use PHPUnit\Framework\Attributes\CoversClass;
9use PHPUnit\Framework\TestCase;
10use ReflectionException;
11use stdClass;
12use ZtdQuery\Adapter\Pdo\Session\BufferedRow;
13
14#[CoversClass(BufferedRow::class)]
15final class BufferedRowTest extends TestCase
16{
17 public function testInModeAnswersTheRowKeyedByColumnWhereThatIsAsked(): void
18 {
19 self::assertSame(
20 ['id' => 1, 'name' => 'ada'],
21 (new BufferedRow())->inMode(['id' => 1, 'name' => 'ada'], PDO::FETCH_ASSOC),
22 );
23 }
24
25 public function testInModeAnswersANamedFetchTheSameWayAsAKeyedOne(): void
26 {
27 self::assertSame(
28 ['id' => 1],
29 (new BufferedRow())->inMode(['id' => 1], PDO::FETCH_NAMED),
30 );
31 }
32
33 public function testInModeAnswersTheValuesAloneWhereOnlyPositionsAreAsked(): void
34 {
35 self::assertSame(
36 [1, 'ada'],
37 (new BufferedRow())->inMode(['id' => 1, 'name' => 'ada'], PDO::FETCH_NUM),
38 );
39 }
40
41 public function testInModeAnswersAnObjectWhereOneIsAsked(): void
42 {
43 $object = (new BufferedRow())->inMode(['id' => 1], PDO::FETCH_OBJ);
44
45 self::assertSame(['id' => 1], is_object($object) ? get_object_vars($object) : []);
46 }
47
48 public function testInModeAnswersTheFirstValueWhereOneColumnIsAsked(): void
49 {
50 self::assertSame(1, (new BufferedRow())->inMode(['id' => 1, 'name' => 'ada'], PDO::FETCH_COLUMN));
51 }
52
53 public function testInModeAnswersFalseWhereOneColumnIsAskedOfAnEmptyRow(): void
54 {
55 self::assertFalse((new BufferedRow())->inMode([], PDO::FETCH_COLUMN));
56 }
57
58 public function testInModeAnswersAModeItDoesNotKnowBothWaysAtOnce(): void
59 {
60 self::assertSame(
61 ['id' => 1, 0 => 1],
62 (new BufferedRow())->inMode(['id' => 1], PDO::FETCH_BOTH),
63 );
64 }
65
66 public function testKeyedBothWaysReachesEveryValueUnderEitherKey(): void
67 {
68 self::assertSame(
69 ['id' => 1, 0 => 1, 'name' => 'ada', 1 => 'ada'],
70 (new BufferedRow())->keyedBothWays(['id' => 1, 'name' => 'ada']),
71 );
72 }
73
74 public function testKeyedBothWaysAnswersNothingForARowWithNoColumns(): void
75 {
76 self::assertSame([], (new BufferedRow())->keyedBothWays([]));
77 }
78 public function testResolveModeUsesExplicitThenStatementThenConnectionMode(): void
79 {
80 $row = new BufferedRow();
81 self::assertSame(PDO::FETCH_NUM, $row->resolveMode(PDO::FETCH_NUM, PDO::FETCH_ASSOC, PDO::FETCH_OBJ));
82 self::assertSame(PDO::FETCH_OBJ, $row->resolveMode(PDO::FETCH_DEFAULT, PDO::FETCH_ASSOC, PDO::FETCH_OBJ));
83 self::assertSame(PDO::FETCH_ASSOC, $row->resolveMode(PDO::FETCH_DEFAULT, PDO::FETCH_ASSOC, null));
84 }
85
86
87 public function testFetchPreservesValues(): void
88 {
89 $rows = new BufferedRow();
90 self::assertSame(['id' => 7, 'name' => null], $rows->fetch(['id' => 7, 'name' => null], PDO::FETCH_ASSOC));
91 }
92
93 public function testAllShapesRowsAndSelectsTheRequestedColumn(): void
94 {
95 $rows = new BufferedRow();
96 self::assertSame(['Ada', 'Grace'], $rows->all([['id' => 7, 'name' => 'Ada'], ['id' => 9, 'name' => 'Grace']], PDO::FETCH_COLUMN, [1]));
97 self::assertSame([7], $rows->all([['id' => 7]], PDO::FETCH_COLUMN, ['invalid column']));
98 self::assertSame([[7, 'Ada']], $rows->all([['id' => 7, 'name' => 'Ada']], PDO::FETCH_NUM, []));
99 }
100
101 public function testColumnPreservesNullAndMissingColumnBehavior(): void
102 {
103 $rows = new BufferedRow();
104 self::assertSame('Ada', $rows->column(['id' => 7, 'name' => 'Ada'], 1));
105 self::assertFalse($rows->column(['id' => 7], 1));
106 self::assertFalse($rows->column(['name' => null], 0));
107 }
108
109 /**
110 * @throws ReflectionException
111 */
112 public function testObjectPreservesAnonymousRowsAndEndOfCursor(): void
113 {
114 $rows = new BufferedRow();
115 $object = $rows->object(['id' => 7, 'name' => null], null, []);
116 self::assertInstanceOf(stdClass::class, $object);
117 self::assertSame(['id' => 7, 'name' => null], get_object_vars($object));
118 self::assertFalse($rows->object(false, null, []));
119 }
120
121 /**
122 * @throws ReflectionException
123 */
124 public function testObjectHydratesDeclaredPropertiesAfterConstruction(): void
125 {
126 $prototype = new class ('initial') {
127 public function __construct(public string $name)
128 {
129 }
130 };
131 $object = (new BufferedRow())->object(['name' => 'Ada', 'unknown' => 7], $prototype::class, ['constructor']);
132 self::assertInstanceOf($prototype::class, $object);
133 self::assertSame(['name' => 'Ada'], get_object_vars($object));
134 }
135}
136