packages/ztd-query-core/tests/Unit/Shadow/Mutation/Table/CreateTableLikeMutationTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Shadow\Mutation\Table;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use RuntimeException;
11use ZtdQuery\Schema\TableDefinition;
12use ZtdQuery\Schema\TableDefinitionRegistry;
13use ZtdQuery\Shadow\Mutation\Table\CreateTableLikeMutation;
14use ZtdQuery\Shadow\ShadowStore;
15
16#[UsesClass(TableDefinition::class)]
17#[UsesClass(TableDefinitionRegistry::class)]
18#[UsesClass(ShadowStore::class)]
19#[CoversClass(CreateTableLikeMutation::class)]
20#[UsesClass(\ZtdQuery\Schema\RowSet::class)]
21final class CreateTableLikeMutationTest extends TestCase
22{
23 public function testApplyCopiesSchemaFromSourceTable(): void
24 {
25 $registry = new TableDefinitionRegistry();
26 $sourceDefinition = new TableDefinition(
27 ['id', 'name'],
28 ['id' => 'INT', 'name' => 'VARCHAR(255)'],
29 ['id'],
30 ['id'],
31 [],
32 );
33 $registry->register('users', $sourceDefinition);
34 $store = new ShadowStore();
35
36 $mutation = new CreateTableLikeMutation('users_backup', 'users', $registry);
37 $mutation->apply($store, []);
38
39 $newDefinition = $registry->get('users_backup');
40 self::assertNotNull($newDefinition);
41 self::assertSame(['id', 'name'], $newDefinition->columns);
42 }
43
44 public function testApplyEnsuresNewTableInShadowStore(): void
45 {
46 $registry = new TableDefinitionRegistry();
47 $sourceDefinition = new TableDefinition(
48 ['id'],
49 ['id' => 'INT'],
50 ['id'],
51 ['id'],
52 [],
53 );
54 $registry->register('users', $sourceDefinition);
55 $store = new ShadowStore();
56
57 $mutation = new CreateTableLikeMutation('users_backup', 'users', $registry);
58 $mutation->apply($store, []);
59
60 self::assertSame([], $store->get('users_backup'));
61 }
62
63 public function testTableNameReturnsNewTableName(): void
64 {
65 $registry = new TableDefinitionRegistry();
66 $mutation = new CreateTableLikeMutation('users_backup', 'users', $registry);
67
68 self::assertSame('users_backup', $mutation->tableName());
69 }
70
71 public function testApplyThrowsExceptionWhenTargetTableExists(): void
72 {
73 $registry = new TableDefinitionRegistry();
74 $sourceDefinition = new TableDefinition(
75 ['id'],
76 ['id' => 'INT'],
77 ['id'],
78 ['id'],
79 [],
80 );
81 $registry->register('users', $sourceDefinition);
82
83 $backupDefinition = new TableDefinition(
84 ['id'],
85 ['id' => 'INT'],
86 ['id'],
87 ['id'],
88 [],
89 );
90 $registry->register('users_backup', $backupDefinition);
91 $store = new ShadowStore();
92
93 $mutation = new CreateTableLikeMutation('users_backup', 'users', $registry);
94
95 $this->expectException(RuntimeException::class);
96 $this->expectExceptionMessage("Table 'users_backup' already exists.");
97
98 $mutation->apply($store, []);
99 }
100
101 public function testApplyWithIfNotExistsSkipsWhenTableExists(): void
102 {
103 $registry = new TableDefinitionRegistry();
104 $sourceDefinition = new TableDefinition(
105 ['id', 'name'],
106 ['id' => 'INT', 'name' => 'VARCHAR(255)'],
107 ['id'],
108 ['id'],
109 [],
110 );
111 $registry->register('users', $sourceDefinition);
112
113 $originalDefinition = new TableDefinition(
114 ['id'],
115 ['id' => 'INT'],
116 ['id'],
117 ['id'],
118 [],
119 );
120 $registry->register('users_backup', $originalDefinition);
121 $store = new ShadowStore();
122
123 $mutation = new CreateTableLikeMutation('users_backup', 'users', $registry, true);
124 $mutation->apply($store, []);
125
126 $def = $registry->get('users_backup');
127 self::assertNotNull($def);
128 self::assertSame(['id'], $def->columns);
129 }
130
131 public function testApplyThrowsExceptionWhenSourceTableDoesNotExist(): void
132 {
133 $registry = new TableDefinitionRegistry();
134 $store = new ShadowStore();
135
136 $mutation = new CreateTableLikeMutation('users_backup', 'users', $registry);
137
138 $this->expectException(RuntimeException::class);
139 $this->expectExceptionMessage("Source table 'users' does not exist.");
140
141 $mutation->apply($store, []);
142 }
143}
144