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