MigrationTest.php 9.1 KB

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