MigrationTest.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. <?php
  2. namespace Test\PhpDevCommunity\PaperORM;
  3. use PhpDevCommunity\PaperORM\Driver\MariaDBDriver;
  4. use PhpDevCommunity\PaperORM\Driver\SqliteDriver;
  5. use PhpDevCommunity\PaperORM\EntityManager;
  6. use PhpDevCommunity\PaperORM\Mapper\ColumnMapper;
  7. use PhpDevCommunity\PaperORM\Mapping\Column\IntColumn;
  8. use PhpDevCommunity\PaperORM\Mapping\Column\StringColumn;
  9. use PhpDevCommunity\PaperORM\Migration\PaperMigration;
  10. use PhpDevCommunity\PaperORM\PaperConfiguration;
  11. use PhpDevCommunity\UniTester\TestCase;
  12. use RuntimeException;
  13. use Test\PhpDevCommunity\PaperORM\Entity\PostTest;
  14. use Test\PhpDevCommunity\PaperORM\Entity\UserTest;
  15. use Test\PhpDevCommunity\PaperORM\Helper\DataBaseHelperTest;
  16. class MigrationTest extends TestCase
  17. {
  18. private string $migrationDir;
  19. protected function setUp(): void
  20. {
  21. $this->migrationDir = __DIR__ . '/migrations';
  22. $this->tearDown();
  23. }
  24. protected function tearDown(): void
  25. {
  26. $folder = $this->migrationDir;
  27. array_map('unlink', glob("$folder/*.*"));
  28. }
  29. protected function execute(): void
  30. {
  31. foreach (DataBaseHelperTest::drivers() as $params) {
  32. $em = EntityManager::createFromConfig(PaperConfiguration::fromArray($params));
  33. $paperMigration = PaperMigration::create($em, 'mig_versions', $this->migrationDir);
  34. $platform = $em->getPlatform();
  35. $platform->createDatabaseIfNotExists();
  36. $platform->dropDatabase();
  37. $platform->createDatabaseIfNotExists();
  38. $this->testDiff($paperMigration);
  39. $this->testExecute($paperMigration);
  40. $this->testColumnModification($paperMigration);
  41. $this->testFailedMigration($paperMigration);
  42. $em->getConnection()->close();
  43. $this->tearDown();
  44. }
  45. }
  46. private function testDiff(PaperMigration $paperMigration): void
  47. {
  48. $em = $paperMigration->getEntityManager();
  49. $driver = $em->getConnection()->getDriver();
  50. $em->getConnection()->close();
  51. $migrationFile = $paperMigration->generateMigrationFromEntities([
  52. UserTest::class,
  53. PostTest::class
  54. ]);
  55. switch (get_class($driver)) {
  56. case SqliteDriver::class:
  57. $lines = file($migrationFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
  58. $this->assertEquals($lines, array (
  59. 0 => '-- UP MIGRATION --',
  60. 1 => 'CREATE TABLE `user` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,`firstname` VARCHAR(255) NOT NULL,`lastname` VARCHAR(255) NOT NULL,`email` VARCHAR(255) NOT NULL,`password` VARCHAR(255) NOT NULL,`token` VARCHAR(32) NOT NULL,`is_active` BOOLEAN NOT NULL,`created_at` DATETIME,`last_post_id` INTEGER,FOREIGN KEY (`last_post_id`) REFERENCES `post` (id) ON DELETE SET NULL ON UPDATE NO ACTION);',
  61. 2 => 'CREATE UNIQUE INDEX UNIQ_8D93D6495F37A13B ON `user` (`token`);',
  62. 3 => 'CREATE UNIQUE INDEX UNIQ_8D93D6492D053F64 ON `user` (`last_post_id`);',
  63. 4 => 'CREATE TABLE `post` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,`title` VARCHAR(255) NOT NULL,`content` VARCHAR(255) NOT NULL,`slug` VARCHAR(128) NOT NULL,`created_at` DATETIME NOT NULL,`user_id` INTEGER,FOREIGN KEY (`user_id`) REFERENCES `user` (id) ON DELETE SET NULL ON UPDATE NO ACTION);',
  64. 5 => 'CREATE UNIQUE INDEX UNIQ_5A8A6C8D989D9B62 ON `post` (`slug`);',
  65. 6 => 'CREATE INDEX IX_5A8A6C8DA76ED395 ON `post` (`user_id`);',
  66. 7 => '-- DOWN MIGRATION --',
  67. 8 => 'DROP INDEX UNIQ_8D93D6495F37A13B;',
  68. 9 => 'DROP INDEX UNIQ_8D93D6492D053F64;',
  69. 10 => 'DROP TABLE `user`;',
  70. 11 => 'DROP INDEX UNIQ_5A8A6C8D989D9B62;',
  71. 12 => 'DROP INDEX IX_5A8A6C8DA76ED395;',
  72. 13 => 'DROP TABLE `post`;',
  73. ));
  74. break;
  75. case MariaDBDriver::class:
  76. $lines = file($migrationFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
  77. $this->assertEquals($lines, array (
  78. 0 => '-- UP MIGRATION --',
  79. 1 => 'CREATE TABLE `user` (`id` INT(11) AUTO_INCREMENT PRIMARY KEY NOT NULL,`firstname` VARCHAR(255) NOT NULL,`lastname` VARCHAR(255) NOT NULL,`email` VARCHAR(255) NOT NULL,`password` VARCHAR(255) NOT NULL,`token` VARCHAR(32) NOT NULL,`is_active` TINYINT(1) NOT NULL,`created_at` DATETIME DEFAULT NULL,`last_post_id` INT(11) DEFAULT NULL);',
  80. 2 => 'CREATE UNIQUE INDEX UNIQ_8D93D6495F37A13B ON `user` (`token`);',
  81. 3 => 'CREATE UNIQUE INDEX UNIQ_8D93D6492D053F64 ON `user` (`last_post_id`);',
  82. 4 => 'CREATE TABLE `post` (`id` INT(11) AUTO_INCREMENT PRIMARY KEY NOT NULL,`title` VARCHAR(255) NOT NULL,`content` VARCHAR(255) NOT NULL,`slug` VARCHAR(128) NOT NULL,`created_at` DATETIME NOT NULL,`user_id` INT(11) DEFAULT NULL);',
  83. 5 => 'CREATE UNIQUE INDEX UNIQ_5A8A6C8D989D9B62 ON `post` (`slug`);',
  84. 6 => 'CREATE INDEX IX_5A8A6C8DA76ED395 ON `post` (`user_id`);',
  85. 7 => 'ALTER TABLE `user` ADD CONSTRAINT FK_8D93D6492D053F64 FOREIGN KEY (`last_post_id`) REFERENCES `post`(`id`) ON DELETE SET NULL ON UPDATE NO ACTION;',
  86. 8 => 'ALTER TABLE `post` ADD CONSTRAINT FK_5A8A6C8DA76ED395 FOREIGN KEY (`user_id`) REFERENCES `user`(`id`) ON DELETE SET NULL ON UPDATE NO ACTION;',
  87. 9 => '-- DOWN MIGRATION --',
  88. 10 => 'ALTER TABLE `user` DROP FOREIGN KEY FK_8D93D6492D053F64;',
  89. 11 => 'ALTER TABLE `post` DROP FOREIGN KEY FK_5A8A6C8DA76ED395;',
  90. 12 => 'DROP INDEX UNIQ_8D93D6495F37A13B ON `user`;',
  91. 13 => 'DROP INDEX UNIQ_8D93D6492D053F64 ON `user`;',
  92. 14 => 'DROP TABLE `user`;',
  93. 15 => 'DROP INDEX UNIQ_5A8A6C8D989D9B62 ON `post`;',
  94. 16 => 'DROP INDEX IX_5A8A6C8DA76ED395 ON `post`;',
  95. 17 => 'DROP TABLE `post`;',
  96. ));
  97. break;
  98. default:
  99. throw new RuntimeException(sprintf('Driver %s not supported', get_class($driver)));
  100. }
  101. }
  102. private function testExecute(PaperMigration $paperMigration): void
  103. {
  104. $paperMigration->migrate();
  105. $successList = $paperMigration->getSuccessList();
  106. $this->assertTrue(count($successList) === 1);
  107. $migrationFile = $paperMigration->generateMigrationFromEntities([UserTest::class]);
  108. $this->assertNull($migrationFile);
  109. }
  110. private function testColumnModification(PaperMigration $paperMigration): void
  111. {
  112. $em = $paperMigration->getEntityManager();
  113. $driver = $em->getConnection()->getDriver();
  114. $userColumns = ColumnMapper::getColumns(UserTest::class);
  115. $userColumns[3] = (new StringColumn(null, 255, true, null, true))->bindProperty('email');
  116. $userColumns[] = (new IntColumn(null, false, 0))->bindProperty('childs');
  117. $migrationFile = $paperMigration->generateMigrationFromTables([
  118. 'user' => [
  119. 'columns' => $userColumns,
  120. 'indexes' => []
  121. ]
  122. ]);
  123. $paperMigration->migrate();
  124. $successList = $paperMigration->getSuccessList();
  125. $this->assertTrue(count($successList) === 1);
  126. $this->assertEquals(pathinfo($migrationFile, PATHINFO_FILENAME), $successList[0]);
  127. switch (get_class($driver)) {
  128. case SqliteDriver::class:
  129. $schema = $driver->createDatabaseSchema();
  130. $lines = file($migrationFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
  131. if ($schema->supportsDropColumn()) {
  132. $this->assertEquals($lines, array());
  133. } else {
  134. $this->assertEquals($lines, array (
  135. 0 => '-- UP MIGRATION --',
  136. 1 => 'ALTER TABLE `user` ADD `childs` INTEGER NOT NULL DEFAULT 0;',
  137. 2 => 'CREATE UNIQUE INDEX UNIQ_8D93D649E7927C74 ON `user` (`email`);',
  138. 3 => '-- Modify column email is not supported with PhpDevCommunity\\PaperORM\\Schema\\SqliteSchema. Consider creating a new column and migrating the data.;',
  139. 4 => '-- DOWN MIGRATION --',
  140. 5 => '-- Drop column childs is not supported with PhpDevCommunity\\PaperORM\\Schema\\SqliteSchema. You might need to manually drop the column.;',
  141. 6 => 'DROP INDEX UNIQ_8D93D649E7927C74;',
  142. ));
  143. }
  144. break;
  145. case MariaDBDriver::class:
  146. $lines = file($migrationFile, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
  147. $this->assertEquals($lines, array (
  148. 0 => '-- UP MIGRATION --',
  149. 1 => 'ALTER TABLE `user` ADD COLUMN `childs` INT(11) NOT NULL DEFAULT 0;',
  150. 2 => 'CREATE UNIQUE INDEX UNIQ_8D93D649E7927C74 ON `user` (`email`);',
  151. 3 => 'ALTER TABLE `user` MODIFY COLUMN `email` VARCHAR(255) DEFAULT NULL;',
  152. 4 => '-- DOWN MIGRATION --',
  153. 5 => 'ALTER TABLE `user` DROP COLUMN `childs`;',
  154. 6 => 'DROP INDEX UNIQ_8D93D649E7927C74 ON `user`;',
  155. 7 => 'ALTER TABLE `user` MODIFY COLUMN `email` VARCHAR(255) NOT NULL;',
  156. ));
  157. break;
  158. default:
  159. throw new RuntimeException(sprintf('Driver %s not supported', get_class($driver)));
  160. }
  161. }
  162. private function testFailedMigration(PaperMigration $paperMigration): void
  163. {
  164. $paperMigration->generateMigration();
  165. $this->expectException(RuntimeException::class, function () use ($paperMigration) {
  166. $paperMigration->migrate();
  167. });
  168. $successList = $paperMigration->getSuccessList();
  169. $this->assertTrue(count($successList) === 0);
  170. }
  171. }