packages/sql-fixture/tests/Unit/Fixture/FixtureSetTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Fixture;
6
7use LogicException;
8use OutOfBoundsException;
9use PHPUnit\Framework\Attributes\CoversClass;
10use PHPUnit\Framework\Attributes\Test;
11use PHPUnit\Framework\TestCase;
12use SqlFixture\Fixture\FixtureSet;
13
14#[CoversClass(FixtureSet::class)]
15final class FixtureSetTest extends TestCase
16{
17 #[Test]
18 public function testReadsByPositionInThePlansOrder(): void
19 {
20 $set = new FixtureSet(
21 ['order' => [['id' => 1]], 'order_detail' => [['id' => 1], ['id' => 2]]],
22 ['order' => false, 'order_detail' => true],
23 ['order', 'order_detail']
24 );
25
26 self::assertSame(['id' => 1], $set->row(0));
27 self::assertCount(2, $set->rows(1));
28 }
29
30 #[Test]
31 public function testOffsetGetSupportsListAssignment(): void
32 {
33 $set = new FixtureSet(
34 ['order' => [['id' => 1]], 'order_detail' => [['id' => 9]]],
35 ['order' => false, 'order_detail' => true],
36 ['order', 'order_detail']
37 );
38
39 [$order, $details] = $set;
40
41 self::assertSame(['id' => 1], $order);
42 self::assertSame([['id' => 9]], $details);
43 }
44
45 #[Test]
46 public function testReadsByTableName(): void
47 {
48 $set = new FixtureSet(['order' => [['id' => 1]]], ['order' => false], ['order']);
49
50 self::assertSame(['id' => 1], $set['order']);
51 }
52
53 #[Test]
54 public function testATableHoldingAListReadsBackAsAList(): void
55 {
56 $set = new FixtureSet(['order_detail' => [['id' => 1]]], ['order_detail' => true], ['order_detail']);
57
58 self::assertSame([['id' => 1]], $set['order_detail']);
59 }
60
61 #[Test]
62 public function testRowIsNullWhereNothingWasGenerated(): void
63 {
64 $set = new FixtureSet(['order_shipping' => []], ['order_shipping' => false], ['order_shipping']);
65
66 self::assertNull($set->row('order_shipping'));
67 self::assertNull($set['order_shipping']);
68 }
69
70 #[Test]
71 public function testRowRefusesATableHoldingAList(): void
72 {
73 $set = new FixtureSet(['order_detail' => [['id' => 1]]], ['order_detail' => true], ['order_detail']);
74
75 $this->expectException(OutOfBoundsException::class);
76 $this->expectExceptionMessage('holds a list of rows');
77
78 $set->row('order_detail');
79 }
80
81 #[Test]
82 public function testRowsAlwaysReturnsAList(): void
83 {
84 $set = new FixtureSet(
85 ['order' => [['id' => 1]], 'order_detail' => [['id' => 2]], 'shipping' => []],
86 ['order' => false, 'order_detail' => true, 'shipping' => false],
87 ['order', 'order_detail', 'shipping']
88 );
89
90 self::assertSame([['id' => 1]], $set->rows('order'));
91 self::assertSame([['id' => 2]], $set->rows('order_detail'));
92 self::assertSame([], $set->rows('shipping'));
93 }
94
95 #[Test]
96 public function testCountsTheTablesNotTheRows(): void
97 {
98 $set = new FixtureSet(
99 ['order' => [['id' => 1]], 'order_detail' => [['id' => 1], ['id' => 2]]],
100 ['order' => false, 'order_detail' => true],
101 ['order', 'order_detail']
102 );
103
104 self::assertCount(2, $set);
105 }
106
107 #[Test]
108 public function testIteratesInThePlansOrder(): void
109 {
110 $set = new FixtureSet(
111 ['order' => [['id' => 1]], 'order_detail' => [['id' => 2]]],
112 ['order' => false, 'order_detail' => true],
113 ['order', 'order_detail']
114 );
115
116 self::assertSame([['id' => 1], [['id' => 2]]], iterator_to_array($set));
117 }
118
119 #[Test]
120 public function testTablesReportsWhichTablesItHolds(): void
121 {
122 $set = new FixtureSet(['order' => [['id' => 1]]], ['order' => false], ['order']);
123
124 self::assertTrue(isset($set['order']));
125 self::assertFalse(isset($set['nope']));
126 self::assertSame(['order'], $set->tables());
127 self::assertSame(['order' => ['id' => 1]], $set->toArray());
128 }
129
130 #[Test]
131 public function testAnUnknownTableReadsBackAsNothing(): void
132 {
133 $set = new FixtureSet(['order' => [['id' => 1]]], ['order' => false], ['order']);
134
135 self::assertNull($set['nope']);
136 self::assertSame([], $set->rows('nope'));
137 }
138
139 #[Test]
140 public function testGetReadsTheEntryWhicheverShapeItHas(): void
141 {
142 $set = new FixtureSet(
143 ['order' => [['id' => 1]], 'order_detail' => [['id' => 2]]],
144 ['order' => false, 'order_detail' => true],
145 ['order', 'order_detail']
146 );
147
148 self::assertSame(['id' => 1], $set->get('order'));
149 self::assertSame([['id' => 2]], $set->get('order_detail'));
150 }
151
152 #[Test]
153 public function testAnUnknownTableIsNotTreatedAsAList(): void
154 {
155 $set = new FixtureSet(['order' => [['id' => 1]]], ['order' => false], ['order']);
156
157 self::assertNull($set->row('nope'));
158 }
159
160 #[Test]
161 public function testToArrayKeepsEveryTable(): void
162 {
163 $set = new FixtureSet(
164 ['order' => [['id' => 1]], 'order_detail' => [['id' => 2]]],
165 ['order' => false, 'order_detail' => true],
166 ['order', 'order_detail']
167 );
168
169 self::assertSame(
170 ['order' => ['id' => 1], 'order_detail' => [['id' => 2]]],
171 $set->toArray()
172 );
173 }
174
175 #[Test]
176 public function testAPositionPastTheEndReadsAsNothing(): void
177 {
178 $set = new FixtureSet(['order' => [['id' => 1]]], ['order' => false], ['order']);
179
180 self::assertNull($set[7]);
181 self::assertFalse(isset($set[7]));
182 }
183 public function testOffsetExistsTracksNamesAndPositions(): void
184 {
185 $set = new FixtureSet(['a' => []], ['a' => true], ['a']);
186 self::assertTrue(isset($set['a']));
187 self::assertTrue(isset($set[0]));
188 self::assertFalse(isset($set[1]));
189 }
190 public function testGetIteratorPreservesPlanOrder(): void
191 {
192 $set = new FixtureSet(['a' => [['id' => 2]], 'b' => []], ['a' => false, 'b' => true], ['b', 'a']);
193 self::assertSame([[], ['id' => 2]], iterator_to_array($set));
194 }
195 public function testOffsetSetRejectsMutation(): void
196 {
197 $set = new FixtureSet(['order' => [['id' => 1]]], ['order' => false], ['order']);
198 $this->expectException(LogicException::class);
199 $this->expectExceptionMessage('A FixtureSet is read-only.');
200 $set['order'] = ['id' => 2];
201 }
202
203 public function testOffsetUnsetRejectsRemoval(): void
204 {
205 $set = new FixtureSet(['order' => [['id' => 1]]], ['order' => false], ['order']);
206 $this->expectException(LogicException::class);
207 $this->expectExceptionMessage('A FixtureSet is read-only.');
208 unset($set['order']);
209 }
210}
211