packages/sql-fixture/tests/Unit/TypeMapper/MySqlTypeMapperTest.php
1<?php
2
3declare(strict_types=1);
4
5namespace Tests\Unit\TypeMapper;
6
7use Faker\Factory;
8use PHPUnit\Framework\Attributes\CoversClass;
9use PHPUnit\Framework\Attributes\Test;
10use PHPUnit\Framework\Attributes\UsesClass;
11use PHPUnit\Framework\TestCase;
12use SqlFixture\Platform\MySql\MySqlTypeMapper as PlatformMySqlTypeMapper;
13use SqlFixture\Schema\ColumnDefinition;
14use SqlFixture\TypeMapper\MySqlTypeMapper;
15
16#[CoversClass(MySqlTypeMapper::class)]
17#[UsesClass(ColumnDefinition::class)]
18#[UsesClass(PlatformMySqlTypeMapper::class)]
19#[UsesClass(\SqlFixture\TypeMapper\TypeMapperInterface::class)]
20#[UsesClass(\SqlFixture\Platform\MySql\Value\ColumnGenerator::class)]
21#[UsesClass(\SqlFixture\Platform\MySql\Value\DecimalGenerator::class)]
22#[UsesClass(\SqlFixture\Platform\MySql\Value\GeometryGenerator::class)]
23#[UsesClass(\SqlFixture\Platform\MySql\Value\IntegerGenerator::class)]
24#[UsesClass(\SqlFixture\Platform\MySql\Value\NumericGenerator::class)]
25#[UsesClass(\SqlFixture\Platform\MySql\Value\SpatialGenerator::class)]
26#[UsesClass(\SqlFixture\Platform\MySql\Value\StringGenerator::class)]
27#[UsesClass(\SqlFixture\Platform\MySql\Value\TextGenerator::class)]
28#[UsesClass(\SqlFixture\TypeMapper\ParagraphGenerator::class)]
29#[UsesClass(\SqlFixture\TypeMapper\IntegerRange::class)]
30#[UsesClass(\SqlFixture\TypeMapper\IntegerWidth::class)]
31#[UsesClass(\SqlFixture\TypeMapper\DecimalRange::class)]
32final class MySqlTypeMapperTest extends TestCase
33{
34 #[Test]
35 public function testGenerateTinyInt(): void
36 {
37 $faker = Factory::create();
38 $faker->seed(12345);
39 $mapper = new MySqlTypeMapper();
40
41 $column = new ColumnDefinition('col', 'TINYINT', nullable: false);
42 $value = $mapper->generate($faker, $column);
43
44 self::assertIsInt($value);
45 self::assertGreaterThanOrEqual(-128, $value);
46 self::assertLessThanOrEqual(127, $value);
47 }
48
49 #[Test]
50 public function testGenerateTinyIntUnsigned(): void
51 {
52 $faker = Factory::create();
53 $faker->seed(12345);
54 $mapper = new MySqlTypeMapper();
55
56 $column = new ColumnDefinition('col', 'TINYINT', unsigned: true, nullable: false);
57 $value = $mapper->generate($faker, $column);
58
59 self::assertIsInt($value);
60 self::assertGreaterThanOrEqual(0, $value);
61 self::assertLessThanOrEqual(255, $value);
62 }
63
64 #[Test]
65 public function testGenerateTinyIntOneAsBoolean(): void
66 {
67 $faker = Factory::create();
68 $faker->seed(12345);
69 $mapper = new MySqlTypeMapper();
70
71 $column = new ColumnDefinition('col', 'TINYINT', length: 1, nullable: false);
72 $value = $mapper->generate($faker, $column);
73
74 self::assertIsBool($value);
75 }
76
77 #[Test]
78 public function testGenerateInt(): void
79 {
80 $faker = Factory::create();
81 $faker->seed(12345);
82 $mapper = new MySqlTypeMapper();
83
84 $column = new ColumnDefinition('col', 'INT', nullable: false);
85 $value = $mapper->generate($faker, $column);
86
87 self::assertIsInt($value);
88 }
89
90 #[Test]
91 public function testGenerateDecimal(): void
92 {
93 $faker = Factory::create();
94 $faker->seed(12345);
95 $mapper = new MySqlTypeMapper();
96
97 $column = new ColumnDefinition('col', 'DECIMAL', precision: 10, scale: 2, nullable: false);
98 $value = $mapper->generate($faker, $column);
99
100 self::assertIsFloat($value);
101 }
102
103 #[Test]
104 public function testGenerateVarchar(): void
105 {
106 $faker = Factory::create();
107 $faker->seed(12345);
108 $mapper = new MySqlTypeMapper();
109
110 $column = new ColumnDefinition('col', 'VARCHAR', length: 100, nullable: false);
111 $value = $mapper->generate($faker, $column);
112
113 self::assertIsString($value);
114 self::assertLessThanOrEqual(100, strlen($value));
115 }
116
117 #[Test]
118 public function testGenerateChar(): void
119 {
120 $faker = Factory::create();
121 $faker->seed(12345);
122 $mapper = new MySqlTypeMapper();
123
124 $column = new ColumnDefinition('col', 'CHAR', length: 5, nullable: false);
125 $value = $mapper->generate($faker, $column);
126
127 self::assertIsString($value);
128 self::assertSame(5, strlen($value));
129 }
130
131 #[Test]
132 public function testGenerateDate(): void
133 {
134 $faker = Factory::create();
135 $faker->seed(12345);
136 $mapper = new MySqlTypeMapper();
137
138 $column = new ColumnDefinition('col', 'DATE', nullable: false);
139 $value = $mapper->generate($faker, $column);
140
141 self::assertIsString($value);
142 self::assertMatchesRegularExpression('/^\d{4}-\d{2}-\d{2}$/', $value);
143 }
144
145 #[Test]
146 public function testGenerateTime(): void
147 {
148 $faker = Factory::create();
149 $faker->seed(12345);
150 $mapper = new MySqlTypeMapper();
151
152 $column = new ColumnDefinition('col', 'TIME', nullable: false);
153 $value = $mapper->generate($faker, $column);
154
155 self::assertIsString($value);
156 self::assertMatchesRegularExpression('/^\d{2}:\d{2}:\d{2}$/', $value);
157 }
158
159 #[Test]
160 public function testGenerateDatetime(): void
161 {
162 $faker = Factory::create();
163 $faker->seed(12345);
164 $mapper = new MySqlTypeMapper();
165
166 $column = new ColumnDefinition('col', 'DATETIME', nullable: false);
167 $value = $mapper->generate($faker, $column);
168
169 self::assertIsString($value);
170 self::assertMatchesRegularExpression('/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/', $value);
171 }
172
173 #[Test]
174 public function testGenerateTimestamp(): void
175 {
176 $faker = Factory::create();
177 $faker->seed(12345);
178 $mapper = new MySqlTypeMapper();
179
180 $column = new ColumnDefinition('col', 'TIMESTAMP', nullable: false);
181 $value = $mapper->generate($faker, $column);
182
183 self::assertIsString($value);
184 $timestamp = strtotime($value);
185 self::assertGreaterThanOrEqual(strtotime('1970-01-01'), $timestamp);
186 self::assertLessThanOrEqual(strtotime('2038-01-19'), $timestamp);
187 }
188
189 #[Test]
190 public function testGenerateYear(): void
191 {
192 $faker = Factory::create();
193 $faker->seed(12345);
194 $mapper = new MySqlTypeMapper();
195
196 $column = new ColumnDefinition('col', 'YEAR', nullable: false);
197 $value = $mapper->generate($faker, $column);
198
199 self::assertIsInt($value);
200 self::assertGreaterThanOrEqual(1901, $value);
201 self::assertLessThanOrEqual(2155, $value);
202 }
203
204 #[Test]
205 public function testGenerateEnum(): void
206 {
207 $faker = Factory::create();
208 $faker->seed(12345);
209 $mapper = new MySqlTypeMapper();
210
211 $column = new ColumnDefinition('col', 'ENUM', enumValues: ['a', 'b', 'c'], nullable: false);
212 $value = $mapper->generate($faker, $column);
213
214 self::assertIsString($value);
215 self::assertContains($value, ['a', 'b', 'c']);
216 }
217
218 #[Test]
219 public function testGenerateSet(): void
220 {
221 $faker = Factory::create();
222 $faker->seed(12345);
223 $mapper = new MySqlTypeMapper();
224
225 $column = new ColumnDefinition('col', 'SET', enumValues: ['x', 'y', 'z'], nullable: false);
226 $value = $mapper->generate($faker, $column);
227
228 self::assertIsString($value);
229 $parts = explode(',', $value);
230 array_walk($parts, static function (string $part): void {
231 self::assertContains($part, ['x', 'y', 'z']);
232 });
233 }
234
235 #[Test]
236 public function testGenerateJson(): void
237 {
238 $faker = Factory::create();
239 $faker->seed(12345);
240 $mapper = new MySqlTypeMapper();
241
242 $column = new ColumnDefinition('col', 'JSON', nullable: false);
243 $value = $mapper->generate($faker, $column);
244
245 self::assertIsString($value);
246 $decoded = json_decode($value, true);
247 self::assertIsArray($decoded);
248 self::assertArrayHasKey('key', $decoded);
249 self::assertArrayHasKey('value', $decoded);
250 }
251
252 #[Test]
253 public function testGeneratePoint(): void
254 {
255 $faker = Factory::create();
256 $faker->seed(12345);
257 $mapper = new MySqlTypeMapper();
258
259 $column = new ColumnDefinition('col', 'POINT', nullable: false);
260 $value = $mapper->generate($faker, $column);
261
262 self::assertIsString($value);
263 self::assertStringStartsWith('POINT(', $value);
264 }
265
266 #[Test]
267 public function testGenerateAutoIncrementReturnsNull(): void
268 {
269 $faker = Factory::create();
270 $faker->seed(12345);
271 $mapper = new MySqlTypeMapper();
272
273 $column = new ColumnDefinition('id', 'INT', autoIncrement: true, nullable: false);
274 $value = $mapper->generate($faker, $column);
275
276 self::assertNull($value);
277 }
278
279 #[Test]
280 public function testGenerateGeneratedColumnReturnsNull(): void
281 {
282 $faker = Factory::create();
283 $faker->seed(12345);
284 $mapper = new MySqlTypeMapper();
285
286 $column = new ColumnDefinition('computed', 'INT', generated: true, nullable: false);
287 $value = $mapper->generate($faker, $column);
288
289 self::assertNull($value);
290 }
291
292 #[Test]
293 public function testGenerateBit(): void
294 {
295 $faker = Factory::create();
296 $faker->seed(12345);
297 $mapper = new MySqlTypeMapper();
298
299 $column = new ColumnDefinition('col', 'BIT', length: 8, nullable: false);
300 $value = $mapper->generate($faker, $column);
301
302 self::assertIsInt($value);
303 self::assertGreaterThanOrEqual(0, $value);
304 self::assertLessThanOrEqual(255, $value);
305 }
306
307 #[Test]
308 public function testGenerateBinary(): void
309 {
310 $faker = Factory::create();
311 $faker->seed(12345);
312 $mapper = new MySqlTypeMapper();
313
314 $column = new ColumnDefinition('col', 'BINARY', length: 16, nullable: false);
315 $value = $mapper->generate($faker, $column);
316
317 self::assertIsString($value);
318 self::assertSame(16, strlen($value));
319 }
320
321 #[Test]
322 public function testGenerateBlob(): void
323 {
324 $faker = Factory::create();
325 $faker->seed(12345);
326 $mapper = new MySqlTypeMapper();
327
328 $column = new ColumnDefinition('col', 'BLOB', nullable: false);
329 $value = $mapper->generate($faker, $column);
330
331 self::assertIsString($value);
332 self::assertGreaterThan(0, strlen($value));
333 }
334
335 #[Test]
336 public function testGenerateText(): void
337 {
338 $faker = Factory::create();
339 $faker->seed(12345);
340 $mapper = new MySqlTypeMapper();
341
342 $column = new ColumnDefinition('col', 'TEXT', nullable: false);
343 $value = $mapper->generate($faker, $column);
344
345 self::assertIsString($value);
346 self::assertGreaterThan(0, strlen($value));
347 }
348
349 #[Test]
350 public function testGenerateSmallInt(): void
351 {
352 $faker = Factory::create();
353 $faker->seed(12345);
354 $mapper = new MySqlTypeMapper();
355
356 $column = new ColumnDefinition('col', 'SMALLINT', nullable: false);
357 $value = $mapper->generate($faker, $column);
358
359 self::assertIsInt($value);
360 self::assertGreaterThanOrEqual(-32768, $value);
361 self::assertLessThanOrEqual(32767, $value);
362 }
363
364 #[Test]
365 public function testGenerateSmallIntUnsigned(): void
366 {
367 $faker = Factory::create();
368 $faker->seed(12345);
369 $mapper = new MySqlTypeMapper();
370
371 $column = new ColumnDefinition('col', 'SMALLINT', unsigned: true, nullable: false);
372 $value = $mapper->generate($faker, $column);
373
374 self::assertIsInt($value);
375 self::assertGreaterThanOrEqual(0, $value);
376 self::assertLessThanOrEqual(65535, $value);
377 }
378
379 #[Test]
380 public function testGenerateMediumInt(): void
381 {
382 $faker = Factory::create();
383 $faker->seed(12345);
384 $mapper = new MySqlTypeMapper();
385
386 $column = new ColumnDefinition('col', 'MEDIUMINT', nullable: false);
387 $value = $mapper->generate($faker, $column);
388
389 self::assertIsInt($value);
390 self::assertGreaterThanOrEqual(-8388608, $value);
391 self::assertLessThanOrEqual(8388607, $value);
392 }
393
394 #[Test]
395 public function testGenerateMediumIntUnsigned(): void
396 {
397 $faker = Factory::create();
398 $faker->seed(12345);
399 $mapper = new MySqlTypeMapper();
400
401 $column = new ColumnDefinition('col', 'MEDIUMINT', unsigned: true, nullable: false);
402 $value = $mapper->generate($faker, $column);
403
404 self::assertIsInt($value);
405 self::assertGreaterThanOrEqual(0, $value);
406 self::assertLessThanOrEqual(16777215, $value);
407 }
408
409 #[Test]
410 public function testGenerateIntUnsigned(): void
411 {
412 $faker = Factory::create();
413 $faker->seed(12345);
414 $mapper = new MySqlTypeMapper();
415
416 $column = new ColumnDefinition('col', 'INT', unsigned: true, nullable: false);
417 $value = $mapper->generate($faker, $column);
418
419 self::assertIsInt($value);
420 self::assertGreaterThanOrEqual(0, $value);
421 }
422
423 #[Test]
424 public function testGenerateBigInt(): void
425 {
426 $faker = Factory::create();
427 $faker->seed(12345);
428 $mapper = new MySqlTypeMapper();
429
430 $column = new ColumnDefinition('col', 'BIGINT', nullable: false);
431 $value = $mapper->generate($faker, $column);
432
433 self::assertIsInt($value);
434 }
435
436 #[Test]
437 public function testGenerateBigIntUnsigned(): void
438 {
439 $faker = Factory::create();
440 $faker->seed(12345);
441 $mapper = new MySqlTypeMapper();
442
443 $column = new ColumnDefinition('col', 'BIGINT', unsigned: true, nullable: false);
444 $value = $mapper->generate($faker, $column);
445
446 self::assertIsInt($value);
447 self::assertGreaterThanOrEqual(0, $value);
448 }
449
450 #[Test]
451 public function testGenerateFloat(): void
452 {
453 $faker = Factory::create();
454 $faker->seed(12345);
455 $mapper = new MySqlTypeMapper();
456
457 $column = new ColumnDefinition('col', 'FLOAT', nullable: false);
458 $value = $mapper->generate($faker, $column);
459
460 self::assertIsFloat($value);
461 }
462
463 #[Test]
464 public function testGenerateDouble(): void
465 {
466 $faker = Factory::create();
467 $faker->seed(12345);
468 $mapper = new MySqlTypeMapper();
469
470 $column = new ColumnDefinition('col', 'DOUBLE', nullable: false);
471 $value = $mapper->generate($faker, $column);
472
473 self::assertIsFloat($value);
474 }
475
476 #[Test]
477 public function testGenerateDecimalUnsigned(): void
478 {
479 $faker = Factory::create();
480 $faker->seed(12345);
481 $mapper = new MySqlTypeMapper();
482
483 $column = new ColumnDefinition('col', 'DECIMAL', precision: 10, scale: 2, unsigned: true, nullable: false);
484 $value = $mapper->generate($faker, $column);
485
486 self::assertIsFloat($value);
487 self::assertGreaterThanOrEqual(0, $value);
488 }
489
490 #[Test]
491 public function testGenerateTinyText(): void
492 {
493 $faker = Factory::create();
494 $faker->seed(12345);
495 $mapper = new MySqlTypeMapper();
496
497 $column = new ColumnDefinition('col', 'TINYTEXT', nullable: false);
498 $value = $mapper->generate($faker, $column);
499
500 self::assertIsString($value);
501 self::assertLessThanOrEqual(255, strlen($value));
502 }
503
504 #[Test]
505 public function testGenerateMediumText(): void
506 {
507 $faker = Factory::create();
508 $faker->seed(12345);
509 $mapper = new MySqlTypeMapper();
510
511 $column = new ColumnDefinition('col', 'MEDIUMTEXT', nullable: false);
512 $value = $mapper->generate($faker, $column);
513
514 self::assertIsString($value);
515 }
516
517 #[Test]
518 public function testGenerateLongText(): void
519 {
520 $faker = Factory::create();
521 $faker->seed(12345);
522 $mapper = new MySqlTypeMapper();
523
524 $column = new ColumnDefinition('col', 'LONGTEXT', nullable: false);
525 $value = $mapper->generate($faker, $column);
526
527 self::assertIsString($value);
528 }
529
530 #[Test]
531 public function testGenerateVarbinary(): void
532 {
533 $faker = Factory::create();
534 $faker->seed(12345);
535 $mapper = new MySqlTypeMapper();
536
537 $column = new ColumnDefinition('col', 'VARBINARY', length: 100, nullable: false);
538 $value = $mapper->generate($faker, $column);
539
540 self::assertIsString($value);
541 self::assertLessThanOrEqual(100, strlen($value));
542 }
543
544 #[Test]
545 public function testGenerateTinyBlob(): void
546 {
547 $faker = Factory::create();
548 $faker->seed(12345);
549 $mapper = new MySqlTypeMapper();
550
551 $column = new ColumnDefinition('col', 'TINYBLOB', nullable: false);
552 $value = $mapper->generate($faker, $column);
553
554 self::assertIsString($value);
555 }
556
557 #[Test]
558 public function testGenerateMediumBlob(): void
559 {
560 $faker = Factory::create();
561 $faker->seed(12345);
562 $mapper = new MySqlTypeMapper();
563
564 $column = new ColumnDefinition('col', 'MEDIUMBLOB', nullable: false);
565 $value = $mapper->generate($faker, $column);
566
567 self::assertIsString($value);
568 }
569
570 #[Test]
571 public function testGenerateLongBlob(): void
572 {
573 $faker = Factory::create();
574 $faker->seed(12345);
575 $mapper = new MySqlTypeMapper();
576
577 $column = new ColumnDefinition('col', 'LONGBLOB', nullable: false);
578 $value = $mapper->generate($faker, $column);
579
580 self::assertIsString($value);
581 }
582
583 #[Test]
584 public function testGenerateEnumEmpty(): void
585 {
586 $faker = Factory::create();
587 $faker->seed(12345);
588 $mapper = new MySqlTypeMapper();
589
590 $column = new ColumnDefinition('col', 'ENUM', enumValues: [], nullable: false);
591 $value = $mapper->generate($faker, $column);
592
593 self::assertNull($value);
594 }
595
596 #[Test]
597 public function testGenerateSetEmpty(): void
598 {
599 $faker = Factory::create();
600 $faker->seed(12345);
601 $mapper = new MySqlTypeMapper();
602
603 $column = new ColumnDefinition('col', 'SET', enumValues: [], nullable: false);
604 $value = $mapper->generate($faker, $column);
605
606 self::assertNull($value);
607 }
608
609 #[Test]
610 public function testGenerateLineString(): void
611 {
612 $faker = Factory::create();
613 $faker->seed(12345);
614 $mapper = new MySqlTypeMapper();
615
616 $column = new ColumnDefinition('col', 'LINESTRING', nullable: false);
617 $value = $mapper->generate($faker, $column);
618
619 self::assertIsString($value);
620 self::assertStringStartsWith('LINESTRING(', $value);
621 }
622
623 #[Test]
624 public function testGeneratePolygon(): void
625 {
626 $faker = Factory::create();
627 $faker->seed(12345);
628 $mapper = new MySqlTypeMapper();
629
630 $column = new ColumnDefinition('col', 'POLYGON', nullable: false);
631 $value = $mapper->generate($faker, $column);
632
633 self::assertIsString($value);
634 self::assertStringStartsWith('POLYGON((', $value);
635 }
636
637 #[Test]
638 public function testGenerateMultiPoint(): void
639 {
640 $faker = Factory::create();
641 $faker->seed(12345);
642 $mapper = new MySqlTypeMapper();
643
644 $column = new ColumnDefinition('col', 'MULTIPOINT', nullable: false);
645 $value = $mapper->generate($faker, $column);
646
647 self::assertIsString($value);
648 self::assertStringStartsWith('MULTIPOINT(', $value);
649 }
650
651 #[Test]
652 public function testGenerateMultiLineString(): void
653 {
654 $faker = Factory::create();
655 $faker->seed(12345);
656 $mapper = new MySqlTypeMapper();
657
658 $column = new ColumnDefinition('col', 'MULTILINESTRING', nullable: false);
659 $value = $mapper->generate($faker, $column);
660
661 self::assertIsString($value);
662 self::assertStringStartsWith('MULTILINESTRING(', $value);
663 }
664
665 #[Test]
666 public function testGenerateMultiPolygon(): void
667 {
668 $faker = Factory::create();
669 $faker->seed(12345);
670 $mapper = new MySqlTypeMapper();
671
672 $column = new ColumnDefinition('col', 'MULTIPOLYGON', nullable: false);
673 $value = $mapper->generate($faker, $column);
674
675 self::assertIsString($value);
676 self::assertStringStartsWith('MULTIPOLYGON(', $value);
677 }
678
679 #[Test]
680 public function testGenerateGeometry(): void
681 {
682 $faker = Factory::create();
683 $faker->seed(12345);
684 $mapper = new MySqlTypeMapper();
685
686 $column = new ColumnDefinition('col', 'GEOMETRY', nullable: false);
687 $value = $mapper->generate($faker, $column);
688
689 self::assertIsString($value);
690 self::assertStringStartsWith('POINT(', $value);
691 }
692
693 #[Test]
694 public function testGenerateGeometryCollection(): void
695 {
696 $faker = Factory::create();
697 $faker->seed(12345);
698 $mapper = new MySqlTypeMapper();
699
700 $column = new ColumnDefinition('col', 'GEOMETRYCOLLECTION', nullable: false);
701 $value = $mapper->generate($faker, $column);
702
703 self::assertIsString($value);
704 self::assertStringStartsWith('GEOMETRYCOLLECTION(', $value);
705 }
706
707 #[Test]
708 public function testGenerateBoolean(): void
709 {
710 $faker = Factory::create();
711 $faker->seed(12345);
712 $mapper = new MySqlTypeMapper();
713
714 $column = new ColumnDefinition('col', 'BOOLEAN', nullable: false);
715 $value = $mapper->generate($faker, $column);
716
717 self::assertIsBool($value);
718 }
719
720 #[Test]
721 public function testGenerateBool(): void
722 {
723 $faker = Factory::create();
724 $faker->seed(12345);
725 $mapper = new MySqlTypeMapper();
726
727 $column = new ColumnDefinition('col', 'BOOL', nullable: false);
728 $value = $mapper->generate($faker, $column);
729
730 self::assertIsBool($value);
731 }
732
733 #[Test]
734 public function testGenerateReal(): void
735 {
736 $faker = Factory::create();
737 $faker->seed(12345);
738 $mapper = new MySqlTypeMapper();
739
740 $column = new ColumnDefinition('col', 'REAL', nullable: false);
741 $value = $mapper->generate($faker, $column);
742
743 self::assertIsFloat($value);
744 }
745
746 #[Test]
747 public function testGenerateNumeric(): void
748 {
749 $faker = Factory::create();
750 $faker->seed(12345);
751 $mapper = new MySqlTypeMapper();
752
753 $column = new ColumnDefinition('col', 'NUMERIC', precision: 8, scale: 2, nullable: false);
754 $value = $mapper->generate($faker, $column);
755
756 self::assertIsFloat($value);
757 }
758
759 #[Test]
760 public function testGenerateInteger(): void
761 {
762 $faker = Factory::create();
763 $faker->seed(12345);
764 $mapper = new MySqlTypeMapper();
765
766 $column = new ColumnDefinition('col', 'INTEGER', nullable: false);
767 $value = $mapper->generate($faker, $column);
768
769 self::assertIsInt($value);
770 }
771
772 #[Test]
773 public function testGenerateUnknownType(): void
774 {
775 $faker = Factory::create();
776 $faker->seed(12345);
777 $mapper = new MySqlTypeMapper();
778
779 $column = new ColumnDefinition('col', 'UNKNOWN_TYPE', nullable: false);
780 $value = $mapper->generate($faker, $column);
781
782 self::assertIsString($value);
783 }
784
785 #[Test]
786 public function testGenerateNullableWithDefaultNull(): void
787 {
788 $faker = Factory::create();
789 $faker->seed(12345);
790 $mapper = new MySqlTypeMapper();
791
792 $column = new ColumnDefinition('col', 'INT', nullable: true, default: null);
793
794 [$hasNull, $hasValue] = (static function () use ($faker, $mapper, $column): array {
795 $hasNull = false;
796 $hasValue = false;
797 for ($i = 0; $i < 100; $i++) {
798 $value = $mapper->generate($faker, $column);
799 if ($value === null) {
800 $hasNull = true;
801 } else {
802 $hasValue = true;
803 self::assertIsInt($value);
804 }
805 if ($hasNull && $hasValue) {
806 break;
807 }
808 }
809
810 return [$hasNull, $hasValue];
811 })();
812
813 self::assertTrue($hasNull, 'Expected at least one null value in 100 iterations');
814 self::assertTrue($hasValue, 'Expected at least one non-null value in 100 iterations');
815 }
816
817 #[Test]
818 public function testGenerateNonNullableNeverReturnsNull(): void
819 {
820 $faker = Factory::create();
821 $faker->seed(12345);
822 $mapper = new MySqlTypeMapper();
823
824 $column = new ColumnDefinition('col', 'INT', nullable: false);
825
826 (static function () use ($faker, $mapper, $column): void {
827 for ($i = 0; $i < 50; $i++) {
828 $value = $mapper->generate($faker, $column);
829 self::assertNotNull($value, 'Non-nullable column should never return null');
830 self::assertIsInt($value);
831 }
832 })();
833 }
834
835 #[Test]
836 public function testGenerateDecimalBoundaryValues(): void
837 {
838 $faker = Factory::create();
839 $faker->seed(12345);
840 $mapper = new MySqlTypeMapper();
841
842 $column = new ColumnDefinition('col', 'DECIMAL', precision: 5, scale: 2, nullable: false);
843
844 (static function () use ($faker, $mapper, $column): void {
845 for ($i = 0; $i < 50; $i++) {
846 $value = $mapper->generate($faker, $column);
847 self::assertIsFloat($value);
848 self::assertGreaterThanOrEqual(-999.99, $value);
849 self::assertLessThanOrEqual(999.99, $value);
850 }
851 })();
852 }
853
854 #[Test]
855 public function testGenerateIntBoundaryValues(): void
856 {
857 $faker = Factory::create();
858 $faker->seed(12345);
859 $mapper = new MySqlTypeMapper();
860
861 $column = new ColumnDefinition('col', 'INT', nullable: false);
862
863 (static function () use ($faker, $mapper, $column): void {
864 for ($i = 0; $i < 50; $i++) {
865 $value = $mapper->generate($faker, $column);
866 self::assertIsInt($value);
867 self::assertGreaterThanOrEqual(-2147483648, $value);
868 self::assertLessThanOrEqual(2147483647, $value);
869 }
870 })();
871 }
872
873 #[Test]
874 public function testGenerateIntUnsignedBoundaryValues(): void
875 {
876 $faker = Factory::create();
877 $faker->seed(12345);
878 $mapper = new MySqlTypeMapper();
879
880 $column = new ColumnDefinition('col', 'INT', unsigned: true, nullable: false);
881
882 (static function () use ($faker, $mapper, $column): void {
883 for ($i = 0; $i < 50; $i++) {
884 $value = $mapper->generate($faker, $column);
885 self::assertIsInt($value);
886 self::assertGreaterThanOrEqual(0, $value);
887 self::assertLessThanOrEqual(4294967295, $value);
888 }
889 })();
890 }
891
892 #[Test]
893 public function testGenerateVarcharRespectsLength(): void
894 {
895 $faker = Factory::create();
896 $faker->seed(12345);
897 $mapper = new MySqlTypeMapper();
898
899 $column = new ColumnDefinition('col', 'VARCHAR', length: 10, nullable: false);
900
901 (static function () use ($faker, $mapper, $column): void {
902 for ($i = 0; $i < 20; $i++) {
903 $value = $mapper->generate($faker, $column);
904 self::assertIsString($value);
905 self::assertLessThanOrEqual(10, strlen($value));
906 self::assertGreaterThan(0, strlen($value));
907 }
908 })();
909 }
910
911 #[Test]
912 public function testGenerateBitBoundaryValues(): void
913 {
914 $faker = Factory::create();
915 $faker->seed(12345);
916 $mapper = new MySqlTypeMapper();
917
918 $column1 = new ColumnDefinition('col', 'BIT', length: 1, nullable: false);
919 $value = $mapper->generate($faker, $column1);
920 self::assertIsInt($value);
921 self::assertGreaterThanOrEqual(0, $value);
922 self::assertLessThanOrEqual(1, $value);
923
924 $column16 = new ColumnDefinition('col', 'BIT', length: 16, nullable: false);
925 (static function () use ($faker, $mapper, $column16): void {
926 for ($i = 0; $i < 20; $i++) {
927 $value = $mapper->generate($faker, $column16);
928 self::assertIsInt($value);
929 self::assertGreaterThanOrEqual(0, $value);
930 self::assertLessThanOrEqual(65535, $value);
931 }
932 })();
933 }
934
935 #[Test]
936 public function testGenerateYearBoundary(): void
937 {
938 $faker = Factory::create();
939 $faker->seed(12345);
940 $mapper = new MySqlTypeMapper();
941
942 $column = new ColumnDefinition('col', 'YEAR', nullable: false);
943
944 (static function () use ($faker, $mapper, $column): void {
945 for ($i = 0; $i < 50; $i++) {
946 $value = $mapper->generate($faker, $column);
947 self::assertIsInt($value);
948 self::assertGreaterThanOrEqual(1901, $value);
949 self::assertLessThanOrEqual(2155, $value);
950 }
951 })();
952 }
953}
954