packages/ztd-query-mysql/tests/Unit/Sql/Value/MySqlCastRendererTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\Sql\Value;
6
7use Generator;
8use PHPUnit\Framework\Attributes\CoversClass;
9use PHPUnit\Framework\Attributes\DataProvider;
10use PHPUnit\Framework\TestCase;
11use ZtdQuery\Platform\MySql\Sql\Value\MySqlCastRenderer;
12use ZtdQuery\Schema\ColumnDeclaration;
13use ZtdQuery\Schema\ColumnTypeFamily;
14
15#[CoversClass(\ZtdQuery\Platform\MySql\Sql\Value\CastTypeResolver::class)]
16#[CoversClass(MySqlCastRenderer::class)]
17final class MySqlCastRendererTest extends TestCase
18{
19 public function testRenderCastInteger(): void
20 {
21 $renderer = new MySqlCastRenderer();
22 $type = new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'INT');
23 $result = $renderer->renderCast('1', $type);
24 self::assertSame('CAST(1 AS SIGNED)', $result);
25 }
26
27 public function testRenderCastPreservesYearCoercionForIntegerFamily(): void
28 {
29 $renderer = new MySqlCastRenderer();
30 self::assertSame('CAST(CAST(78 AS YEAR) AS SIGNED)', $renderer->renderCast('78', new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'YEAR')));
31 self::assertSame('CAST(CAST(69 AS YEAR) AS SIGNED)', $renderer->renderCast('69', new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'year(4)')));
32 self::assertSame('CAST(NULL AS SIGNED)', $renderer->renderNullCast(new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'YEAR')));
33 }
34
35 public function testRenderCastString(): void
36 {
37 $type = new ColumnDeclaration(ColumnTypeFamily::STRING, 'VARCHAR(255)');
38 $result = (new MySqlCastRenderer())->renderCast("'Alice'", $type);
39 self::assertSame("CAST('Alice' AS CHAR)", $result);
40 }
41
42 public function testRenderCastText(): void
43 {
44 $type = new ColumnDeclaration(ColumnTypeFamily::TEXT, 'TEXT');
45 $result = (new MySqlCastRenderer())->renderCast("'content'", $type);
46 self::assertSame("CAST('content' AS CHAR)", $result);
47 }
48
49 public function testRenderCastDecimalWithPrecision(): void
50 {
51 $type = new ColumnDeclaration(ColumnTypeFamily::DECIMAL, 'DECIMAL(10,2)');
52 $result = (new MySqlCastRenderer())->renderCast("'99.99'", $type);
53 self::assertSame("CAST('99.99' AS DECIMAL(10,2))", $result);
54 }
55
56 public function testRenderCastDecimalWithoutPrecision(): void
57 {
58 $type = new ColumnDeclaration(ColumnTypeFamily::DECIMAL, 'DECIMAL');
59 $result = (new MySqlCastRenderer())->renderCast("'99.99'", $type);
60 self::assertSame("CAST('99.99' AS DECIMAL(65,30))", $result);
61 }
62
63 public function testRenderCastDecimalWithSinglePrecision(): void
64 {
65 $type = new ColumnDeclaration(ColumnTypeFamily::DECIMAL, 'DECIMAL(10)');
66 $result = (new MySqlCastRenderer())->renderCast("'99'", $type);
67 self::assertSame("CAST('99' AS DECIMAL(10,0))", $result);
68 }
69
70 public function testRenderCastFloat(): void
71 {
72 $type = new ColumnDeclaration(ColumnTypeFamily::FLOAT, 'FLOAT');
73 $result = (new MySqlCastRenderer())->renderCast("'1.5'", $type);
74 self::assertSame("CAST('1.5' AS FLOAT)", $result);
75 }
76
77 public function testRenderCastDouble(): void
78 {
79 $type = new ColumnDeclaration(ColumnTypeFamily::DOUBLE, 'DOUBLE');
80 $result = (new MySqlCastRenderer())->renderCast("'1.5'", $type);
81 self::assertSame("CAST('1.5' AS DOUBLE)", $result);
82 }
83
84 public function testRenderCastBoolean(): void
85 {
86 $type = new ColumnDeclaration(ColumnTypeFamily::BOOLEAN, 'BOOLEAN');
87 $result = (new MySqlCastRenderer())->renderCast("'1'", $type);
88 self::assertSame("CAST('1' AS UNSIGNED)", $result);
89 }
90
91 public function testRenderCastDate(): void
92 {
93 $type = new ColumnDeclaration(ColumnTypeFamily::DATE, 'DATE');
94 $result = (new MySqlCastRenderer())->renderCast("'2024-01-01'", $type);
95 self::assertSame("CAST('2024-01-01' AS DATE)", $result);
96 }
97
98 public function testRenderCastDatetime(): void
99 {
100 $type = new ColumnDeclaration(ColumnTypeFamily::DATETIME, 'DATETIME');
101 $result = (new MySqlCastRenderer())->renderCast("'2024-01-01 00:00:00'", $type);
102 self::assertSame("CAST('2024-01-01 00:00:00' AS DATETIME)", $result);
103 }
104
105 public function testRenderCastTimestamp(): void
106 {
107 $type = new ColumnDeclaration(ColumnTypeFamily::TIMESTAMP, 'TIMESTAMP');
108 $result = (new MySqlCastRenderer())->renderCast("'2024-01-01 00:00:00'", $type);
109 self::assertSame("CAST('2024-01-01 00:00:00' AS DATETIME)", $result);
110 }
111
112 public function testRenderCastTime(): void
113 {
114 $type = new ColumnDeclaration(ColumnTypeFamily::TIME, 'TIME');
115 $result = (new MySqlCastRenderer())->renderCast("'12:00:00'", $type);
116 self::assertSame("CAST('12:00:00' AS TIME)", $result);
117 }
118
119 public function testRenderCastJson(): void
120 {
121 $type = new ColumnDeclaration(ColumnTypeFamily::JSON, 'JSON');
122 $result = (new MySqlCastRenderer())->renderCast("'{}'", $type);
123 self::assertSame("CAST('{}' AS JSON)", $result);
124 }
125
126 public function testRenderCastBinary(): void
127 {
128 $type = new ColumnDeclaration(ColumnTypeFamily::BINARY, 'BINARY');
129 $result = (new MySqlCastRenderer())->renderCast("'data'", $type);
130 self::assertSame("CAST('data' AS BINARY)", $result);
131 }
132
133 public function testRenderNullCastInteger(): void
134 {
135 $type = new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'INT');
136 $result = (new MySqlCastRenderer())->renderNullCast($type);
137 self::assertSame('CAST(NULL AS SIGNED)', $result);
138 }
139
140 public function testRenderNullCastString(): void
141 {
142 $type = new ColumnDeclaration(ColumnTypeFamily::STRING, 'VARCHAR(255)');
143 $result = (new MySqlCastRenderer())->renderNullCast($type);
144 self::assertSame('CAST(NULL AS CHAR)', $result);
145 }
146
147 public function testRenderNullCastJson(): void
148 {
149 $type = new ColumnDeclaration(ColumnTypeFamily::JSON, 'JSON');
150 $result = (new MySqlCastRenderer())->renderNullCast($type);
151 self::assertSame('CAST(NULL AS JSON)', $result);
152 }
153
154 public function testRenderCastUnknownFamilyFallsBackToNativeType(): void
155 {
156 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'YEAR');
157 $result = (new MySqlCastRenderer())->renderCast("'2024'", $type);
158 self::assertSame("CAST('2024' AS YEAR)", $result);
159 }
160
161 public function testRenderCastUnknownFamilyUnknownNativeType(): void
162 {
163 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'CUSTOM_TYPE');
164 $result = (new MySqlCastRenderer())->renderCast("'value'", $type);
165 self::assertSame("CAST('value' AS CHAR)", $result);
166 }
167
168 #[DataProvider('providerAllFamilies')]
169 public function testAllColumnTypeFamiliesProduceNonEmptyOutput(ColumnTypeFamily $family): void
170 {
171 $type = new ColumnDeclaration($family, 'TEST_TYPE');
172 $result = (new MySqlCastRenderer())->renderNullCast($type);
173 self::assertNotEmpty($result, "renderNullCast() returned empty for family {$family->value}");
174 }
175
176 #[DataProvider('providerAllFamilies')]
177 public function testOutputContainsCastKeyword(ColumnTypeFamily $family): void
178 {
179 $type = new ColumnDeclaration($family, 'TEST_TYPE');
180 $result = (new MySqlCastRenderer())->renderNullCast($type);
181 self::assertStringContainsString('CAST(', $result, "renderNullCast() missing CAST keyword for family {$family->value}");
182 }
183
184 public function testRenderCastIsDeterministic(): void
185 {
186 $type = new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'INT');
187 $result1 = (new MySqlCastRenderer())->renderCast('42', $type);
188 $result2 = (new MySqlCastRenderer())->renderCast('42', $type);
189 self::assertSame($result1, $result2);
190 }
191
192 #[DataProvider('providerAllFamilies')]
193 public function testRenderNullCastContainsNull(ColumnTypeFamily $family): void
194 {
195 $type = new ColumnDeclaration($family, 'TEST_TYPE');
196 $result = (new MySqlCastRenderer())->renderNullCast($type);
197 self::assertStringContainsString('NULL', $result, "renderNullCast() missing NULL for family {$family->value}");
198 }
199
200 public function testUnknownNativeIntMapsToSigned(): void
201 {
202 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'INT');
203 self::assertSame("CAST('1' AS SIGNED)", (new MySqlCastRenderer())->renderCast("'1'", $type));
204 }
205
206 public function testUnknownNativeIntegerMapsToSigned(): void
207 {
208 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'INTEGER');
209 self::assertSame("CAST('1' AS SIGNED)", (new MySqlCastRenderer())->renderCast("'1'", $type));
210 }
211
212 public function testUnknownNativeTinyintMapsToSigned(): void
213 {
214 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'TINYINT');
215 self::assertSame("CAST('1' AS SIGNED)", (new MySqlCastRenderer())->renderCast("'1'", $type));
216 }
217
218 public function testUnknownNativeSmallintMapsToSigned(): void
219 {
220 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'SMALLINT');
221 self::assertSame("CAST('1' AS SIGNED)", (new MySqlCastRenderer())->renderCast("'1'", $type));
222 }
223
224 public function testUnknownNativeMediumintMapsToSigned(): void
225 {
226 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'MEDIUMINT');
227 self::assertSame("CAST('1' AS SIGNED)", (new MySqlCastRenderer())->renderCast("'1'", $type));
228 }
229
230 public function testUnknownNativeBigintMapsToSigned(): void
231 {
232 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'BIGINT');
233 self::assertSame("CAST('1' AS SIGNED)", (new MySqlCastRenderer())->renderCast("'1'", $type));
234 }
235
236 public function testUnknownNativeDecimalMapsToDecimal(): void
237 {
238 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'DECIMAL(10,2)');
239 self::assertSame("CAST('1' AS DECIMAL(10,2))", (new MySqlCastRenderer())->renderCast("'1'", $type));
240 }
241
242 public function testUnknownNativeNumericMapsToDecimal(): void
243 {
244 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'NUMERIC');
245 self::assertSame("CAST('1' AS DECIMAL(65,30))", (new MySqlCastRenderer())->renderCast("'1'", $type));
246 }
247
248 public function testUnknownNativeFloatMapsToFloat(): void
249 {
250 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'FLOAT');
251 self::assertSame("CAST('1' AS FLOAT)", (new MySqlCastRenderer())->renderCast("'1'", $type));
252 }
253
254 public function testUnknownNativeDoubleMapsToDouble(): void
255 {
256 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'DOUBLE');
257 self::assertSame("CAST('1' AS DOUBLE)", (new MySqlCastRenderer())->renderCast("'1'", $type));
258 }
259
260 public function testUnknownNativeRealMapsToDouble(): void
261 {
262 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'REAL');
263 self::assertSame("CAST('1' AS DOUBLE)", (new MySqlCastRenderer())->renderCast("'1'", $type));
264 }
265
266 public function testUnknownNativeDateMapsToDate(): void
267 {
268 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'DATE');
269 self::assertSame("CAST('1' AS DATE)", (new MySqlCastRenderer())->renderCast("'1'", $type));
270 }
271
272 public function testUnknownNativeDatetimeMapsToDatetime(): void
273 {
274 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'DATETIME');
275 self::assertSame("CAST('1' AS DATETIME)", (new MySqlCastRenderer())->renderCast("'1'", $type));
276 }
277
278 public function testUnknownNativeTimestampMapsToDatetime(): void
279 {
280 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'TIMESTAMP');
281 self::assertSame("CAST('1' AS DATETIME)", (new MySqlCastRenderer())->renderCast("'1'", $type));
282 }
283
284 public function testUnknownNativeTimeMapsToTime(): void
285 {
286 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'TIME');
287 self::assertSame("CAST('1' AS TIME)", (new MySqlCastRenderer())->renderCast("'1'", $type));
288 }
289
290 public function testUnknownNativeJsonMapsToJson(): void
291 {
292 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'JSON');
293 self::assertSame("CAST('1' AS JSON)", (new MySqlCastRenderer())->renderCast("'1'", $type));
294 }
295
296 public function testUnknownNativeBinaryMapsToBinary(): void
297 {
298 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'BINARY');
299 self::assertSame("CAST('1' AS BINARY)", (new MySqlCastRenderer())->renderCast("'1'", $type));
300 }
301
302 public function testUnknownNativeVarbinaryMapsToBinary(): void
303 {
304 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'VARBINARY');
305 self::assertSame("CAST('1' AS BINARY)", (new MySqlCastRenderer())->renderCast("'1'", $type));
306 }
307
308 public function testUnknownNativeBlobMapsToBinary(): void
309 {
310 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'BLOB');
311 self::assertSame("CAST('1' AS BINARY)", (new MySqlCastRenderer())->renderCast("'1'", $type));
312 }
313
314 public function testUnknownNativeTinyblobMapsToBinary(): void
315 {
316 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'TINYBLOB');
317 self::assertSame("CAST('1' AS BINARY)", (new MySqlCastRenderer())->renderCast("'1'", $type));
318 }
319
320 public function testUnknownNativeMediumblobMapsToBinary(): void
321 {
322 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'MEDIUMBLOB');
323 self::assertSame("CAST('1' AS BINARY)", (new MySqlCastRenderer())->renderCast("'1'", $type));
324 }
325
326 public function testUnknownNativeLongblobMapsToBinary(): void
327 {
328 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'LONGBLOB');
329 self::assertSame("CAST('1' AS BINARY)", (new MySqlCastRenderer())->renderCast("'1'", $type));
330 }
331
332 public function testUnknownNativeWithParenthesesStrippedForMatch(): void
333 {
334 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'INT(11)');
335 self::assertSame("CAST('1' AS SIGNED)", (new MySqlCastRenderer())->renderCast("'1'", $type));
336 }
337
338 public function testRenderCastExpressionContainedInOutput(): void
339 {
340 $type = new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'INT');
341 $result = (new MySqlCastRenderer())->renderCast('my_column', $type);
342 self::assertStringContainsString('my_column', $result);
343 }
344
345 public function testRenderNullCastDecimal(): void
346 {
347 $type = new ColumnDeclaration(ColumnTypeFamily::DECIMAL, 'DECIMAL(10,2)');
348 $result = (new MySqlCastRenderer())->renderNullCast($type);
349 self::assertSame('CAST(NULL AS DECIMAL(10,2))', $result);
350 }
351
352 public function testRenderNullCastFloat(): void
353 {
354 $type = new ColumnDeclaration(ColumnTypeFamily::FLOAT, 'FLOAT');
355 $result = (new MySqlCastRenderer())->renderNullCast($type);
356 self::assertSame('CAST(NULL AS FLOAT)', $result);
357 }
358
359 public function testRenderNullCastDouble(): void
360 {
361 $type = new ColumnDeclaration(ColumnTypeFamily::DOUBLE, 'DOUBLE');
362 $result = (new MySqlCastRenderer())->renderNullCast($type);
363 self::assertSame('CAST(NULL AS DOUBLE)', $result);
364 }
365
366 public function testRenderNullCastBoolean(): void
367 {
368 $type = new ColumnDeclaration(ColumnTypeFamily::BOOLEAN, 'BOOLEAN');
369 $result = (new MySqlCastRenderer())->renderNullCast($type);
370 self::assertSame('CAST(NULL AS UNSIGNED)', $result);
371 }
372
373 public function testRenderNullCastDate(): void
374 {
375 $type = new ColumnDeclaration(ColumnTypeFamily::DATE, 'DATE');
376 $result = (new MySqlCastRenderer())->renderNullCast($type);
377 self::assertSame('CAST(NULL AS DATE)', $result);
378 }
379
380 public function testRenderNullCastDatetime(): void
381 {
382 $type = new ColumnDeclaration(ColumnTypeFamily::DATETIME, 'DATETIME');
383 $result = (new MySqlCastRenderer())->renderNullCast($type);
384 self::assertSame('CAST(NULL AS DATETIME)', $result);
385 }
386
387 public function testRenderNullCastTimestamp(): void
388 {
389 $type = new ColumnDeclaration(ColumnTypeFamily::TIMESTAMP, 'TIMESTAMP');
390 $result = (new MySqlCastRenderer())->renderNullCast($type);
391 self::assertSame('CAST(NULL AS DATETIME)', $result);
392 }
393
394 public function testRenderNullCastTime(): void
395 {
396 $type = new ColumnDeclaration(ColumnTypeFamily::TIME, 'TIME');
397 $result = (new MySqlCastRenderer())->renderNullCast($type);
398 self::assertSame('CAST(NULL AS TIME)', $result);
399 }
400
401 public function testRenderNullCastBinary(): void
402 {
403 $type = new ColumnDeclaration(ColumnTypeFamily::BINARY, 'BINARY');
404 $result = (new MySqlCastRenderer())->renderNullCast($type);
405 self::assertSame('CAST(NULL AS BINARY)', $result);
406 }
407
408 public function testRenderNullCastText(): void
409 {
410 $type = new ColumnDeclaration(ColumnTypeFamily::TEXT, 'TEXT');
411 $result = (new MySqlCastRenderer())->renderNullCast($type);
412 self::assertSame('CAST(NULL AS CHAR)', $result);
413 }
414
415 public function testRenderCastDecimalWithLowercaseNativeType(): void
416 {
417 $type = new ColumnDeclaration(ColumnTypeFamily::DECIMAL, 'decimal(10,2)');
418 $result = (new MySqlCastRenderer())->renderCast("'1'", $type);
419 self::assertSame("CAST('1' AS DECIMAL(10,2))", $result);
420 }
421
422 public function testRenderCastUnknownFamilyWithLowercaseNativeType(): void
423 {
424 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'int');
425 $result = (new MySqlCastRenderer())->renderCast("'1'", $type);
426 self::assertSame("CAST('1' AS SIGNED)", $result);
427 }
428
429 public function testRenderCastUnknownFamilyWithLowercaseNativeTypeWithParams(): void
430 {
431 $type = new ColumnDeclaration(ColumnTypeFamily::UNKNOWN, 'int(11)');
432 $result = (new MySqlCastRenderer())->renderCast("'1'", $type);
433 self::assertSame("CAST('1' AS SIGNED)", $result);
434 }
435
436 #[DataProvider('providerFamilyWithExpectedCastType')]
437 public function testEachFamilyProducesDistinctCastType(ColumnTypeFamily $family, string $expectedType): void
438 {
439 $type = new ColumnDeclaration($family, 'NATIVE');
440 $result = (new MySqlCastRenderer())->renderCast("'x'", $type);
441 self::assertSame("CAST('x' AS $expectedType)", $result, "Family {$family->value} did not produce expected cast type");
442 }
443
444 /**
445 * @return Generator<string, array{ColumnTypeFamily}>
446 */
447 public static function providerAllFamilies(): Generator
448 {
449 foreach (ColumnTypeFamily::cases() as $family) {
450 yield $family->value => [$family];
451 }
452 }
453
454 /**
455 * @return Generator<string, array{ColumnTypeFamily, string}>
456 */
457 public static function providerFamilyWithExpectedCastType(): Generator
458 {
459 yield 'INTEGER' => [ColumnTypeFamily::INTEGER, 'SIGNED'];
460 yield 'FLOAT' => [ColumnTypeFamily::FLOAT, 'FLOAT'];
461 yield 'DOUBLE' => [ColumnTypeFamily::DOUBLE, 'DOUBLE'];
462 yield 'BOOLEAN' => [ColumnTypeFamily::BOOLEAN, 'UNSIGNED'];
463 yield 'DATE' => [ColumnTypeFamily::DATE, 'DATE'];
464 yield 'DATETIME' => [ColumnTypeFamily::DATETIME, 'DATETIME'];
465 yield 'TIME' => [ColumnTypeFamily::TIME, 'TIME'];
466 yield 'JSON' => [ColumnTypeFamily::JSON, 'JSON'];
467 yield 'BINARY' => [ColumnTypeFamily::BINARY, 'BINARY'];
468 yield 'STRING' => [ColumnTypeFamily::STRING, 'CHAR'];
469 }
470
471 /**
472 * @return iterable<string, array{ColumnTypeFamily, string}>
473 */
474 public static function providerNativeTypes(): iterable
475 {
476 yield 'integer' => [ColumnTypeFamily::INTEGER, 'INT'];
477 yield 'float' => [ColumnTypeFamily::FLOAT, 'FLOAT'];
478 yield 'double' => [ColumnTypeFamily::DOUBLE, 'DOUBLE'];
479 yield 'decimal' => [ColumnTypeFamily::DECIMAL, 'DECIMAL(10,2)'];
480 yield 'string' => [ColumnTypeFamily::STRING, 'VARCHAR(255)'];
481 yield 'text' => [ColumnTypeFamily::TEXT, 'TEXT'];
482 yield 'boolean' => [ColumnTypeFamily::BOOLEAN, 'TINYINT(1)'];
483 yield 'date' => [ColumnTypeFamily::DATE, 'DATE'];
484 yield 'time' => [ColumnTypeFamily::TIME, 'TIME'];
485 yield 'datetime' => [ColumnTypeFamily::DATETIME, 'DATETIME'];
486 yield 'timestamp' => [ColumnTypeFamily::TIMESTAMP, 'TIMESTAMP'];
487 yield 'binary' => [ColumnTypeFamily::BINARY, 'BLOB'];
488 yield 'json' => [ColumnTypeFamily::JSON, 'JSON'];
489 yield 'unknown' => [ColumnTypeFamily::UNKNOWN, 'GEOMETRY'];
490 }
491
492 #[DataProvider('providerNativeTypes')]
493 public function testRenderCastHandlesEveryNativeType(ColumnTypeFamily $family, string $nativeType): void
494 {
495 $renderer = new MySqlCastRenderer();
496 $type = new ColumnDeclaration($family, $nativeType);
497
498 self::assertNotEmpty($renderer->renderCast("'test'", $type));
499 self::assertNotEmpty($renderer->renderCast("'value'", $type));
500 self::assertNotEmpty($renderer->renderNullCast($type));
501 self::assertStringContainsString('CAST(', $renderer->renderNullCast($type));
502 self::assertStringContainsString('NULL', $renderer->renderNullCast($type));
503 }
504
505 public function testRenderCastForIntegerProducesExactForm(): void
506 {
507 self::assertSame("CAST('42' AS SIGNED)", (new MySqlCastRenderer())->renderCast("'42'", new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'INT')));
508 }
509
510 public function testRenderNullCastProducesExactForm(): void
511 {
512 self::assertSame('CAST(NULL AS SIGNED)', (new MySqlCastRenderer())->renderNullCast(new ColumnDeclaration(ColumnTypeFamily::INTEGER, 'INT')));
513 }
514
515 public function testRenderCastForStringUsesCharType(): void
516 {
517 self::assertSame("CAST('hello' AS CHAR)", (new MySqlCastRenderer())->renderCast("'hello'", new ColumnDeclaration(ColumnTypeFamily::STRING, 'VARCHAR(255)')));
518 }
519}
520