aboutsummaryrefslogtreecommitdiff
path: root/tests/lib/Minz/MigratorTest.php
diff options
context:
space:
mode:
Diffstat (limited to 'tests/lib/Minz/MigratorTest.php')
-rw-r--r--tests/lib/Minz/MigratorTest.php321
1 files changed, 321 insertions, 0 deletions
diff --git a/tests/lib/Minz/MigratorTest.php b/tests/lib/Minz/MigratorTest.php
new file mode 100644
index 000000000..8f23895aa
--- /dev/null
+++ b/tests/lib/Minz/MigratorTest.php
@@ -0,0 +1,321 @@
+<?php
+
+use PHPUnit\Framework\TestCase;
+
+class Minz_MigratorTest extends TestCase
+{
+ public function testAddMigration() {
+ $migrator = new Minz_Migrator();
+
+ $migrator->addMigration('foo', function () {
+ return true;
+ });
+
+ $migrations = $migrator->migrations();
+ $this->assertArrayHasKey('foo', $migrations);
+ $result = $migrations['foo']();
+ $this->assertTrue($result);
+ }
+
+ public function testAddMigrationFailsIfUncallableMigration() {
+ $this->expectException(BadFunctionCallException::class);
+ $this->expectExceptionMessage('foo migration cannot be called.');
+
+ $migrator = new Minz_Migrator();
+ $migrator->addMigration('foo', null);
+ }
+
+ public function testMigrationsIsSorted() {
+ $migrator = new Minz_Migrator();
+ $migrator->addMigration('2_foo', function () {
+ return true;
+ });
+ $migrator->addMigration('10_foo', function () {
+ return true;
+ });
+ $migrator->addMigration('1_foo', function () {
+ return true;
+ });
+ $expected_versions = ['1_foo', '2_foo', '10_foo'];
+
+ $migrations = $migrator->migrations();
+
+ $this->assertSame($expected_versions, array_keys($migrations));
+ }
+
+ public function testSetAppliedVersions() {
+ $migrator = new Minz_Migrator();
+ $migrator->addMigration('foo', function () {
+ return true;
+ });
+
+ $migrator->setAppliedVersions(['foo']);
+
+ $this->assertSame(['foo'], $migrator->appliedVersions());
+ }
+
+ public function testSetAppliedVersionsTrimArgument() {
+ $migrator = new Minz_Migrator();
+ $migrator->addMigration('foo', function () {
+ return true;
+ });
+
+ $migrator->setAppliedVersions(["foo\n"]);
+
+ $this->assertSame(['foo'], $migrator->appliedVersions());
+ }
+
+ public function testSetAppliedVersionsFailsIfMigrationDoesNotExist() {
+ $this->expectException(DomainException::class);
+ $this->expectExceptionMessage('foo migration does not exist.');
+
+ $migrator = new Minz_Migrator();
+
+ $migrator->setAppliedVersions(['foo']);
+ }
+
+ public function testVersions() {
+ $migrator = new Minz_Migrator();
+ $migrator->addMigration('foo', function () {
+ return true;
+ });
+ $migrator->addMigration('bar', function () {
+ return true;
+ });
+
+ $versions = $migrator->versions();
+
+ $this->assertSame(['bar', 'foo'], $versions);
+ }
+
+ public function testMigrate() {
+ $migrator = new Minz_Migrator();
+ $spy = false;
+ $migrator->addMigration('foo', function () use (&$spy) {
+ $spy = true;
+ return true;
+ });
+ $this->assertEmpty($migrator->appliedVersions());
+
+ $result = $migrator->migrate();
+
+ $this->assertTrue($spy);
+ $this->assertSame(['foo'], $migrator->appliedVersions());
+ $this->assertSame([
+ 'foo' => true,
+ ], $result);
+ }
+
+ public function testMigrateCallsMigrationsInSortedOrder() {
+ $migrator = new Minz_Migrator();
+ $spy_foo_1_is_called = false;
+ $migrator->addMigration('2_foo', function () use (&$spy_foo_1_is_called) {
+ return $spy_foo_1_is_called;
+ });
+ $migrator->addMigration('1_foo', function () use (&$spy_foo_1_is_called) {
+ $spy_foo_1_is_called = true;
+ return true;
+ });
+
+ $result = $migrator->migrate();
+
+ $this->assertSame(['1_foo', '2_foo'], $migrator->appliedVersions());
+ $this->assertSame([
+ '1_foo' => true,
+ '2_foo' => true,
+ ], $result);
+ }
+
+ public function testMigrateDoesNotCallAppliedMigrations() {
+ $migrator = new Minz_Migrator();
+ $spy = false;
+ $migrator->addMigration('1_foo', function () use (&$spy) {
+ $spy = true;
+ return true;
+ });
+ $migrator->setAppliedVersions(['1_foo']);
+
+ $result = $migrator->migrate();
+
+ $this->assertFalse($spy);
+ $this->assertSame([], $result);
+ }
+
+ public function testMigrateCallNonAppliedBetweenTwoApplied() {
+ $migrator = new Minz_Migrator();
+ $migrator->addMigration('1_foo', function () {
+ return true;
+ });
+ $migrator->addMigration('2_foo', function () {
+ return true;
+ });
+ $migrator->addMigration('3_foo', function () {
+ return true;
+ });
+ $migrator->setAppliedVersions(['1_foo', '3_foo']);
+
+ $result = $migrator->migrate();
+
+ $this->assertSame(['1_foo', '2_foo', '3_foo'], $migrator->appliedVersions());
+ $this->assertSame([
+ '2_foo' => true,
+ ], $result);
+ }
+
+ public function testMigrateWithMigrationReturningFalseDoesNotApplyVersion() {
+ $migrator = new Minz_Migrator();
+ $migrator->addMigration('1_foo', function () {
+ return true;
+ });
+ $migrator->addMigration('2_foo', function () {
+ return false;
+ });
+
+ $result = $migrator->migrate();
+
+ $this->assertSame(['1_foo'], $migrator->appliedVersions());
+ $this->assertSame([
+ '1_foo' => true,
+ '2_foo' => false,
+ ], $result);
+ }
+
+ public function testMigrateWithMigrationReturningFalseDoesNotExecuteNextMigrations() {
+ $migrator = new Minz_Migrator();
+ $migrator->addMigration('1_foo', function () {
+ return false;
+ });
+ $spy = false;
+ $migrator->addMigration('2_foo', function () use (&$spy) {
+ $spy = true;
+ return true;
+ });
+
+ $result = $migrator->migrate();
+
+ $this->assertEmpty($migrator->appliedVersions());
+ $this->assertFalse($spy);
+ $this->assertSame([
+ '1_foo' => false,
+ ], $result);
+ }
+
+ public function testMigrateWithFailingMigration() {
+ $migrator = new Minz_Migrator();
+ $migrator->addMigration('foo', function () {
+ throw new \Exception('Oops, it failed.');
+ });
+
+ $result = $migrator->migrate();
+
+ $this->assertEmpty($migrator->appliedVersions());
+ $this->assertSame([
+ 'foo' => 'Oops, it failed.',
+ ], $result);
+ }
+
+ public function testUpToDate() {
+ $migrator = new Minz_Migrator();
+ $migrator->addMigration('foo', function () {
+ return true;
+ });
+ $migrator->setAppliedVersions(['foo']);
+
+ $upToDate = $migrator->upToDate();
+
+ $this->assertTrue($upToDate);
+ }
+
+ public function testUpToDateIfRemainingMigration() {
+ $migrator = new Minz_Migrator();
+ $migrator->addMigration('1_foo', function () {
+ return true;
+ });
+ $migrator->addMigration('2_foo', function () {
+ return true;
+ });
+ $migrator->setAppliedVersions(['2_foo']);
+
+ $upToDate = $migrator->upToDate();
+
+ $this->assertFalse($upToDate);
+ }
+
+ public function testUpToDateIfNoMigrations() {
+ $migrator = new Minz_Migrator();
+
+ $upToDate = $migrator->upToDate();
+
+ $this->assertTrue($upToDate);
+ }
+
+ public function testConstructorLoadsDirectory() {
+ $migrations_path = TESTS_PATH . '/fixtures/migrations/';
+ $migrator = new Minz_Migrator($migrations_path);
+ $expected_versions = ['2019_12_22_FooBar', '2019_12_23_Baz'];
+
+ $migrations = $migrator->migrations();
+
+ $this->assertSame($expected_versions, array_keys($migrations));
+ }
+
+ public function testExecute() {
+ $migrations_path = TESTS_PATH . '/fixtures/migrations/';
+ $applied_migrations_path = tempnam('/tmp', 'applied_migrations.txt');
+
+ $result = Minz_Migrator::execute($migrations_path, $applied_migrations_path);
+
+ $this->assertTrue($result);
+ $versions = file_get_contents($applied_migrations_path);
+ $this->assertSame("2019_12_22_FooBar\n2019_12_23_Baz", $versions);
+ }
+
+ public function testExecuteWithAlreadyAppliedMigration() {
+ $migrations_path = TESTS_PATH . '/fixtures/migrations/';
+ $applied_migrations_path = tempnam('/tmp', 'applied_migrations.txt');
+ file_put_contents($applied_migrations_path, '2019_12_22_FooBar');
+
+ $result = Minz_Migrator::execute($migrations_path, $applied_migrations_path);
+
+ $this->assertTrue($result);
+ $versions = file_get_contents($applied_migrations_path);
+ $this->assertSame("2019_12_22_FooBar\n2019_12_23_Baz", $versions);
+ }
+
+ public function testExecuteWithAppliedMigrationInDifferentOrder() {
+ $migrations_path = TESTS_PATH . '/fixtures/migrations/';
+ $applied_migrations_path = tempnam('/tmp', 'applied_migrations.txt');
+ file_put_contents($applied_migrations_path, "2019_12_23_Baz\n2019_12_22_FooBar");
+
+ $result = Minz_Migrator::execute($migrations_path, $applied_migrations_path);
+
+ $this->assertTrue($result);
+ $versions = file_get_contents($applied_migrations_path);
+ // if the order changes, it probably means the first versions comparaison
+ // test doesn't work anymore
+ $this->assertSame("2019_12_23_Baz\n2019_12_22_FooBar", $versions);
+ }
+
+ public function testExecuteFailsIfVersionPathDoesNotExist() {
+ $migrations_path = TESTS_PATH . '/fixtures/migrations/';
+ $applied_migrations_path = tempnam('/tmp', 'applied_migrations.txt');
+ $expected_result = "Cannot open the {$applied_migrations_path} file";
+ unlink($applied_migrations_path);
+
+ $result = Minz_Migrator::execute($migrations_path, $applied_migrations_path);
+
+ $this->assertSame($expected_result, $result);
+ }
+
+ public function testExecuteFailsIfAMigrationIsFailing() {
+ $migrations_path = TESTS_PATH . '/fixtures/migrations_with_failing/';
+ $applied_migrations_path = tempnam('/tmp', 'applied_migrations.txt');
+ $expected_result = 'A migration failed to be applied, please see previous logs';
+
+ $result = Minz_Migrator::execute($migrations_path, $applied_migrations_path);
+
+ $this->assertSame($expected_result, $result);
+ $versions = file_get_contents($applied_migrations_path);
+ $this->assertSame('2020_01_11_FooBar', $versions);
+ }
+}