diff --git a/src/AntiMattr/MongoDB/Migrations/Configuration/Configuration.php b/src/AntiMattr/MongoDB/Migrations/Configuration/Configuration.php index 0de1bd3..483d25a 100644 --- a/src/AntiMattr/MongoDB/Migrations/Configuration/Configuration.php +++ b/src/AntiMattr/MongoDB/Migrations/Configuration/Configuration.php @@ -295,6 +295,16 @@ public function getMigratedVersions() return $versions; } + /** + * Return all migrated versions from versions collection that have migration files deleted. + * + * @return array + */ + public function getUnavailableMigratedVersions() + { + return array_diff($this->getMigratedVersions(), $this->getAvailableVersions()); + } + /** * @param string $name */ @@ -620,12 +630,11 @@ public function getDetailsMap() $availableMigrations = $this->getAvailableVersions(); $numAvailableMigrations = count($availableMigrations); - // New migration count - $numNewMigrations = count($availableMigrations) - count($executedMigrations); - // Executed Unavailable migration count - $executedUnavailableMigrations = array_diff($executedMigrations, $availableMigrations); - $numExecutedUnavailableMigrations = count($executedUnavailableMigrations); + $numExecutedUnavailableMigrations = count($this->getUnavailableMigratedVersions()); + + // New migration count + $numNewMigrations = $numAvailableMigrations - ($numExecutedMigrations - $numExecutedUnavailableMigrations); return array( 'name' => $this->getName(), diff --git a/src/AntiMattr/MongoDB/Migrations/Tools/Console/Command/StatusCommand.php b/src/AntiMattr/MongoDB/Migrations/Tools/Console/Command/StatusCommand.php index 032d938..c61db9b 100644 --- a/src/AntiMattr/MongoDB/Migrations/Tools/Console/Command/StatusCommand.php +++ b/src/AntiMattr/MongoDB/Migrations/Tools/Console/Command/StatusCommand.php @@ -110,14 +110,15 @@ public function execute(InputInterface $input, OutputInterface $output) foreach ($migrations as $version) { $isMigrated = in_array($version->getVersion(), $migratedVersions); $status = $isMigrated ? 'migrated' : 'not migrated'; - $output->writeln(' >> '.$configuration->formatVersion($version->getVersion()).' ('.$version->getVersion().')'.str_repeat(' ', 30 - strlen($name)).$status); + $output->writeln(' >> '.Configuration::formatVersion($version->getVersion()).' ('.$version->getVersion().')'.str_repeat(' ', 30 - strlen($name)).$status); } } + $executedUnavailableMigrations = $configuration->getUnavailableMigratedVersions(); if ($executedUnavailableMigrations) { $output->writeln("\n == Previously Executed Unavailable Migration Versions\n"); foreach ($executedUnavailableMigrations as $executedUnavailableMigration) { - $output->writeln(' >> '.$configuration->formatVersion($executedUnavailableMigration).' ('.$executedUnavailableMigration.')'); + $output->writeln(' >> '.Configuration::formatVersion($executedUnavailableMigration).' ('.$executedUnavailableMigration.')'); } } } diff --git a/tests/AntiMattr/Tests/MongoDB/Migrations/Configuration/ConfigurationTest.php b/tests/AntiMattr/Tests/MongoDB/Migrations/Configuration/ConfigurationTest.php index af3e428..82f0d58 100644 --- a/tests/AntiMattr/Tests/MongoDB/Migrations/Configuration/ConfigurationTest.php +++ b/tests/AntiMattr/Tests/MongoDB/Migrations/Configuration/ConfigurationTest.php @@ -250,6 +250,22 @@ public function testValidateThrowsConfigurationValidationException() $this->configuration->validate(); } + public function testGetUnavailableMigratedVersions() + { + $configuration = $this->getMockBuilder('AntiMattr\MongoDB\Migrations\Configuration\Configuration') + ->disableOriginalConstructor() + ->setMethods(array('getMigratedVersions', 'getAvailableVersions')) + ->getMock(); + $configuration->expects($this->once()) + ->method('getMigratedVersions') + ->will($this->returnValue(array('1', '2'))); + $configuration->expects($this->once()) + ->method('getAvailableVersions') + ->will($this->returnValue(array('2', '3'))); + + $this->assertEquals(array('1'), $configuration->getUnavailableMigratedVersions()); + } + public function testValidate() { $this->prepareValidConfiguration(); diff --git a/tests/AntiMattr/Tests/MongoDB/Migrations/Tools/Console/Command/StatusCommandTest.php b/tests/AntiMattr/Tests/MongoDB/Migrations/Tools/Console/Command/StatusCommandTest.php index ec55615..ebc77c5 100644 --- a/tests/AntiMattr/Tests/MongoDB/Migrations/Tools/Console/Command/StatusCommandTest.php +++ b/tests/AntiMattr/Tests/MongoDB/Migrations/Tools/Console/Command/StatusCommandTest.php @@ -20,6 +20,7 @@ class StatusCommandTest extends AntiMattrTestCase private $config; private $migration; private $version; + private $version2; protected function setUp() { @@ -28,6 +29,7 @@ protected function setUp() $this->config = $this->buildMock('AntiMattr\MongoDB\Migrations\Configuration\Configuration'); $this->migration = $this->buildMock('AntiMattr\MongoDB\Migrations\Migration'); $this->version = $this->buildMock('AntiMattr\MongoDB\Migrations\Version'); + $this->version2 = $this->buildMock('AntiMattr\MongoDB\Migrations\Version'); $this->command->setMigrationConfiguration($this->config); } @@ -213,6 +215,254 @@ public function testExecuteWithoutShowingVersions() $this->output ); } + + public function testExecuteWithShowingVersions() + { + $input = new ArgvInput( + array( + StatusCommand::NAME, + '--show-versions', + ) + ); + + $configName = 'config-name'; + $databaseDriver = 'MongoDB'; + $migrationsDatabaseName = ' migrations-database-name'; + $migrationsCollectionName = 'migrations-collection-name'; + $migrationsNamespace = 'migrations-namespace'; + $migrationsDirectory = 'migrations-directory'; + $currentVersion = 'abcdefghijk'; + $latestVersion = '1234567890'; + $numExecutedMigrations = 2; + $numExecutedUnavailableMigrations = 1; + $numAvailableMigrations = 2; + $numNewMigrations = 1; + $notMigratedVersion = '20140822185743'; + $migratedVersion = '20140822185745'; + $unavailableMigratedVersion = '20140822185744'; + + // Expectations + $this->version->expects($this->exactly(3)) + ->method('getVersion') + ->will($this->returnValue($notMigratedVersion)); + + $this->version2->expects($this->exactly(3)) + ->method('getVersion') + ->will($this->returnValue($migratedVersion)); + + $this->config->expects($this->once()) + ->method('getDetailsMap') + ->will( + $this->returnValue( + array( + 'name' => $configName, + 'database_driver' => $databaseDriver, + 'migrations_database_name' => $migrationsDatabaseName, + 'migrations_collection_name' => $migrationsCollectionName, + 'migrations_namespace' => $migrationsNamespace, + 'migrations_directory' => $migrationsDirectory, + 'current_version' => $currentVersion, + 'latest_version' => $latestVersion, + 'num_executed_migrations' => $numExecutedMigrations, + 'num_executed_unavailable_migrations' => $numExecutedUnavailableMigrations, + 'num_available_migrations' => $numAvailableMigrations, + 'num_new_migrations' => $numNewMigrations, + ) + ) + ) + ; + $this->config->expects($this->once()) + ->method('getMigrations') + ->will( + $this->returnValue( + array($this->version, $this->version2) + ) + ) + ; + $this->config->expects($this->once()) + ->method('getMigratedVersions') + ->will( + $this->returnValue( + array($unavailableMigratedVersion, $migratedVersion) + ) + ) + ; + $this->config->expects($this->once()) + ->method('getUnavailableMigratedVersions') + ->will( + $this->returnValue( + array($unavailableMigratedVersion) + ) + ) + ; + + $this->output->expects($this->at(0)) + ->method('writeln') + ->with( + "\n == Configuration\n" + ) + ; + $this->output->expects($this->at(1)) + ->method('writeln') + ->with( + sprintf( + '%s::%s', + 'Name', + $configName + ) + ) + ; + $this->output->expects($this->at(2)) + ->method('writeln') + ->with( + sprintf( + '%s::%s', + 'Database Driver', + 'MongoDB' + ) + ) + ; + $this->output->expects($this->at(3)) + ->method('writeln') + ->with( + sprintf( + '%s::%s', + 'Database Name', + $migrationsDatabaseName + ) + ) + ; + $this->output->expects($this->at(4)) + ->method('writeln') + ->with( + sprintf( + '%s::%s', + 'Configuration Source', + 'manually configured' + ) + ) + ; + $this->output->expects($this->at(5)) + ->method('writeln') + ->with( + sprintf( + '%s::%s', + 'Version Collection Name', + $migrationsCollectionName + ) + ) + ; + $this->output->expects($this->at(6)) + ->method('writeln') + ->with( + sprintf( + '%s::%s', + 'Migrations Namespace', + $migrationsNamespace + ) + ) + ; + $this->output->expects($this->at(7)) + ->method('writeln') + ->with( + sprintf( + '%s::%s', + 'Migrations Directory', + $migrationsDirectory + ) + ) + ; + $this->output->expects($this->at(8)) // current version formatted + ->method('writeln') + ; + $this->output->expects($this->at(9)) // latest version formatted + ->method('writeln') + ; + $this->output->expects($this->at(10)) + ->method('writeln') + ->with( + sprintf( + '%s::%s', + 'Executed Migrations', + $numExecutedMigrations + ) + ) + ; + $this->output->expects($this->at(11)) + ->method('writeln') + ->with( + sprintf( + '%s::%s', + 'Executed Unavailable Migrations', + $numExecutedUnavailableMigrations + ) + ) + ; + $this->output->expects($this->at(12)) + ->method('writeln') + ->with( + sprintf( + '%s::%s', + 'Available Migrations', + $numAvailableMigrations + ) + ) + ; + $this->output->expects($this->at(13)) + ->method('writeln') + ->with( + sprintf( + '%s::%s', + 'New Migrations', + $numNewMigrations + ) + ) + ; + $this->output->expects($this->at(14)) + ->method('writeln') + ->with("\n == Available Migration Versions\n") + ; + $this->output->expects($this->at(15)) + ->method('writeln') + ->with( + sprintf( + ' >> %s (%s) not migrated', + \DateTime::createFromFormat('YmdHis', $notMigratedVersion)->format('Y-m-d H:i:s'), + $notMigratedVersion + ) + ) + ; + $this->output->expects($this->at(16)) + ->method('writeln') + ->with( + sprintf( + ' >> %s (%s) migrated', + \DateTime::createFromFormat('YmdHis', $migratedVersion)->format('Y-m-d H:i:s'), + $migratedVersion + ) + ) + ; + $this->output->expects($this->at(17)) + ->method('writeln') + ->with("\n == Previously Executed Unavailable Migration Versions\n") + ; + $this->output->expects($this->at(18)) + ->method('writeln') + ->with( + sprintf( + ' >> %s (%s)', + \DateTime::createFromFormat('YmdHis', $unavailableMigratedVersion)->format('Y-m-d H:i:s'), + $unavailableMigratedVersion + ) + ) + ; + + // Run command, run. + $this->command->run( + $input, + $this->output + ); + } } class StatusCommandStub extends StatusCommand