diff --git a/phpcs.xml b/phpcs.xml index 9ef5ab011..6040f3c23 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -4,6 +4,12 @@ + + + + + + src/ diff --git a/src/Phinx/Console/Command/AbstractCommand.php b/src/Phinx/Console/Command/AbstractCommand.php index c53d95a9b..de5722654 100644 --- a/src/Phinx/Console/Command/AbstractCommand.php +++ b/src/Phinx/Console/Command/AbstractCommand.php @@ -21,6 +21,7 @@ use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\OutputInterface; use UnexpectedValueException; @@ -439,7 +440,7 @@ protected function writeEnvironmentOutput(?string &$environment, OutputInterface } if (!$this->getConfig()->hasEnvironment($environment)) { - $output->writeln(sprintf('The environment "%s" does not exist', $environment)); + self::getErrorOutput($output)->writeln(sprintf('The environment "%s" does not exist', $environment)); return false; } @@ -478,7 +479,7 @@ protected function writeInformationOutput(?string &$environment, OutputInterface } $output->writeln('using database ' . $name, $this->verbosityLevel); } else { - $output->writeln('Could not determine database name! Please specify a database name in your config file.'); + self::getErrorOutput($output)->writeln('Could not determine database name! Please specify a database name in your config file.'); return false; } @@ -492,4 +493,15 @@ protected function writeInformationOutput(?string &$environment, OutputInterface return true; } + + /** + * Returns the error output to use + * + * @param \Symfony\Component\Console\Output\OutputInterface $output Output + * @return \Symfony\Component\Console\Output\OutputInterface + */ + protected static function getErrorOutput(OutputInterface $output): OutputInterface + { + return $output instanceof ConsoleOutputInterface ? $output->getErrorOutput() : $output; + } } diff --git a/src/Phinx/Console/Command/ListAliases.php b/src/Phinx/Console/Command/ListAliases.php index ffe85e2bf..1f02f2fdc 100644 --- a/src/Phinx/Console/Command/ListAliases.php +++ b/src/Phinx/Console/Command/ListAliases.php @@ -70,10 +70,10 @@ function ($alias, $class) use ($maxAliasLength, $maxClassLength) { ); } else { $output->writeln( - sprintf( - 'No aliases defined in %s', - Util::relativePath($this->config->getConfigFilePath()) - ) + 'warning no aliases defined in ' . Util::relativePath( + $this->config->getConfigFilePath() + ), + $this->verbosityLevel ); } diff --git a/src/Phinx/Console/Command/Migrate.php b/src/Phinx/Console/Command/Migrate.php index 6f9e7e143..699fa4a62 100644 --- a/src/Phinx/Console/Command/Migrate.php +++ b/src/Phinx/Console/Command/Migrate.php @@ -9,7 +9,6 @@ namespace Phinx\Console\Command; use DateTime; -use Exception; use Symfony\Component\Console\Attribute\AsCommand; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -92,12 +91,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int $this->getManager()->migrate($environment, $version, $fake); } $end = microtime(true); - } catch (Exception $e) { - $output->writeln('' . $e->__toString() . ''); - - return self::CODE_ERROR; } catch (Throwable $e) { - $output->writeln('' . $e->__toString() . ''); + self::getErrorOutput($output)->writeln('' . $e->__toString() . ''); return self::CODE_ERROR; } diff --git a/src/Phinx/Db/Adapter/SQLiteAdapter.php b/src/Phinx/Db/Adapter/SQLiteAdapter.php index 16cc10ee1..1dc1ddd3d 100644 --- a/src/Phinx/Db/Adapter/SQLiteAdapter.php +++ b/src/Phinx/Db/Adapter/SQLiteAdapter.php @@ -204,7 +204,7 @@ public function connect(): void */ public static function getSuffix(array $options): string { - if ($options['name'] === self::MEMORY) { + if (($options['name'] ?? '') === self::MEMORY) { return ''; } diff --git a/tests/Phinx/Console/Command/ListAliasesTest.php b/tests/Phinx/Console/Command/ListAliasesTest.php index 0504da136..27e0b346c 100644 --- a/tests/Phinx/Console/Command/ListAliasesTest.php +++ b/tests/Phinx/Console/Command/ListAliasesTest.php @@ -38,18 +38,18 @@ public function testListingAliases($file, $hasAliases) ], ['decorated' => false] ); - $this->assertEquals(AbstractCommand::CODE_SUCCESS, $exitCode); + $this->assertSame(AbstractCommand::CODE_SUCCESS, $exitCode); $display = $commandTester->getDisplay(false); if ($hasAliases) { - $this->assertStringNotContainsString('No aliases defined in ', $display); + $this->assertStringNotContainsString('no aliases defined in ', $display); $this->assertStringContainsString('Alias Class ', $display); $this->assertStringContainsString('================ ==================================================', $display); $this->assertStringContainsString('MakePermission Vendor\Package\Migration\Creation\MakePermission ', $display); $this->assertStringContainsString('RemovePermission Vendor\Package\Migration\Creation\RemovePermission', $display); } else { - $this->assertStringContainsString('No aliases defined in ', $display); + $this->assertStringContainsString('no aliases defined in ', $display); } } } diff --git a/tests/Phinx/Console/Command/MigrateTest.php b/tests/Phinx/Console/Command/MigrateTest.php index c948199d4..7ba4892b5 100644 --- a/tests/Phinx/Console/Command/MigrateTest.php +++ b/tests/Phinx/Console/Command/MigrateTest.php @@ -3,31 +3,29 @@ namespace Test\Phinx\Console\Command; +use DateTime; use Phinx\Config\Config; +use Phinx\Config\ConfigInterface; use Phinx\Console\Command\AbstractCommand; use Phinx\Console\Command\Migrate; use Phinx\Console\PhinxApplication; +use Phinx\Migration\Manager; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +use RuntimeException; use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\StreamOutput; use Symfony\Component\Console\Tester\CommandTester; class MigrateTest extends TestCase { - /** - * @var ConfigInterface|array - */ - protected $config = []; + private ConfigInterface $config; - /** - * @var InputInterface $input - */ - protected $input; + private InputInterface $input; - /** - * @var OutputInterface $output - */ - protected $output; + private OutputInterface $output; protected function setUp(): void { @@ -50,7 +48,7 @@ protected function setUp(): void ]); $this->input = new ArrayInput([]); - $this->output = new StreamOutput(fopen('php://memory', 'a', false)); + $this->output = new StreamOutput(fopen('php://memory', 'ab')); } public function testExecute() @@ -62,8 +60,8 @@ public function testExecute() $command = $application->find('migrate'); // mock the manager class - /** @var Manager|\PHPUnit\Framework\MockObject\MockObject $managerStub */ - $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') + /** @var Manager&MockObject $managerStub */ + $managerStub = $this->getMockBuilder(Manager::class) ->setConstructorArgs([$this->config, $this->input, $this->output]) ->getMock(); $managerStub->expects($this->once()) @@ -103,8 +101,8 @@ public function testExecuteWithDsn() ]); // mock the manager class - /** @var Manager|\PHPUnit\Framework\MockObject\MockObject $managerStub */ - $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') + /** @var Manager&MockObject $managerStub */ + $managerStub = $this->getMockBuilder(Manager::class) ->setConstructorArgs([$config, $this->input, $this->output]) ->getMock(); $managerStub->expects($this->once()) @@ -131,8 +129,8 @@ public function testExecuteWithEnvironmentOption() $command = $application->find('migrate'); // mock the manager class - /** @var Manager|\PHPUnit\Framework\MockObject\MockObject $managerStub */ - $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') + /** @var Manager&MockObject $managerStub */ + $managerStub = $this->getMockBuilder(Manager::class) ->setConstructorArgs([$this->config, $this->input, $this->output]) ->getMock(); $managerStub->expects($this->once()) @@ -157,8 +155,8 @@ public function testExecuteWithInvalidEnvironmentOption() $command = $application->find('migrate'); // mock the manager class - /** @var Manager|\PHPUnit\Framework\MockObject\MockObject $managerStub */ - $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') + /** @var Manager&MockObject $managerStub */ + $managerStub = $this->getMockBuilder(Manager::class) ->setConstructorArgs([$this->config, $this->input, $this->output]) ->getMock(); $managerStub->expects($this->never()) @@ -184,8 +182,8 @@ public function testDatabaseNameSpecified() $command = $application->find('migrate'); // mock the manager class - /** @var Manager|\PHPUnit\Framework\MockObject\MockObject $managerStub */ - $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') + /** @var Manager&MockObject $managerStub */ + $managerStub = $this->getMockBuilder(Manager::class) ->setConstructorArgs([$this->config, $this->input, $this->output]) ->getMock(); $managerStub->expects($this->once()) @@ -210,8 +208,8 @@ public function testFakeMigrate() $command = $application->find('migrate'); // mock the manager class - /** @var Manager|\PHPUnit\Framework\MockObject\MockObject $managerStub */ - $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') + /** @var Manager&MockObject $managerStub */ + $managerStub = $this->getMockBuilder(Manager::class) ->setConstructorArgs([$this->config, $this->input, $this->output]) ->getMock(); $managerStub->expects($this->once()) @@ -238,8 +236,8 @@ public function testMigrateExecutionOrder() $command = $application->find('migrate'); // mock the manager class - /** @var Manager|\PHPUnit\Framework\MockObject\MockObject $managerStub */ - $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') + /** @var Manager&MockObject $managerStub */ + $managerStub = $this->getMockBuilder(Manager::class) ->setConstructorArgs([$this->config, $this->input, $this->output]) ->getMock(); $managerStub->expects($this->once()) @@ -280,8 +278,8 @@ public function testMigrateMemorySqlite() $command = $application->find('migrate'); // mock the manager class - /** @var Manager|\PHPUnit\Framework\MockObject\MockObject $managerStub */ - $managerStub = $this->getMockBuilder('\Phinx\Migration\Manager') + /** @var Manager&MockObject $managerStub */ + $managerStub = $this->getMockBuilder(Manager::class) ->setConstructorArgs([$config, $this->input, $this->output]) ->getMock(); $managerStub->expects($this->once()) @@ -301,4 +299,69 @@ public function testMigrateMemorySqlite() ]) . PHP_EOL, $commandTester->getDisplay()); $this->assertSame(AbstractCommand::CODE_SUCCESS, $exitCode); } + + public function testExecuteWithDate(): void + { + $application = new PhinxApplication(); + $application->add(new Migrate()); + + /** @var Migrate $command */ + $command = $application->find('migrate'); + + // mock the manager class + /** @var Manager&MockObject $managerStub */ + $managerStub = $this->getMockBuilder(Manager::class) + ->setConstructorArgs([$this->config, $this->input, $this->output]) + ->getMock(); + $managerStub->expects($this->never()) + ->method('migrate'); + $managerStub->expects($this->once()) + ->method('migrateToDateTime') + ->with('development', new DateTime('yesterday'), false); + + $command->setConfig($this->config); + $command->setManager($managerStub); + + $commandTester = new CommandTester($command); + $exitCode = $commandTester->execute( + ['command' => $command->getName(), '--environment' => 'development', '--date' => 'yesterday'], + ['decorated' => false] + ); + + $this->assertStringContainsString('using environment development', $commandTester->getDisplay()); + $this->assertSame(AbstractCommand::CODE_SUCCESS, $exitCode); + } + + public function testExecuteWithError(): void + { + $exception = new RuntimeException('oops'); + + $application = new PhinxApplication(); + $application->add(new Migrate()); + + /** @var Migrate $command */ + $command = $application->find('migrate'); + + // mock the manager class + /** @var Manager&MockObject $managerStub */ + $managerStub = $this->getMockBuilder(Manager::class) + ->setConstructorArgs([$this->config, $this->input, $this->output]) + ->getMock(); + $managerStub->expects($this->once()) + ->method('migrate') + ->willThrowException($exception); + + $command->setConfig($this->config); + $command->setManager($managerStub); + + $commandTester = new CommandTester($command); + $exitCode = $commandTester->execute( + ['command' => $command->getName(), '--environment' => 'development'], + ['decorated' => false, 'capture_stderr_separately' => true] + ); + + $this->assertStringContainsString('using environment development', $commandTester->getDisplay()); + $this->assertStringContainsString('RuntimeException: oops', $commandTester->getErrorOutput()); + $this->assertSame(AbstractCommand::CODE_ERROR, $exitCode); + } }