MigrationGeneratorTest.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. <?php
  2. declare(strict_types=1);
  3. namespace SixShop\MakerBundle\Tests\Unit\Generator;
  4. use PHPUnit\Framework\TestCase;
  5. use SixShop\MakerBundle\Generator\MigrationGenerator;
  6. /**
  7. * Unit tests for MigrationGenerator
  8. */
  9. class MigrationGeneratorTest extends TestCase
  10. {
  11. private MigrationGenerator $generator;
  12. private string $testDir;
  13. protected function setUp(): void
  14. {
  15. $this->testDir = sys_get_temp_dir() . '/sixshop_test_' . uniqid();
  16. if (!is_dir($this->testDir)) {
  17. mkdir($this->testDir, 0755, true);
  18. }
  19. $this->generator = new MigrationGenerator($this->testDir);
  20. }
  21. protected function tearDown(): void
  22. {
  23. if (is_dir($this->testDir)) {
  24. $this->removeDirectory($this->testDir);
  25. }
  26. }
  27. private function removeDirectory(string $dir): void
  28. {
  29. if (is_dir($dir)) {
  30. $files = array_diff(scandir($dir), ['.', '..']);
  31. foreach ($files as $file) {
  32. $path = $dir . DIRECTORY_SEPARATOR . $file;
  33. is_dir($path) ? $this->removeDirectory($path) : unlink($path);
  34. }
  35. rmdir($dir);
  36. }
  37. }
  38. public function testConstructorSetsCorrectPath(): void
  39. {
  40. $this->assertEquals($this->testDir, $this->generator->getMigrationsPath());
  41. }
  42. public function testGetSupportedFieldTypes(): void
  43. {
  44. $supportedTypes = $this->generator->getSupportedFieldTypes();
  45. $expectedTypes = [
  46. 'integer', 'biginteger', 'string', 'text', 'boolean',
  47. 'decimal', 'float', 'datetime', 'timestamp', 'date',
  48. 'time', 'binary', 'json'
  49. ];
  50. foreach ($expectedTypes as $type) {
  51. $this->assertContains($type, $supportedTypes);
  52. }
  53. }
  54. public function testGenerateCreateTableMigration(): void
  55. {
  56. $tableName = 'test_users';
  57. $fields = [
  58. [
  59. 'name' => 'id',
  60. 'type' => 'biginteger',
  61. 'null' => false,
  62. 'comment' => 'Primary key'
  63. ],
  64. [
  65. 'name' => 'username',
  66. 'type' => 'string',
  67. 'length' => 100,
  68. 'null' => false,
  69. 'unique' => true,
  70. 'comment' => 'User login name'
  71. ],
  72. [
  73. 'name' => 'email',
  74. 'type' => 'string',
  75. 'length' => 255,
  76. 'null' => false,
  77. 'unique' => true,
  78. 'comment' => 'User email address'
  79. ]
  80. ];
  81. $result = $this->generator->generateMigration($tableName, $fields, 'create');
  82. $this->assertTrue($result);
  83. // Check if migration file was created
  84. $files = glob($this->testDir . '/*_create_test_users_table.php');
  85. $this->assertCount(1, $files);
  86. // Check migration content
  87. $migrationFile = $files[0];
  88. $content = file_get_contents($migrationFile);
  89. $this->assertStringContainsString('class CreateTestUsersTable', $content);
  90. $this->assertStringContainsString('$table = $this->table(\'test_users\')', $content);
  91. $this->assertStringContainsString('username', $content);
  92. $this->assertStringContainsString('email', $content);
  93. }
  94. public function testGenerateAddColumnMigration(): void
  95. {
  96. $tableName = 'test_users';
  97. $fields = [
  98. [
  99. 'name' => 'phone',
  100. 'type' => 'string',
  101. 'length' => 20,
  102. 'null' => true,
  103. 'comment' => 'User phone number'
  104. ]
  105. ];
  106. $result = $this->generator->generateMigration($tableName, $fields, 'add_column');
  107. $this->assertTrue($result);
  108. // Check if migration file was created
  109. $files = glob($this->testDir . '/*_add_column_to_test_users_table.php');
  110. $this->assertCount(1, $files);
  111. // Check migration content
  112. $migrationFile = $files[0];
  113. $content = file_get_contents($migrationFile);
  114. $this->assertStringContainsString('class AddColumnToTestUsersTable', $content);
  115. $this->assertStringContainsString('phone', $content);
  116. }
  117. public function testGenerateDropColumnMigration(): void
  118. {
  119. $tableName = 'test_users';
  120. $fields = [
  121. ['name' => 'deprecated_field']
  122. ];
  123. $result = $this->generator->generateMigration($tableName, $fields, 'drop_column');
  124. $this->assertTrue($result);
  125. // Check if migration file was created
  126. $files = glob($this->testDir . '/*_drop_column_from_test_users_table.php');
  127. $this->assertCount(1, $files);
  128. // Check migration content
  129. $migrationFile = $files[0];
  130. $content = file_get_contents($migrationFile);
  131. $this->assertStringContainsString('class DropColumnFromTestUsersTable', $content);
  132. $this->assertStringContainsString('deprecated_field', $content);
  133. }
  134. public function testDecimalFieldOptions(): void
  135. {
  136. $tableName = 'test_products';
  137. $fields = [
  138. [
  139. 'name' => 'price',
  140. 'type' => 'decimal',
  141. 'precision' => 10,
  142. 'scale' => 2,
  143. 'null' => false,
  144. 'comment' => 'Product price'
  145. ]
  146. ];
  147. $result = $this->generator->generateMigration($tableName, $fields, 'create');
  148. $this->assertTrue($result);
  149. // Check migration content for decimal precision and scale
  150. $files = glob($this->testDir . '/*_create_test_products_table.php');
  151. $this->assertCount(1, $files);
  152. $migrationFile = $files[0];
  153. $content = file_get_contents($migrationFile);
  154. $this->assertStringContainsString('\'precision\' => 10', $content);
  155. $this->assertStringContainsString('\'scale\' => 2', $content);
  156. }
  157. public function testJsonFieldType(): void
  158. {
  159. $tableName = 'test_settings';
  160. $fields = [
  161. [
  162. 'name' => 'config_data',
  163. 'type' => 'json',
  164. 'null' => true,
  165. 'comment' => 'Configuration JSON data'
  166. ]
  167. ];
  168. $result = $this->generator->generateMigration($tableName, $fields, 'create');
  169. $this->assertTrue($result);
  170. // Check migration content for JSON field
  171. $files = glob($this->testDir . '/*_create_test_settings_table.php');
  172. $this->assertCount(1, $files);
  173. $migrationFile = $files[0];
  174. $content = file_get_contents($migrationFile);
  175. $this->assertStringContainsString('config_data', $content);
  176. $this->assertStringContainsString('json', $content);
  177. }
  178. public function testMigrationPathCreation(): void
  179. {
  180. $newPath = sys_get_temp_dir() . '/sixshop_new_path_' . uniqid();
  181. $generator = new MigrationGenerator($newPath);
  182. $fields = [['name' => 'test_field', 'type' => 'string']];
  183. $result = $generator->generateMigration('test_table', $fields, 'create');
  184. $this->assertTrue($result);
  185. $this->assertTrue(is_dir($newPath));
  186. // Cleanup
  187. $this->removeDirectory($newPath);
  188. }
  189. public function testInvalidActionType(): void
  190. {
  191. $tableName = 'test_table';
  192. $fields = [['name' => 'test_field', 'type' => 'string']];
  193. $result = $this->generator->generateMigration($tableName, $fields, 'invalid_action');
  194. // Should handle gracefully and return false or throw exception
  195. $this->assertFalse($result);
  196. }
  197. }