From 2706a4c0f2bf83b721cf5e370b66609bfda14b12 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 17 Mar 2024 16:21:24 -0400 Subject: [PATCH 1/4] Extract a factory for migration config/manager Looks like we're going to need this in most migrations commands. --- src/Command/MigrateCommand.php | 86 ++---------- src/Command/StatusCommand.php | 88 ++----------- src/Migration/ManagerFactory.php | 130 +++++++++++++++++++ tests/TestCase/Command/StatusCommandTest.php | 3 +- 4 files changed, 150 insertions(+), 157 deletions(-) create mode 100644 src/Migration/ManagerFactory.php diff --git a/src/Command/MigrateCommand.php b/src/Command/MigrateCommand.php index b44b7feb..93150d24 100644 --- a/src/Command/MigrateCommand.php +++ b/src/Command/MigrateCommand.php @@ -27,6 +27,7 @@ use Migrations\Config\Config; use Migrations\Config\ConfigInterface; use Migrations\Migration\Manager; +use Migrations\Migration\ManagerFactory; use Throwable; /** @@ -92,83 +93,6 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar return $parser; } - /** - * Generate a configuration object for the migrations operation. - * - * @param \Cake\Console\Arguments $args The console arguments - * @return \Migrations\Config\Config The generated config instance. - */ - protected function getConfig(Arguments $args): Config - { - $folder = (string)$args->getOption('source'); - - // Get the filepath for migrations and seeds(not implemented yet) - $dir = ROOT . DS . 'config' . DS . $folder; - if (defined('CONFIG')) { - $dir = CONFIG . $folder; - } - $plugin = $args->getOption('plugin'); - if ($plugin && is_string($plugin)) { - $dir = Plugin::path($plugin) . 'config' . DS . $folder; - } - - // Get the phinxlog table name. Plugins have separate migration history. - // The names and separate table history is something we could change in the future. - $table = 'phinxlog'; - if ($plugin && is_string($plugin)) { - $prefix = Inflector::underscore($plugin) . '_'; - $prefix = str_replace(['\\', '/', '.'], '_', $prefix); - $table = $prefix . $table; - } - $templatePath = dirname(__DIR__) . DS . 'templates' . DS; - $connectionName = (string)$args->getOption('connection'); - - // TODO this all needs to go away. But first Environment and Manager need to work - // with Cake's ConnectionManager. - $connectionConfig = ConnectionManager::getConfig($connectionName); - if (!$connectionConfig) { - throw new StopException("Could not find connection `{$connectionName}`"); - } - - /** @var array $connectionConfig */ - $adapter = $connectionConfig['scheme'] ?? null; - $adapterConfig = [ - 'adapter' => $adapter, - 'connection' => $connectionName, - 'database' => $connectionConfig['database'], - 'migration_table' => $table, - 'dryrun' => $args->getOption('dry-run'), - ]; - - $configData = [ - 'paths' => [ - 'migrations' => $dir, - ], - 'templates' => [ - 'file' => $templatePath . 'Phinx/create.php.template', - ], - 'migration_base_class' => 'Migrations\AbstractMigration', - 'environment' => $adapterConfig, - // TODO do we want to support the DI container in migrations? - ]; - - return new Config($configData); - } - - /** - * Get the migration manager for the current CLI options and application configuration. - * - * @param \Cake\Console\Arguments $args The command arguments. - * @param \Cake\Console\ConsoleIo $io The command io. - * @return \Migrations\Migration\Manager - */ - protected function getManager(Arguments $args, ConsoleIo $io): Manager - { - $config = $this->getConfig($args); - - return new Manager($config, $io); - } - /** * Execute the command. * @@ -201,7 +125,13 @@ protected function executeMigrations(Arguments $args, ConsoleIo $io): ?int $date = $args->getOption('date'); $fake = (bool)$args->getOption('fake'); - $manager = $this->getManager($args, $io); + $factory = new ManagerFactory([ + 'plugin' => $args->getOption('plugin'), + 'source' => $args->getOption('source'), + 'connection' => $args->getOption('connection'), + 'dry-run' => $args->getOption('dry-run'), + ]); + $manager = $factory->createManager($io); $config = $manager->getConfig(); $versionOrder = $config->getVersionOrder(); diff --git a/src/Command/StatusCommand.php b/src/Command/StatusCommand.php index 8562949a..bd40026a 100644 --- a/src/Command/StatusCommand.php +++ b/src/Command/StatusCommand.php @@ -24,6 +24,7 @@ use Migrations\Config\Config; use Migrations\Config\ConfigInterface; use Migrations\Migration\Manager; +use Migrations\Migration\ManagerFactory; /** * Status command for built in backend @@ -89,83 +90,6 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar return $parser; } - /** - * Generate a configuration object for the migrations operation. - * - * @param \Cake\Console\Arguments $args The console arguments - * @return \Migrations\Config\Config The generated config instance. - */ - protected function getConfig(Arguments $args): Config - { - $folder = (string)$args->getOption('source'); - - // Get the filepath for migrations and seeds(not implemented yet) - $dir = ROOT . '/config/' . $folder; - if (defined('CONFIG')) { - $dir = CONFIG . $folder; - } - $plugin = $args->getOption('plugin'); - if ($plugin && is_string($plugin)) { - $dir = Plugin::path($plugin) . 'config/' . $folder; - } - - // Get the phinxlog table name. Plugins have separate migration history. - // The names and separate table history is something we could change in the future. - $table = 'phinxlog'; - if ($plugin && is_string($plugin)) { - $prefix = Inflector::underscore($plugin) . '_'; - $prefix = str_replace(['\\', '/', '.'], '_', $prefix); - $table = $prefix . $table; - } - $templatePath = dirname(__DIR__) . DS . 'templates' . DS; - $connectionName = (string)$args->getOption('connection'); - - // TODO this all needs to go away. But first Environment and Manager need to work - // with Cake's ConnectionManager. - $connectionConfig = ConnectionManager::getConfig($connectionName); - if (!$connectionConfig) { - throw new StopException("Could not find connection `{$connectionName}`"); - } - - /** @var array $connectionConfig */ - $adapter = $connectionConfig['scheme'] ?? null; - $adapterConfig = [ - 'adapter' => $adapter, - 'connection' => $connectionName, - 'database' => $connectionConfig['database'], - 'migration_table' => $table, - 'dryrun' => $args->getOption('dry-run'), - ]; - - $configData = [ - 'paths' => [ - 'migrations' => $dir, - ], - 'templates' => [ - 'file' => $templatePath . 'Phinx/create.php.template', - ], - 'migration_base_class' => 'Migrations\AbstractMigration', - 'environment' => $adapterConfig, - // TODO do we want to support the DI container in migrations? - ]; - - return new Config($configData); - } - - /** - * Get the migration manager for the current CLI options and application configuration. - * - * @param \Cake\Console\Arguments $args The command arguments. - * @param \Cake\Console\ConsoleIo $io The command io. - * @return \Migrations\Migration\Manager - */ - protected function getManager(Arguments $args, ConsoleIo $io): Manager - { - $config = $this->getConfig($args); - - return new Manager($config, $io); - } - /** * Execute the command. * @@ -177,7 +101,15 @@ public function execute(Arguments $args, ConsoleIo $io): ?int { /** @var string|null $format */ $format = $args->getOption('format'); - $migrations = $this->getManager($args, $io)->printStatus($format); + + $factory = new ManagerFactory([ + 'plugin' => $args->getOption('plugin'), + 'source' => $args->getOption('source'), + 'connection' => $args->getOption('connection'), + 'dry-run' => $args->getOption('dry-run'), + ]); + $manager = $factory->createManager($io); + $migrations = $manager->printStatus($format); switch ($format) { case 'json': diff --git a/src/Migration/ManagerFactory.php b/src/Migration/ManagerFactory.php new file mode 100644 index 00000000..b7700984 --- /dev/null +++ b/src/Migration/ManagerFactory.php @@ -0,0 +1,130 @@ +options[$name])) { + return null; + } + + return $this->options[$name]; + } + + public function createConfig(): ConfigInterface + { + $folder = (string)$this->getOption('source'); + + // Get the filepath for migrations and seeds(not implemented yet) + $dir = ROOT . DS . 'config' . DS . $folder; + if (defined('CONFIG')) { + $dir = CONFIG . $folder; + } + $plugin = $this->getOption('plugin'); + if ($plugin && is_string($plugin)) { + $dir = Plugin::path($plugin) . 'config' . DS . $folder; + } + + // Get the phinxlog table name. Plugins have separate migration history. + // The names and separate table history is something we could change in the future. + $table = 'phinxlog'; + if ($plugin && is_string($plugin)) { + $prefix = Inflector::underscore($plugin) . '_'; + $prefix = str_replace(['\\', '/', '.'], '_', $prefix); + $table = $prefix . $table; + } + $templatePath = dirname(__DIR__) . DS . 'templates' . DS; + $connectionName = (string)$this->getOption('connection'); + + // TODO this all needs to go away. But first Environment and Manager need to work + // with Cake's ConnectionManager. + $connectionConfig = ConnectionManager::getConfig($connectionName); + if (!$connectionConfig) { + throw new RuntimeException("Could not find connection `{$connectionName}`"); + } + + /** @var array $connectionConfig */ + $adapter = $connectionConfig['scheme'] ?? null; + $adapterConfig = [ + 'adapter' => $adapter, + 'connection' => $connectionName, + 'database' => $connectionConfig['database'], + 'migration_table' => $table, + 'dryrun' => $this->getOption('dry-run'), + ]; + + $configData = [ + 'paths' => [ + 'migrations' => $dir, + ], + 'templates' => [ + 'file' => $templatePath . 'Phinx/create.php.template', + ], + 'migration_base_class' => 'Migrations\AbstractMigration', + 'environment' => $adapterConfig, + // TODO do we want to support the DI container in migrations? + ]; + + return new Config($configData); + } + + /** + * Get the migration manager for the current CLI options and application configuration. + * + * @param \Cake\Console\ConsoleIo $io The command io. + * @param \Migrations\Config\ConfigInterface $config A config instance. Providing null will create a new Config + * based on the factory constructor options. + * @return \Migrations\Migration\Manager + */ + public function createManager(ConsoleIo $io, ConfigInterface|null $config = null): Manager + { + $config ??= $this->createConfig(); + + return new Manager($config, $io); + } +} + diff --git a/tests/TestCase/Command/StatusCommandTest.php b/tests/TestCase/Command/StatusCommandTest.php index 05487437..d9562b73 100644 --- a/tests/TestCase/Command/StatusCommandTest.php +++ b/tests/TestCase/Command/StatusCommandTest.php @@ -8,6 +8,7 @@ use Cake\Core\Exception\MissingPluginException; use Cake\Database\Exception\DatabaseException; use Cake\TestSuite\TestCase; +use RuntimeException; class StatusCommandTest extends TestCase { @@ -74,7 +75,7 @@ public function testExecutePluginDoesNotExist(): void public function testExecuteConnectionDoesNotExist(): void { + $this->expectException(RuntimeException::class); $this->exec('migrations status -c lolnope'); - $this->assertExitError(); } } From a4c1a16c06a27edb839a2654a58908efd6d426ee Mon Sep 17 00:00:00 2001 From: Mark Story Date: Sun, 17 Mar 2024 17:07:06 -0400 Subject: [PATCH 2/4] Port dump command to new migrations backend Add test coverage based on what we had before. --- src/Command/DumpCommand.php | 123 ++++++++++++++++++ src/Command/MigrateCommand.php | 6 - src/Command/StatusCommand.php | 6 - src/Config/Config.php | 2 +- src/Migration/ManagerFactory.php | 14 +- src/MigrationsPlugin.php | 2 + src/TableFinderTrait.php | 1 + tests/TestCase/Command/DumpCommandTest.php | 102 +++++++++++++++ .../TestCase/Db/Adapter/PhinxAdapterTest.php | 8 -- 9 files changed, 241 insertions(+), 23 deletions(-) create mode 100644 src/Command/DumpCommand.php create mode 100644 tests/TestCase/Command/DumpCommandTest.php diff --git a/src/Command/DumpCommand.php b/src/Command/DumpCommand.php new file mode 100644 index 00000000..c8e2e539 --- /dev/null +++ b/src/Command/DumpCommand.php @@ -0,0 +1,123 @@ +setDescription([ + 'Dumps the current scheam of the database to be used while baking a diff', + '', + 'migrations dump -c secondary', + ])->addOption('plugin', [ + 'short' => 'p', + 'help' => 'The plugin to dump migrations for', + ])->addOption('connection', [ + 'short' => 'c', + 'help' => 'The datasource connection to use', + 'default' => 'default', + ])->addOption('source', [ + 'short' => 's', + 'help' => 'The folder under src/Config that migrations are in', + 'default' => ConfigInterface::DEFAULT_MIGRATION_FOLDER, + ]); + + return $parser; + } + + /** + * Execute the command. + * + * @param \Cake\Console\Arguments $args The command arguments. + * @param \Cake\Console\ConsoleIo $io The console io + * @return int|null The exit code or null for success + */ + public function execute(Arguments $args, ConsoleIo $io): ?int + { + $factory = new ManagerFactory([ + 'plugin' => $args->getOption('plugin'), + 'source' => $args->getOption('source'), + 'connection' => $args->getOption('connection'), + ]); + $config = $factory->createConfig(); + $path = $config->getMigrationPaths()[0]; + $connectionName = (string)$config->getConnection(); + $connection = ConnectionManager::get($connectionName); + assert($connection instanceof Connection); + + $collection = $connection->getSchemaCollection(); + $options = [ + 'require-table' => false, + 'plugin' => $args->getOption('plugin'), + ]; + // The connection property is used by the trait methods. + $this->connection = $connectionName; + $tables = $this->getTablesToBake($collection, $options); + + $dump = []; + if ($tables) { + foreach ($tables as $table) { + $schema = $collection->describe($table); + $dump[$table] = $schema; + } + } + + $filePath = $path . DS . 'schema-dump-' . $connectionName . '.lock'; + $io->out("Writing dump file `{$filePath}`..."); + if (file_put_contents($filePath, serialize($dump))) { + $io->out("Dump file `{$filePath}` was successfully written"); + + return self::CODE_SUCCESS; + } + $io->out("An error occurred while writing dump file `{$filePath}`"); + + return self::CODE_ERROR; + } +} diff --git a/src/Command/MigrateCommand.php b/src/Command/MigrateCommand.php index 93150d24..40752731 100644 --- a/src/Command/MigrateCommand.php +++ b/src/Command/MigrateCommand.php @@ -17,16 +17,10 @@ use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; -use Cake\Console\Exception\StopException; -use Cake\Core\Plugin; -use Cake\Datasource\ConnectionManager; use Cake\Event\EventDispatcherTrait; -use Cake\Utility\Inflector; use DateTime; use Exception; -use Migrations\Config\Config; use Migrations\Config\ConfigInterface; -use Migrations\Migration\Manager; use Migrations\Migration\ManagerFactory; use Throwable; diff --git a/src/Command/StatusCommand.php b/src/Command/StatusCommand.php index bd40026a..999cc09c 100644 --- a/src/Command/StatusCommand.php +++ b/src/Command/StatusCommand.php @@ -17,13 +17,7 @@ use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; -use Cake\Console\Exception\StopException; -use Cake\Core\Plugin; -use Cake\Datasource\ConnectionManager; -use Cake\Utility\Inflector; -use Migrations\Config\Config; use Migrations\Config\ConfigInterface; -use Migrations\Migration\Manager; use Migrations\Migration\ManagerFactory; /** diff --git a/src/Config/Config.php b/src/Config/Config.php index 6c475ad7..80f50202 100644 --- a/src/Config/Config.php +++ b/src/Config/Config.php @@ -113,7 +113,7 @@ public function getSeedBaseClassName(bool $dropNamespace = true): string */ public function getConnection(): string|false { - return $this->values['connection'] ?? false; + return $this->values['environment']['connection'] ?? false; } /** diff --git a/src/Migration/ManagerFactory.php b/src/Migration/ManagerFactory.php index b7700984..c37ebbe9 100644 --- a/src/Migration/ManagerFactory.php +++ b/src/Migration/ManagerFactory.php @@ -46,6 +46,12 @@ public function __construct(protected array $options) { } + /** + * Read configuration options used for this factory + * + * @param string $name The option name to read + * @return mixed Option value or null + */ public function getOption(string $name): mixed { if (!isset($this->options[$name])) { @@ -55,6 +61,11 @@ public function getOption(string $name): mixed return $this->options[$name]; } + /** + * Create a ConfigInterface instance based on the factory options. + * + * @return \Migrations\Config\ConfigInterface + */ public function createConfig(): ConfigInterface { $folder = (string)$this->getOption('source'); @@ -120,11 +131,10 @@ public function createConfig(): ConfigInterface * based on the factory constructor options. * @return \Migrations\Migration\Manager */ - public function createManager(ConsoleIo $io, ConfigInterface|null $config = null): Manager + public function createManager(ConsoleIo $io, ?ConfigInterface $config = null): Manager { $config ??= $this->createConfig(); return new Manager($config, $io); } } - diff --git a/src/MigrationsPlugin.php b/src/MigrationsPlugin.php index 1343eb43..acdb42f6 100644 --- a/src/MigrationsPlugin.php +++ b/src/MigrationsPlugin.php @@ -22,6 +22,7 @@ use Migrations\Command\BakeMigrationDiffCommand; use Migrations\Command\BakeMigrationSnapshotCommand; use Migrations\Command\BakeSeedCommand; +use Migrations\Command\DumpCommand; use Migrations\Command\MigrateCommand; use Migrations\Command\MigrationsCacheBuildCommand; use Migrations\Command\MigrationsCacheClearCommand; @@ -94,6 +95,7 @@ public function console(CommandCollection $commands): CommandCollection $classes = [ StatusCommand::class, MigrateCommand::class, + DumpCommand::class, ]; if (class_exists(SimpleBakeCommand::class)) { $classes[] = BakeMigrationCommand::class; diff --git a/src/TableFinderTrait.php b/src/TableFinderTrait.php index 36528382..7320ebcc 100644 --- a/src/TableFinderTrait.php +++ b/src/TableFinderTrait.php @@ -20,6 +20,7 @@ use Cake\ORM\TableRegistry; use ReflectionClass; +// TODO(mark) Make this into a standalone class instead of a trait. trait TableFinderTrait { /** diff --git a/tests/TestCase/Command/DumpCommandTest.php b/tests/TestCase/Command/DumpCommandTest.php new file mode 100644 index 00000000..1b33818f --- /dev/null +++ b/tests/TestCase/Command/DumpCommandTest.php @@ -0,0 +1,102 @@ +connection */ + $this->connection = ConnectionManager::get('test'); + $this->connection->execute('DROP TABLE IF EXISTS numbers'); + $this->connection->execute('DROP TABLE IF EXISTS letters'); + $this->connection->execute('DROP TABLE IF EXISTS parts'); + $this->connection->execute('DROP TABLE IF EXISTS phinxlog'); + + $this->dumpFile = ROOT . DS . 'config/TestsMigrations/schema-dump-test.lock'; + } + + public function tearDown(): void + { + parent::tearDown(); + + $this->connection->execute('DROP TABLE IF EXISTS numbers'); + $this->connection->execute('DROP TABLE IF EXISTS letters'); + $this->connection->execute('DROP TABLE IF EXISTS parts'); + $this->connection->execute('DROP TABLE IF EXISTS phinxlog'); + if (file_exists($this->dumpFile)) { + unlink($this->dumpFile); + } + } + + public function testExecuteIncorrectConnection(): void + { + $this->expectException(RuntimeException::class); + $this->exec('migrations dump --connection lolnope'); + } + + public function testExecuteIncorrectPlugin(): void + { + $this->expectException(MissingPluginException::class); + $this->exec('migrations dump --plugin lolnope'); + } + + public function testExecuteSuccess(): void + { + // Run migrations + $this->exec('migrations migrate --connection test --source TestsMigrations --no-lock'); + $this->assertExitSuccess(); + + // Generate dump file. + $this->exec('migrations dump --connection test --source TestsMigrations'); + + $this->assertExitSuccess(); + $this->assertOutputContains('config/TestsMigrations/schema-dump-test.lock'); + + $this->assertFileExists($this->dumpFile); + /** @var array $generatedDump */ + $generatedDump = unserialize(file_get_contents($this->dumpFile)); + + $this->assertArrayHasKey('letters', $generatedDump); + $this->assertArrayHasKey('numbers', $generatedDump); + $this->assertInstanceOf(TableSchema::class, $generatedDump['numbers']); + $this->assertInstanceOf(TableSchema::class, $generatedDump['letters']); + $this->assertEquals(['id', 'number', 'radix'], $generatedDump['numbers']->columns()); + $this->assertEquals(['id', 'letter'], $generatedDump['letters']->columns()); + } + + public function testExecutePlugin(): void + { + $this->loadPlugins(['Migrator']); + + $this->exec('migrations dump --connection test --plugin Migrator'); + + $this->assertExitSuccess(); + $this->assertOutputContains('Migrator/config/Migrations/schema-dump-test.lock'); + + $dumpFile = Plugin::path('Migrator') . '/config/Migrations/schema-dump-test.lock'; + if (file_exists($dumpFile)) { + unlink($dumpFile); + } + } +} diff --git a/tests/TestCase/Db/Adapter/PhinxAdapterTest.php b/tests/TestCase/Db/Adapter/PhinxAdapterTest.php index 40c43603..e4e66315 100644 --- a/tests/TestCase/Db/Adapter/PhinxAdapterTest.php +++ b/tests/TestCase/Db/Adapter/PhinxAdapterTest.php @@ -14,18 +14,12 @@ use Migrations\Db\Adapter\SqliteAdapter; use Migrations\Db\Literal; use Migrations\Db\Table\ForeignKey; -use PDO; use PDOException; use Phinx\Db\Table as PhinxTable; use Phinx\Db\Table\Column as PhinxColumn; use Phinx\Util\Literal as PhinxLiteral; use PHPUnit\Framework\TestCase; use RuntimeException; -use Symfony\Component\Console\Input\ArrayInput; -use Symfony\Component\Console\Input\InputDefinition; -use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\BufferedOutput; -use UnexpectedValueException; class PhinxAdapterTest extends TestCase { @@ -1136,7 +1130,6 @@ public function testDumpCreateTable() */ public function testDumpInsert() { - $table = new PhinxTable('table1', [], $this->adapter); $table->addColumn('string_col', 'string') ->addColumn('int_col', 'integer') @@ -1177,7 +1170,6 @@ public function testDumpInsert() */ public function testDumpBulkinsert() { - $table = new PhinxTable('table1', [], $this->adapter); $table->addColumn('string_col', 'string') ->addColumn('int_col', 'integer') From 6c972861fa80023f7667cf3907565b64f5bfd79a Mon Sep 17 00:00:00 2001 From: Mark Story Date: Mon, 18 Mar 2024 23:54:42 -0400 Subject: [PATCH 3/4] Fix tests --- tests/TestCase/Command/CompletionTest.php | 2 +- tests/TestCase/Command/Phinx/DumpTest.php | 2 ++ tests/TestCase/Config/AbstractConfigTestCase.php | 6 +++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/TestCase/Command/CompletionTest.php b/tests/TestCase/Command/CompletionTest.php index 7a92ed49..c9daf91f 100644 --- a/tests/TestCase/Command/CompletionTest.php +++ b/tests/TestCase/Command/CompletionTest.php @@ -44,7 +44,7 @@ public function testMigrationsSubcommands() { $this->exec('completion subcommands migrations.migrations'); $expected = [ - 'migrate orm-cache-build orm-cache-clear create dump mark_migrated rollback seed status', + 'dump migrate orm-cache-build orm-cache-clear create mark_migrated rollback seed status', ]; $actual = $this->_out->messages(); $this->assertEquals($expected, $actual); diff --git a/tests/TestCase/Command/Phinx/DumpTest.php b/tests/TestCase/Command/Phinx/DumpTest.php index f6d2a6bf..847fa58b 100644 --- a/tests/TestCase/Command/Phinx/DumpTest.php +++ b/tests/TestCase/Command/Phinx/DumpTest.php @@ -91,6 +91,7 @@ public function setUp(): void $this->connection->execute('DROP TABLE IF EXISTS numbers'); $this->connection->execute('DROP TABLE IF EXISTS letters'); $this->connection->execute('DROP TABLE IF EXISTS parts'); + $this->connection->execute('DROP TABLE IF EXISTS stores'); $this->dumpfile = ROOT . DS . 'config/TestsMigrations/schema-dump-test.lock'; } @@ -106,6 +107,7 @@ public function tearDown(): void $this->connection->execute('DROP TABLE IF EXISTS numbers'); $this->connection->execute('DROP TABLE IF EXISTS letters'); $this->connection->execute('DROP TABLE IF EXISTS parts'); + $this->connection->execute('DROP TABLE IF EXISTS stores'); } /** diff --git a/tests/TestCase/Config/AbstractConfigTestCase.php b/tests/TestCase/Config/AbstractConfigTestCase.php index 049739fc..5929161a 100644 --- a/tests/TestCase/Config/AbstractConfigTestCase.php +++ b/tests/TestCase/Config/AbstractConfigTestCase.php @@ -34,9 +34,9 @@ public function getConfigArray() $adapter = [ 'migration_table' => 'phinxlog', 'adapter' => $connectionConfig['scheme'], - 'user' => $connectionConfig['username'], - 'pass' => $connectionConfig['password'], - 'host' => $connectionConfig['host'], + 'user' => $connectionConfig['username'] ?? '', + 'pass' => $connectionConfig['password'] ?? '', + 'host' => $connectionConfig['host'] ?? '', 'name' => $connectionConfig['database'], ]; From 2815b64001c921aa773f556d38c256d8a6decef0 Mon Sep 17 00:00:00 2001 From: Mark Story Date: Tue, 19 Mar 2024 10:05:17 -0400 Subject: [PATCH 4/4] Fix paths for windows --- tests/TestCase/Command/DumpCommandTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/TestCase/Command/DumpCommandTest.php b/tests/TestCase/Command/DumpCommandTest.php index 1b33818f..12e0c494 100644 --- a/tests/TestCase/Command/DumpCommandTest.php +++ b/tests/TestCase/Command/DumpCommandTest.php @@ -71,7 +71,7 @@ public function testExecuteSuccess(): void $this->exec('migrations dump --connection test --source TestsMigrations'); $this->assertExitSuccess(); - $this->assertOutputContains('config/TestsMigrations/schema-dump-test.lock'); + $this->assertOutputContains('config' . DS . 'TestsMigrations' . DS . 'schema-dump-test.lock'); $this->assertFileExists($this->dumpFile); /** @var array $generatedDump */ @@ -92,7 +92,7 @@ public function testExecutePlugin(): void $this->exec('migrations dump --connection test --plugin Migrator'); $this->assertExitSuccess(); - $this->assertOutputContains('Migrator/config/Migrations/schema-dump-test.lock'); + $this->assertOutputContains('Migrator' . DS . 'config' . DS . 'Migrations' . DS . 'schema-dump-test.lock'); $dumpFile = Plugin::path('Migrator') . '/config/Migrations/schema-dump-test.lock'; if (file_exists($dumpFile)) {