packages/ztd-query-core/tests/Unit/Schema/TableDefinitionRegistryTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Schema;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use ZtdQuery\Schema\TableDefinition;
11use ZtdQuery\Schema\TableDefinitionRegistry;
12
13#[UsesClass(TableDefinition::class)]
14#[CoversClass(TableDefinitionRegistry::class)]
15final class TableDefinitionRegistryTest extends TestCase
16{
17 public function testSnapshotRestoreReplacesRegistryState(): void
18 {
19 $registry = new TableDefinitionRegistry();
20 $definition = new TableDefinition(['id'], ['id' => 'INT'], ['id'], ['id'], []);
21 $registry->register('users', $definition);
22 $snapshot = $registry->snapshot();
23
24 $registry->unregister('users');
25 $registry->restore($snapshot);
26
27 self::assertSame($definition, $registry->get('users'));
28 }
29
30 public function testRegisterAndGet(): void
31 {
32 $registry = new TableDefinitionRegistry();
33 $definition = new TableDefinition(['id'], ['id' => 'INT'], [], [], []);
34
35 $registry->register('users', $definition);
36
37 self::assertSame($definition, $registry->get('users'));
38 }
39
40 public function testRemovedDefinitionIsInactiveUntilRegisteredAgain(): void
41 {
42 $registry = new TableDefinitionRegistry();
43 $definition = new TableDefinition(['id'], ['id' => 'INT'], [], [], []);
44 $replacement = new TableDefinition(['code'], ['code' => 'TEXT'], [], [], []);
45 $registry->register('users', $definition);
46
47 $registry->markRemoved('users');
48
49 self::assertFalse($registry->has('users'));
50 self::assertNull($registry->get('users'));
51 self::assertTrue($registry->isRemoved('users'));
52 self::assertSame(['users' => $definition], $registry->getAllRemoved());
53
54 $registry->register('users', $replacement);
55
56 self::assertSame($replacement, $registry->get('users'));
57 self::assertFalse($registry->isRemoved('users'));
58 self::assertSame([], $registry->getAllRemoved());
59 }
60
61 public function testSnapshotRestoreIncludesRemovedDefinitions(): void
62 {
63 $registry = new TableDefinitionRegistry();
64 $definition = new TableDefinition(['id'], ['id' => 'INT'], [], [], []);
65 $registry->register('users', $definition);
66 $registry->markRemoved('users');
67 $snapshot = $registry->snapshot();
68
69 $registry->unregister('users');
70 self::assertFalse($registry->isRemoved('users'));
71
72 $registry->restore($snapshot);
73
74 self::assertTrue($registry->isRemoved('users'));
75 self::assertSame(['users' => $definition], $registry->getAllRemoved());
76 }
77
78 public function testClearGetAllClearRemovesActiveAndRemovedDefinitions(): void
79 {
80 $registry = new TableDefinitionRegistry();
81 $definition = new TableDefinition(['id'], ['id' => 'INT'], [], [], []);
82 $registry->register('active', $definition);
83 $registry->register('removed', $definition);
84 $registry->markRemoved('removed');
85
86 $registry->clear();
87
88 self::assertSame([], $registry->getAll());
89 self::assertSame([], $registry->getAllRemoved());
90 }
91
92 public function testGetReturnsNullForUnknownTable(): void
93 {
94 $registry = new TableDefinitionRegistry();
95
96 self::assertNull($registry->get('nonexistent'));
97 }
98
99 public function testHas(): void
100 {
101 $registry = new TableDefinitionRegistry();
102 $definition = new TableDefinition(['id'], ['id' => 'INT'], [], [], []);
103
104 $registry->register('users', $definition);
105
106 self::assertTrue($registry->has('users'));
107 self::assertFalse($registry->has('nonexistent'));
108 }
109
110 public function testGetAllAnswersEveryTableStillDescribed(): void
111 {
112 $registry = new TableDefinitionRegistry();
113 $order = new TableDefinition(['id'], [], ['id'], [], []);
114 $registry->register('order', $order);
115
116 self::assertSame(['order' => $order], $registry->getAll());
117 }
118
119 public function testGetAllRemovedAnswersTheTablesThatWereDropped(): void
120 {
121 $registry = new TableDefinitionRegistry();
122 $order = new TableDefinition(['id'], [], ['id'], [], []);
123 $registry->register('order', $order);
124 $registry->markRemoved('order');
125
126 self::assertSame(['order' => $order], $registry->getAllRemoved());
127 self::assertSame([], $registry->getAll());
128 }
129
130 public function testMarkRemovedDoesNothingForATableNothingDescribed(): void
131 {
132 $registry = new TableDefinitionRegistry();
133
134 $registry->markRemoved('order');
135
136 self::assertSame([], $registry->getAllRemoved());
137 }
138
139 public function testIsRemovedTellsADroppedTableFromOneThatWasNeverThere(): void
140 {
141 $registry = new TableDefinitionRegistry();
142 $registry->register('order', new TableDefinition(['id'], [], ['id'], [], []));
143 $registry->markRemoved('order');
144
145 self::assertTrue($registry->isRemoved('order'));
146 self::assertFalse($registry->isRemoved('other'));
147 }
148
149 public function testHasAnyTablesIsFalseUntilOneIsRegistered(): void
150 {
151 $registry = new TableDefinitionRegistry();
152
153 self::assertFalse($registry->hasAnyTables());
154
155 $registry->register('order', new TableDefinition(['id'], [], ['id'], [], []));
156
157 self::assertTrue($registry->hasAnyTables());
158 }
159
160 public function testUnregisterLeavesNoTraceOfTheTableAtAll(): void
161 {
162 $registry = new TableDefinitionRegistry();
163 $registry->register('order', new TableDefinition(['id'], [], ['id'], [], []));
164 $registry->markRemoved('order');
165
166 $registry->unregister('order');
167
168 self::assertFalse($registry->isRemoved('order'));
169 self::assertNull($registry->get('order'));
170 }
171
172 public function testRestorePutsBackWhatWasDroppedAsWellAsWhatWasThere(): void
173 {
174 $registry = new TableDefinitionRegistry();
175 $registry->register('order', new TableDefinition(['id'], [], ['id'], [], []));
176 $registry->markRemoved('order');
177 $snapshot = $registry->snapshot();
178 $registry->clear();
179
180 $registry->restore($snapshot);
181
182 self::assertTrue($registry->isRemoved('order'));
183 }
184}
185