packages/ztd-query-core/tests/Unit/Config/ZtdConfigTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Config;
6
7use PHPUnit\Framework\Attributes\CoversClass;
8use PHPUnit\Framework\Attributes\UsesClass;
9use PHPUnit\Framework\TestCase;
10use ZtdQuery\Config\SqlBehaviorRule;
11use ZtdQuery\Config\UnknownSchemaBehavior;
12use ZtdQuery\Config\UnsupportedSqlBehavior;
13use ZtdQuery\Config\ZtdConfig;
14
15#[UsesClass(SqlBehaviorRule::class)]
16#[CoversClass(ZtdConfig::class)]
17final class ZtdConfigTest extends TestCase
18{
19 public function testDefaultCreatesConfigWithExceptionBehavior(): void
20 {
21 $config = ZtdConfig::default();
22
23 self::assertSame(UnsupportedSqlBehavior::Exception, $config->unsupportedBehavior());
24 self::assertSame(UnknownSchemaBehavior::Passthrough, $config->unknownSchemaBehavior());
25 self::assertSame([], $config->behaviorRules());
26 }
27
28 public function testUnsupportedBehaviorReturnsConfiguredValue(): void
29 {
30 $config = new ZtdConfig(UnsupportedSqlBehavior::Ignore);
31
32 self::assertSame(UnsupportedSqlBehavior::Ignore, $config->unsupportedBehavior());
33 }
34
35 public function testUnknownSchemaBehaviorReturnsConfiguredValue(): void
36 {
37 $config = new ZtdConfig(
38 UnsupportedSqlBehavior::Exception,
39 UnknownSchemaBehavior::Exception
40 );
41
42 self::assertSame(UnknownSchemaBehavior::Exception, $config->unknownSchemaBehavior());
43 }
44
45 public function testBehaviorRulesReturnsConfiguredRules(): void
46 {
47 $config = new ZtdConfig(
48 UnsupportedSqlBehavior::Exception,
49 UnknownSchemaBehavior::Passthrough,
50 [
51 'SET' => UnsupportedSqlBehavior::Ignore,
52 '/^SHOW\s+/i' => UnsupportedSqlBehavior::Notice,
53 ]
54 );
55
56 $rules = $config->behaviorRules();
57
58 self::assertCount(2, $rules);
59 self::assertSame('SET', $rules[0]->pattern());
60 self::assertSame(UnsupportedSqlBehavior::Ignore, $rules[0]->behavior());
61 self::assertSame('/^SHOW\s+/i', $rules[1]->pattern());
62 self::assertSame(UnsupportedSqlBehavior::Notice, $rules[1]->behavior());
63 }
64
65 public function testGetBehaviorForReturnsMatchingRuleBehavior(): void
66 {
67 $config = new ZtdConfig(
68 UnsupportedSqlBehavior::Exception,
69 UnknownSchemaBehavior::Passthrough,
70 [
71 '/^SET\s+/i' => UnsupportedSqlBehavior::Notice,
72 'BEGIN' => UnsupportedSqlBehavior::Ignore,
73 ]
74 );
75
76 self::assertSame(UnsupportedSqlBehavior::Notice, $config->getBehaviorFor('SET foo = 1'));
77 self::assertSame(UnsupportedSqlBehavior::Ignore, $config->getBehaviorFor('BEGIN'));
78 }
79
80 public function testGetBehaviorForReturnsNullWhenNoMatch(): void
81 {
82 $config = new ZtdConfig(
83 UnsupportedSqlBehavior::Exception,
84 UnknownSchemaBehavior::Passthrough,
85 ['SET' => UnsupportedSqlBehavior::Ignore]
86 );
87
88 self::assertNull($config->getBehaviorFor('DROP TABLE users'));
89 }
90
91 public function testResolveUnsupportedBehaviorUsesMatchingRule(): void
92 {
93 $config = new ZtdConfig(
94 UnsupportedSqlBehavior::Exception,
95 UnknownSchemaBehavior::Passthrough,
96 ['SET' => UnsupportedSqlBehavior::Ignore]
97 );
98
99 self::assertSame(
100 UnsupportedSqlBehavior::Ignore,
101 $config->resolveUnsupportedBehavior('SET foo = 1')
102 );
103 }
104
105 public function testResolveUnsupportedBehaviorUsesDefaultWhenNoMatch(): void
106 {
107 $config = new ZtdConfig(
108 UnsupportedSqlBehavior::Exception,
109 UnknownSchemaBehavior::Passthrough,
110 ['SET' => UnsupportedSqlBehavior::Ignore]
111 );
112
113 self::assertSame(
114 UnsupportedSqlBehavior::Exception,
115 $config->resolveUnsupportedBehavior('DROP TABLE users')
116 );
117 }
118
119 public function testFirstMatchWins(): void
120 {
121 $config = new ZtdConfig(
122 UnsupportedSqlBehavior::Exception,
123 UnknownSchemaBehavior::Passthrough,
124 [
125 '/^SET\s+SESSION/i' => UnsupportedSqlBehavior::Ignore,
126 '/^SET\s+/i' => UnsupportedSqlBehavior::Notice,
127 ]
128 );
129
130 self::assertSame(
131 UnsupportedSqlBehavior::Ignore,
132 $config->getBehaviorFor('SET SESSION foo = 1')
133 );
134
135 self::assertSame(
136 UnsupportedSqlBehavior::Notice,
137 $config->getBehaviorFor('SET foo = 1')
138 );
139 }
140
141 public function testPrefixMatchingBehavior(): void
142 {
143 $config = new ZtdConfig(
144 UnsupportedSqlBehavior::Exception,
145 UnknownSchemaBehavior::Passthrough,
146 [
147 'SHOW' => UnsupportedSqlBehavior::Ignore,
148 'SET SESSION' => UnsupportedSqlBehavior::Notice,
149 ]
150 );
151
152 self::assertSame(UnsupportedSqlBehavior::Ignore, $config->getBehaviorFor('SHOW TABLES'));
153 self::assertSame(UnsupportedSqlBehavior::Ignore, $config->getBehaviorFor('show tables'));
154 self::assertSame(UnsupportedSqlBehavior::Ignore, $config->getBehaviorFor(' SHOW TABLES'));
155 self::assertSame(UnsupportedSqlBehavior::Notice, $config->getBehaviorFor('SET SESSION foo = 1'));
156 self::assertNull($config->getBehaviorFor('SET foo = 1'));
157 self::assertNull($config->getBehaviorFor('SELECT * FROM users'));
158 }
159
160 public function testRegexMatchingBehavior(): void
161 {
162 $config = new ZtdConfig(
163 UnsupportedSqlBehavior::Exception,
164 UnknownSchemaBehavior::Passthrough,
165 [
166 '/^SHOW\s+VARIABLES/i' => UnsupportedSqlBehavior::Ignore,
167 '/@@\w+/' => UnsupportedSqlBehavior::Notice,
168 ]
169 );
170
171 self::assertSame(UnsupportedSqlBehavior::Ignore, $config->getBehaviorFor('SHOW VARIABLES'));
172 self::assertSame(UnsupportedSqlBehavior::Ignore, $config->getBehaviorFor('SHOW VARIABLES'));
173 self::assertSame(UnsupportedSqlBehavior::Notice, $config->getBehaviorFor('SELECT @@version'));
174 self::assertNull($config->getBehaviorFor('SELECT version()'));
175 }
176
177 public function testMixedPrefixAndRegexRules(): void
178 {
179 $config = new ZtdConfig(
180 UnsupportedSqlBehavior::Exception,
181 UnknownSchemaBehavior::Passthrough,
182 [
183 'BEGIN' => UnsupportedSqlBehavior::Ignore,
184 '/^COMMIT\b/i' => UnsupportedSqlBehavior::Ignore,
185 'ROLLBACK' => UnsupportedSqlBehavior::Ignore,
186 '/^SET\s+/i' => UnsupportedSqlBehavior::Notice,
187 ]
188 );
189
190 self::assertSame(UnsupportedSqlBehavior::Ignore, $config->getBehaviorFor('BEGIN'));
191 self::assertSame(UnsupportedSqlBehavior::Ignore, $config->getBehaviorFor('COMMIT'));
192 self::assertSame(UnsupportedSqlBehavior::Ignore, $config->getBehaviorFor('ROLLBACK TO SAVEPOINT sp1'));
193 self::assertSame(UnsupportedSqlBehavior::Notice, $config->getBehaviorFor('SET NAMES utf8mb4'));
194 self::assertNull($config->getBehaviorFor('DROP TABLE users'));
195 }
196
197 public function testEmptyBehaviorRules(): void
198 {
199 $config = new ZtdConfig(
200 UnsupportedSqlBehavior::Notice,
201 UnknownSchemaBehavior::Passthrough,
202 []
203 );
204
205 self::assertNull($config->getBehaviorFor('SET foo = 1'));
206 self::assertSame(
207 UnsupportedSqlBehavior::Notice,
208 $config->resolveUnsupportedBehavior('SET foo = 1')
209 );
210 }
211}
212