From e1f6858142401a412d283d70f54da5d1eec7959b Mon Sep 17 00:00:00 2001 From: Kevin Pfeifer Date: Mon, 30 Mar 2026 19:32:59 +0200 Subject: [PATCH] add rector --- composer.json | 3 + phpstan-baseline.neon | 12 + rector.php | 54 +++ src/BaseMigration.php | 35 +- src/BaseSeed.php | 27 +- src/Command/BakeMigrationCommand.php | 5 +- src/Command/BakeMigrationDiffCommand.php | 48 +- src/Command/BakeMigrationSnapshotCommand.php | 5 +- src/Command/BakeSeedCommand.php | 13 +- src/Command/BakeSimpleMigrationCommand.php | 10 +- src/Command/DumpCommand.php | 17 +- src/Command/EntryCommand.php | 6 +- src/Command/MarkMigratedCommand.php | 13 +- src/Command/MigrateCommand.php | 4 +- src/Command/RollbackCommand.php | 4 +- src/Command/SeedCommand.php | 4 +- src/Command/SeedResetCommand.php | 18 +- src/Command/SeedStatusCommand.php | 14 +- src/Command/SeedsEntryCommand.php | 6 +- src/Command/StatusCommand.php | 3 +- src/Command/UpgradeCommand.php | 24 +- src/Config/Config.php | 5 +- src/Config/ConfigInterface.php | 1 + src/Db/Action/Action.php | 3 - src/Db/Action/AddColumn.php | 2 - src/Db/Action/AddForeignKey.php | 2 - src/Db/Action/AddIndex.php | 2 - src/Db/Action/AddPartition.php | 3 - src/Db/Action/ChangeColumn.php | 6 +- src/Db/Action/ChangeComment.php | 2 - src/Db/Action/DropForeignKey.php | 2 - src/Db/Action/DropIndex.php | 2 - src/Db/Action/DropPartition.php | 3 - src/Db/Action/RemoveColumn.php | 2 - src/Db/Action/RenameColumn.php | 4 - src/Db/Action/RenameTable.php | 2 - src/Db/Action/SetPartitioning.php | 3 - src/Db/Adapter/AbstractAdapter.php | 112 ++--- src/Db/Adapter/AdapterFactory.php | 4 +- src/Db/Adapter/AdapterInterface.php | 50 ++ src/Db/Adapter/AdapterWrapper.php | 3 - src/Db/Adapter/MysqlAdapter.php | 89 ++-- src/Db/Adapter/PostgresAdapter.php | 94 ++-- src/Db/Adapter/RecordingAdapter.php | 2 +- src/Db/Adapter/SqliteAdapter.php | 237 +++++----- src/Db/Adapter/SqlserverAdapter.php | 42 +- src/Db/Adapter/TimedOutputAdapter.php | 10 +- src/Db/Expression.php | 4 +- src/Db/Literal.php | 4 +- src/Db/Plan/AlterTable.php | 2 - src/Db/Plan/NewTable.php | 2 - src/Db/Plan/Plan.php | 21 +- src/Db/Plan/Solver/ActionSplitter.php | 7 +- src/Db/Table.php | 60 +-- src/Db/Table/Column.php | 61 +-- src/Db/Table/ForeignKey.php | 6 + src/Db/Table/Partition.php | 11 +- src/Db/Table/TableMetadata.php | 6 - .../PendingMigrationsMiddleware.php | 2 - src/Migration/BuiltinBackend.php | 4 - src/Migration/Environment.php | 19 +- src/Migration/Manager.php | 109 ++--- src/Migration/ManagerFactory.php | 4 +- src/Migrations.php | 2 - src/TestSuite/Migrator.php | 31 +- src/Util/ColumnParser.php | 45 +- src/Util/TableFinder.php | 12 +- src/Util/Util.php | 14 +- src/Util/UtilTrait.php | 4 +- src/View/Helper/MigrationHelper.php | 33 +- .../Command/BakeMigrationCommandTest.php | 48 +- .../Command/BakeMigrationDiffCommandTest.php | 65 +-- .../BakeMigrationSnapshotCommandTest.php | 43 +- .../TestCase/Command/BakeSeedCommandTest.php | 20 +- tests/TestCase/Command/CompletionTest.php | 14 +- tests/TestCase/Command/DumpCommandTest.php | 6 +- tests/TestCase/Command/EntryCommandTest.php | 6 +- tests/TestCase/Command/MarkMigratedTest.php | 16 +- tests/TestCase/Command/MigrateCommandTest.php | 26 +- .../TestCase/Command/RollbackCommandTest.php | 7 +- tests/TestCase/Command/SeedCommandTest.php | 26 +- tests/TestCase/Command/StatusCommandTest.php | 5 +- tests/TestCase/Command/UpgradeCommandTest.php | 16 +- .../Config/ConfigMigrationPathsTest.php | 4 +- tests/TestCase/Config/ConfigSeedPathsTest.php | 6 +- tests/TestCase/Config/ConfigTest.php | 18 +- .../Db/Adapter/AbstractAdapterTest.php | 17 +- .../Db/Adapter/AdapterFactoryTest.php | 40 +- .../TestCase/Db/Adapter/MysqlAdapterTest.php | 422 +++++++++-------- .../Db/Adapter/PostgresAdapterTest.php | 323 ++++++------- .../Db/Adapter/RecordingAdapterTest.php | 37 +- .../TestCase/Db/Adapter/SqliteAdapterTest.php | 428 +++++++++--------- .../Db/Adapter/SqlserverAdapterTest.php | 176 ++++--- .../UnifiedMigrationsTableStorageTest.php | 16 +- tests/TestCase/Db/LiteralTest.php | 6 +- tests/TestCase/Db/Table/ColumnTest.php | 8 +- tests/TestCase/Db/Table/ForeignKeyTest.php | 29 +- tests/TestCase/Db/Table/IndexTest.php | 2 +- tests/TestCase/Db/Table/TableTest.php | 79 ++-- .../PendingMigrationsMiddlewareTest.php | 14 +- tests/TestCase/Migration/EnvironmentTest.php | 46 +- .../TestCase/Migration/ManagerFactoryTest.php | 8 +- tests/TestCase/Migration/ManagerTest.php | 88 ++-- tests/TestCase/MigrationsTest.php | 49 +- tests/TestCase/TestCase.php | 14 +- tests/TestCase/TestSuite/MigratorTest.php | 6 +- tests/TestCase/Util/ColumnParserTest.php | 32 +- tests/TestCase/Util/UtilTest.php | 16 +- .../20120111235330_test_migration.php | 4 +- .../View/Helper/MigrationHelperTest.php | 20 +- tests/bootstrap.php | 6 +- .../test_app/App/Http/TestRequestHandler.php | 5 +- .../Migrations/20211001000000_migrator.php | 2 +- .../Migrations2/20211002000000_migrator2.php | 2 +- ...0190928205056_first_fk_index_migration.php | 4 +- ...190928205060_second_fk_index_migration.php | 2 +- ...13232502_create_drop_fk_initial_schema.php | 2 +- .../20121223011815_add_regression_drop_fk.php | 2 +- .../20121223011816_change_fk_regression.php | 2 +- ...0121223011817_change_column_regression.php | 2 +- ...20190928205056_first_drop_fk_migration.php | 2 +- ...0190928205060_second_drop_fk_migration.php | 2 +- ...0120111235330_duplicate_migration_name.php | 4 +- ...0120111235331_duplicate_migration_name.php | 4 +- .../20120111235330_duplicate_migration.php | 4 +- .../20120111235330_duplicate_migration_2.php | 4 +- .../20120111235330_invalid_class.php | 4 +- .../20120111235330_test_migration.php | 4 +- .../20120116183504_test_migration_2.php | 4 +- .../20180516025208_snapshot_pgsql.php | 4 +- .../20121213232502_create_initial_schema.php | 2 +- .../20121223011815_update_info_table.php | 2 +- ...49_rename_info_table_to_statuses_table.php | 2 +- ...20121224200739_rename_bio_to_biography.php | 2 +- ...0121224200852_create_user_logins_table.php | 2 +- ...24134305_direction_aware_reversible_up.php | 2 +- ...121929_direction_aware_reversible_down.php | 2 +- .../20180431121930_tricky_edge_case.php | 2 +- ...reate_test_index_limit_specifier_table.php | 2 +- .../20190928220334_add_column_index_fk.php | 2 +- ...207205056_should_not_execute_migration.php | 2 +- ...0201207205057_should_execute_migration.php | 2 +- 142 files changed, 1813 insertions(+), 1957 deletions(-) create mode 100644 rector.php diff --git a/composer.json b/composer.json index 2f2b54396..e4cea556e 100644 --- a/composer.json +++ b/composer.json @@ -76,6 +76,9 @@ "stan-setup": "phive install", "lowest": "validate-prefer-lowest", "lowest-setup": "composer update --prefer-lowest --prefer-stable --prefer-dist --no-interaction && cp composer.json composer.backup && composer require --dev dereuromark/composer-prefer-lowest && mv composer.backup composer.json", + "rector-setup": "cp composer.json composer.backup && composer require --dev rector/rector:\"~2.3.1\" && mv composer.backup composer.json", + "rector-check": "vendor/bin/rector process --dry-run", + "rector-fix": "vendor/bin/rector process", "test": "phpunit", "test-coverage": "phpunit --coverage-clover=clover.xml" } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 2cda39ed2..9a7200326 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -60,12 +60,24 @@ parameters: count: 1 path: src/Migration/Environment.php + - + message: '#^Method Migrations\\Migration\\Manager\:\:getMigrationClassName\(\) should return class\-string\ but returns string\.$#' + identifier: return.type + count: 2 + path: src/Migration/Manager.php + - message: '#^Parameter \#1 \.\.\.\$arg1 of function max expects non\-empty\-array, array given\.$#' identifier: argument.type count: 1 path: src/Migration/Manager.php + - + message: '#^Parameter \#3 \$length of function substr expects int\|null, int\<0, max\>\|false given\.$#' + identifier: argument.type + count: 1 + path: src/Migration/Manager.php + - message: '#^Offset 0 on non\-empty\-list\ in isset\(\) always exists and is not nullable\.$#' identifier: isset.offset diff --git a/rector.php b/rector.php new file mode 100644 index 000000000..a93e7edcf --- /dev/null +++ b/rector.php @@ -0,0 +1,54 @@ +withPaths([ + __DIR__ . '/src', + __DIR__ . '/tests', + ]) + + ->withCache( + cacheClass: FileCacheStorage::class, + cacheDirectory: $cacheDir, + ) + + ->withPhpSets() + ->withAttributesSets() + + ->withSets([ + SetList::CODE_QUALITY, + SetList::CODING_STYLE, + SetList::DEAD_CODE, + SetList::EARLY_RETURN, + SetList::INSTANCEOF, + SetList::TYPE_DECLARATION, + ]) + + ->withSkip([ + ClassPropertyAssignToConstructorPromotionRector::class, + CatchExceptionNameMatchingTypeRector::class, + ClosureToArrowFunctionRector::class, + RemoveUselessReturnTagRector::class, + CompactToVariablesRector::class, + ReturnTypeFromStrictFluentReturnRector::class, + SplitDoubleAssignRector::class, + NewlineAfterStatementRector::class, + ExplicitBoolCompareRector::class, + TypedPropertyFromCreateMockAssignRector::class, + ]); diff --git a/src/BaseMigration.php b/src/BaseMigration.php index 2969933aa..1e521d461 100644 --- a/src/BaseMigration.php +++ b/src/BaseMigration.php @@ -30,24 +30,18 @@ class BaseMigration implements MigrationInterface { /** * The Adapter instance - * - * @var \Migrations\Db\Adapter\AdapterInterface */ protected ?AdapterInterface $adapter = null; /** * The ConsoleIo instance - * - * @var \Cake\Console\ConsoleIo */ protected ?ConsoleIo $io = null; /** * The config instance. - * - * @var \Migrations\Config\ConfigInterface */ - protected ?ConfigInterface $config; + protected ?ConfigInterface $config = null; /** * List of all the table objects created by this migration @@ -58,15 +52,11 @@ class BaseMigration implements MigrationInterface /** * Is migrating up prop - * - * @var bool */ protected bool $isMigratingUp = true; /** * The version number. - * - * @var int */ protected int $version; @@ -77,8 +67,6 @@ class BaseMigration implements MigrationInterface * This option is global for all tables created in the migration file. * If you set it to false, you have to manually add the primary keys for your * tables using the Migrations\Table::addPrimaryKey() method - * - * @var bool */ public bool $autoId = true; @@ -110,7 +98,7 @@ public function setAdapter(AdapterInterface $adapter) */ public function getAdapter(): AdapterInterface { - if (!$this->adapter) { + if (!$this->adapter instanceof AdapterInterface) { throw new RuntimeException('Adapter not set.'); } @@ -458,18 +446,13 @@ public function index(string|array $columns): Index */ public function preFlightCheck(): void { - if (method_exists($this, MigrationInterface::CHANGE)) { - if ( - method_exists($this, MigrationInterface::UP) || - method_exists($this, MigrationInterface::DOWN) - ) { - $io = $this->getIo(); - if ($io) { - $io->out( - 'warning Migration contains both change() and up()/down() methods.' . - ' Ignoring up() and down().', - ); - } + if (method_exists($this, MigrationInterface::CHANGE) && (method_exists($this, MigrationInterface::UP) || method_exists($this, MigrationInterface::DOWN))) { + $io = $this->getIo(); + if ($io instanceof ConsoleIo) { + $io->out( + 'warning Migration contains both change() and up()/down() methods.' . + ' Ignoring up() and down().', + ); } } } diff --git a/src/BaseSeed.php b/src/BaseSeed.php index 146abc4e1..634fa9b27 100644 --- a/src/BaseSeed.php +++ b/src/BaseSeed.php @@ -25,31 +25,18 @@ class BaseSeed implements SeedInterface { /** * The Adapter instance - * - * @var \Migrations\Db\Adapter\AdapterInterface */ protected ?AdapterInterface $adapter = null; /** * The ConsoleIo instance - * - * @var \Cake\Console\ConsoleIo */ protected ?ConsoleIo $io = null; /** * The config instance. - * - * @var \Migrations\Config\ConfigInterface - */ - protected ?ConfigInterface $config; - - /** - * No-op constructor. */ - public function __construct() - { - } + protected ?ConfigInterface $config = null; /** * {@inheritDoc} @@ -81,7 +68,7 @@ public function setAdapter(AdapterInterface $adapter) */ public function getAdapter(): AdapterInterface { - if (!$this->adapter) { + if (!$this->adapter instanceof AdapterInterface) { throw new RuntimeException('Adapter not set.'); } @@ -130,10 +117,8 @@ public function setConfig(ConfigInterface $config) public function getName(): string { $name = static::class; - if (str_starts_with($name, 'Migrations\BaseSeed@anonymous')) { - if (preg_match('#[/\\\\]([a-zA-Z0-9_]+)\.php:#', $name, $matches)) { - $name = $matches[1]; - } + if (str_starts_with($name, 'Migrations\BaseSeed@anonymous') && preg_match('#[/\\\\](\w+)\.php:#', $name, $matches)) { + return $matches[1]; } return $name; @@ -238,7 +223,7 @@ public function isIdempotent(): bool public function call(string $seeder, array $options = []): void { $io = $this->getIo(); - if ($io === null) { + if (!$io instanceof ConsoleIo) { throw new RuntimeException('ConsoleIo is required for calling other seeders.'); } $io->out(''); @@ -287,7 +272,7 @@ protected function runCall(string $seeder, array $options = []): void 'source' => $options['source'], ]); $io = $this->getIo(); - if ($io === null) { + if (!$io instanceof ConsoleIo) { throw new RuntimeException('ConsoleIo is required for calling other seeders.'); } $manager = $factory->createManager($io); diff --git a/src/Command/BakeMigrationCommand.php b/src/Command/BakeMigrationCommand.php index c727b03ee..8b59fc715 100644 --- a/src/Command/BakeMigrationCommand.php +++ b/src/Command/BakeMigrationCommand.php @@ -29,9 +29,6 @@ */ class BakeMigrationCommand extends BakeSimpleMigrationCommand { - /** - * @var string - */ protected string $_name; /** @@ -45,7 +42,7 @@ public static function defaultName(): string /** * @inheritDoc */ - public function bake(string $name, Arguments $args, ConsoleIo $io): void + protected function bake(string $name, Arguments $args, ConsoleIo $io): void { EventManager::instance()->on('Bake.initialize', function (Event $event): void { /** @var \Bake\View\BakeView $view */ diff --git a/src/Command/BakeMigrationDiffCommand.php b/src/Command/BakeMigrationDiffCommand.php index 920af9371..08418fc0d 100644 --- a/src/Command/BakeMigrationDiffCommand.php +++ b/src/Command/BakeMigrationDiffCommand.php @@ -50,29 +50,21 @@ class BakeMigrationDiffCommand extends BakeSimpleMigrationCommand /** * Array of migrations that have already been migrated - * - * @var array */ protected array $migratedItems = []; /** * Path to the migration files - * - * @var string */ protected string $migrationsPath; /** * Migration files that are stored in the self::migrationsPath - * - * @var array */ protected array $migrationsFiles = []; /** * Name of the phinx log table - * - * @var string */ protected string $phinxTable; @@ -121,7 +113,7 @@ public static function defaultName(): string /** * @inheritDoc */ - public function bake(string $name, Arguments $args, ConsoleIo $io): void + protected function bake(string $name, Arguments $args, ConsoleIo $io): void { $this->setup($args); @@ -271,7 +263,7 @@ protected function getColumns(): void foreach ($addedColumns as $columnName) { $column = $this->safeGetColumn($currentSchema, $columnName); /** @var int $key */ - $key = array_search($columnName, $currentColumns); + $key = array_search($columnName, $currentColumns, true); if ($key > 0) { $column['after'] = $currentColumns[$key - 1]; } @@ -359,16 +351,14 @@ protected function getColumns(): void $this->templateData[$table]['columns']['remove'] = []; } $removedColumns = array_diff($oldColumns, $currentColumns); - if ($removedColumns) { - foreach ($removedColumns as $columnName) { - $column = $this->safeGetColumn($this->dumpSchema[$table], $columnName); - /** @var int $key */ - $key = array_search($columnName, $oldColumns); - if ($key > 0) { - $column['after'] = $oldColumns[$key - 1]; - } - $this->templateData[$table]['columns']['remove'][$columnName] = $column; + foreach ($removedColumns as $columnName) { + $column = $this->safeGetColumn($this->dumpSchema[$table], $columnName); + /** @var int $key */ + $key = array_search($columnName, $oldColumns, true); + if ($key > 0) { + $column['after'] = $oldColumns[$key - 1]; } + $this->templateData[$table]['columns']['remove'][$columnName] = $column; } } } @@ -475,10 +465,8 @@ protected function getIndexes(): void $removedIndexes = array_diff($oldIndexes, $currentIndexes); $parts = []; - if ($removedIndexes) { - foreach ($removedIndexes as $index) { - $parts[$index] = $this->dumpSchema[$table]->getIndex($index); - } + foreach ($removedIndexes as $index) { + $parts[$index] = $this->dumpSchema[$table]->getIndex($index); } $this->templateData[$table]['indexes']['remove'] = array_merge( $this->templateData[$table]['indexes']['remove'], @@ -516,7 +504,7 @@ protected function checkSync(): bool // Extract version numbers from current context's migration files $fileVersions = []; foreach ($this->migrationsFiles as $file) { - $filename = basename($file); + $filename = basename((string)$file); if (preg_match('/^(\d+)_/', $filename, $matches)) { $fileVersions[] = $matches[1]; } @@ -530,7 +518,7 @@ protected function checkSync(): bool } } - if (empty($contextMigratedVersions)) { + if ($contextMigratedVersions === []) { // No migrations from this context have been run yet return false; } @@ -539,7 +527,7 @@ protected function checkSync(): bool $lastVersion = max($contextMigratedVersions); $lastFile = end($this->migrationsFiles); - return $lastFile && str_contains($lastFile, $lastVersion); + return $lastFile && str_contains((string)$lastFile, $lastVersion); } /** @@ -555,6 +543,7 @@ protected function bakeSnapshot(string $name, Arguments $args, ConsoleIo $io): ? { $io->out('Your migrations history is empty and you do not have any migrations files.'); $io->out('Falling back to baking a snapshot...'); + $newArgs = []; $newArgs[] = $name; @@ -644,10 +633,13 @@ protected function getCurrentSchema(): array } foreach ($tablesToDescribe as $table) { - if (preg_match('/^.*phinxlog$/', $table) === 1) { + if (preg_match('/^.*phinxlog$/', (string)$table) === 1) { + continue; + } + if ($table === 'cake_migrations') { continue; } - if ($table === 'cake_migrations' || $table === 'cake_seeds') { + if ($table === 'cake_seeds') { continue; } diff --git a/src/Command/BakeMigrationSnapshotCommand.php b/src/Command/BakeMigrationSnapshotCommand.php index 259b62bfd..54afb2c85 100644 --- a/src/Command/BakeMigrationSnapshotCommand.php +++ b/src/Command/BakeMigrationSnapshotCommand.php @@ -35,9 +35,6 @@ class BakeMigrationSnapshotCommand extends BakeSimpleMigrationCommand use SnapshotTrait; use UtilTrait; - /** - * @var string - */ protected string $_name; /** @@ -51,7 +48,7 @@ public static function defaultName(): string /** * @inheritDoc */ - public function bake(string $name, Arguments $args, ConsoleIo $io): void + protected function bake(string $name, Arguments $args, ConsoleIo $io): void { $collection = $this->getCollection($this->connection); diff --git a/src/Command/BakeSeedCommand.php b/src/Command/BakeSeedCommand.php index 8cedabf45..cecf2ec99 100644 --- a/src/Command/BakeSeedCommand.php +++ b/src/Command/BakeSeedCommand.php @@ -32,20 +32,13 @@ class BakeSeedCommand extends SimpleBakeCommand { /** * path to Migration directory - * - * @var string */ public string $pathFragment = 'config/Seeds/'; - /** - * @var string - */ protected string $_name; /** * Arguments - * - * @var \Cake\Console\Arguments|null */ protected ?Arguments $args = null; @@ -160,7 +153,7 @@ public function templateData(Arguments $arguments): array /** * @inheritDoc */ - public function bake(string $name, Arguments $args, ConsoleIo $io): void + protected function bake(string $name, Arguments $args, ConsoleIo $io): void { $this->args = $args; /** @var array $options */ @@ -257,7 +250,7 @@ protected function prettifyArray(array $array, int $tabCount = 3, string $indent if ($line[$j] === '\\') { // skip character right after an escape \ $j++; - } elseif ($line[$j] === '\'') { + } elseif ($line[$j] === "'") { // check string open/end $inString = !$inString; } @@ -272,7 +265,7 @@ protected function prettifyArray(array $array, int $tabCount = 3, string $indent unset($line); // Remove marked lines - $lines = array_filter($lines, function ($line) { + $lines = array_filter($lines, function ($line): bool { return $line !== false; }); diff --git a/src/Command/BakeSimpleMigrationCommand.php b/src/Command/BakeSimpleMigrationCommand.php index 622b61fcc..622f4d1cb 100644 --- a/src/Command/BakeSimpleMigrationCommand.php +++ b/src/Command/BakeSimpleMigrationCommand.php @@ -44,22 +44,16 @@ abstract class BakeSimpleMigrationCommand extends SimpleBakeCommand /** * path to Migration directory - * - * @var string */ public string $pathFragment = 'config'; /** * Console IO - * - * @var \Cake\Console\ConsoleIo|null */ protected ?ConsoleIo $io = null; /** * Arguments - * - * @var \Cake\Console\Arguments|null */ protected ?Arguments $args = null; @@ -154,7 +148,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int /** * @inheritDoc */ - public function bake(string $name, Arguments $args, ConsoleIo $io): void + protected function bake(string $name, Arguments $args, ConsoleIo $io): void { $this->io = $io; $this->args = $args; @@ -189,6 +183,7 @@ public function bake(string $name, Arguments $args, ConsoleIo $io): void $renderer = new TemplateRenderer($this->theme); $renderer->set('name', $name); $renderer->set($this->templateData($args)); + $contents = $renderer->generate($this->template()); $path = $this->getPath($args); @@ -271,7 +266,6 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar /** * If reserved PHP keyword. * - * @param string $name * @return bool */ protected function isReservedKeyword(string $name): bool diff --git a/src/Command/DumpCommand.php b/src/Command/DumpCommand.php index ff779e598..d0469a06b 100644 --- a/src/Command/DumpCommand.php +++ b/src/Command/DumpCommand.php @@ -45,7 +45,6 @@ public static function defaultName(): string /** * Extract options for the dump command from another migrations option parser. * - * @param \Cake\Console\Arguments $args * @return array */ public static function extractArgs(Arguments $args): array @@ -74,7 +73,7 @@ public static function extractArgs(Arguments $args): array * @param \Cake\Console\ConsoleOptionParser $parser The option parser to configure * @return \Cake\Console\ConsoleOptionParser */ - public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser + protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { $parser->setDescription([ 'Dumps the current schema of the database to be used while baking a diff', @@ -133,21 +132,19 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $tables = $finder->getTablesToBake($collection, $options); $dump = []; - if ($tables) { - foreach ($tables as $table) { - $schema = $collection->describe($table); - $dump[$table] = $schema; - } + foreach ($tables as $table) { + $schema = $collection->describe($table); + $dump[$table] = $schema; } $filePath = $path . DS . 'schema-dump-' . $connectionName . '.lock'; - $io->verbose("Writing dump file `{$filePath}`..."); + $io->verbose(sprintf('Writing dump file `%s`...', $filePath)); if (file_put_contents($filePath, serialize($dump))) { - $io->verbose("Dump file `{$filePath}` was successfully written"); + $io->verbose(sprintf('Dump file `%s` was successfully written', $filePath)); return self::CODE_SUCCESS; } - $io->err("An error occurred while writing dump file `{$filePath}`"); + $io->err(sprintf('An error occurred while writing dump file `%s`', $filePath)); return self::CODE_ERROR; } diff --git a/src/Command/EntryCommand.php b/src/Command/EntryCommand.php index 3651d928d..0577b2dbc 100644 --- a/src/Command/EntryCommand.php +++ b/src/Command/EntryCommand.php @@ -31,8 +31,6 @@ class EntryCommand extends Command implements CommandCollectionAwareInterface { /** * The command collection to get help on. - * - * @var \Cake\Console\CommandCollection */ protected CommandCollection $commands; @@ -109,7 +107,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int if ($args->hasArgumentAt(0)) { $name = $args->getArgumentAt(0); $io->err( - "Could not find migrations command named `$name`." + sprintf('Could not find migrations command named `%s`.', $name) . ' Run `migrations --help` to get a list of commands.', ); @@ -135,7 +133,7 @@ public function getHelp(): HelpCommand // Remove `migrations` array_shift($parts); - if (count($parts) === 0) { + if ($parts === []) { continue; } $commands[$command] = $class; diff --git a/src/Command/MarkMigratedCommand.php b/src/Command/MarkMigratedCommand.php index bb7cb6f44..6e86a36c3 100644 --- a/src/Command/MarkMigratedCommand.php +++ b/src/Command/MarkMigratedCommand.php @@ -42,7 +42,7 @@ public static function defaultName(): string * @param \Cake\Console\ConsoleOptionParser $parser The option parser to configure * @return \Cake\Console\ConsoleOptionParser */ - public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser + protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { $parser->setDescription([ 'Mark a migration as applied', @@ -95,9 +95,12 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar */ protected function invalidOnlyOrExclude(Arguments $args): bool { - return ($args->getOption('exclude') && $args->getOption('only')) || - ($args->getOption('exclude') || $args->getOption('only')) && - $args->getOption('target') === null; + if ($args->getOption('exclude') && $args->getOption('only')) { + return true; + } + + return ($args->getOption('exclude') || $args->getOption('only')) && + $args->getOption('target') === null; } /** @@ -135,7 +138,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int } $output = $manager->markVersionsAsMigrated($path, $versions); - array_map(fn($line) => $io->out($line), $output); + array_map(fn(string $line): ?int => $io->out($line), $output); return self::CODE_SUCCESS; } diff --git a/src/Command/MigrateCommand.php b/src/Command/MigrateCommand.php index abc73655f..a5aab5f4f 100644 --- a/src/Command/MigrateCommand.php +++ b/src/Command/MigrateCommand.php @@ -50,7 +50,7 @@ public static function defaultName(): string * @param \Cake\Console\ConsoleOptionParser $parser The option parser to configure * @return \Cake\Console\ConsoleOptionParser */ - public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser + protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { $parser->setDescription([ 'Apply migrations to a SQL datasource', @@ -152,7 +152,7 @@ protected function executeMigrations(Arguments $args, ConsoleIo $io): ?int if ($config->isDryRun()) { $io->info('DRY-RUN mode enabled'); } - $io->verbose('using connection ' . (string)$args->getOption('connection')); + $io->verbose('using connection ' . $args->getOption('connection')); $io->verbose('using paths ' . $config->getMigrationPath()); $io->verbose('ordering by ' . $versionOrder . ' time'); diff --git a/src/Command/RollbackCommand.php b/src/Command/RollbackCommand.php index d3647f542..7e4ae14ec 100644 --- a/src/Command/RollbackCommand.php +++ b/src/Command/RollbackCommand.php @@ -51,7 +51,7 @@ public static function defaultName(): string * @param \Cake\Console\ConsoleOptionParser $parser The option parser to configure * @return \Cake\Console\ConsoleOptionParser */ - public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser + protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { $parser->setDescription([ 'Rollback migrations to a specific migration', @@ -154,7 +154,7 @@ protected function executeMigrations(Arguments $args, ConsoleIo $io): ?int $config = $manager->getConfig(); $versionOrder = $config->getVersionOrder(); - $io->verbose('using connection ' . (string)$args->getOption('connection')); + $io->verbose('using connection ' . $args->getOption('connection')); $io->verbose('using paths ' . $config->getMigrationPath()); $io->verbose('ordering by ' . $versionOrder . ' time'); diff --git a/src/Command/SeedCommand.php b/src/Command/SeedCommand.php index 9ccb761b1..38154ea65 100644 --- a/src/Command/SeedCommand.php +++ b/src/Command/SeedCommand.php @@ -49,7 +49,7 @@ public static function defaultName(): string * @param \Cake\Console\ConsoleOptionParser $parser The option parser to configure * @return \Cake\Console\ConsoleOptionParser */ - public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser + protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { $description = [ 'Seed the database with data', @@ -166,7 +166,7 @@ protected function executeSeeds(Arguments $args, ConsoleIo $io): ?int if ($fake) { $io->warning('performing fake seeding'); } - $io->verbose('using connection ' . (string)$args->getOption('connection')); + $io->verbose('using connection ' . $args->getOption('connection')); $io->verbose('using paths ' . $config->getMigrationPath()); $io->verbose('ordering by ' . $versionOrder . ' time'); diff --git a/src/Command/SeedResetCommand.php b/src/Command/SeedResetCommand.php index f11964d03..f35daf45a 100644 --- a/src/Command/SeedResetCommand.php +++ b/src/Command/SeedResetCommand.php @@ -42,7 +42,7 @@ public static function defaultName(): string * @param \Cake\Console\ConsoleOptionParser $parser The option parser to configure * @return \Cake\Console\ConsoleOptionParser */ - public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser + protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { $parser->setDescription([ 'The reset command removes seed execution records from the log', @@ -98,7 +98,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $io->info('DRY-RUN mode enabled'); } - $io->verbose('using connection ' . (string)$args->getOption('connection')); + $io->verbose('using connection ' . $args->getOption('connection')); $io->verbose('using paths ' . $config->getSeedPath()); $seeds = $manager->getSeeds(); @@ -109,13 +109,13 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $seedsToReset = $seeds; if ($seedOption) { - $requestedSeeds = array_map('trim', explode(',', (string)$seedOption)); + $requestedSeeds = array_map(trim(...), explode(',', (string)$seedOption)); $seedsToReset = []; foreach ($requestedSeeds as $requestedSeed) { $normalizedName = $manager->normalizeSeedName($requestedSeed, $seeds); if ($normalizedName === null) { - $io->error("Seed `{$requestedSeed}` does not exist."); + $io->error(sprintf('Seed `%s` does not exist.', $requestedSeed)); return self::CODE_ERROR; } @@ -123,7 +123,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int } } - if (empty($seedsToReset)) { + if ($seedsToReset === []) { $io->warning('No seeds to reset.'); return self::CODE_SUCCESS; @@ -155,18 +155,18 @@ public function execute(Arguments $args, ConsoleIo $io): ?int if (!$config->isDryRun()) { $adapter->removeSeedFromLog($seed); } - $io->info("Reset: {$seedName} seed"); + $io->info(sprintf('Reset: %s seed', $seedName)); $count++; } else { - $io->verbose("Skipped (not executed): {$seedName} seed"); + $io->verbose(sprintf('Skipped (not executed): %s seed', $seedName)); } } $io->out(''); if ($config->isDryRun()) { - $io->success("DRY-RUN: Would reset {$count} seed(s)."); + $io->success(sprintf('DRY-RUN: Would reset %d seed(s).', $count)); } else { - $io->success("Reset {$count} seed(s)."); + $io->success(sprintf('Reset %d seed(s).', $count)); } return self::CODE_SUCCESS; diff --git a/src/Command/SeedStatusCommand.php b/src/Command/SeedStatusCommand.php index 49a49d66f..68f983136 100644 --- a/src/Command/SeedStatusCommand.php +++ b/src/Command/SeedStatusCommand.php @@ -43,7 +43,7 @@ public static function defaultName(): string * @param \Cake\Console\ConsoleOptionParser $parser The option parser to configure * @return \Cake\Console\ConsoleOptionParser */ - public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser + protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { $parser->setDescription([ 'The status command prints a list of all seeds, along with their execution status', @@ -91,7 +91,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $manager = $factory->createManager($io); $config = $manager->getConfig(); - $io->verbose('using connection ' . (string)$args->getOption('connection')); + $io->verbose('using connection ' . $args->getOption('connection')); $io->verbose('using paths ' . $config->getSeedPath()); $seeds = $manager->getSeeds(); @@ -109,7 +109,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $appNamespace = Configure::read('App.namespace', 'App'); foreach ($seeds as $seed) { $plugin = null; - $className = get_class($seed); + $className = $seed::class; if (str_contains($className, '\\')) { $parts = explode('\\', $className); @@ -163,8 +163,8 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $io->out('Current seed execution status:'); $io->out(''); - $maxNameLength = max(array_map(fn($s) => strlen($s['seedName']), $statuses)); - $maxPluginLength = max(array_map(fn($s) => strlen($s['plugin'] ?? ''), $statuses)); + $maxNameLength = max(array_map(fn(array $s): int => strlen($s['seedName']), $statuses)); + $maxPluginLength = max(array_map(fn(array $s): int => strlen($s['plugin'] ?? ''), $statuses)); foreach ($statuses as $status) { $seedName = str_pad($status['seedName'], $maxNameLength); @@ -174,10 +174,10 @@ public function execute(Arguments $args, ConsoleIo $io): ?int if ($status['status'] === 'executed') { $statusText = 'executed'; $date = $status['executedAt'] ? ' (' . $status['executedAt'] . ')' : ''; - $io->out(" {$statusText} {$plugin} {$seedName}{$date}{$idempotent}"); + $io->out(sprintf(' %s %s %s%s%s', $statusText, $plugin, $seedName, $date, $idempotent)); } else { $statusText = 'pending '; - $io->out(" {$statusText} {$plugin} {$seedName}{$idempotent}"); + $io->out(sprintf(' %s %s %s%s', $statusText, $plugin, $seedName, $idempotent)); } } diff --git a/src/Command/SeedsEntryCommand.php b/src/Command/SeedsEntryCommand.php index e353b7db5..cc0ea6f57 100644 --- a/src/Command/SeedsEntryCommand.php +++ b/src/Command/SeedsEntryCommand.php @@ -31,8 +31,6 @@ class SeedsEntryCommand extends Command implements CommandCollectionAwareInterfa { /** * The command collection to get help on. - * - * @var \Cake\Console\CommandCollection */ protected CommandCollection $commands; @@ -109,7 +107,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int if ($args->hasArgumentAt(0)) { $name = $args->getArgumentAt(0); $io->err( - "Could not find seeds command named `$name`." + sprintf('Could not find seeds command named `%s`.', $name) . ' Run `seeds --help` to get a list of commands.', ); @@ -135,7 +133,7 @@ public function getHelp(): HelpCommand // Remove `seeds` array_shift($parts); - if (count($parts) === 0) { + if ($parts === []) { continue; } $commands[$command] = $class; diff --git a/src/Command/StatusCommand.php b/src/Command/StatusCommand.php index 7d344c604..7fb7defcd 100644 --- a/src/Command/StatusCommand.php +++ b/src/Command/StatusCommand.php @@ -57,7 +57,7 @@ public static function defaultName(): string * @param \Cake\Console\ConsoleOptionParser $parser The option parser to configure * @return \Cake\Console\ConsoleOptionParser */ - public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser + protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { $parser->setDescription([ 'The status command prints a list of all migrations, along with their current status', @@ -146,7 +146,6 @@ public function execute(Arguments $args, ConsoleIo $io): ?int /** * Print migration status to stdout. * - * @param array $migrations * @param \Cake\Console\ConsoleIo $io The console io * @param string $tableName The migration tracking table name * @return void diff --git a/src/Command/UpgradeCommand.php b/src/Command/UpgradeCommand.php index 140eb02f2..ba2ab65f3 100644 --- a/src/Command/UpgradeCommand.php +++ b/src/Command/UpgradeCommand.php @@ -51,7 +51,7 @@ public static function defaultName(): string * @param \Cake\Console\ConsoleOptionParser $parser The option parser to configure * @return \Cake\Console\ConsoleOptionParser */ - public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser + protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { $parser->setDescription([ 'Upgrades migration tracking from legacy phinxlog tables to unified cake_migrations table.', @@ -114,20 +114,20 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $io->out(sprintf('Found %d phinxlog table(s):', count($legacyTables))); foreach ($legacyTables as $table => $plugin) { - $pluginLabel = $plugin === null ? '(app)' : "({$plugin})"; - $io->out(" - {$table} {$pluginLabel}"); + $pluginLabel = $plugin === null ? '(app)' : sprintf('(%s)', $plugin); + $io->out(sprintf(' - %s %s', $table, $pluginLabel)); } $io->out(''); // Create unified table if needed $unifiedTableName = UnifiedMigrationsTableStorage::TABLE_NAME; if (!$this->tableExists($connection, $unifiedTableName)) { - $io->out("Creating unified table {$unifiedTableName}..."); + $io->out(sprintf('Creating unified table %s...', $unifiedTableName)); if (!$dryRun) { $this->createUnifiedTable($connection, $io); } } else { - $io->out("Unified table {$unifiedTableName} already exists."); + $io->out(sprintf('Unified table %s already exists.', $unifiedTableName)); } $io->out(''); @@ -144,10 +144,10 @@ public function execute(Arguments $args, ConsoleIo $io): ?int if (!$dryRun) { // Clean up legacy tables $io->out(''); - foreach ($legacyTables as $tableName => $plugin) { + foreach (array_keys($legacyTables) as $tableName) { if ($dropTables) { - $io->out("Dropping legacy table {$tableName}..."); - $connection->execute("DROP TABLE {$connection->getDriver()->quoteIdentifier($tableName)}"); + $io->out(sprintf('Dropping legacy table %s...', $tableName)); + $connection->execute('DROP TABLE ' . $connection->getDriver()->quoteIdentifier($tableName)); } else { $io->out('Retaining legacy table. You should drop these tables once you have verified your upgrade.'); } @@ -158,12 +158,12 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $io->out(''); $io->out('Next steps:'); if ($dropTables) { - $io->out(' 1. Set \'Migrations\' => [\'legacyTables\' => false] in your config'); + $io->out(" 1. Set 'Migrations' => ['legacyTables' => false] in your config"); $io->out(' 2. Test your application'); } else { $io->out(' 1. Test your application'); $io->out(' 2. Drop the phinxlog tables (re-run `bin/cake migrations upgrade --drop-tables`)'); - $io->out(' 3. Set \'Migrations\' => [\'legacyTables\' => false] in your config'); + $io->out(" 3. Set 'Migrations' => ['legacyTables' => false] in your config"); } } else { $io->out(''); @@ -299,7 +299,7 @@ protected function migrateTable( $rows = $query->execute()->fetchAll('assoc'); $count = count($rows); - $io->out("Migrating {$count} record(s) from {$tableName} ({$pluginLabel})..."); + $io->out(sprintf('Migrating %d record(s) from %s (%s)...', $count, $tableName, $pluginLabel)); if ($dryRun || $count === 0) { return $count; @@ -320,7 +320,7 @@ protected function migrateTable( 'breakpoint' => (int)($row['breakpoint'] ?? 0), ]); $insertQuery->execute(); - } catch (QueryException $e) { + } catch (QueryException) { $io->out('Already migrated ' . $row['migration_name'] . '.'); } } diff --git a/src/Config/Config.php b/src/Config/Config.php index 03361772d..829f1358b 100644 --- a/src/Config/Config.php +++ b/src/Config/Config.php @@ -28,9 +28,6 @@ class Config implements ConfigInterface */ public const VERSION_ORDER_EXECUTION_TIME = 'execution'; - /** - * @var array - */ protected array $values = []; /** @@ -114,7 +111,7 @@ public function isVersionOrderCreationTime(): bool { $versionOrder = $this->getVersionOrder(); - return $versionOrder == self::VERSION_ORDER_CREATION_TIME; + return $versionOrder === self::VERSION_ORDER_CREATION_TIME; } /** diff --git a/src/Config/ConfigInterface.php b/src/Config/ConfigInterface.php index 57e4ffc7f..e4cb37cc9 100644 --- a/src/Config/ConfigInterface.php +++ b/src/Config/ConfigInterface.php @@ -18,6 +18,7 @@ interface ConfigInterface extends ArrayAccess { public const DEFAULT_MIGRATION_FOLDER = 'Migrations'; + public const DEFAULT_SEED_FOLDER = 'Seeds'; /** diff --git a/src/Db/Action/Action.php b/src/Db/Action/Action.php index 4718b2682..73fddf752 100644 --- a/src/Db/Action/Action.php +++ b/src/Db/Action/Action.php @@ -12,9 +12,6 @@ abstract class Action { - /** - * @var \Migrations\Db\Table\TableMetadata - */ protected TableMetadata $table; /** diff --git a/src/Db/Action/AddColumn.php b/src/Db/Action/AddColumn.php index c4948740a..5029d727b 100644 --- a/src/Db/Action/AddColumn.php +++ b/src/Db/Action/AddColumn.php @@ -15,8 +15,6 @@ class AddColumn extends Action { /** * The column to add - * - * @var \Migrations\Db\Table\Column */ protected Column $column; diff --git a/src/Db/Action/AddForeignKey.php b/src/Db/Action/AddForeignKey.php index a1cfa00c5..f7a97cabd 100644 --- a/src/Db/Action/AddForeignKey.php +++ b/src/Db/Action/AddForeignKey.php @@ -15,8 +15,6 @@ class AddForeignKey extends Action { /** * The foreign key to add - * - * @var \Migrations\Db\Table\ForeignKey */ protected ForeignKey $foreignKey; diff --git a/src/Db/Action/AddIndex.php b/src/Db/Action/AddIndex.php index f818ed4c6..85d38a207 100644 --- a/src/Db/Action/AddIndex.php +++ b/src/Db/Action/AddIndex.php @@ -15,8 +15,6 @@ class AddIndex extends Action { /** * The index to add to the table - * - * @var \Migrations\Db\Table\Index */ protected Index $index; diff --git a/src/Db/Action/AddPartition.php b/src/Db/Action/AddPartition.php index aeb0a0bdc..a87d6feaf 100644 --- a/src/Db/Action/AddPartition.php +++ b/src/Db/Action/AddPartition.php @@ -16,9 +16,6 @@ */ class AddPartition extends Action { - /** - * @var \Migrations\Db\Table\PartitionDefinition - */ protected PartitionDefinition $partition; /** diff --git a/src/Db/Action/ChangeColumn.php b/src/Db/Action/ChangeColumn.php index 267e30aa9..cb2fa7192 100644 --- a/src/Db/Action/ChangeColumn.php +++ b/src/Db/Action/ChangeColumn.php @@ -15,15 +15,11 @@ class ChangeColumn extends Action { /** * The column definition - * - * @var \Migrations\Db\Table\Column */ protected Column $column; /** * The name of the column to be changed - * - * @var string */ protected string $columnName; @@ -41,7 +37,7 @@ public function __construct(TableMetadata $table, string $columnName, Column $co $this->column = $column; // if the name was omitted use the existing column name - if ($column->getName() === null || strlen((string)$column->getName()) === 0) { + if ($column->getName() === null || $column->getName() === '') { $column->setName($columnName); } } diff --git a/src/Db/Action/ChangeComment.php b/src/Db/Action/ChangeComment.php index 0fb773c90..d3b2d4f4b 100644 --- a/src/Db/Action/ChangeComment.php +++ b/src/Db/Action/ChangeComment.php @@ -14,8 +14,6 @@ class ChangeComment extends Action { /** * The new comment for the table - * - * @var string|null */ protected ?string $newComment = null; diff --git a/src/Db/Action/DropForeignKey.php b/src/Db/Action/DropForeignKey.php index c311f1bc8..5e9cfde9d 100644 --- a/src/Db/Action/DropForeignKey.php +++ b/src/Db/Action/DropForeignKey.php @@ -15,8 +15,6 @@ class DropForeignKey extends Action { /** * The foreign key to remove - * - * @var \Migrations\Db\Table\ForeignKey */ protected ForeignKey $foreignKey; diff --git a/src/Db/Action/DropIndex.php b/src/Db/Action/DropIndex.php index 4c9bbf014..9299dd36d 100644 --- a/src/Db/Action/DropIndex.php +++ b/src/Db/Action/DropIndex.php @@ -15,8 +15,6 @@ class DropIndex extends Action { /** * The index to drop - * - * @var \Migrations\Db\Table\Index */ protected Index $index; diff --git a/src/Db/Action/DropPartition.php b/src/Db/Action/DropPartition.php index 3647ff47d..e6b9c2cdb 100644 --- a/src/Db/Action/DropPartition.php +++ b/src/Db/Action/DropPartition.php @@ -15,9 +15,6 @@ */ class DropPartition extends Action { - /** - * @var string - */ protected string $partitionName; /** diff --git a/src/Db/Action/RemoveColumn.php b/src/Db/Action/RemoveColumn.php index 5aaa4a253..a73c5512e 100644 --- a/src/Db/Action/RemoveColumn.php +++ b/src/Db/Action/RemoveColumn.php @@ -15,8 +15,6 @@ class RemoveColumn extends Action { /** * The column to be removed - * - * @var \Migrations\Db\Table\Column */ protected Column $column; diff --git a/src/Db/Action/RenameColumn.php b/src/Db/Action/RenameColumn.php index 2565d753d..1092a5f7d 100644 --- a/src/Db/Action/RenameColumn.php +++ b/src/Db/Action/RenameColumn.php @@ -15,15 +15,11 @@ class RenameColumn extends Action { /** * The column to be renamed - * - * @var \Migrations\Db\Table\Column */ protected Column $column; /** * The new name for the column - * - * @var string */ protected string $newName; diff --git a/src/Db/Action/RenameTable.php b/src/Db/Action/RenameTable.php index 1f0b11e63..7b58ac653 100644 --- a/src/Db/Action/RenameTable.php +++ b/src/Db/Action/RenameTable.php @@ -14,8 +14,6 @@ class RenameTable extends Action { /** * The new name for the table - * - * @var string */ protected string $newName; diff --git a/src/Db/Action/SetPartitioning.php b/src/Db/Action/SetPartitioning.php index 0e24e048a..b56e32c6b 100644 --- a/src/Db/Action/SetPartitioning.php +++ b/src/Db/Action/SetPartitioning.php @@ -16,9 +16,6 @@ */ class SetPartitioning extends Action { - /** - * @var \Migrations\Db\Table\Partition - */ protected Partition $partition; /** diff --git a/src/Db/Adapter/AbstractAdapter.php b/src/Db/Adapter/AbstractAdapter.php index 556a60787..2bf053717 100644 --- a/src/Db/Adapter/AbstractAdapter.php +++ b/src/Db/Adapter/AbstractAdapter.php @@ -64,9 +64,6 @@ abstract class AbstractAdapter implements AdapterInterface, DirectActionInterfac */ protected array $options = []; - /** - * @var \Cake\Console\ConsoleIo - */ protected ConsoleIo $io; /** @@ -74,24 +71,12 @@ abstract class AbstractAdapter implements AdapterInterface, DirectActionInterfac */ protected array $createdTables = []; - /** - * @var string - */ protected string $schemaTableName = 'phinxlog'; - /** - * @var string - */ protected string $seedSchemaTableName = 'cake_seeds'; - /** - * @var array - */ protected array $dataDomain = []; - /** - * @var \Cake\Database\Connection|null - */ protected ?Connection $connection = null; /** @@ -103,7 +88,7 @@ abstract class AbstractAdapter implements AdapterInterface, DirectActionInterfac public function __construct(array $options, ?ConsoleIo $io = null) { $this->setOptions($options); - if ($io !== null) { + if ($io instanceof ConsoleIo) { $this->setIo($io); } } @@ -197,7 +182,7 @@ protected function getSchemaDialect(): SchemaDialect */ public function getConnection(): Connection { - if ($this->connection === null) { + if (!$this->connection instanceof Connection) { $this->connection = $this->getOption('connection'); $this->connect(); } @@ -294,9 +279,9 @@ protected function verboseLog(string $message): void { $io = $this->getIo(); if ( - $io === null || ( + !$io instanceof ConsoleIo || ( !$this->isDryRunEnabled() && - $io->level() != ConsoleIo::VERBOSE + $io->level() !== ConsoleIo::VERBOSE ) ) { return; @@ -465,7 +450,7 @@ public function isDryRunEnabled(): bool protected function addCreatedTable(string $tableName): void { $tableName = $this->quoteTableName($tableName); - if (substr_compare($tableName, 'phinxlog', -strlen('phinxlog')) !== 0) { + if (!str_ends_with($tableName, 'phinxlog')) { $this->createdTables[] = $tableName; } } @@ -694,22 +679,18 @@ protected function generateInsertSql( $upsertClause = $this->getUpsertClause($mode, $updateColumns, $conflictColumns); if ($this->isDryRunEnabled()) { - $sql .= ' VALUES (' . implode(', ', array_map($this->quoteValue(...), $row)) . ')' . $upsertClause . ';'; - - return $sql; - } else { - $values = []; - foreach ($row as $value) { - $placeholder = '?'; - if ($value instanceof Literal) { - $placeholder = (string)$value; - } - $values[] = $placeholder; + return $sql . (' VALUES (' . implode(', ', array_map($this->quoteValue(...), $row)) . ')' . $upsertClause . ';'); + } + $values = []; + foreach ($row as $value) { + $placeholder = '?'; + if ($value instanceof Literal) { + $placeholder = (string)$value; } - $sql .= ' VALUES (' . implode(',', $values) . ')' . $upsertClause; - - return $sql; + $values[] = $placeholder; } + + return $sql . (' VALUES (' . implode(',', $values) . ')' . $upsertClause); } /** @@ -748,7 +729,7 @@ protected function getUpsertClause(?InsertMode $mode, ?array $updateColumns, ?ar if ($conflictColumns !== null && $conflictColumns !== []) { trigger_error( 'The $conflictColumns parameter is ignored by MySQL. ' . - 'MySQL\'s ON DUPLICATE KEY UPDATE applies to all unique constraints on the table.', + "MySQL's ON DUPLICATE KEY UPDATE applies to all unique constraints on the table.", E_USER_WARNING, ); } @@ -875,30 +856,27 @@ protected function generateBulkInsertSql( $upsertClause = $this->getUpsertClause($mode, $updateColumns, $conflictColumns); if ($this->isDryRunEnabled()) { - $values = array_map(function ($row) { + $values = array_map(function ($row): string { return '(' . implode(', ', array_map($this->quoteValue(...), $row)) . ')'; }, $rows); - $sql .= implode(', ', $values) . $upsertClause . ';'; - return $sql; - } else { - $queries = []; - foreach ($rows as $row) { - $values = []; - foreach ($row as $v) { - $placeholder = '?'; - if ($v instanceof Literal) { - $placeholder = (string)$v; - } - $values[] = $placeholder; + return $sql . (implode(', ', $values) . $upsertClause . ';'); + } + $queries = []; + foreach ($rows as $row) { + $values = []; + foreach ($row as $v) { + $placeholder = '?'; + if ($v instanceof Literal) { + $placeholder = (string)$v; } - $query = '(' . implode(', ', $values) . ')'; - $queries[] = $query; + $values[] = $placeholder; } - $sql .= implode(',', $queries) . $upsertClause; - - return $sql; + $query = '(' . implode(', ', $values) . ')'; + $queries[] = $query; } + + return $sql . implode(',', $queries) . $upsertClause; } /** @@ -969,7 +947,7 @@ protected function isUsingUnifiedTable(): bool // Autodetect mode (config is null or not set) // Check if the main legacy phinxlog table exists - if ($this->connection !== null) { + if ($this->connection instanceof Connection) { $dialect = $this->connection->getDriver()->schemaDialect(); if ($dialect->hasTable('phinxlog')) { return false; @@ -987,16 +965,11 @@ protected function isUsingUnifiedTable(): bool */ public function getVersionLog(): array { - switch ($this->options['version_order']) { - case Config::VERSION_ORDER_CREATION_TIME: - $orderBy = ['version' => 'ASC']; - break; - case Config::VERSION_ORDER_EXECUTION_TIME: - $orderBy = ['start_time' => 'ASC', 'version' => 'ASC']; - break; - default: - throw new RuntimeException('Invalid version_order configuration option'); - } + $orderBy = match ($this->options['version_order']) { + Config::VERSION_ORDER_CREATION_TIME => ['version' => 'ASC'], + Config::VERSION_ORDER_EXECUTION_TIME => ['start_time' => 'ASC', 'version' => 'ASC'], + default => throw new RuntimeException('Invalid version_order configuration option'), + }; $query = $this->migrationsTable()->getVersions($orderBy); // This will throw an exception if doing a --dry-run without any migrations as phinxlog @@ -1113,7 +1086,7 @@ public function getSeedLog(): array public function seedExecuted(SeedInterface $seed, string $executedTime): AdapterInterface { $plugin = null; - $className = get_class($seed); + $className = $seed::class; if (str_contains($className, '\\')) { $parts = explode('\\', $className); @@ -1144,7 +1117,7 @@ public function seedExecuted(SeedInterface $seed, string $executedTime): Adapter public function removeSeedFromLog(SeedInterface $seed): AdapterInterface { $plugin = null; - $className = get_class($seed); + $className = $seed::class; if (str_contains($className, '\\')) { $parts = explode('\\', $className); @@ -1278,7 +1251,7 @@ protected function getDefaultValueDefinition(mixed $default, ?string $columnType $default = $this->castToBool((bool)$default); } - return isset($default) ? " DEFAULT $default" : ''; + return isset($default) ? ' DEFAULT ' . $default : ''; } /** @@ -1291,7 +1264,7 @@ protected function getDefaultValueDefinition(mixed $default, ?string $columnType protected function executeAlterSteps(string $tableName, AlterInstructions $instructions): void { $alter = sprintf('ALTER TABLE %s %%s', $this->quoteTableName($tableName)); - $instructions->execute($alter, [$this, 'execute']); + $instructions->execute($alter, $this->execute(...)); } /** @@ -1710,7 +1683,6 @@ public function executeActions(TableMetadata $table, array $actions): void break; case $action instanceof DropTable: - /** @var \Migrations\Db\Action\DropTable $action */ $instructions->merge($this->getDropTableInstructions( $table->getName(), )); @@ -1777,7 +1749,7 @@ public function executeActions(TableMetadata $table, array $actions): void default: throw new InvalidArgumentException( - sprintf("Don't know how to execute action `%s`", get_class($action)), + sprintf("Don't know how to execute action `%s`", $action::class), ); } } diff --git a/src/Db/Adapter/AdapterFactory.php b/src/Db/Adapter/AdapterFactory.php index 4c7691f2b..b0dafb929 100644 --- a/src/Db/Adapter/AdapterFactory.php +++ b/src/Db/Adapter/AdapterFactory.php @@ -30,7 +30,7 @@ class AdapterFactory */ public static function instance(): static { - if (!static::$instance) { + if (!static::$instance instanceof AdapterFactory) { static::$instance = new static(); } @@ -72,7 +72,7 @@ public static function instance(): static public function registerAdapter(string $name, Closure|string $class) { if ( - !($class instanceof Closure || is_subclass_of($class, AdapterInterface::class)) + !$class instanceof Closure && !is_subclass_of($class, AdapterInterface::class) ) { throw new RuntimeException(sprintf( 'Adapter class `%s` must implement `Migrations\\Db\\Adapter\\AdapterInterface`', diff --git a/src/Db/Adapter/AdapterInterface.php b/src/Db/Adapter/AdapterInterface.php index 0dad1ca37..bc3f2442e 100644 --- a/src/Db/Adapter/AdapterInterface.php +++ b/src/Db/Adapter/AdapterInterface.php @@ -29,29 +29,50 @@ interface AdapterInterface { public const TYPE_STRING = TableSchemaInterface::TYPE_STRING; + public const TYPE_CHAR = TableSchemaInterface::TYPE_CHAR; + public const TYPE_TEXT = TableSchemaInterface::TYPE_TEXT; + public const TYPE_INTEGER = TableSchemaInterface::TYPE_INTEGER; + public const TYPE_TINYINTEGER = TableSchemaInterface::TYPE_TINYINTEGER; + public const TYPE_SMALLINTEGER = TableSchemaInterface::TYPE_SMALLINTEGER; + public const TYPE_BIGINTEGER = TableSchemaInterface::TYPE_BIGINTEGER; + public const TYPE_FLOAT = TableSchemaInterface::TYPE_FLOAT; + public const TYPE_DECIMAL = TableSchemaInterface::TYPE_DECIMAL; + public const TYPE_DATETIME = TableSchemaInterface::TYPE_DATETIME; + public const TYPE_TIMESTAMP = TableSchemaInterface::TYPE_TIMESTAMP; + public const TYPE_TIME = TableSchemaInterface::TYPE_TIME; + public const TYPE_DATE = TableSchemaInterface::TYPE_DATE; + public const TYPE_BINARY = TableSchemaInterface::TYPE_BINARY; + public const TYPE_BINARY_UUID = TableSchemaInterface::TYPE_BINARY_UUID; + public const TYPE_BOOLEAN = TableSchemaInterface::TYPE_BOOLEAN; + public const TYPE_JSON = TableSchemaInterface::TYPE_JSON; + public const TYPE_UUID = TableSchemaInterface::TYPE_UUID; + public const TYPE_NATIVE_UUID = TableSchemaInterface::TYPE_NATIVE_UUID; // Geospatial database types public const TYPE_GEOMETRY = TableSchemaInterface::TYPE_GEOMETRY; + public const TYPE_POINT = TableSchemaInterface::TYPE_POINT; + public const TYPE_LINESTRING = TableSchemaInterface::TYPE_LINESTRING; + public const TYPE_POLYGON = TableSchemaInterface::TYPE_POLYGON; public const TYPES_GEOSPATIAL = [ @@ -63,90 +84,113 @@ interface AdapterInterface // only for mysql so far public const TYPE_YEAR = TableSchemaInterface::TYPE_YEAR; + public const TYPE_BIT = TableSchemaInterface::TYPE_BIT; // only for postgresql so far public const TYPE_CIDR = TableSchemaInterface::TYPE_CIDR; + public const TYPE_INET = TableSchemaInterface::TYPE_INET; + public const TYPE_MACADDR = TableSchemaInterface::TYPE_MACADDR; + public const TYPE_INTERVAL = TableSchemaInterface::TYPE_INTERVAL; /** * @deprecated 5.0.0 Use TYPE_STRING instead. */ public const PHINX_TYPE_STRING = self::TYPE_STRING; + /** * @deprecated 5.0.0 Use TYPE_CHAR instead. */ public const PHINX_TYPE_CHAR = self::TYPE_CHAR; + /** * @deprecated 5.0.0 Use TYPE_TEXT instead. */ public const PHINX_TYPE_TEXT = self::TYPE_TEXT; + /** * @deprecated 5.0.0 Use TYPE_INTEGER instead. */ public const PHINX_TYPE_INTEGER = self::TYPE_INTEGER; + /** * @deprecated 5.0.0 Use TYPE_TINYINTEGER instead. */ public const PHINX_TYPE_TINY_INTEGER = self::TYPE_TINYINTEGER; + /** * @deprecated 5.0.0 Use TYPE_SMALLINTEGER instead. */ public const PHINX_TYPE_SMALL_INTEGER = self::TYPE_SMALLINTEGER; + /** * @deprecated 5.0.0 Use TYPE_BIGINTEGER instead. */ public const PHINX_TYPE_BIG_INTEGER = self::TYPE_BIGINTEGER; + /** * @deprecated 5.0.0 Use TYPE_FLOAT instead. */ public const PHINX_TYPE_FLOAT = self::TYPE_FLOAT; + /** * @deprecated 5.0.0 Use TYPE_DECIMAL instead. */ public const PHINX_TYPE_DECIMAL = self::TYPE_DECIMAL; + /** * @deprecated 5.0.0 Use TYPE_DATETIME instead. */ public const PHINX_TYPE_DATETIME = self::TYPE_DATETIME; + /** * @deprecated 5.0.0 Use TYPE_TIMESTAMP instead. */ public const PHINX_TYPE_TIMESTAMP = self::TYPE_TIMESTAMP; + /** * @deprecated 5.0.0 Use TYPE_TIME instead. */ public const PHINX_TYPE_TIME = self::TYPE_TIME; + /** * @deprecated 5.0.0 Use TYPE_DATE instead. */ public const PHINX_TYPE_DATE = self::TYPE_DATE; + /** * @deprecated 5.0.0 Use TYPE_BINARY instead. */ public const PHINX_TYPE_BINARY = self::TYPE_BINARY; + /** * @deprecated 5.0.0 Use TYPE_BINARY_UUID instead. */ public const PHINX_TYPE_BINARYUUID = self::TYPE_BINARY_UUID; + /** * @deprecated 5.0.0 Use TYPE_BOOLEAN instead. */ public const PHINX_TYPE_BOOLEAN = self::TYPE_BOOLEAN; + /** * @deprecated 5.0.0 Use TYPE_JSON instead. */ public const PHINX_TYPE_JSON = self::TYPE_JSON; + /** * @deprecated 5.0.0 Use TableSchemaInterface::TYPE_JSON instead. */ public const PHINX_TYPE_JSONB = 'jsonb'; + /** * @deprecated 5.0.0 Use TYPE_UUID instead. */ public const PHINX_TYPE_UUID = self::TYPE_UUID; + /** * @deprecated 5.0.0 Use TYPE_NATIVE_UUID instead. */ @@ -156,14 +200,17 @@ interface AdapterInterface * @deprecated 5.0.0 Use TYPE_GEOMETRY instead. */ public const PHINX_TYPE_GEOMETRY = self::TYPE_GEOMETRY; + /** * @deprecated 5.0.0 Use TYPE_POINT instead. */ public const PHINX_TYPE_POINT = self::TYPE_POINT; + /** * @deprecated 5.0.0 Use TYPE_LINESTRING instead. */ public const PHINX_TYPE_LINESTRING = self::TYPE_LINESTRING; + /** * @deprecated 5.0.0 Use TYPE_POLYGON instead. */ @@ -188,14 +235,17 @@ interface AdapterInterface * @deprecated 5.0.0 Use TYPE_CIDR instead. */ public const PHINX_TYPE_CIDR = self::TYPE_CIDR; + /** * @deprecated 5.0.0 Use TYPE_INET instead. */ public const PHINX_TYPE_INET = self::TYPE_INET; + /** * @deprecated 5.0.0 Use TYPE_MACADDR instead. */ public const PHINX_TYPE_MACADDR = self::TYPE_MACADDR; + /** * @deprecated 5.0.0 Use TYPE_INTERVAL instead. */ diff --git a/src/Db/Adapter/AdapterWrapper.php b/src/Db/Adapter/AdapterWrapper.php index 597e9926d..e87b8473e 100644 --- a/src/Db/Adapter/AdapterWrapper.php +++ b/src/Db/Adapter/AdapterWrapper.php @@ -30,9 +30,6 @@ */ abstract class AdapterWrapper implements WrapperInterface { - /** - * @var \Migrations\Db\Adapter\AdapterInterface - */ protected AdapterInterface $adapter; /** diff --git a/src/Db/Adapter/MysqlAdapter.php b/src/Db/Adapter/MysqlAdapter.php index dabf3a95e..c8bb76e97 100644 --- a/src/Db/Adapter/MysqlAdapter.php +++ b/src/Db/Adapter/MysqlAdapter.php @@ -53,26 +53,32 @@ class MysqlAdapter extends AbstractAdapter * @deprecated 5.0.0 Enum column support will be removed in a future release. */ public const PHINX_TYPE_ENUM = 'enum'; + /** * @deprecated 5.0.0 Set column support will be removed in a future release. */ public const PHINX_TYPE_SET = 'set'; + /** * @deprecated 5.0.0 Use binary type with with no limit instead. */ public const PHINX_TYPE_BLOB = 'blob'; + /** * @deprecated 5.0.0 Use binary type with with limit BLOB_SMALL instead. */ public const PHINX_TYPE_TINYBLOB = 'tinyblob'; + /** * @deprecated 5.0.0 Use binary type with with limit BLOB_MEDIUM instead. */ public const PHINX_TYPE_MEDIUMBLOB = 'mediumblob'; + /** * @deprecated 5.0.0 Use binary type with with limit BLOB_LONG instead. */ public const PHINX_TYPE_LONGBLOB = 'longblob'; + /** * @deprecated 5.0.0 Use binary type instead. */ @@ -84,29 +90,45 @@ class MysqlAdapter extends AbstractAdapter // as its actual value is its regular value is larger than PHP_INT_MAX. We do this // to keep consistent the type hints for Column::$limit being integers. public const TEXT_TINY = 255; + public const TEXT_SMALL = 255; /* deprecated, alias of TEXT_TINY */ /** @deprecated Use length of null instead **/ public const TEXT_REGULAR = 65535; + public const TEXT_MEDIUM = 16777215; + public const TEXT_LONG = 2147483647; // According to https://dev.mysql.com/doc/refman/5.0/en/blob.html BLOB sizes are the same as TEXT public const BLOB_TINY = TableSchema::LENGTH_TINY; - public const BLOB_SMALL = TableSchema::LENGTH_TINY; /* deprecated, alias of BLOB_TINY */ + + public const BLOB_SMALL = TableSchema::LENGTH_TINY; + + /* deprecated, alias of BLOB_TINY */ public const BLOB_REGULAR = 65535; + public const BLOB_MEDIUM = TableSchema::LENGTH_MEDIUM; + public const BLOB_LONG = TableSchema::LENGTH_LONG; public const INT_TINY = 255; + public const INT_SMALL = 65535; + public const INT_MEDIUM = 16777215; + public const INT_REGULAR = 1073741823; + public const INT_BIG = 2147483647; public const INT_DISPLAY_TINY = 4; + public const INT_DISPLAY_SMALL = 6; + public const INT_DISPLAY_MEDIUM = 8; + public const INT_DISPLAY_REGULAR = 11; + public const INT_DISPLAY_BIG = 20; public const BIT = 64; @@ -154,8 +176,11 @@ class MysqlAdapter extends AbstractAdapter * @see https://mariadb.com/kb/en/alter-table/#algorithm */ public const ALGORITHM_DEFAULT = 'DEFAULT'; + public const ALGORITHM_INSTANT = 'INSTANT'; + public const ALGORITHM_INPLACE = 'INPLACE'; + public const ALGORITHM_COPY = 'COPY'; /** @@ -182,8 +207,11 @@ class MysqlAdapter extends AbstractAdapter * @see https://mariadb.com/kb/en/alter-table/#lock */ public const LOCK_DEFAULT = 'DEFAULT'; + public const LOCK_NONE = 'NONE'; + public const LOCK_SHARED = 'SHARED'; + public const LOCK_EXCLUSIVE = 'EXCLUSIVE'; /** @@ -218,7 +246,7 @@ public function hasTable(string $tableName): bool return true; } - if (strpos($tableName, '.') !== false) { + if (str_contains($tableName, '.')) { [$schema, $table] = explode('.', $tableName); $exists = $this->hasTableWithSchema($schema, $table); // Only break here on success, because it is possible for table names to contain a dot. @@ -306,7 +334,7 @@ public function createTable(TableMetadata $table, array $columns = [], array $in // process table collation if (isset($options['collation'])) { - $charset = explode('_', $options['collation']); + $charset = explode('_', (string)$options['collation']); $optionsStr .= sprintf(' CHARACTER SET %s', $charset[0]); $optionsStr .= sprintf(' COLLATE %s', $options['collation']); } @@ -354,7 +382,7 @@ public function createTable(TableMetadata $table, array $columns = [], array $in // add partitioning $partition = $table->getPartition(); - if ($partition !== null) { + if ($partition instanceof Partition) { $sql .= ' ' . $this->getPartitionSqlDefinition($partition); } @@ -450,7 +478,7 @@ protected function columnDefinitionSql(SchemaDialect $dialect, Column $column): $sql = $this->quoteColumnName($columnData['name']) . ' ' . $columnData['type']; $values = $column->getValues(); if ($values) { - $sql .= '(' . implode(', ', array_map(function ($value) { + $sql .= '(' . implode(', ', array_map(function ($value): string { // Special case NULL to trigger errors as it isn't allowed // in enum values. return $value === null ? 'NULL' : $this->quoteString($value); @@ -512,7 +540,7 @@ protected function getChangeCommentInstructions(TableMetadata $table, ?string $n $instructions = new AlterInstructions(); // passing 'null' is to remove table comment - $newComment = $newComment ?? ''; + $newComment ??= ''; $sql = sprintf(' COMMENT=%s ', $this->quoteString($newComment)); $instructions->addAlter($sql); @@ -632,7 +660,7 @@ public function getColumns(string $tableName): array $rawTypes = []; $rows = $this->fetchAll(sprintf('SHOW COLUMNS FROM %s', $this->quoteTableName($tableName))); foreach ($rows as $row) { - $rawTypes[$row['Field']] = strtolower($row['Type']); + $rawTypes[$row['Field']] = strtolower((string)$row['Type']); } $columns = []; @@ -734,7 +762,7 @@ protected function getRenameColumnInstructions(string $tableName, string $column $targetColumn = null; foreach ($columns as $column) { - if (strcasecmp($column->getName(), $columnName) === 0) { + if (strcasecmp((string)$column->getName(), $columnName) === 0) { $targetColumn = $column; break; } @@ -751,7 +779,7 @@ protected function getRenameColumnInstructions(string $tableName, string $column $rows = $this->fetchAll(sprintf('SHOW FULL COLUMNS FROM %s', $this->quoteTableName($tableName))); foreach ($rows as $row) { - if (strcasecmp($row['Field'], $columnName) === 0) { + if (strcasecmp((string)$row['Field'], $columnName) === 0) { $null = $row['Null'] === 'NO' ? 'NOT NULL' : 'NULL'; $comment = isset($row['Comment']) && $row['Comment'] !== '' ? ' COMMENT ' . $this->getConnection()->getDriver()->schemaValue($row['Comment']) @@ -759,8 +787,8 @@ protected function getRenameColumnInstructions(string $tableName, string $column // create the extra string by also filtering out the DEFAULT_GENERATED option (MySQL 8 fix) $extras = array_filter( - explode(' ', strtoupper($row['Extra'])), - static function ($value) { + explode(' ', strtoupper((string)$row['Extra'])), + static function (string $value): bool { return $value !== 'DEFAULT_GENERATED'; }, ); @@ -833,9 +861,8 @@ protected function getDropColumnInstructions(string $tableName, string $columnNa protected function getIndexes(string $tableName): array { $dialect = $this->getSchemaDialect(); - $indexes = $dialect->describeIndexes($tableName); - return $indexes; + return $dialect->describeIndexes($tableName); } /** @@ -879,7 +906,7 @@ protected function getDropIndexByColumnsInstructions(string $tableName, $columns } $indexes = $this->getIndexes($tableName); - $columns = array_map('strtolower', $columns); + $columns = array_map(strtolower(...), $columns); foreach ($indexes as $index) { if ($columns == $index['columns']) { @@ -933,11 +960,10 @@ public function hasPrimaryKey(string $tableName, string|array $columns, ?string if ($constraint) { return $primaryKey['name'] === $constraint; - } else { - $missingColumns = array_diff((array)$columns, (array)$primaryKey['columns']); - - return empty($missingColumns); } + $missingColumns = array_diff((array)$columns, (array)$primaryKey['columns']); + + return $missingColumns === []; } /** @@ -972,9 +998,8 @@ public function getPrimaryKey(string $tableName): array protected function getForeignKeys(string $tableName): array { $dialect = $this->getSchemaDialect(); - $foreignKeys = $dialect->describeForeignKeys($tableName); - return $foreignKeys; + return $dialect->describeForeignKeys($tableName); } /** @@ -1012,12 +1037,12 @@ protected function getDropForeignKeyByColumnsInstructions(string $tableName, arr { $instructions = new AlterInstructions(); - $columns = array_map('mb_strtolower', $columns); + $columns = array_map(mb_strtolower(...), $columns); $matches = []; $foreignKeys = $this->getForeignKeys($tableName); foreach ($foreignKeys as $key) { - if (array_map('mb_strtolower', $key['columns']) === $columns) { + if (array_map(mb_strtolower(...), $key['columns']) === $columns) { $matches[] = $key['name']; } } @@ -1165,7 +1190,7 @@ protected function getIndexSqlDefinition(Index $index): string $columnNames = (array)$index->getColumns(); $order = $index->getOrder() ?? []; - $columnNames = array_map(function ($columnName) use ($order) { + $columnNames = array_map(function (string $columnName) use ($order): string { $ret = $this->quoteColumnName($columnName); if (isset($order[$columnName])) { $ret .= ' ' . $order[$columnName]; @@ -1307,7 +1332,7 @@ protected function getPartitionSqlDefinition(Partition $partition): string if ($columns instanceof Literal) { $columnsSql = (string)$columns; } else { - $columnsSql = implode(', ', array_map(fn($col) => $this->quoteColumnName($col), $columns)); + $columnsSql = implode(', ', array_map($this->quoteColumnName(...), $columns)); } $sql = sprintf('PARTITION BY %s (%s)', $type, $columnsSql); @@ -1357,14 +1382,14 @@ protected function getPartitionDefinitionSql(string $type, PartitionDefinition $ if ($value === 'MAXVALUE' || $value === Partition::TYPE_RANGE . '_MAXVALUE') { $sql .= 'MAXVALUE'; } elseif (is_array($value)) { - $sql .= '(' . implode(', ', array_map(fn($v) => $this->quotePartitionValue($v), $value)) . ')'; + $sql .= '(' . implode(', ', array_map($this->quotePartitionValue(...), $value)) . ')'; } else { $sql .= '(' . $this->quotePartitionValue($value) . ')'; } } elseif ($isListType) { $sql .= ' VALUES IN ('; if (is_array($value)) { - $sql .= implode(', ', array_map(fn($v) => $this->quotePartitionValue($v), $value)); + $sql .= implode(', ', array_map($this->quotePartitionValue(...), $value)); } else { $sql .= $this->quotePartitionValue($value); } @@ -1425,7 +1450,7 @@ protected function getSetPartitioningInstructions(TableMetadata $table, Partitio */ protected function getAddPartitionsInstructions(TableMetadata $table, array $partitions): AlterInstructions { - if (empty($partitions)) { + if ($partitions === []) { return new AlterInstructions(); } @@ -1451,11 +1476,11 @@ protected function getAddPartitionsInstructions(TableMetadata $table, array $par */ protected function getDropPartitionsInstructions(string $tableName, array $partitionNames): AlterInstructions { - if (empty($partitionNames)) { + if ($partitionNames === []) { return new AlterInstructions(); } - $quotedNames = array_map(fn($name) => $this->quoteColumnName($name), $partitionNames); + $quotedNames = array_map($this->quoteColumnName(...), $partitionNames); $sql = 'DROP PARTITION ' . implode(', ', $quotedNames); return new AlterInstructions([$sql]); @@ -1486,7 +1511,7 @@ protected function getAddPartitionSql(PartitionDefinition $partition): string } elseif (is_array($value)) { // Likely LIST $sql .= ' VALUES IN ('; - $sql .= implode(', ', array_map(fn($v) => $this->quotePartitionValue($v), $value)); + $sql .= implode(', ', array_map($this->quotePartitionValue(...), $value)); $sql .= ')'; } @@ -1506,7 +1531,7 @@ protected function getAddPartitionSql(PartitionDefinition $partition): string protected function hasNativeUuid(): bool { // Prevent infinite connect() loop when MysqlAdapter is used as a stub. - if ($this->connection === null || !$this->getOption('connection')) { + if (!$this->connection instanceof Connection || !$this->getOption('connection')) { return false; } $connection = $this->getConnection(); @@ -1523,7 +1548,7 @@ protected function hasNativeUuid(): bool protected function isMariaDb(): bool { // Prevent infinite connect() loop when MysqlAdapter is used as a stub. - if ($this->connection === null || !$this->getOption('connection')) { + if (!$this->connection instanceof Connection || !$this->getOption('connection')) { return false; } $connection = $this->getConnection(); diff --git a/src/Db/Adapter/PostgresAdapter.php b/src/Db/Adapter/PostgresAdapter.php index b0e61d220..162acc682 100644 --- a/src/Db/Adapter/PostgresAdapter.php +++ b/src/Db/Adapter/PostgresAdapter.php @@ -33,7 +33,9 @@ class PostgresAdapter extends AbstractAdapter protected const IDENTIFIER_MAX_LENGTH = 63; public const GENERATED_ALWAYS = 'ALWAYS'; + public const GENERATED_BY_DEFAULT = 'BY DEFAULT'; + /** * Allow insert when a column was created with the GENERATED ALWAYS clause. * This is required for seeding the database. @@ -65,8 +67,6 @@ class PostgresAdapter extends AbstractAdapter /** * Use identity columns if available (Postgres >= 10.0) - * - * @var bool */ protected bool $useIdentity; @@ -174,7 +174,7 @@ public function createTable(TableMetadata $table, array $columns = [], array $in if (is_string($options['primary_key'])) { // handle primary_key => 'id' $sql .= $this->quoteColumnName($options['primary_key']); } elseif (is_array($options['primary_key'])) { // handle primary_key => array('tag_id', 'resource_id') - $sql .= implode(',', array_map([$this, 'quoteColumnName'], $options['primary_key'])); + $sql .= implode(',', array_map($this->quoteColumnName(...), $options['primary_key'])); } $sql .= ')'; } else { @@ -185,24 +185,20 @@ public function createTable(TableMetadata $table, array $columns = [], array $in // add partitioning clause $partition = $table->getPartition(); - if ($partition !== null) { + if ($partition instanceof Partition) { $sql .= ' ' . $this->getPartitionSqlDefinition($partition); } $queries[] = $sql; // process column comments - if ($this->columnsWithComments) { - foreach ($this->columnsWithComments as $column) { - $queries[] = $this->getColumnCommentSqlDefinition($column, $table->getName()); - } + foreach ($this->columnsWithComments as $column) { + $queries[] = $this->getColumnCommentSqlDefinition($column, $table->getName()); } // set the indexes - if ($indexes) { - foreach ($indexes as $index) { - $queries[] = $this->getIndexSqlDefinition($index, $table->getName()); - } + foreach ($indexes as $index) { + $queries[] = $this->getIndexSqlDefinition($index, $table->getName()); } // process table comments @@ -215,7 +211,7 @@ public function createTable(TableMetadata $table, array $columns = [], array $in } // create partition tables for PostgreSQL declarative partitioning - if ($partition !== null) { + if ($partition instanceof Partition) { foreach ($partition->getDefinitions() as $definition) { $queries[] = $this->getPartitionTableSql($table->getName(), $partition, $definition); } @@ -280,7 +276,7 @@ protected function getChangePrimaryKeyInstructions(TableMetadata $table, array|s if (is_string($newColumns)) { // handle primary_key => 'id' $sql .= $this->quoteColumnName($newColumns); } else { // handle primary_key => array('tag_id', 'resource_id') - $sql .= implode(',', array_map([$this, 'quoteColumnName'], $newColumns)); + $sql .= implode(',', array_map($this->quoteColumnName(...), $newColumns)); } $sql .= ')'; $instructions->addAlter($sql); @@ -426,7 +422,7 @@ protected function getRenameColumnInstructions( ]; $result = $this->query($sql, $params)->fetch('assoc'); if (!$result || !(bool)$result['column_exists']) { - throw new InvalidArgumentException("The specified column does not exist: $columnName"); + throw new InvalidArgumentException('The specified column does not exist: ' . $columnName); } $instructions = new AlterInstructions(); @@ -462,7 +458,7 @@ protected function getChangeColumnInstructions( // Remove the column name from $columnSql $columnType = preg_replace('/^"?(?:[^"]+)"?\s+/', '', $columnSql); // Remove generated clause - $columnType = preg_replace('/GENERATED (?:ALWAYS|BY DEFAULT) AS IDENTITY/', '', $columnType); + $columnType = preg_replace('/GENERATED (?:ALWAYS|BY DEFAULT) AS IDENTITY/', '', (string)$columnType); $sql = sprintf( 'ALTER COLUMN %s TYPE %s', @@ -475,13 +471,13 @@ protected function getChangeColumnInstructions( $quotedColumnName, ); } - if (in_array($newColumn->getType(), ['uuid', 'nativeuuid', 'binaryuuid'])) { + if (in_array($newColumn->getType(), ['uuid', 'nativeuuid', 'binaryuuid'], true)) { $sql .= sprintf( ' USING (%s::uuid)', $quotedColumnName, ); } - if (in_array($newColumn->getType(), ['json'])) { + if ($newColumn->getType() === 'json') { $sql .= sprintf( ' USING (%s::jsonb)', $quotedColumnName, @@ -489,9 +485,9 @@ protected function getChangeColumnInstructions( } // NULL and DEFAULT cannot be set while changing column type $sql = preg_replace('/ NOT NULL/', '', $sql); - $sql = preg_replace('/ DEFAULT NULL/', '', $sql); + $sql = preg_replace('/ DEFAULT NULL/', '', (string)$sql); // If it is set, DEFAULT is the last definition - $sql = preg_replace('/DEFAULT .*/', '', $sql); + $sql = preg_replace('/DEFAULT .*/', '', (string)$sql); if ($newColumn->getType() === 'boolean') { $sql .= sprintf( ' USING (CASE WHEN %s IS NULL THEN NULL WHEN %s::int=0 THEN FALSE ELSE TRUE END)', @@ -502,7 +498,7 @@ protected function getChangeColumnInstructions( $instructions->addAlter($sql); $column = $this->getColumn($tableName, $columnName); - assert($column !== null, 'Column must exist'); + assert($column instanceof Column, 'Column must exist'); if ($this->useIdentity) { // process identity @@ -512,9 +508,9 @@ protected function getChangeColumnInstructions( ); if ($newColumn->isIdentity() && $newColumn->getGenerated() !== null) { if ($column->isIdentity()) { - $sql .= sprintf(' SET GENERATED %s', (string)$newColumn->getGenerated()); + $sql .= sprintf(' SET GENERATED %s', $newColumn->getGenerated()); } else { - $sql .= sprintf(' ADD GENERATED %s AS IDENTITY', (string)$newColumn->getGenerated()); + $sql .= sprintf(' ADD GENERATED %s AS IDENTITY', $newColumn->getGenerated()); } } else { $sql .= ' DROP IDENTITY IF EXISTS'; @@ -540,7 +536,7 @@ protected function getChangeColumnInstructions( $instructions->addAlter(sprintf( 'ALTER COLUMN %s SET %s', $quotedColumnName, - $this->getDefaultValueDefinition($newColumn->getDefault(), (string)$newColumn->getType()), + $this->getDefaultValueDefinition($newColumn->getDefault(), $newColumn->getType()), )); } elseif (!$newColumn->getIdentity()) { //drop default @@ -607,9 +603,8 @@ protected function getDropColumnInstructions(string $tableName, string $columnNa protected function getIndexes(string $tableName): array { $dialect = $this->getSchemaDialect(); - $indexes = $dialect->describeIndexes($tableName); - return $indexes; + return $dialect->describeIndexes($tableName); } /** @@ -680,14 +675,13 @@ public function hasPrimaryKey(string $tableName, $columns, ?string $constraint = if ($constraint) { return $primaryKey['constraint'] === $constraint; - } else { - if (is_string($columns)) { - $columns = [$columns]; // str to array - } - $missingColumns = array_diff($columns, $primaryKey['columns']); - - return empty($missingColumns); } + if (is_string($columns)) { + $columns = [$columns]; // str to array + } + $missingColumns = array_diff($columns, $primaryKey['columns']); + + return $missingColumns === []; } /** @@ -718,9 +712,8 @@ public function getPrimaryKey(string $tableName): array protected function getForeignKeys(string $tableName): array { $dialect = $this->getSchemaDialect(); - $foreignKeys = $dialect->describeForeignKeys($tableName); - return $foreignKeys; + return $dialect->describeForeignKeys($tableName); } /** @@ -789,9 +782,8 @@ protected function getDropForeignKeyByColumnsInstructions(string $tableName, arr protected function getCheckConstraints(string $tableName): array { $dialect = $this->getSchemaDialect(); - $constraints = $dialect->describeCheckConstraints($tableName); - return $constraints; + return $dialect->describeCheckConstraints($tableName); } /** @@ -905,12 +897,12 @@ protected function getIndexSqlDefinition(Index $index, string $tableName): strin $columnNames = (array)$index->getColumns(); $indexName = $index->getName(); - if ($indexName === null || strlen($indexName) === 0) { + if ($indexName === null || $indexName === '') { $indexName = sprintf('%s_%s', $parts['table'], implode('_', $columnNames)); } $order = $index->getOrder() ?? []; - $columnNames = array_map(function ($columnName) use ($order) { + $columnNames = array_map(function (string $columnName) use ($order): string { $ret = '"' . $columnName . '"'; if (isset($order[$columnName])) { $ret .= ' ' . $order[$columnName]; @@ -937,7 +929,7 @@ protected function getIndexSqlDefinition(Index $index, string $tableName): strin $createIndexSentence, $index->getType() === Index::UNIQUE ? 'UNIQUE ' : '', $index->getConcurrently() ? ' CONCURRENTLY' : '', - $this->quoteColumnName((string)$indexName), + $this->quoteColumnName($indexName), $this->quoteTableName($tableName), implode(',', $columnNames), $includedColumns, @@ -961,13 +953,13 @@ protected function getForeignKeySqlDefinition(ForeignKey $foreignKey, string $ta ' FOREIGN KEY (' . $columnList . ')' . ' REFERENCES ' . $this->quoteTableName($foreignKey->getReferencedTable()) . ' (' . $refColumnList . ')'; if ($foreignKey->getOnDelete()) { - $def .= " ON DELETE {$foreignKey->getOnDelete()}"; + $def .= ' ON DELETE ' . $foreignKey->getOnDelete(); } if ($foreignKey->getOnUpdate()) { - $def .= " ON UPDATE {$foreignKey->getOnUpdate()}"; + $def .= ' ON UPDATE ' . $foreignKey->getOnUpdate(); } if ($foreignKey->getDeferrableMode()) { - $def .= " {$foreignKey->getDeferrableMode()}"; + $def .= ' ' . $foreignKey->getDeferrableMode(); } return $def; @@ -1138,7 +1130,11 @@ public function getColumnTypes(): array public function isValidColumnType(Column $column): bool { // If not a standard column type, maybe it is array type? - return parent::isValidColumnType($column) || $this->isArrayType($column->getType()); + if (parent::isValidColumnType($column)) { + return true; + } + + return $this->isArrayType($column->getType()); } /** @@ -1166,7 +1162,7 @@ protected function getSchemaName(string $tableName): array { $schema = $this->getGlobalSchemaName(); $table = $tableName; - if (strpos($tableName, '.') !== false) { + if (str_contains($tableName, '.')) { [$schema, $table] = explode('.', $tableName); } @@ -1291,7 +1287,7 @@ public function bulkinsert( $conflictClause = $this->getConflictClause($mode, $updateColumns, $conflictColumns); if ($this->isDryRunEnabled()) { - $values = array_map(function ($row) { + $values = array_map(function ($row): string { return '(' . implode(', ', array_map($this->quoteValue(...), $row)) . ')'; }, $rows); $sql .= implode(', ', $values) . $conflictClause . ';'; @@ -1388,7 +1384,7 @@ protected function getPartitionSqlDefinition(Partition $partition): string if ($columns instanceof Literal) { $columnsSql = (string)$columns; } else { - $columnsSql = implode(', ', array_map(fn($col) => $this->quoteColumnName($col), $columns)); + $columnsSql = implode(', ', array_map($this->quoteColumnName(...), $columns)); } return sprintf('PARTITION BY %s (%s)', $type, $columnsSql); @@ -1419,7 +1415,7 @@ protected function getPartitionTableSql(string $tableName, Partition $partition, } elseif ($type === Partition::TYPE_LIST) { $sql .= ' FOR VALUES IN ('; if (is_array($value)) { - $sql .= implode(', ', array_map(fn($v) => $this->quotePartitionValue($v), $value)); + $sql .= implode(', ', array_map($this->quotePartitionValue(...), $value)); } else { $sql .= $this->quotePartitionValue($value); } @@ -1538,7 +1534,7 @@ private function getAddPartitionSql(TableMetadata $table, PartitionDefinition $p } elseif (is_array($value)) { // LIST partition $sql .= ' FOR VALUES IN ('; - $sql .= implode(', ', array_map(fn($v) => $this->quotePartitionValue($v), $value)); + $sql .= implode(', ', array_map($this->quotePartitionValue(...), $value)); $sql .= ')'; } else { // Simple RANGE (upper bound only) diff --git a/src/Db/Adapter/RecordingAdapter.php b/src/Db/Adapter/RecordingAdapter.php index aab4b41b3..cfcbddc34 100644 --- a/src/Db/Adapter/RecordingAdapter.php +++ b/src/Db/Adapter/RecordingAdapter.php @@ -107,7 +107,7 @@ public function getInvertedCommands(): Intent default: throw new IrreversibleMigrationException(sprintf( 'Cannot reverse a "%s" command', - get_class($command), + $command::class, )); } } diff --git a/src/Db/Adapter/SqliteAdapter.php b/src/Db/Adapter/SqliteAdapter.php index 82a3812df..b32752ebd 100644 --- a/src/Db/Adapter/SqliteAdapter.php +++ b/src/Db/Adapter/SqliteAdapter.php @@ -59,9 +59,6 @@ class SqliteAdapter extends AbstractAdapter self::TYPE_UUID => 'uuid_text', ]; - /** - * @var string - */ protected string $suffix = '.sqlite3'; /** @@ -89,7 +86,7 @@ public function setOptions(array $options): AdapterInterface } //don't "fix" the file extension if it is blank, some people //might want a SQLITE db file with absolutely no extension. - if ($this->suffix !== '' && strpos($this->suffix, '.') !== 0) { + if ($this->suffix !== '' && !str_starts_with($this->suffix, '.')) { $this->suffix = '.' . $this->suffix; } @@ -129,11 +126,7 @@ protected function possiblyQuotedIdentifierRegex(string $identifier, bool $space $identifiers[] = "'" . ($hasSingleQuote ? str_replace("'", "''", $identifier) : $identifier) . "'"; if (!$hasTick && !$hasDoubleQuote && !$hasSingleQuote) { - if ($spacedNoQuotes) { - $identifiers[] = "\s+$identifier\s+"; - } else { - $identifiers[] = $identifier; - } + $identifiers[] = $spacedNoQuotes ? sprintf('\s+%s\s+', $identifier) : $identifier; } return '(' . implode('|', $identifiers) . ')'; @@ -179,7 +172,7 @@ protected function resolveTable(string $tableName): array // the temp schema is always first to be searched $schemata = ['temp']; foreach ($rows as $row) { - if (strtolower($row['name']) !== 'temp') { + if (strtolower((string)$row['name']) !== 'temp') { $schemata[] = $row['name']; } } @@ -190,9 +183,9 @@ protected function resolveTable(string $tableName): array $defaultSchema = $info['schema']; } - $table = strtolower($info['table']); + $table = strtolower((string)$info['table']); foreach ($schemata as $schema) { - if (strtolower($schema) === 'temp') { + if (strtolower((string)$schema) === 'temp') { $master = 'sqlite_temp_master'; } else { $master = sprintf('%s.%s', $this->quoteColumnName($schema), 'sqlite_master'); @@ -200,14 +193,14 @@ protected function resolveTable(string $tableName): array $rows = []; try { $result = $this->query( - "SELECT name FROM {$master} WHERE type = 'table' AND lower(name) = ?", + sprintf("SELECT name FROM %s WHERE type = 'table' AND lower(name) = ?", $master), [$table], ); // null on error if ($result !== null) { $rows = $result->fetchAll('assoc'); } - } catch (PDOException $e) { + } catch (PDOException) { // an exception can occur if the schema part of the table refers to a database which is not attached break; } @@ -215,7 +208,7 @@ protected function resolveTable(string $tableName): array // this somewhat pedantic check with strtolower is performed because the SQL lower function may be redefined, // and can act on all Unicode characters if the ICU extension is loaded, while SQL identifiers are only case-insensitive for ASCII foreach ($rows as $row) { - if (strtolower($row['name']) === $table) { + if (strtolower((string)$row['name']) === $table) { return ['schema' => $schema, 'table' => $row['name'], 'exists' => true]; } } @@ -292,7 +285,7 @@ public function createTable(TableMetadata $table, array $columns = [], array $in if (is_string($options['primary_key'])) { // handle primary_key => 'id' $sql .= $this->quoteColumnName($options['primary_key']); } elseif (is_array($options['primary_key'])) { // handle primary_key => array('tag_id', 'resource_id') - $sql .= implode(',', array_map([$this, 'quoteColumnName'], $options['primary_key'])); + $sql .= implode(',', array_map($this->quoteColumnName(...), $options['primary_key'])); } $sql .= ')'; } else { @@ -436,44 +429,50 @@ protected function parseDefaultValue(mixed $default, string $columnType): mixed PCRE_PATTERN; preg_match_all($pattern, $default, $matches); // strip out any comment tokens - $matches = array_map(function ($v) { + $matches = array_map(function (string $v): string { return preg_match('/^(?:\/\*|--)/', $v) ? ' ' : $v; }, $matches[0]); // reconstitute the string, trimming whitespace as well as parentheses $defaultClean = trim(implode('', $matches)); $defaultBare = rtrim(ltrim($defaultClean, $trimChars . '('), $trimChars . ')'); - // match the string against one of several patterns if ($columnType === TableSchemaInterface::TYPE_TEXT || $columnType === TableschemaInterface::TYPE_STRING) { // string literal return Literal::from($default); - } elseif ($columnType === TableSchemaInterface::TYPE_BOOLEAN) { + } + if ($columnType === TableSchemaInterface::TYPE_BOOLEAN) { // boolean literal return (int)filter_var($defaultClean, FILTER_VALIDATE_BOOLEAN); - } elseif (preg_match('/^CURRENT_(?:DATE|TIME|TIMESTAMP)$/i', $default)) { + } + if (preg_match('/^CURRENT_(?:DATE|TIME|TIMESTAMP)$/i', $default)) { // magic date or time return strtoupper($default); - } elseif (preg_match('/^[+-]?\d+$/i', $default)) { + } + if (preg_match('/^[+-]?\d+$/i', $default)) { $int = (int)$default; // integer literal if ($columnType === self::TYPE_BOOLEAN && ($int === 0 || $int === 1)) { return (bool)$int; - } else { - return $int; } - } elseif (preg_match('/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i', $default)) { + + return $int; + } + if (preg_match('/^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/i', $default)) { // float literal return (float)$default; - } elseif (preg_match('/^0x[0-9a-f]+$/i', $default)) { + } + if (preg_match('/^0x[0-9a-f]+$/i', $default)) { // hexadecimal literal return hexdec(substr($default, 2)); - } elseif (preg_match('/^null$/i', $defaultBare)) { + } + + // match the string against one of several patterns + if (preg_match('/^null$/i', $defaultBare)) { // null literal return null; - } else { - // any other expression: return the expression with parentheses, but without comments - return Expression::from($default); } + // any other expression: return the expression with parentheses, but without comments + return Expression::from($default); } /** @@ -489,24 +488,21 @@ protected function resolveIdentity(string $tableName): ?string $result = null; // make sure the table has only one primary key column which is of type integer foreach ($this->getColumnData($tableName) as $col) { - $type = strtolower($col['type']); + $type = strtolower((string)$col['type']); if ($col['pk'] > 1) { // the table has a composite primary key return null; - } elseif ($col['pk'] == 0) { + } + if ($col['pk'] == 0) { // the column is not a primary key column and is thus not relevant continue; - } elseif ($type !== 'integer') { + } + if ($type !== 'integer') { // if the primary key's type is not exactly INTEGER, it cannot be a row ID alias return null; - } else { - // the column is a candidate for a row ID alias - $result = $col['name']; } - } - // if there is no suitable PK column, stop now - if ($result === null) { - return null; + // the column is a candidate for a row ID alias + $result = $col['name']; } return $result; @@ -560,7 +556,7 @@ protected function getAddColumnInstructions(TableMetadata $table, Column $column $instructions = $this->beginAlterByCopyTable($tableName); - $instructions->addPostStep(function ($state) use ($tableName, $column) { + $instructions->addPostStep(function (array $state) use ($tableName, $column): array { // we use the final column to anchor our regex to insert the new column, // as the alternative is unwinding all possible table constraints which // gets messy quickly with CHECK constraints. @@ -587,7 +583,7 @@ protected function getAddColumnInstructions(TableMetadata $table, Column $column return $state; }); - $instructions->addPostStep(function ($state) use ($tableName) { + $instructions->addPostStep(function ($state) use ($tableName): array { $newState = $this->calculateNewTableColumns($tableName, false, false); return $newState + $state; @@ -615,25 +611,23 @@ protected function getDeclaringSql(string $tableName): string $columnsInfo = $this->getColumnData($tableName); foreach ($columnsInfo as $column) { - $columnName = preg_quote($column['name'], '#'); - $columnNamePattern = "\"$columnName\"|`$columnName`|\\[$columnName\\]|$columnName"; - $columnNamePattern = "#([\(,]+\\s*)($columnNamePattern)(\\s)#iU"; + $columnName = preg_quote((string)$column['name'], '#'); + $columnNamePattern = sprintf('"%s"|`%s`|\[%s\]|%s', $columnName, $columnName, $columnName, $columnName); + $columnNamePattern = sprintf('#([\(,]+\s*)(%s)(\s)#iU', $columnNamePattern); $sql = preg_replace_callback( $columnNamePattern, - function ($matches) use ($column) { + function (array $matches) use ($column): string { return $matches[1] . $this->quoteColumnName($column['name']) . $matches[3]; }, - $sql, + (string)$sql, ); } - $tableNamePattern = "\"$tableName\"|`$tableName`|\\[$tableName\\]|$tableName"; - $tableNamePattern = "#^(CREATE TABLE)\s*($tableNamePattern)\s*(\()#Ui"; + $tableNamePattern = sprintf('"%s"|`%s`|\[%s\]|%s', $tableName, $tableName, $tableName, $tableName); + $tableNamePattern = sprintf('#^(CREATE TABLE)\s*(%s)\s*(\()#Ui', $tableNamePattern); - $sql = preg_replace($tableNamePattern, "$1 `$tableName` $3", $sql, 1); - - return $sql; + return preg_replace($tableNamePattern, sprintf('$1 `%s` $3', $tableName), (string)$sql, 1); } /** @@ -791,8 +785,8 @@ protected function updateIndicesForRenamedColumn( $state['indices'][$key]['sql'] = preg_replace( sprintf($pattern, preg_quote($oldColumnName, '/')), - "\\1\\2$newColumnName\\4\\5\\6", - $index['sql'], + sprintf('\1\2%s\4\5\6', $newColumnName), + (string)$index['sql'], ); } } @@ -852,14 +846,14 @@ protected function validateForeignKeys(AlterInstructions $instructions, string $ foreach ($otherTables as $otherTable) { $foreignKeyList = $this->getForeignKeys($otherTable['name']); foreach ($foreignKeyList as $foreignKey) { - if (strcasecmp($foreignKey['references'][0], $tableName) === 0) { + if (strcasecmp((string)$foreignKey['references'][0], $tableName) === 0) { $tablesToCheck[] = $otherTable['name']; break; } } } - $tablesToCheck = array_unique(array_map('strtolower', $tablesToCheck)); + $tablesToCheck = array_unique(array_map(strtolower(...), $tablesToCheck)); foreach ($tablesToCheck as $tableToCheck) { $schema = $this->getSchemaName($tableToCheck, true)['schema']; @@ -915,7 +909,7 @@ protected function copyDataToNewTable(string $tableName, string $tmpTableName, a */ protected function copyAndDropTmpTable(AlterInstructions $instructions, string $tableName): AlterInstructions { - $instructions->addPostStep(function ($state) use ($tableName) { + $instructions->addPostStep(function (array $state) use ($tableName): array { $this->copyDataToNewTable( $state['tmpTableName'], $tableName, @@ -974,14 +968,14 @@ protected function calculateNewTableColumns(string $tableName, string|false $col $writeColumns[] = $writeName; } } - $selectColumns = array_filter($selectColumns, fn($value) => $value !== ''); - $writeColumns = array_filter($writeColumns, fn($value) => $value !== ''); - $selectColumns = array_map([$this, 'quoteColumnName'], $selectColumns); - $writeColumns = array_map([$this, 'quoteColumnName'], $writeColumns); + $selectColumns = array_filter($selectColumns, fn($value): bool => $value !== ''); + $writeColumns = array_filter($writeColumns, fn($value): bool => $value !== ''); + $selectColumns = array_map($this->quoteColumnName(...), $selectColumns); + $writeColumns = array_map($this->quoteColumnName(...), $writeColumns); if ($columnName && !$found) { throw new InvalidArgumentException(sprintf( - 'The specified column doesn\'t exist: %s', + "The specified column doesn't exist: %s", $columnName, )); } @@ -999,8 +993,8 @@ protected function calculateNewTableColumns(string $tableName, string|false $col protected function beginAlterByCopyTable(string $tableName): AlterInstructions { $instructions = new AlterInstructions(); - $instructions->addPostStep(function ($state) use ($tableName) { - $tmpTableName = "tmp_{$tableName}"; + $instructions->addPostStep(function ($state) use ($tableName): array { + $tmpTableName = 'tmp_' . $tableName; $createSQL = $this->getDeclaringSql($tableName); // Table name in SQLite can be hilarious inside declaring SQL: @@ -1016,7 +1010,7 @@ protected function beginAlterByCopyTable(string $tableName): AlterInstructions $createSQL, ); - $createSQL = "CREATE TABLE {$this->quoteTableName($tmpTableName)} ({$createSQL}"; + $createSQL = sprintf('CREATE TABLE %s (%s', $this->quoteTableName($tmpTableName), $createSQL); return compact('createSQL', 'tmpTableName') + $state; }); @@ -1055,7 +1049,7 @@ protected function endAlterByCopyTable( } $result = $this->fetchRow('PRAGMA foreign_keys'); - $foreignKeysEnabled = $result ? (bool)$result['foreign_keys'] : false; + $foreignKeysEnabled = $result && (bool)$result['foreign_keys']; if ($foreignKeysEnabled) { $instructions->addPostStep('PRAGMA foreign_keys = OFF'); @@ -1072,7 +1066,7 @@ protected function endAlterByCopyTable( $foreignKeysEnabled && $validateForeignKeys ) { - $instructions = $this->validateForeignKeys($instructions, $tableName); + return $this->validateForeignKeys($instructions, $tableName); } return $instructions; @@ -1085,7 +1079,7 @@ protected function getRenameColumnInstructions(string $tableName, string $column { $instructions = $this->beginAlterByCopyTable($tableName); - $instructions->addPostStep(function ($state) use ($columnName, $newColumnName) { + $instructions->addPostStep(function (array $state) use ($columnName, $newColumnName): array { $sql = str_replace( $this->quoteColumnName($columnName), $this->quoteColumnName($newColumnName), @@ -1096,7 +1090,7 @@ protected function getRenameColumnInstructions(string $tableName, string $column return $state; }); - $instructions->addPostStep(function ($state) use ($columnName, $newColumnName, $tableName) { + $instructions->addPostStep(function ($state) use ($columnName, $newColumnName, $tableName): array { $newState = $this->calculateNewTableColumns($tableName, $columnName, $newColumnName); return $newState + $state; @@ -1113,7 +1107,7 @@ protected function getChangeColumnInstructions(string $tableName, string $column $instructions = $this->beginAlterByCopyTable($tableName); $newColumnName = (string)$newColumn->getName(); - $instructions->addPostStep(function ($state) use ($columnName, $newColumn) { + $instructions->addPostStep(function (array $state) use ($columnName, $newColumn): array { $dialect = $this->getSchemaDialect(); $sql = preg_replace( sprintf("/%s(?:\/\*.*?\*\/|\([^)]+\)|'[^']*?'|[^,])+([,)])/", $this->quoteColumnName($columnName)), @@ -1126,7 +1120,7 @@ protected function getChangeColumnInstructions(string $tableName, string $column return $state; }); - $instructions->addPostStep(function ($state) use ($columnName, $newColumnName, $tableName) { + $instructions->addPostStep(function ($state) use ($columnName, $newColumnName, $tableName): array { $newState = $this->calculateNewTableColumns($tableName, $columnName, $newColumnName); return $newState + $state; @@ -1142,20 +1136,20 @@ protected function getDropColumnInstructions(string $tableName, string $columnNa { $instructions = $this->beginAlterByCopyTable($tableName); - $instructions->addPostStep(function ($state) use ($tableName, $columnName) { + $instructions->addPostStep(function ($state) use ($tableName, $columnName): array { $newState = $this->calculateNewTableColumns($tableName, $columnName, false); return $newState + $state; }); - $instructions->addPostStep(function ($state) use ($columnName) { + $instructions->addPostStep(function (array $state) use ($columnName): array { $sql = preg_replace( sprintf("/%s\s\w+.*(,\s(?!')|\)$)/U", preg_quote($this->quoteColumnName($columnName))), '', (string)$state['createSQL'], ); - if (substr($sql, -2) === ', ') { + if (str_ends_with($sql, ', ')) { $sql = substr($sql, 0, -2) . ')'; } @@ -1176,9 +1170,8 @@ protected function getDropColumnInstructions(string $tableName, string $columnNa protected function getIndexes(string $tableName): array { $dialect = $this->getSchemaDialect(); - $indexes = $dialect->describeIndexes($tableName); - return $indexes; + return $dialect->describeIndexes($tableName); } /** @@ -1190,12 +1183,12 @@ protected function getIndexes(string $tableName): array */ protected function resolveIndex(string $tableName, string|array $columns): array { - $columns = array_map('strtolower', (array)$columns); + $columns = array_map(strtolower(...), (array)$columns); $indexes = $this->getIndexes($tableName); $matches = []; foreach ($indexes as $index) { - $indexCols = array_map('strtolower', $index['columns']); + $indexCols = array_map(strtolower(...), $index['columns']); if ($columns == $indexCols) { $matches[] = $index['name']; } @@ -1242,7 +1235,7 @@ protected function getDropIndexByColumnsInstructions(string $tableName, $columns if ($indexName === 'primary') { continue; } - if (strpos($indexName, 'sqlite_autoindex_') !== 0) { + if (!str_starts_with((string)$indexName, 'sqlite_autoindex_')) { $instructions->addPostStep(sprintf( 'DROP INDEX %s%s', $schema, @@ -1265,7 +1258,7 @@ protected function getDropIndexByNameInstructions(string $tableName, string $ind $found = false; foreach ($indexes as $index) { - if ($indexName === strtolower($index['name'])) { + if ($indexName === strtolower((string)$index['name'])) { $found = true; break; } @@ -1294,14 +1287,10 @@ public function hasPrimaryKey(string $tableName, $columns, ?string $constraint = throw new InvalidArgumentException('SQLite does not support named constraints.'); } - $columns = array_map('strtolower', (array)$columns); - $primaryKey = array_map('strtolower', $this->getPrimaryKey($tableName)); - - if (array_diff($primaryKey, $columns) || array_diff($columns, $primaryKey)) { - return false; - } + $columns = array_map(strtolower(...), (array)$columns); + $primaryKey = array_map(strtolower(...), $this->getPrimaryKey($tableName)); - return true; + return !array_diff($primaryKey, $columns) && !array_diff($columns, $primaryKey); } /** @@ -1332,9 +1321,8 @@ protected function getPrimaryKey(string $tableName): array protected function getForeignKeys(string $tableName): array { $dialect = $this->getSchemaDialect(); - $keys = $dialect->describeForeignKeys($tableName); - return $keys; + return $dialect->describeForeignKeys($tableName); } /** @@ -1347,26 +1335,22 @@ protected function getAddPrimaryKeyInstructions(TableMetadata $table, string $co $instructions = $this->beginAlterByCopyTable($table->getName()); $tableName = $table->getName(); - $instructions->addPostStep(function ($state) use ($column) { + $instructions->addPostStep(function (array $state) use ($column): array { $quotedColumn = preg_quote($column); - $columnPattern = "`{$quotedColumn}`|\"{$quotedColumn}\"|\[{$quotedColumn}\]"; - $matchPattern = "/($columnPattern)\s+(\w+(\(\d+\))?)(\s+(NOT )?NULL)?(\s+(?:PRIMARY KEY\s+)?AUTOINCREMENT)?/i"; + $columnPattern = sprintf('`%s`|"%s"|\[%s\]', $quotedColumn, $quotedColumn, $quotedColumn); + $matchPattern = sprintf('/(%s)\s+(\w+(\(\d+\))?)(\s+(NOT )?NULL)?(\s+(?:PRIMARY KEY\s+)?AUTOINCREMENT)?/i', $columnPattern); $sql = $state['createSQL']; - if (preg_match($matchPattern, $state['createSQL'], $matches)) { - if (isset($matches[2])) { - $hasAutoIncrement = isset($matches[6]) && stripos($matches[6], 'AUTOINCREMENT') !== false; - - if ($matches[2] === 'INTEGER' && $hasAutoIncrement) { - // Only add AUTOINCREMENT if the column already had it - $replace = '$1 INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT'; - } else { - $replace = '$1 $2 NOT NULL PRIMARY KEY'; - } - - $sql = preg_replace($matchPattern, $replace, (string)$state['createSQL'], 1); + if (preg_match($matchPattern, (string)$state['createSQL'], $matches) && isset($matches[2])) { + $hasAutoIncrement = isset($matches[6]) && stripos($matches[6], 'AUTOINCREMENT') !== false; + if ($matches[2] === 'INTEGER' && $hasAutoIncrement) { + // Only add AUTOINCREMENT if the column already had it + $replace = '$1 INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT'; + } else { + $replace = '$1 $2 NOT NULL PRIMARY KEY'; } + $sql = preg_replace($matchPattern, $replace, (string)$state['createSQL'], 1); } $this->execute($sql); @@ -1374,9 +1358,9 @@ protected function getAddPrimaryKeyInstructions(TableMetadata $table, string $co return $state; }); - $instructions->addPostStep(function ($state) { + $instructions->addPostStep(function (array $state): array { $columns = $this->fetchAll(sprintf('pragma table_info(%s)', $this->quoteTableName($state['tmpTableName']))); - $names = array_map([$this, 'quoteColumnName'], array_column($columns, 'name')); + $names = array_map($this->quoteColumnName(...), array_column($columns, 'name')); $selectColumns = $writeColumns = $names; return compact('selectColumns', 'writeColumns') + $state; @@ -1395,7 +1379,7 @@ protected function getDropPrimaryKeyInstructions(TableMetadata $table, string $c $tableName = $table->getName(); $instructions = $this->beginAlterByCopyTable($tableName); - $instructions->addPostStep(function ($state) { + $instructions->addPostStep(function (array $state): array { $search = "/(,?\s*PRIMARY KEY\s*\([^\)]*\)|\s+PRIMARY KEY(\s+AUTOINCREMENT)?)/"; $sql = preg_replace($search, '', (string)$state['createSQL'], 1); @@ -1406,7 +1390,7 @@ protected function getDropPrimaryKeyInstructions(TableMetadata $table, string $c return $state; }); - $instructions->addPostStep(function ($state) use ($column) { + $instructions->addPostStep(function (array $state) use ($column): array { $newState = $this->calculateNewTableColumns($state['tmpTableName'], $column, $column); return $newState + $state; @@ -1423,16 +1407,16 @@ protected function getAddForeignKeyInstructions(TableMetadata $table, ForeignKey $instructions = $this->beginAlterByCopyTable($table->getName()); $tableName = $table->getName(); - $instructions->addPostStep(function ($state) use ($foreignKey, $tableName) { + $instructions->addPostStep(function (array $state) use ($foreignKey, $tableName): array { $this->execute('pragma foreign_keys = ON'); - $sql = substr($state['createSQL'], 0, -1) . ',' . $this->getForeignKeySqlDefinition($foreignKey, $tableName) . '); '; + $sql = substr((string)$state['createSQL'], 0, -1) . ',' . $this->getForeignKeySqlDefinition($foreignKey, $tableName) . '); '; //Delete indexes from original table and recreate them in temporary table $schema = $this->getSchemaName($tableName, true)['schema']; $tmpTableName = $state['tmpTableName']; $indexes = $this->getIndexes($tableName); foreach ($indexes as $index) { - if (strpos($index['name'], 'sqlite_autoindex_') !== 0) { + if (!str_starts_with((string)$index['name'], 'sqlite_autoindex_')) { $sql .= sprintf( 'DROP INDEX %s%s; ', $schema, @@ -1440,7 +1424,7 @@ protected function getAddForeignKeyInstructions(TableMetadata $table, ForeignKey ); $createIndexSQL = $this->getDeclaringIndexSQL($tableName, $index['name']); $sql .= preg_replace( - "/\b{$tableName}\b/", + sprintf('/\b%s\b/', $tableName), $tmpTableName, $createIndexSQL, ); @@ -1452,9 +1436,9 @@ protected function getAddForeignKeyInstructions(TableMetadata $table, ForeignKey return $state; }); - $instructions->addPostStep(function ($state) { + $instructions->addPostStep(function (array $state): array { $columns = $this->fetchAll(sprintf('pragma table_info(%s)', $this->quoteTableName($state['tmpTableName']))); - $names = array_map([$this, 'quoteColumnName'], array_column($columns, 'name')); + $names = array_map($this->quoteColumnName(...), array_column($columns, 'name')); $selectColumns = $writeColumns = $names; return compact('selectColumns', 'writeColumns') + $state; @@ -1491,13 +1475,13 @@ protected function getDropForeignKeyByColumnsInstructions(string $tableName, arr $instructions = $this->beginAlterByCopyTable($tableName); - $instructions->addPostStep(function ($state) use ($columns) { + $instructions->addPostStep(function (array $state) use ($columns): array { $search = sprintf( "/,[^,]+?\(\s*%s\s*\)\s*REFERENCES[^,]*\([^\)]*\)[^,)]*/is", implode( '\s*,\s*', array_map( - fn($column) => $this->possiblyQuotedIdentifierRegex($column, false), + fn(string $column): string => $this->possiblyQuotedIdentifierRegex($column, false), $columns, ), ), @@ -1511,7 +1495,7 @@ protected function getDropForeignKeyByColumnsInstructions(string $tableName, arr return $state; }); - $instructions->addPostStep(function ($state) { + $instructions->addPostStep(function (array $state): array { $newState = $this->calculateNewTableColumns($state['tmpTableName'], false, false); return $newState + $state; @@ -1541,7 +1525,7 @@ protected function getAddCheckConstraintInstructions(TableMetadata $table, Check $tableName = $table->getName(); $instructions = $this->beginAlterByCopyTable($tableName); - $instructions->addPostStep(function ($state) use ($checkConstraint) { + $instructions->addPostStep(function (array $state) use ($checkConstraint): array { $constraintName = $checkConstraint->getName(); if ($constraintName === null) { // Auto-generate constraint name if not provided @@ -1555,13 +1539,13 @@ protected function getAddCheckConstraintInstructions(TableMetadata $table, Check ); // Add the check constraint before the closing parenthesis - $sql = substr($state['createSQL'], 0, -1) . ', ' . $checkDef . ')'; + $sql = substr((string)$state['createSQL'], 0, -1) . ', ' . $checkDef . ')'; $this->execute($sql); return $state; }); - $instructions->addPostStep(function ($state) use ($tableName) { + $instructions->addPostStep(function ($state) use ($tableName): array { $newState = $this->calculateNewTableColumns($tableName, false, false); return $newState + $state; @@ -1577,11 +1561,11 @@ protected function getDropCheckConstraintInstructions(string $tableName, string { $instructions = $this->beginAlterByCopyTable($tableName); - $instructions->addPostStep(function ($state) use ($constraintName) { + $instructions->addPostStep(function (array $state) use ($constraintName): array { // Remove the check constraint from the CREATE TABLE statement // Match CONSTRAINT name CHECK (expression) or just CHECK (expression) $quotedName = $this->possiblyQuotedIdentifierRegex($constraintName, false); - $pattern = "/,?\s*CONSTRAINT\s+{$quotedName}\s+CHECK\s*\([^)]+(?:\([^)]*\)[^)]*)*\)/is"; + $pattern = sprintf('/,?\s*CONSTRAINT\s+%s\s+CHECK\s*\([^)]+(?:\([^)]*\)[^)]*)*\)/is', $quotedName); $sql = preg_replace($pattern, '', (string)$state['createSQL'], 1); if ($sql) { @@ -1591,7 +1575,7 @@ protected function getDropCheckConstraintInstructions(string $tableName, string return $state; }); - $instructions->addPostStep(function ($state) use ($tableName) { + $instructions->addPostStep(function ($state) use ($tableName): array { $newState = $this->calculateNewTableColumns($tableName, false, false); return $newState + $state; @@ -1640,11 +1624,7 @@ public function dropDatabase(string $name): void */ protected function getIndexSqlDefinition(TableMetadata $table, Index $index): string { - if ($index->getType() === Index::UNIQUE) { - $def = 'UNIQUE INDEX'; - } else { - $def = 'INDEX'; - } + $def = $index->getType() === Index::UNIQUE ? 'UNIQUE INDEX' : 'INDEX'; $indexName = $index->getName(); if ($indexName == '') { $indexName = $table->getName() . '_'; @@ -1653,9 +1633,8 @@ protected function getIndexSqlDefinition(TableMetadata $table, Index $index): st } $indexName .= 'index'; } - $def .= ' ' . $this->quoteColumnName($indexName); - return $def; + return $def . ' ' . $this->quoteColumnName($indexName); } /** diff --git a/src/Db/Adapter/SqlserverAdapter.php b/src/Db/Adapter/SqlserverAdapter.php index 67f08c00c..8867fdc4d 100644 --- a/src/Db/Adapter/SqlserverAdapter.php +++ b/src/Db/Adapter/SqlserverAdapter.php @@ -41,9 +41,6 @@ class SqlserverAdapter extends AbstractAdapter self::TYPE_NATIVE_UUID, ]; - /** - * @var string - */ protected string $schema = 'dbo'; /** @@ -221,7 +218,7 @@ protected function getColumnCommentSqlDefinition(Column $column, ?string $tableN // passing 'null' is to remove column comment $currentComment = $this->getColumnComment((string)$tableName, $column->getName()); - $comment = strcasecmp((string)$column->getComment(), 'NULL') !== 0 ? $this->quoteString((string)$column->getComment()) : '\'\''; + $comment = strcasecmp((string)$column->getComment(), 'NULL') !== 0 ? $this->quoteString((string)$column->getComment()) : "''"; $command = $currentComment === null ? 'sp_addextendedproperty' : 'sp_updateextendedproperty'; return sprintf( @@ -295,7 +292,7 @@ public function getColumnComment(string $tableName, ?string $columnName): ?strin $row = $this->query($sql, $params)->fetch('assoc'); if ($row) { - return trim($row['comment']); + return trim((string)$row['comment']); } return null; @@ -343,7 +340,7 @@ protected function parseDefault(?string $default): int|string|null $result = preg_replace(["/\('(.*)'\)/", "/\(\((.*)\)\)/", "/\((.*)\)/"], '$1', $default); - if (strtoupper($result) === 'NULL') { + if (strtoupper((string)$result) === 'NULL') { $result = null; } elseif (is_numeric($result)) { $result = (int)$result; @@ -375,13 +372,13 @@ protected function getAddColumnInstructions(TableMetadata $table, Column $column protected function getRenameColumnInstructions(string $tableName, string $columnName, string $newColumnName): AlterInstructions { if (!$this->hasColumn($tableName, $columnName)) { - throw new InvalidArgumentException("The specified column does not exist: $columnName"); + throw new InvalidArgumentException('The specified column does not exist: ' . $columnName); } $instructions = new AlterInstructions(); - $oldConstraintName = "DF_{$tableName}_{$columnName}"; - $newConstraintName = "DF_{$tableName}_{$newColumnName}"; + $oldConstraintName = sprintf('DF_%s_%s', $tableName, $columnName); + $newConstraintName = sprintf('DF_%s_%s', $tableName, $newColumnName); $sql = sprintf( 'IF (OBJECT_ID(%s, \'D\') IS NOT NULL) BEGIN @@ -394,7 +391,7 @@ protected function getRenameColumnInstructions(string $tableName, string $column $instructions->addPostStep($sql); $instructions->addPostStep(sprintf( - 'EXECUTE sp_rename %s, %s, N\'COLUMN\'', + "EXECUTE sp_rename %s, %s, N'COLUMN'", $this->quoteString($tableName . '.' . $columnName), $this->quoteString($newColumnName), )); @@ -411,15 +408,11 @@ protected function getRenameColumnInstructions(string $tableName, string $column */ protected function getChangeDefault(string $tableName, Column $newColumn): AlterInstructions { - $constraintName = "DF_{$tableName}_{$newColumn->getName()}"; + $constraintName = sprintf('DF_%s_%s', $tableName, $newColumn->getName()); $default = $newColumn->getDefault(); $instructions = new AlterInstructions(); - if ($default === null) { - $default = 'DEFAULT NULL'; - } else { - $default = ltrim($this->getDefaultValueDefinition($default, (string)$newColumn->getType())); - } + $default = $default === null ? 'DEFAULT NULL' : ltrim($this->getDefaultValueDefinition($default, $newColumn->getType())); if (!$default) { return $instructions; @@ -450,7 +443,7 @@ protected function getChangeColumnInstructions(string $tableName, string $column } } if ($oldColumn === null) { - throw new InvalidArgumentException("Unknown column {$columnName} cannot be changed."); + throw new InvalidArgumentException(sprintf('Unknown column %s cannot be changed.', $columnName)); } $changeDefault = @@ -480,6 +473,7 @@ protected function getChangeColumnInstructions(string $tableName, string $column $dialect->columnDefinitionSql($columnData), ); $alterColumn = preg_replace('/DEFAULT NULL/', '', $alterColumn); + $instructions->addPostStep($alterColumn); // change column comment if needed @@ -562,7 +556,7 @@ protected function getIndexColumns(string $tableId, string $indexId): array $rows = $this->query($sql, $params)->fetchAll('assoc'); $columns = []; foreach ($rows as $row) { - $columns[] = strtolower($row['column_name']); + $columns[] = strtolower((string)$row['column_name']); } return $columns; @@ -603,7 +597,7 @@ protected function getDropIndexByColumnsInstructions(string $tableName, $columns } $indexes = $this->getIndexes($tableName); - $columns = array_map('strtolower', $columns); + $columns = array_map(strtolower(...), $columns); $instructions = new AlterInstructions(); foreach ($indexes as $index) { @@ -833,7 +827,7 @@ protected function getIndexSqlDefinition(Index $index, string $tableName): strin $indexName = sprintf('%s_%s', $parts['table'], implode('_', $columnNames)); } $order = $index->getOrder() ?? []; - $columnNames = array_map(function ($columnName) use ($order) { + $columnNames = array_map(function (string $columnName) use ($order): string { $ret = '[' . $columnName . ']'; if (isset($order[$columnName])) { $ret .= ' ' . $order[$columnName]; @@ -877,10 +871,10 @@ protected function getForeignKeySqlDefinition(ForeignKey $foreignKey, string $ta $def .= ' FOREIGN KEY (' . $columnList . ')'; $def .= ' REFERENCES ' . $this->quoteTableName($foreignKey->getReferencedTable()) . ' (' . $refColumnList . ')'; if ($foreignKey->getOnDelete()) { - $def .= " ON DELETE {$foreignKey->getOnDelete()}"; + $def .= ' ON DELETE ' . $foreignKey->getOnDelete(); } if ($foreignKey->getOnUpdate()) { - $def .= " ON UPDATE {$foreignKey->getOnUpdate()}"; + $def .= ' ON UPDATE ' . $foreignKey->getOnUpdate(); } return $def; @@ -1003,7 +997,7 @@ protected function getSchemaName(string $tableName): array { $schema = $this->getGlobalSchemaName(); $table = $tableName; - if (strpos($tableName, '.') !== false) { + if (str_contains($tableName, '.')) { [$schema, $table] = explode('.', $tableName); } @@ -1106,7 +1100,7 @@ public function bulkinsert( if ($v instanceof Literal) { $placeholder = (string)$v; } - if ($placeholder == '?') { + if ($placeholder === '?') { if ($v instanceof DateTime) { $vals[] = $v->toDateTimeString(); } elseif ($v instanceof Date) { diff --git a/src/Db/Adapter/TimedOutputAdapter.php b/src/Db/Adapter/TimedOutputAdapter.php index f5e11be62..4e7025d40 100644 --- a/src/Db/Adapter/TimedOutputAdapter.php +++ b/src/Db/Adapter/TimedOutputAdapter.php @@ -54,16 +54,16 @@ public function startCommandTimer(): callable public function writeCommand(string $command, array $args = []): void { $io = $this->getIo(); - if ($io && $io->level() < ConsoleIo::VERBOSE) { + if ($io instanceof ConsoleIo && $io->level() < ConsoleIo::VERBOSE) { return; } - if (count($args)) { + if ($args !== []) { $outArr = []; foreach ($args as $arg) { if (is_array($arg)) { $arg = array_map( - function ($value) { - return '\'' . $value . '\''; + function (string $value): string { + return "'" . $value . "'"; }, $arg, ); @@ -71,7 +71,7 @@ function ($value) { continue; } - $outArr[] = '\'' . $arg . '\''; + $outArr[] = "'" . $arg . "'"; } $this->getIo()?->verbose(' -- ' . $command . '(' . implode(', ', $outArr) . ')'); diff --git a/src/Db/Expression.php b/src/Db/Expression.php index 46d9a4f66..10b6dc5d2 100644 --- a/src/Db/Expression.php +++ b/src/Db/Expression.php @@ -8,7 +8,9 @@ namespace Migrations\Db; -class Expression +use Stringable; + +class Expression implements Stringable { /** * @var string The expression diff --git a/src/Db/Literal.php b/src/Db/Literal.php index b318daa14..843ad5645 100644 --- a/src/Db/Literal.php +++ b/src/Db/Literal.php @@ -8,11 +8,13 @@ namespace Migrations\Db; +use Stringable; + /** * Represent a value that should be used as a literal value when being * interpolated into SQL commands. */ -class Literal +class Literal implements Stringable { /** * @var string The literal's value diff --git a/src/Db/Plan/AlterTable.php b/src/Db/Plan/AlterTable.php index 47d0ac64a..3c5146139 100644 --- a/src/Db/Plan/AlterTable.php +++ b/src/Db/Plan/AlterTable.php @@ -18,8 +18,6 @@ class AlterTable { /** * The table - * - * @var \Migrations\Db\Table\TableMetadata */ protected TableMetadata $table; diff --git a/src/Db/Plan/NewTable.php b/src/Db/Plan/NewTable.php index 826283b6a..0e0723fc8 100644 --- a/src/Db/Plan/NewTable.php +++ b/src/Db/Plan/NewTable.php @@ -19,8 +19,6 @@ class NewTable { /** * The table to create - * - * @var \Migrations\Db\Table\TableMetadata */ protected TableMetadata $table; diff --git a/src/Db/Plan/Plan.php b/src/Db/Plan/Plan.php index dcbaa718d..b764a7b87 100644 --- a/src/Db/Plan/Plan.php +++ b/src/Db/Plan/Plan.php @@ -211,7 +211,7 @@ protected function resolveConflicts(): void $splitter = new ActionSplitter( RenameColumn::class, ChangeColumn::class, - function (RenameColumn $a, ChangeColumn $b) { + function (RenameColumn $a, ChangeColumn $b): bool { return $a->getNewName() === $b->getColumnName(); }, ); @@ -231,7 +231,7 @@ function (RenameColumn $a, ChangeColumn $b) { $splitter = new ActionSplitter( DropForeignKey::class, AddForeignKey::class, - function (DropForeignKey $a, AddForeignKey $b) { + function (DropForeignKey $a, AddForeignKey $b): bool { return $a->getForeignKey()->getColumns() === $b->getForeignKey()->getColumns(); }, ); @@ -308,7 +308,7 @@ protected function remapContraintAndIndexConflicts(AlterTable $alter): AlterTabl protected function forgetDropIndex(TableMetadata $table, array $columns, array $actions): array { $dropIndexActions = new ArrayObject(); - $indexes = array_map(function ($alter) use ($table, $columns, $dropIndexActions) { + $indexes = array_map(function (AlterTable $alter) use ($table, $columns, $dropIndexActions): AlterTable { if ($alter->getTable()->getName() !== $table->getName()) { return $alter; } @@ -340,7 +340,7 @@ protected function forgetDropIndex(TableMetadata $table, array $columns, array $ protected function forgetRemoveColumn(TableMetadata $table, array $columns, array $actions): array { $removeColumnActions = new ArrayObject(); - $indexes = array_map(function ($alter) use ($table, $columns, $removeColumnActions) { + $indexes = array_map(function (AlterTable $alter) use ($table, $columns, $removeColumnActions): AlterTable { if ($alter->getTable()->getName() !== $table->getName()) { return $alter; } @@ -407,8 +407,9 @@ protected function gatherUpdates(array $actions): void && !($action instanceof RemoveColumn) && !($action instanceof RenameColumn) ) { - continue; - } elseif (isset($this->tableCreates[$action->getTable()->getName()])) { + continue; + } + if (isset($this->tableCreates[$action->getTable()->getName()])) { continue; } $table = $action->getTable(); @@ -467,7 +468,8 @@ protected function gatherIndexes(array $actions): void foreach ($actions as $action) { if (!($action instanceof AddIndex) && !($action instanceof DropIndex)) { continue; - } elseif (isset($this->tableCreates[$action->getTable()->getName()])) { + } + if (isset($this->tableCreates[$action->getTable()->getName()])) { continue; } @@ -491,7 +493,7 @@ protected function gatherIndexes(array $actions): void protected function gatherConstraints(array $actions): void { foreach ($actions as $action) { - if (!($action instanceof AddForeignKey || $action instanceof DropForeignKey)) { + if (!$action instanceof AddForeignKey && !$action instanceof DropForeignKey) { continue; } $table = $action->getTable(); @@ -520,7 +522,8 @@ protected function gatherPartitions(array $actions): void && !($action instanceof SetPartitioning) ) { continue; - } elseif (isset($this->tableCreates[$action->getTable()->getName()])) { + } + if (isset($this->tableCreates[$action->getTable()->getName()])) { continue; } diff --git a/src/Db/Plan/Solver/ActionSplitter.php b/src/Db/Plan/Solver/ActionSplitter.php index 48dd92a3e..358b30120 100644 --- a/src/Db/Plan/Solver/ActionSplitter.php +++ b/src/Db/Plan/Solver/ActionSplitter.php @@ -8,6 +8,7 @@ namespace Migrations\Db\Plan\Solver; +use Migrations\Db\Action\Action; use Migrations\Db\Plan\AlterTable; /** @@ -21,16 +22,12 @@ class ActionSplitter { /** * The fully qualified class name of the Action class to match for conflicts - * - * @var string */ protected string $conflictClass; /** * The fully qualified class name of the Action class to match for conflicts, which * is the dual of $conflictClass. For example `AddColumn` and `DropColumn` are duals. - * - * @var string */ protected string $conflictClassDual; @@ -70,7 +67,7 @@ public function __construct(string $conflictClass, string $conflictClassDual, ca */ public function __invoke(AlterTable $alter): array { - $conflictActions = array_filter($alter->getActions(), function ($action) { + $conflictActions = array_filter($alter->getActions(), function (Action $action): bool { return $action instanceof $this->conflictClass; }); diff --git a/src/Db/Table.php b/src/Db/Table.php index aeeb09066..151a3f677 100644 --- a/src/Db/Table.php +++ b/src/Db/Table.php @@ -51,30 +51,16 @@ */ class Table { - /** - * @var \Migrations\Db\Table\TableMetadata - */ protected TableMetadata $table; - /** - * @var \Migrations\Db\Adapter\AdapterInterface|null - */ protected ?AdapterInterface $adapter = null; - /** - * @var \Migrations\Db\Plan\Intent - */ protected Intent $actions; - /** - * @var array - */ protected array $data = []; /** * Insert mode for data operations - * - * @var \Migrations\Db\InsertMode|null */ protected ?InsertMode $insertMode = null; @@ -111,7 +97,7 @@ public function __construct(string $name, array $options = [], ?AdapterInterface $this->table = new TableMetadata($name, $options); $this->actions = new Intent(); - if ($adapter !== null) { + if ($adapter instanceof AdapterInterface) { $this->setAdapter($adapter); } } @@ -167,7 +153,7 @@ public function setAdapter(AdapterInterface $adapter) */ public function getAdapter(): AdapterInterface { - if (!$this->adapter) { + if (!$this->adapter instanceof AdapterInterface) { throw new RuntimeException('There is no database adapter set yet, cannot proceed'); } @@ -181,7 +167,11 @@ public function getAdapter(): AdapterInterface */ public function hasPendingActions(): bool { - return count($this->actions->getActions()) > 0 || count($this->data) > 0; + if ($this->actions->getActions() !== []) { + return true; + } + + return $this->data !== []; } /** @@ -277,7 +267,7 @@ public function getColumn(string $name): ?Column { $columns = array_filter( $this->getColumns(), - function ($column) use ($name) { + function (Column $column) use ($name): bool { return $column->getName() === $name; }, ); @@ -369,7 +359,7 @@ public function addColumn(string|Column $columnName, ?string $type = null, array if (!$this->getAdapter()->isValidColumnType($action->getColumn())) { throw new InvalidArgumentException(sprintf( 'An invalid column type "%s" was specified for column "%s".', - (string)$action->getColumn()->getType(), + $action->getColumn()->getType(), (string)$action->getColumn()->getName(), )); } @@ -459,13 +449,13 @@ public function changeColumn(string $columnName, string|Column|null $newColumnTy if ($newColumnType === null) { if (!$this->hasColumn($columnName)) { throw new RuntimeException( - "Cannot preserve column type for '$columnName' - column does not exist in table '{$this->getName()}'", + sprintf("Cannot preserve column type for '%s' - column does not exist in table '%s'", $columnName, $this->getName()), ); } $existingColumn = $this->getColumn($columnName); - if ($existingColumn === null) { + if (!$existingColumn instanceof Column) { throw new RuntimeException( - "Cannot retrieve column definition for '$columnName' in table '{$this->getName()}'", + sprintf("Cannot retrieve column definition for '%s' in table '%s'", $columnName, $this->getName()), ); } $newColumnType = $existingColumn->getType(); @@ -474,7 +464,7 @@ public function changeColumn(string $columnName, string|Column|null $newColumnTy if ($preserveUnspecified && $this->hasColumn($columnName)) { // Get existing column definition $existingColumn = $this->getColumn($columnName); - if ($existingColumn !== null) { + if ($existingColumn instanceof Column) { // Merge existing attributes with new ones $options = $this->mergeColumnOptions($existingColumn, $newColumnType, $options); } @@ -582,7 +572,7 @@ public function addForeignKey(string|array|ForeignKey $columns, string|TableMeta if ($columns instanceof ForeignKey) { $action = new AddForeignKey($this->table, $columns); } else { - if (!$referencedTable) { + if ($referencedTable === null) { throw new InvalidArgumentException('Referenced table is required'); } $action = AddForeignKey::build($this->table, $columns, $referencedTable, $referencedColumns, $options); @@ -646,7 +636,7 @@ public function partitionBy(string $type, string|array|Literal $columns, array $ public function addPartition(string $name, mixed $value = null, array $options = []) { $partition = $this->table->getPartition(); - if ($partition === null) { + if (!$partition instanceof Partition) { throw new RuntimeException('Must call partitionBy() before addPartition()'); } @@ -707,15 +697,15 @@ public function addPartitionToExisting(string $name, mixed $value, array $option */ public function addTimestamps(string|false|null $createdAt = 'created', string|false|null $updatedAt = 'updated', bool $withTimezone = false) { - $createdAt = $createdAt ?? 'created'; - $updatedAt = $updatedAt ?? 'updated'; + $createdAt ??= 'created'; + $updatedAt ??= 'updated'; if (!$createdAt && !$updatedAt) { throw new RuntimeException('Cannot set both created_at and updated_at columns to false'); } $timestampConfig = (bool)Configure::read('Migrations.add_timestamps_use_datetime'); $timestampType = 'timestamp'; - if ($timestampConfig === true) { + if ($timestampConfig) { $timestampType = 'datetime'; } @@ -778,7 +768,7 @@ public function insert(array $data) return $this; } - if (count($data) > 0) { + if ($data !== []) { $this->data[] = $data; } @@ -851,7 +841,7 @@ public function insertOrUpdate(array $data, array $updateColumns, array $conflic public function create(): void { $options = $this->getTable()->getOptions(); - if ((!isset($options['id']) || $options['id'] === false) && !empty($this->primaryKey)) { + if ((!isset($options['id']) || $options['id'] === false) && (isset($this->primaryKey) && !in_array($this->primaryKey, ['', '0', []], true))) { $options['primary_key'] = (array)$this->primaryKey; $this->filterPrimaryKey($options); } @@ -894,14 +884,14 @@ protected function filterPrimaryKey(array $options): void /** @var \Cake\Collection\Collection $columnsCollection */ $columnsCollection = (new Collection($this->actions->getActions())) - ->filter(function ($action) { + ->filter(function ($action): bool { return $action instanceof AddColumn; }) ->map(function ($action) { /** @var \Migrations\Db\Action\ChangeColumn|\Migrations\Db\Action\RenameColumn|\Migrations\Db\Action\RemoveColumn|\Migrations\Db\Action\AddColumn $action */ return $action->getColumn(); }); - $primaryKeyColumns = $columnsCollection->filter(function (Column $columnDef, $key) use ($primaryKey) { + $primaryKeyColumns = $columnsCollection->filter(function (Column $columnDef, $key) use ($primaryKey): bool { return isset($primaryKey[$columnDef->getName()]); })->toArray(); @@ -1036,7 +1026,7 @@ protected function executeActions(bool $exists): void // If table exists and has partition configuration, create SetPartitioning action if ($exists) { $partition = $this->table->getPartition(); - if ($partition !== null && $partition->getDefinitions()) { + if ($partition instanceof Partition && $partition->getDefinitions()) { $this->actions->addAction(new SetPartitioning($this->table, $partition)); } } @@ -1063,8 +1053,8 @@ protected function executeActions(bool $exists): void protected function mergeColumnOptions(Column $existingColumn, string $newColumnType, array $options): array { // Determine if type is changing - $newTypeString = (string)$newColumnType; - $existingTypeString = (string)$existingColumn->getType(); + $newTypeString = $newColumnType; + $existingTypeString = $existingColumn->getType(); $typeChanging = $newTypeString !== $existingTypeString; // Build array of existing column attributes diff --git a/src/Db/Table/Column.php b/src/Db/Table/Column.php index e608560ee..57a480471 100644 --- a/src/Db/Table/Column.php +++ b/src/Db/Table/Column.php @@ -42,84 +42,77 @@ class Column extends DatabaseColumn { public const BIGINTEGER = TableSchemaInterface::TYPE_BIGINTEGER; + public const SMALLINTEGER = TableSchemaInterface::TYPE_SMALLINTEGER; + public const TINYINTEGER = TableSchemaInterface::TYPE_TINYINTEGER; + public const BINARY = TableSchemaInterface::TYPE_BINARY; + public const BOOLEAN = TableSchemaInterface::TYPE_BOOLEAN; + public const CHAR = TableSchemaInterface::TYPE_CHAR; + public const DATE = TableSchemaInterface::TYPE_DATE; + public const DATETIME = TableSchemaInterface::TYPE_DATETIME; + public const DECIMAL = TableSchemaInterface::TYPE_DECIMAL; + public const FLOAT = TableSchemaInterface::TYPE_FLOAT; + public const INTEGER = TableSchemaInterface::TYPE_INTEGER; + public const STRING = TableSchemaInterface::TYPE_STRING; + public const TEXT = TableSchemaInterface::TYPE_TEXT; + public const TIME = TableSchemaInterface::TYPE_TIME; + public const TIMESTAMP = TableSchemaInterface::TYPE_TIMESTAMP; + public const UUID = TableSchemaInterface::TYPE_UUID; + public const BINARYUUID = TableSchemaInterface::TYPE_BINARY_UUID; + public const NATIVEUUID = TableSchemaInterface::TYPE_NATIVE_UUID; + /** MySQL-only column type */ public const YEAR = TableSchemaInterface::TYPE_YEAR; + /** MySQL/Postgres-only column type */ public const JSON = TableSchemaInterface::TYPE_JSON; + /** Postgres-only column type */ public const CIDR = TableSchemaInterface::TYPE_CIDR; + /** Postgres-only column type */ public const INET = TableSchemaInterface::TYPE_INET; + /** Postgres-only column type */ public const MACADDR = TableSchemaInterface::TYPE_MACADDR; + /** Postgres-only column type */ public const INTERVAL = TableSchemaInterface::TYPE_INTERVAL; - /** - * @var int|null - */ protected ?int $seed = null; - /** - * @var int|null - */ protected ?int $scale = null; - /** - * @var string|null - */ protected ?string $update = null; - /** - * @var bool - */ protected bool $timezone = false; - /** - * @var array - */ protected array $properties = []; - /** - * @var string|null - */ protected ?string $collation = null; - /** - * @var array|null - */ protected ?array $values = null; - /** - * @var string|null - */ protected ?string $algorithm = null; - /** - * @var string|null - */ protected ?string $lock = null; - /** - * @var bool|null - */ protected ?bool $fixed = null; /** @@ -142,7 +135,6 @@ class Column extends DatabaseColumn * @param int|null $srid The SRID for spatial columns. * @param string|null $encoding The character set encoding for the column. * @param string|null $baseType The base type for the column. - * @return void */ public function __construct( protected string $name = '', @@ -552,14 +544,9 @@ public function getUnsigned(): bool if ($this->identity && Configure::read('Migrations.unsigned_primary_keys')) { return true; } - // Check general integer configuration - if (Configure::read('Migrations.unsigned_ints')) { - return true; - } - // Default to signed for backward compatibility - return false; + return (bool)Configure::read('Migrations.unsigned_ints'); } /** diff --git a/src/Db/Table/ForeignKey.php b/src/Db/Table/ForeignKey.php index 3e4a4d394..f15e34472 100644 --- a/src/Db/Table/ForeignKey.php +++ b/src/Db/Table/ForeignKey.php @@ -23,11 +23,17 @@ class ForeignKey extends DatabaseForeignKey { public const CASCADE = 'CASCADE'; + public const RESTRICT = 'RESTRICT'; + public const SET_NULL = 'SET NULL'; + public const NO_ACTION = 'NO ACTION'; + public const DEFERRED = 'DEFERRABLE INITIALLY DEFERRED'; + public const IMMEDIATE = 'DEFERRABLE INITIALLY IMMEDIATE'; + public const NOT_DEFERRED = 'NOT DEFERRABLE'; /** diff --git a/src/Db/Table/Partition.php b/src/Db/Table/Partition.php index 12f8fe2a6..dffd7410a 100644 --- a/src/Db/Table/Partition.php +++ b/src/Db/Table/Partition.php @@ -18,10 +18,17 @@ class Partition { public const TYPE_RANGE = 'RANGE'; - public const TYPE_RANGE_COLUMNS = 'RANGE COLUMNS'; // MySQL: for DATE/STRING columns + + public const TYPE_RANGE_COLUMNS = 'RANGE COLUMNS'; + + // MySQL: for DATE/STRING columns public const TYPE_LIST = 'LIST'; - public const TYPE_LIST_COLUMNS = 'LIST COLUMNS'; // MySQL: for STRING columns + + public const TYPE_LIST_COLUMNS = 'LIST COLUMNS'; + + // MySQL: for STRING columns public const TYPE_HASH = 'HASH'; + public const TYPE_KEY = 'KEY'; // MySQL only /** diff --git a/src/Db/Table/TableMetadata.php b/src/Db/Table/TableMetadata.php index 09edd8500..3fc5b4a45 100644 --- a/src/Db/Table/TableMetadata.php +++ b/src/Db/Table/TableMetadata.php @@ -15,9 +15,6 @@ */ class TableMetadata { - /** - * @var string - */ protected string $name; /** @@ -25,9 +22,6 @@ class TableMetadata */ protected array $options; - /** - * @var \Migrations\Db\Table\Partition|null - */ protected ?Partition $partition = null; /** diff --git a/src/Middleware/PendingMigrationsMiddleware.php b/src/Middleware/PendingMigrationsMiddleware.php index 9c140a719..8c2ba5427 100644 --- a/src/Middleware/PendingMigrationsMiddleware.php +++ b/src/Middleware/PendingMigrationsMiddleware.php @@ -122,7 +122,6 @@ protected function checkAppMigrations(): bool } /** - * @param string $plugin * @return bool */ protected function checkPluginMigrations(string $plugin): bool @@ -158,7 +157,6 @@ protected function checkPluginMigrations(string $plugin): bool } /** - * @param \Psr\Http\Message\ServerRequestInterface $request * @return bool */ protected function isSkipped(ServerRequestInterface $request): bool diff --git a/src/Migration/BuiltinBackend.php b/src/Migration/BuiltinBackend.php index ab1118a31..9de414418 100644 --- a/src/Migration/BuiltinBackend.php +++ b/src/Migration/BuiltinBackend.php @@ -31,8 +31,6 @@ class BuiltinBackend implements BackendInterface { /** * Manager instance - * - * @var \Migrations\Migration\Manager|null */ protected ?Manager $manager = null; @@ -47,8 +45,6 @@ class BuiltinBackend implements BackendInterface * Current command being run. * Useful if some logic needs to be applied in the ConfigurationTrait depending * on the command - * - * @var string */ protected string $command; diff --git a/src/Migration/Environment.php b/src/Migration/Environment.php index b6861cae6..2dd7de09d 100644 --- a/src/Migration/Environment.php +++ b/src/Migration/Environment.php @@ -18,9 +18,6 @@ class Environment { - /** - * @var string - */ protected string $name; /** @@ -28,24 +25,12 @@ class Environment */ protected array $options; - /** - * @var \Cake\Console\ConsoleIo|null - */ protected ?ConsoleIo $io = null; - /** - * @var int - */ protected int $currentVersion; - /** - * @var string - */ protected string $schemaTableName = 'phinxlog'; - /** - * @var \Migrations\Db\Adapter\AdapterInterface - */ protected AdapterInterface $adapter; /** @@ -323,7 +308,7 @@ public function getAdapter(): AdapterInterface // Get the driver classname as those are aligned with adapter names. $driver = $connection->getDriver(); - $driverClass = get_class($driver); + $driverClass = $driver::class; $driverName = strtolower(substr($driverClass, (int)strrpos($driverClass, '\\') + 1)); $options['adapter'] = $driverName; @@ -340,7 +325,7 @@ public function getAdapter(): AdapterInterface } $io = $this->getIo(); - if ($io) { + if ($io instanceof ConsoleIo) { $adapter->setIo($io); } $this->setAdapter($adapter); diff --git a/src/Migration/Manager.php b/src/Migration/Manager.php index 6baad31e8..8b77bfc4c 100644 --- a/src/Migration/Manager.php +++ b/src/Migration/Manager.php @@ -24,23 +24,16 @@ class Manager { public const BREAKPOINT_TOGGLE = 1; + public const BREAKPOINT_SET = 2; + public const BREAKPOINT_UNSET = 3; - /** - * @var \Migrations\Config\ConfigInterface - */ protected ConfigInterface $config; - /** - * @var \Cake\Console\ConsoleIo - */ protected ConsoleIo $io; - /** - * @var \Migrations\Migration\Environment|null - */ - protected ?Environment $environment; + protected ?Environment $environment = null; /** * @var \Migrations\MigrationInterface[]|null @@ -52,9 +45,6 @@ class Manager */ protected ?array $seeds = null; - /** - * @var \Psr\Container\ContainerInterface - */ protected ContainerInterface $container; /** @@ -225,7 +215,7 @@ public function isSeedExecuted(SeedInterface $seed): bool $seedLog = $adapter->getSeedLog(); $plugin = null; - $className = get_class($seed); + $className = $seed::class; if (str_contains($className, '\\')) { $parts = explode('\\', $className); @@ -306,7 +296,7 @@ public function markMigrated(int $version, string $path): bool } // Check if the file returns an anonymous class instance - if (is_object($migrationInstance) && $migrationInstance instanceof MigrationInterface) { + if ($migrationInstance instanceof MigrationInterface) { $migration = $migrationInstance; $migration->setVersion($version); } elseif (class_exists($className)) { @@ -336,15 +326,14 @@ public function markMigrated(int $version, string $path): bool */ protected function getMigrationClassName(string $path): string { - $class = (string)preg_replace('/^[0-9]+_/', '', basename($path)); + $class = (string)preg_replace('/^\d+_/', '', basename($path)); $class = str_replace('_', ' ', $class); $class = ucwords($class); $class = str_replace(' ', '', $class); - if (strpos($class, '.') !== false) { - $class = substr($class, 0, strpos($class, '.')); + if (str_contains($class, '.')) { + return substr($class, 0, strpos($class, '.')); } - /** @var class-string<\Migrations\MigrationInterface> */ return $class; } @@ -376,17 +365,17 @@ public function getVersionsToMark(Arguments $args): array if ($args->getOption('only') || $versionArg) { if (!in_array($version, $versions)) { - throw new InvalidArgumentException("Migration `$version` was not found !"); + throw new InvalidArgumentException(sprintf('Migration `%d` was not found !', $version)); } return [$version]; } $lengthIncrease = $args->getOption('exclude') ? 0 : 1; - $index = array_search($version, $versions); + $index = array_search($version, $versions, true); if ($index === false) { - throw new InvalidArgumentException("Migration `$version` was not found !"); + throw new InvalidArgumentException(sprintf('Migration `%d` was not found !', $version)); } return array_slice($versions, 0, $index + $lengthIncrease); @@ -460,15 +449,13 @@ public function migrate(?int $version = null, bool $fake = false, ?int $count = if ($version === null) { $version = max(array_merge($versions, array_keys($migrations))); - } else { - if ($version !== 0 && !isset($migrations[$version])) { - $this->getIo()->out(sprintf( - 'warning %s is not a valid version', - $version, - )); + } elseif ($version !== 0 && !isset($migrations[$version])) { + $this->getIo()->out(sprintf( + 'warning %s is not a valid version', + $version, + )); - return; - } + return; } // are we migrating up or down? @@ -583,14 +570,12 @@ public function executeSeed(SeedInterface $seed, bool $force = false, bool $fake // Auto-execute missing dependencies $missingDeps = $this->getSeedDependenciesNotExecuted($seed); - if (!empty($missingDeps)) { - foreach ($missingDeps as $depSeed) { - $this->getIo()->verbose(sprintf( - ' Auto-executing dependency: %s', - $depSeed->getName(), - )); - $this->executeSeed($depSeed, $force, $fake); - } + foreach ($missingDeps as $depSeed) { + $this->getIo()->verbose(sprintf( + ' Auto-executing dependency: %s', + $depSeed->getName(), + )); + $this->executeSeed($depSeed, $force, $fake); } $this->printSeedStatus($seed, 'seeding'); @@ -733,7 +718,7 @@ public function rollback(int|string|null $target = null, bool $force = false, bo $target = 0; } elseif (!is_numeric($target) && $target !== null) { // try to find a target version based on name // search through the migrations using the name - $migrationNames = array_map(function ($item) { + $migrationNames = array_map(function (array $item) { return $item['migration_name']; }, $executedVersions); $found = array_search($target, $migrationNames, true); @@ -742,7 +727,7 @@ public function rollback(int|string|null $target = null, bool $force = false, bo if ($found !== false) { $target = (string)$found; } else { - $io->out("No migration found with name ($target)"); + $io->out(sprintf('No migration found with name (%s)', $target)); return; } @@ -765,7 +750,7 @@ public function rollback(int|string|null $target = null, bool $force = false, bo // If the target must match a version, check the target version exists if ($targetMustMatchVersion && $target !== 0 && !isset($migrations[$target])) { - $io->out("Target version ($target) not found"); + $io->out(sprintf('Target version (%s) not found', $target)); return; } @@ -781,13 +766,8 @@ public function rollback(int|string|null $target = null, bool $force = false, bo if (in_array($migration->getVersion(), $executedVersionCreationTimes)) { $executedArray = $executedVersions[$migration->getVersion()]; - if (!$targetMustMatchVersion) { - if ( - ($this->getConfig()->isVersionOrderCreationTime() && $executedArray['version'] <= $target) || - (!$this->getConfig()->isVersionOrderCreationTime() && $executedArray['start_time'] <= $target) - ) { - break; - } + if (!$targetMustMatchVersion && ($this->getConfig()->isVersionOrderCreationTime() && $executedArray['version'] <= $target || !$this->getConfig()->isVersionOrderCreationTime() && $executedArray['start_time'] <= $target)) { + break; } if ((int)$executedArray['breakpoint'] !== 0 && !$force) { @@ -843,7 +823,7 @@ public function seed(?string $seed = null, bool $force = false, bool $fake = fal */ public function getEnvironment(): Environment { - if (isset($this->environment)) { + if ($this->environment instanceof Environment) { return $this->environment; } @@ -885,7 +865,6 @@ public function getIo(): ConsoleIo /** * Replace the environment * - * @param \Migrations\Migration\Environment $environment * @return $this */ public function setEnvironment(Environment $environment) @@ -937,8 +916,8 @@ public function getMigrations(): array $io->verbose('Migration file'); $io->verbose( array_map( - function ($phpFile) { - return " {$phpFile}"; + function (string $phpFile): string { + return sprintf(' %s', $phpFile); }, $phpFiles, ), @@ -952,7 +931,7 @@ function ($phpFile) { $io = $this->getIo(); foreach ($phpFiles as $filePath) { if (Util::isValidMigrationFileName(basename($filePath))) { - $io->verbose("Valid migration file {$filePath}."); + $io->verbose(sprintf('Valid migration file %s.', $filePath)); $version = Util::getVersionFromFileName(basename($filePath)); @@ -973,7 +952,7 @@ function ($phpFile) { $fileNames[$class] = basename($filePath); - $io->verbose("Loading class $class from $filePath."); + $io->verbose(sprintf('Loading class %s from %s.', $class, $filePath)); $this->checkMigrationClass($filePath); @@ -992,13 +971,13 @@ function ($phpFile) { ini_set('display_errors', $orig_display_errors_setting); // Check if the file returns an anonymous class instance - if (is_object($migrationInstance) && $migrationInstance instanceof MigrationInterface) { - $io->verbose("Using anonymous class from $filePath."); + if ($migrationInstance instanceof MigrationInterface) { + $io->verbose(sprintf('Using anonymous class from %s.', $filePath)); $migration = $migrationInstance; $migration->setVersion($version); } elseif (class_exists($class)) { // Fall back to traditional class-based migration - $io->verbose("Constructing $class."); + $io->verbose(sprintf('Constructing %s.', $class)); $migration = new $class($version); } else { throw new InvalidArgumentException(sprintf( @@ -1015,7 +994,7 @@ function ($phpFile) { $versions[$version] = $migration; } else { - $io->verbose("Invalid migration file {$filePath}."); + $io->verbose(sprintf('Invalid migration file %s.', $filePath)); } } @@ -1205,19 +1184,15 @@ public function getSeeds(): array } // Check if the file returns an anonymous class instance - if (is_object($seedInstance) && $seedInstance instanceof SeedInterface) { - $io->verbose("Using anonymous class from $filePath."); + if ($seedInstance instanceof SeedInterface) { + $io->verbose(sprintf('Using anonymous class from %s.', $filePath)); $seed = $seedInstance; } elseif (class_exists($class)) { // Fall back to traditional class-based seed - $io->verbose("Instantiating $class."); + $io->verbose(sprintf('Instantiating %s.', $class)); // instantiate it /** @var \Migrations\SeedInterface $seed */ - if (isset($this->container)) { - $seed = $this->container->get($class); - } else { - $seed = new $class(); - } + $seed = isset($this->container) ? $this->container->get($class) : new $class(); } else { throw new InvalidArgumentException(sprintf( 'Could not find class `%s` in file `%s` and file did not return a seed instance', @@ -1432,7 +1407,7 @@ public function cleanupMissingMigrations(): int // Find missing migrations (those in migration table but not in filesystem) $missingVersions = []; - foreach ($versions as $versionId => $versionInfo) { + foreach (array_keys($versions) as $versionId) { if (!isset($defaultMigrations[$versionId])) { $missingVersions[] = $versionId; } diff --git a/src/Migration/ManagerFactory.php b/src/Migration/ManagerFactory.php index 362a06305..d4636f6c7 100644 --- a/src/Migration/ManagerFactory.php +++ b/src/Migration/ManagerFactory.php @@ -99,10 +99,10 @@ public function createConfig(): ConfigInterface $connectionConfig = ConnectionManager::getConfig($connectionName); } if (!$connectionConfig) { - throw new RuntimeException("Could not find connection `{$connectionName}`"); + throw new RuntimeException(sprintf('Could not find connection `%s`', $connectionName)); } if (!isset($connectionConfig['database'])) { - throw new RuntimeException("The `{$connectionName}` connection has no `database` key defined."); + throw new RuntimeException(sprintf('The `%s` connection has no `database` key defined.', $connectionName)); } $adapter = $connectionConfig['scheme'] ?? null; diff --git a/src/Migrations.php b/src/Migrations.php index b61bf07cf..3555f5f42 100644 --- a/src/Migrations.php +++ b/src/Migrations.php @@ -33,8 +33,6 @@ class Migrations * Current command being run. * Useful if some logic needs to be applied in the ConfigurationTrait depending * on the command - * - * @var string */ protected string $command = ''; diff --git a/src/TestSuite/Migrator.php b/src/TestSuite/Migrator.php index a0c30160b..c3c3991aa 100644 --- a/src/TestSuite/Migrator.php +++ b/src/TestSuite/Migrator.php @@ -23,9 +23,6 @@ class Migrator { - /** - * @var \Cake\TestSuite\ConnectionHelper - */ protected ConnectionHelper $helper; /** @@ -115,7 +112,7 @@ public function runMany( try { if (!$migrations->migrate($migrationSet)) { throw new RuntimeException( - "Unable to migrate fixtures for `{$migrationSet['connection']}`.", + sprintf('Unable to migrate fixtures for `%s`.', $migrationSet['connection']), ); } } catch (Exception $e) { @@ -124,7 +121,7 @@ public function runMany( "Migrations failed to apply with message:\n\n" . $e->getMessage() . "\n\n" . 'If you are using the `skip` option and running multiple sets of migrations ' . - 'on the same connection, you can\'t skip tables managed by CakePHP in the connection.', + "on the same connection, you can't skip tables managed by CakePHP in the connection.", 0, $e, ); @@ -170,7 +167,7 @@ public function truncate(string $connection, array $skip = []): void */ protected function shouldDropTables(Migrations $migrations, array $options): bool { - Log::write('debug', "Reading migrations status for {$options['connection']}..."); + Log::write('debug', sprintf('Reading migrations status for %s...', $options['connection'])); $messages = [ 'down' => [], @@ -179,24 +176,24 @@ protected function shouldDropTables(Migrations $migrations, array $options): boo foreach ($migrations->status($options) as $migration) { if ($migration['status'] === 'up' && ($migration['missing'] ?? false)) { $messages['missing'][] = 'Applied but, missing Migration ' . - "source={$migration['name']} id={$migration['id']}"; + sprintf('source=%s id=%s', $migration['name'], $migration['id']); } if ($migration['status'] === 'down') { - $messages['down'][] = "Migration to reverse. source={$migration['name']} id={$migration['id']}"; + $messages['down'][] = sprintf('Migration to reverse. source=%s id=%s', $migration['name'], $migration['id']); } } $output = []; $hasProblems = false; - $itemize = function ($item) { + $itemize = function (string $item): string { return '- ' . $item; }; - if (!empty($messages['down'])) { + if ($messages['down'] !== []) { $hasProblems = true; $output[] = 'Migrations needing to be reversed:'; $output = array_merge($output, array_map($itemize, $messages['down'])); $output[] = ''; } - if (!empty($messages['missing'])) { + if ($messages['missing'] !== []) { $hasProblems = true; $output[] = 'Applied but missing migrations:'; $output = array_merge($output, array_map($itemize, $messages['missing'])); @@ -225,11 +222,11 @@ protected function shouldDropTables(Migrations $migrations, array $options): boo protected function dropTables(string $connection, array $skip = []): void { $dropTables = $this->getNonPhinxTables($connection, $skip); - if (count($dropTables)) { + if ($dropTables !== []) { $this->helper->dropTables($connection, $dropTables); } $phinxTables = $this->getPhinxTables($connection); - if (count($phinxTables)) { + if ($phinxTables !== []) { $this->helper->truncateTables($connection, $phinxTables); } } @@ -246,8 +243,8 @@ protected function getPhinxTables(string $connection): array assert($connection instanceof Connection); $tables = $connection->getSchemaCollection()->listTables(); - return array_filter($tables, function ($table) { - return strpos($table, 'phinxlog') !== false; + return array_filter($tables, function (string $table): bool { + return str_contains($table, 'phinxlog'); }); } @@ -266,9 +263,9 @@ protected function getNonPhinxTables(string $connection, array $skip): array $skip[] = '*phinxlog*'; $skip[] = 'cake_migrations'; - return array_filter($tables, function ($table) use ($skip) { + return array_filter($tables, function (string $table) use ($skip): bool { foreach ($skip as $pattern) { - if (fnmatch($pattern, $table) === true) { + if (fnmatch($pattern, $table)) { return false; } } diff --git a/src/Util/ColumnParser.php b/src/Util/ColumnParser.php index 97b9efdc0..c7ca1423b 100644 --- a/src/Util/ColumnParser.php +++ b/src/Util/ColumnParser.php @@ -16,8 +16,6 @@ class ColumnParser { /** * Regex used to parse the column definition passed through the shell - * - * @var string */ protected string $regexpParseColumn = '/ ^ @@ -36,8 +34,6 @@ class ColumnParser /** * Regex used to parse the field type and length - * - * @var string */ protected string $regexpParseField = '/(\w+\??)\[([0-9,]+)\]/'; @@ -74,7 +70,7 @@ public function parseFields(array $arguments): array $type = str_contains($type, '?') ? 'integer?' : 'integer'; } - $nullable = str_contains($type, '?'); + $nullable = str_contains((string)$type, '?'); $type = $nullable ? str_replace('?', '', $type) : $type; [$type, $length] = $this->getTypeAndLength($field, $type); @@ -94,7 +90,7 @@ public function parseFields(array $arguments): array } } - if ($isPrimaryKey === true && $type === 'integer') { + if ($isPrimaryKey && $type === 'integer') { $fields[$field]['options']['autoIncrement'] = true; } } @@ -120,15 +116,16 @@ public function parseIndexes(array $arguments): array $indexName = Hash::get($matches, 5); // Skip references - they create foreign keys, not indexes - if ($type && str_starts_with($type, 'references')) { + if ($type && str_starts_with((string)$type, 'references')) { continue; } - - if ( - in_array($type, ['primary', 'primary_key'], true) || - in_array($indexType, ['primary', 'primary_key'], true) || - $indexType === null - ) { + if (in_array($type, ['primary', 'primary_key'], true)) { + continue; + } + if (in_array($indexType, ['primary', 'primary_key'], true)) { + continue; + } + if ($indexType === null) { continue; } @@ -202,7 +199,7 @@ public function parseForeignKeys(array $arguments): array $indexName = Hash::get($matches, 5); // Check if type is 'references' or 'references?' - $isReference = str_starts_with($type, 'references'); + $isReference = str_starts_with((string)$type, 'references'); if (!$isReference) { continue; } @@ -242,7 +239,7 @@ public function validArguments(array $arguments): array { $collection = new Collection($arguments); - return $collection->filter(function ($value, $field) { + return $collection->filter(function ($value, $field): int|false { return preg_match($this->regexpParseColumn, (string)$field); })->toArray(); } @@ -259,11 +256,7 @@ public function getTypeAndLength(string $field, ?string $type): array { if ($type && preg_match($this->regexpParseField, $type, $matches)) { $length = $matches[2]; - if (str_contains($length, ',')) { - $length = array_map('intval', explode(',', $length)); - } else { - $length = (int)$length; - } + $length = str_contains($length, ',') ? array_map(intval(...), explode(',', $length)) : (int)$length; return [$matches[1], $length]; } @@ -287,9 +280,9 @@ public function getType(string $field, ?string $type): ?string $reflector = new ReflectionClass(AdapterInterface::class); $collection = new Collection($reflector->getConstants()); - $validTypes = $collection->filter(function ($value, $constant) { - return substr($constant, 0, strlen('TYPE_')) === 'TYPE_' || - substr($constant, 0, strlen('PHINX_TYPE_')) === 'PHINX_TYPE_'; + $validTypes = $collection->filter(function ($value, $constant): bool { + return str_starts_with($constant, 'TYPE_') || + str_starts_with($constant, 'PHINX_TYPE_'); })->toArray(); $fieldType = $type; if ($type === null || !in_array($type, $validTypes, true)) { @@ -297,7 +290,7 @@ public function getType(string $field, ?string $type): ?string $fieldType = 'integer'; } elseif ($field === 'id') { $fieldType = 'integer'; - } elseif (in_array($field, ['created', 'modified', 'updated'], true) || substr($field, -3) === '_at') { + } elseif (in_array($field, ['created', 'modified', 'updated'], true) || str_ends_with($field, '_at')) { $fieldType = 'datetime'; } elseif (in_array($field, ['latitude', 'longitude', 'lat', 'lng'], true)) { $fieldType = 'decimal'; @@ -402,12 +395,12 @@ public function parseDefaultValue(?string $value, string $columnType): string|in } // Handle integers - if (preg_match('/^-?[0-9]+$/', $value)) { + if (preg_match('/^-?\d+$/', $value)) { return (int)$value; } // Handle floats - if (preg_match('/^-?[0-9]+\.[0-9]+$/', $value)) { + if (preg_match('/^-?\d+\.\d+$/', $value)) { return (float)$value; } diff --git a/src/Util/TableFinder.php b/src/Util/TableFinder.php index a96b4e03b..5aeeb1f7f 100644 --- a/src/Util/TableFinder.php +++ b/src/Util/TableFinder.php @@ -34,8 +34,6 @@ class TableFinder /** * Regex of Table name to skip - * - * @var string */ public string $skipTablesRegex = '_phinxlog'; @@ -94,7 +92,7 @@ public function getTablesToBake(CollectionInterface $collection, array $options $tables = $tableNamesInPlugin; } else { foreach ($tables as $num => $table) { - if (in_array($table, $this->skipTables, true) || (strpos($table, $this->skipTablesRegex) !== false)) { + if (in_array($table, $this->skipTables, true) || (str_contains($table, $this->skipTablesRegex))) { unset($tables[$num]); continue; } @@ -138,17 +136,13 @@ public function getTableNames(?string $pluginName = null): array public function findTables(?string $pluginName = null): array { $path = 'Model' . DS . 'Table' . DS; - if ($pluginName) { - $path = CorePlugin::path($pluginName) . 'src' . DS . $path; - } else { - $path = APP . $path; - } + $path = $pluginName ? CorePlugin::path($pluginName) . 'src' . DS . $path : APP . $path; if (!is_dir($path)) { return []; } - return array_map('basename', glob($path . '*.php') ?: []); + return array_map(basename(...), glob($path . '*.php') ?: []); } /** diff --git a/src/Util/Util.php b/src/Util/Util.php index e8138cd09..25bf5e736 100644 --- a/src/Util/Util.php +++ b/src/Util/Util.php @@ -37,7 +37,7 @@ class Util * @var string * @phpstan-var non-empty-string */ - protected const MIGRATION_FILE_NAME_NO_NAME_PATTERN = '/^[0-9]{14}\.php$/'; + protected const MIGRATION_FILE_NAME_NO_NAME_PATTERN = '/^\d{14}\.php$/'; /** * Enhanced migration file name pattern with readable timestamp and CamelCase @@ -115,7 +115,7 @@ public static function getVersionFromFileName(string $fileName): int } // Traditional format - preg_match('/^[0-9]+/', $baseName, $matches); + preg_match('/^\d+/', $baseName, $matches); $value = (int)($matches[0] ?? null); if (!$value) { throw new RuntimeException(sprintf('Cannot get a valid version from filename `%s`', $fileName)); @@ -134,13 +134,12 @@ public static function getVersionFromFileName(string $fileName): int */ public static function mapClassNameToFileName(string $className): string { - $snake = function ($matches) { - return '_' . strtolower($matches[0]); + $snake = function ($matches): string { + return '_' . strtolower((string)$matches[0]); }; $fileName = preg_replace_callback('/\d+|[A-Z]/', $snake, $className); - $fileName = static::getCurrentTimestamp() . "$fileName.php"; - return $fileName; + return static::getCurrentTimestamp() . $fileName . '.php'; } /** @@ -250,7 +249,7 @@ public static function glob(string $path): array */ public static function getFiles(string|array $paths): array { - $files = static::globAll(array_map(function ($path) { + $files = static::globAll(array_map(function (string $path): string { return $path . DIRECTORY_SEPARATOR . '*.php'; }, (array)$paths)); // glob() can return the same file multiple times @@ -263,7 +262,6 @@ public static function getFiles(string|array $paths): array } /** - * @param string|null $plugin * @return string */ public static function tableName(?string $plugin): string diff --git a/src/Util/UtilTrait.php b/src/Util/UtilTrait.php index fc3ab3b89..ad49afee5 100644 --- a/src/Util/UtilTrait.php +++ b/src/Util/UtilTrait.php @@ -53,7 +53,7 @@ protected function getPhinxTable(?string $plugin = null, ?Connection $connection } // Autodetect mode (config is null or not set) - if ($connection !== null && $this->detectLegacyTables($connection)) { + if ($connection instanceof Connection && $this->detectLegacyTables($connection)) { return $this->getLegacyTableName($plugin); } @@ -113,7 +113,7 @@ protected function isUsingLegacyTables(?Connection $connection = null): bool } // Autodetect - if ($connection !== null) { + if ($connection instanceof Connection) { return $this->detectLegacyTables($connection); } diff --git a/src/View/Helper/MigrationHelper.php b/src/View/Helper/MigrationHelper.php index 9aec4dae7..827fc8794 100644 --- a/src/View/Helper/MigrationHelper.php +++ b/src/View/Helper/MigrationHelper.php @@ -23,7 +23,6 @@ use Cake\Utility\Hash; use Cake\Utility\Inflector; use Cake\View\Helper; -use Cake\View\View; use Migrations\Db\Adapter\MysqlAdapter; use Migrations\Db\Table\ForeignKey; @@ -76,22 +75,6 @@ public function getReturnedData(): array return $this->returnedData; } - /** - * Constructor - * - * ### Settings - * - * - `collection` \Cake\Database\Schema\Collection - * - `connection` \Cake\Database\Connection - * - * @param \Cake\View\View $View The View this helper is being attached to. - * @param array $config Configuration settings for the helper. - */ - public function __construct(View $View, array $config = []) - { - parent::__construct($View, $config); - } - /** * Returns the method to be used for the Table::save() * @@ -206,10 +189,8 @@ public function indexes(TableSchemaInterface|string $table): array $tableIndexes = $tableSchema->indexes(); $indexes = []; - if ($tableIndexes) { - foreach ($tableIndexes as $name) { - $indexes[$name] = $tableSchema->getIndex($name); - } + foreach ($tableIndexes as $name) { + $indexes[$name] = $tableSchema->getIndex($name); } return $indexes; @@ -466,7 +447,7 @@ public function getColumnOption(array $options): array */ public function value(string|float|int|bool|null $value, bool $numbersAsString = false): string|float { - if ($value === null || $value === 'null' || $value === 'NULL') { + if (in_array($value, [null, 'null', 'NULL'], true)) { return 'null'; } @@ -607,7 +588,7 @@ public function stringifyList(array $list, array $options = [], array $wantedOpt $v = $this->value($v, $k === 'default'); } if (!is_numeric($k)) { - $v = "'$k' => $v"; + $v = sprintf("'%s' => %s", $k, $v); } } @@ -632,14 +613,14 @@ public function stringifyList(array $list, array $options = [], array $wantedOpt */ public function tableStatement(string $table, bool $reset = false): string { - if ($reset === true) { + if ($reset) { unset($this->tableStatementStatus[$table]); } if (!isset($this->tableStatementStatus[$table])) { $this->tableStatementStatus[$table] = true; - return '$this->table(\'' . addslashes($table) . '\')'; + return '$this->table(\'' . addslashes($table) . "')"; } return ''; @@ -734,7 +715,7 @@ public function getCreateTablesElementData(array $tables): array $data = $this->getCreateTableData($table); $tableConstraintsNoUnique = array_filter( $data['constraints'], - function ($constraint) { + function (array $constraint): bool { return $constraint['type'] !== 'unique'; }, ); diff --git a/tests/TestCase/Command/BakeMigrationCommandTest.php b/tests/TestCase/Command/BakeMigrationCommandTest.php index 5e525e50a..aa1fd0f63 100644 --- a/tests/TestCase/Command/BakeMigrationCommandTest.php +++ b/tests/TestCase/Command/BakeMigrationCommandTest.php @@ -33,14 +33,14 @@ class BakeMigrationCommandTest extends TestCase * * @return void */ - public function setUp(): void + protected function setUp(): void { parent::setUp(); $this->_compareBasePath = Plugin::path('Migrations') . 'tests' . DS . 'comparisons' . DS . 'Migration' . DS; } - public function tearDown(): void + protected function tearDown(): void { parent::tearDown(); $files = glob(ROOT . DS . 'config' . DS . 'Migrations' . DS . '*Users.php'); @@ -84,7 +84,7 @@ public function tearDown(): void * * @return void */ - public function testNoContents() + public function testNoContents(): void { $this->exec('bake migration NoContents --connection test'); @@ -101,7 +101,7 @@ public function testNoContents() * * @return array */ - public static function nameVariations() + public static function nameVariations(): array { return [ ['name', '.php'], @@ -118,9 +118,9 @@ public static function nameVariations() * @return void */ #[DataProvider('nameVariations')] - public function testCreate($name, $fileSuffix) + public function testCreate(string $name, string $fileSuffix): void { - $this->exec("bake migration CreateUsers {$name} --connection test"); + $this->exec(sprintf('bake migration CreateUsers %s --connection test', $name)); $file = glob(ROOT . DS . 'config' . DS . 'Migrations' . DS . '*_CreateUsers.php'); $filePath = current($file); @@ -133,7 +133,7 @@ public function testCreate($name, $fileSuffix) /** * Tests that baking a migration with the name as another will throw an exception. */ - public function testCreateDuplicateName() + public function testCreateDuplicateName(): void { $this->exec('bake migration CreateUsers --connection test'); $this->exec('bake migration CreateUsers --connection test'); @@ -144,7 +144,7 @@ public function testCreateDuplicateName() /** * Tests that baking a migration with the name as reserved keyword triggers prefixing. */ - public function testCreateWithReservedKeyword() + public function testCreateWithReservedKeyword(): void { $this->exec('bake migration New --connection test', ['Prefix']); @@ -152,7 +152,7 @@ public function testCreateWithReservedKeyword() $this->assertOutputRegExp('/Wrote.*?PrefixNew\.php/'); } - public function testCreateBuiltInAlias() + public function testCreateBuiltInAlias(): void { $this->exec('migrations create CreateUsers --connection test'); $this->assertExitCode(BaseCommand::CODE_SUCCESS); @@ -162,7 +162,7 @@ public function testCreateBuiltInAlias() /** * Tests that baking a migration with the "drop" string inside the name generates a valid drop migration. */ - public function testCreateDropMigration() + public function testCreateDropMigration(): void { $this->exec('bake migration DropUsers --connection test'); $this->assertOutputRegExp('/Wrote.*?DropUsers\.php/'); @@ -178,7 +178,7 @@ public function testCreateDropMigration() /** * Tests that baking a migration with the name as another with the parameter "force", will delete the existing file. */ - public function testCreateDuplicateNameWithForce() + public function testCreateDuplicateNameWithForce(): void { $this->exec('bake migration CreateUsers --connection test --force'); @@ -197,7 +197,7 @@ public function testCreateDuplicateNameWithForce() * * @return void */ - public function testAddPrimaryKeyToExistingTable() + public function testAddPrimaryKeyToExistingTable(): void { $this->exec('bake migration AddPkToUsers somefield:primary_key --connection test'); @@ -211,7 +211,7 @@ public function testAddPrimaryKeyToExistingTable() * * @return void */ - public function testAddPrimaryKeyToExistingUsersTable() + public function testAddPrimaryKeyToExistingUsersTable(): void { $this->exec('bake migration AlterUsers somefield:primary_key --connection test'); @@ -222,7 +222,7 @@ public function testAddPrimaryKeyToExistingUsersTable() /** * @return void */ - public function testDetectAction() + public function testDetectAction(): void { $command = new BakeMigrationCommand(); $this->assertEquals( @@ -382,7 +382,7 @@ public function testDetectAction() * * @return void */ - public function testActionWithoutValidPrefix() + public function testActionWithoutValidPrefix(): void { $this->exec('bake migration SleepUsers name:string --connection test'); @@ -395,7 +395,7 @@ public function testActionWithoutValidPrefix() * * @return void */ - public function testCreateAnonymousStyle() + public function testCreateAnonymousStyle(): void { $this->exec('bake migration CreateUsers name:string --style=anonymous --connection test'); @@ -403,7 +403,7 @@ public function testCreateAnonymousStyle() $this->assertCount(1, $files); $filePath = current($files); - $fileName = basename($filePath); + $fileName = basename((string)$filePath); // Check the file name format $this->assertMatchesRegularExpression('/^\d{4}_\d{2}_\d{2}_\d{6}_CreateUsers\.php$/', $fileName); @@ -422,7 +422,7 @@ public function testCreateAnonymousStyle() * * @return void */ - public function testCreateAnonymousStyleWithConfigure() + public function testCreateAnonymousStyleWithConfigure(): void { Configure::write('Migrations.style', 'anonymous'); @@ -432,7 +432,7 @@ public function testCreateAnonymousStyleWithConfigure() $this->assertCount(1, $files); $filePath = current($files); - $fileName = basename($filePath); + $fileName = basename((string)$filePath); // Check the file name format $this->assertMatchesRegularExpression('/^\d{4}_\d{2}_\d{2}_\d{6}_CreateUsers\.php$/', $fileName); @@ -451,7 +451,7 @@ public function testCreateAnonymousStyleWithConfigure() * * @return void */ - public function testCreateWithReferences() + public function testCreateWithReferences(): void { $this->exec('bake migration CreatePosts title:string user_id:references --connection test'); @@ -468,7 +468,7 @@ public function testCreateWithReferences() * * @return void */ - public function testCreateWithReferencesCustomTable() + public function testCreateWithReferencesCustomTable(): void { $this->exec('bake migration CreateArticles title:string author_id:references:authors --connection test'); @@ -485,7 +485,7 @@ public function testCreateWithReferencesCustomTable() * * @return void */ - public function testAddFieldWithReference() + public function testAddFieldWithReference(): void { $this->exec('bake migration AddCategoryIdToProducts category_id:references --connection test'); @@ -497,10 +497,10 @@ public function testAddFieldWithReference() $this->assertSameAsFile(__FUNCTION__ . '.php', $result); } - public function testBakeMigrationWithoutBake() + public function testBakeMigrationWithoutBake(): void { // Make sure to unload the Bake plugin - $this->createApp()->getEventManager()->on('Console.buildCommands', function ($event, $commands) { + $this->createApp()->getEventManager()->on('Console.buildCommands', function ($event, $commands): void { Plugin::getCollection()->remove('Bake'); }); diff --git a/tests/TestCase/Command/BakeMigrationDiffCommandTest.php b/tests/TestCase/Command/BakeMigrationDiffCommandTest.php index 963571e17..0309c92af 100644 --- a/tests/TestCase/Command/BakeMigrationDiffCommandTest.php +++ b/tests/TestCase/Command/BakeMigrationDiffCommandTest.php @@ -49,7 +49,7 @@ class BakeMigrationDiffCommandTest extends TestCase * * @return void */ - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -82,13 +82,13 @@ public function setUp(): void try { $connection = ConnectionManager::get('test_comparisons'); $connection->execute('DROP TABLE IF EXISTS test_decimal_types'); - } catch (Exception $e) { + } catch (Exception) { // Ignore errors if connection doesn't exist yet } } } - public function tearDown(): void + protected function tearDown(): void { parent::tearDown(); foreach ($this->generatedFiles as $file) { @@ -121,7 +121,7 @@ public function tearDown(): void $connection = ConnectionManager::get('test_comparisons'); $tables = ['articles', 'categories', 'comments', 'users', 'orphan_table', 'phinxlog', 'cake_migrations', 'tags', 'test_blog_phinxlog', 'test_decimal_types']; foreach ($tables as $table) { - $connection->execute("DROP TABLE IF EXISTS $table"); + $connection->execute('DROP TABLE IF EXISTS ' . $table); } Cache::clear('_cake_model_'); } @@ -132,7 +132,7 @@ public function tearDown(): void * * @return void */ - public function testHistoryNotInSync() + public function testHistoryNotInSync(): void { $expectedMessage = 'Your migrations history is not in sync with your migrations files. ' . 'Make sure all your migrations have been migrated before baking a diff.'; @@ -195,7 +195,7 @@ public function testCheckSyncWithPluginMigrationsMoreRecent(): void * * @return void */ - public function testEmptyHistoryNoMigrations() + public function testEmptyHistoryNoMigrations(): void { $this->exec('bake migration_diff EmptyHistoryNoMigrations -c test -p Blog'); @@ -215,7 +215,7 @@ public function testEmptyHistoryNoMigrations() * * @return void */ - public function testBakeMigrationDiffInCustomFolder() + public function testBakeMigrationDiffInCustomFolder(): void { $customFolderName = 'CustomMigrationsFolder'; $this->exec('bake migration_diff MigrationDiffForCustomFolder -c test -s ' . $customFolderName); @@ -237,7 +237,7 @@ public function testBakeMigrationDiffInCustomFolder() * * @return void */ - public function testBakeMigrationDiffGenerateOnly() + public function testBakeMigrationDiffGenerateOnly(): void { //$this->skipIf(!env('DB_URL_COMPARE')); @@ -276,7 +276,7 @@ public function testBakeMigrationDiffGenerateOnly() * * @return void */ - public function testBakingDiff() + public function testBakingDiff(): void { $this->skipIf(!env('DB_URL_COMPARE')); @@ -292,7 +292,7 @@ public function testBakingDiff() * * @return void */ - public function testBakingDiffSimple() + public function testBakingDiffSimple(): void { $this->skipIf(!env('DB_URL_COMPARE')); @@ -305,7 +305,7 @@ public function testBakingDiffSimple() * * @return void */ - public function testBakingDiffAddRemove() + public function testBakingDiffAddRemove(): void { $this->skipIf(!env('DB_URL_COMPARE')); @@ -462,11 +462,11 @@ protected function runDiffBakingTest(string $scenario): void $diffMigrationsPath = $diffConfigFolder . $prefix . Inflector::underscore($scenario) . '_' . $db . '.php'; $diffDumpPath = $diffConfigFolder . 'schema-dump-test_comparisons_' . $db . '.lock'; - $destinationConfigDir = ROOT . DS . 'config' . DS . "MigrationsDiff{$scenario}" . DS; + $destinationConfigDir = ROOT . DS . 'config' . DS . 'MigrationsDiff' . $scenario . DS; if (!is_dir($destinationConfigDir)) { mkdir($destinationConfigDir, 0777, true); } - $destination = $destinationConfigDir . "20160415220805_{$classPrefix}{$scenario}" . ucfirst($db) . '.php'; + $destination = $destinationConfigDir . sprintf('20160415220805_%s%s', $classPrefix, $scenario) . ucfirst($db) . '.php'; $destinationDumpPath = $destinationConfigDir . 'schema-dump-test_comparisons_' . $db . '.lock'; copy($diffMigrationsPath, $destination); @@ -475,7 +475,7 @@ protected function runDiffBakingTest(string $scenario): void $destinationDumpPath, ]; - $migrations = $this->getMigrations("MigrationsDiff$scenario"); + $migrations = $this->getMigrations('MigrationsDiff' . $scenario); $migrations->migrate(); copy($diffDumpPath, $destinationDumpPath); @@ -493,14 +493,14 @@ protected function runDiffBakingTest(string $scenario): void $this->_compareBasePath = Plugin::path('Migrations') . 'tests' . DS . 'comparisons' . DS . 'Diff' . DS . lcfirst($scenario) . DS; - $bakeName = $this->getBakeName("TheDiff{$scenario}"); - $targetFolder = "MigrationsDiff{$scenario}"; + $bakeName = $this->getBakeName('TheDiff' . $scenario); + $targetFolder = 'MigrationsDiff' . $scenario; $comparison = lcfirst($scenario); - $this->exec("custom bake migration_diff {$bakeName} -c test_comparisons --test-target-folder {$targetFolder} --comparison {$comparison}"); + $this->exec(sprintf('custom bake migration_diff %s -c test_comparisons --test-target-folder %s --comparison %s', $bakeName, $targetFolder, $comparison)); $this->generatedFiles[] = ROOT . DS . 'config' . DS . 'Migrations' . DS . 'schema-dump-test_comparisons.lock'; - $generatedMigration = $this->getGeneratedMigrationName($destinationConfigDir, "*TheDiff$scenario*"); + $generatedMigration = $this->getGeneratedMigrationName($destinationConfigDir, sprintf('*TheDiff%s*', $scenario)); $fileName = pathinfo($generatedMigration, PATHINFO_FILENAME); $this->assertOutputContains('Marking the migration ' . $fileName . ' as migrated...'); $this->assertOutputContains('Creating a dump of the new database state...'); @@ -525,7 +525,7 @@ protected function runDiffBakingTest(string $scenario): void ->into($schemaTable) ->values($values) ->execute(); - $this->getMigrations("MigrationsDiff{$scenario}")->rollback(['target' => 'all']); + $this->getMigrations('MigrationsDiff' . $scenario)->rollback(['target' => 'all']); } /** @@ -537,14 +537,17 @@ protected function getDbType(): string { $connection = ConnectionManager::get('test_comparisons'); $driver = $connection->getDriver(); - if ($driver instanceof Mysql) { return 'mysql'; - } elseif ($driver instanceof Postgres) { + } + if ($driver instanceof Postgres) { return 'pgsql'; - } elseif ($driver instanceof Sqlite) { + } + if ($driver instanceof Sqlite) { return 'sqlite'; - } elseif ($driver instanceof Sqlserver) { + } + + if ($driver instanceof Sqlserver) { return 'sqlserver'; } @@ -557,15 +560,14 @@ protected function getDbType(): string * @param string $name Name of the baked file, unaware of the DB environment * @return string Baked filename */ - public function getBakeName($name) + public function getBakeName(string $name): string { $db = getenv('DB'); if (!$db) { $db = $this->getDbType(); } - $name .= ucfirst($db); - return $name; + return $name . ucfirst($db); } /** @@ -575,15 +577,14 @@ public function getBakeName($name) * @param string $source Source folder where migrations are located * @return Migrations */ - protected function getMigrations($source = 'MigrationsDiff') + protected function getMigrations($source = 'MigrationsDiff'): Migrations { $params = [ 'connection' => 'test_comparisons', 'source' => $source, ]; - $migrations = new Migrations($params); - return $migrations; + return new Migrations($params); } /** @@ -608,7 +609,7 @@ public function assertSameAsFile(string $path, string $result): void * @param string $result Results generated by the test to be compared * @return void */ - public function assertCorrectSnapshot($bakeName, $result) + public function assertCorrectSnapshot($bakeName, string $result): void { $dbenv = getenv('DB'); if (!$dbenv) { @@ -629,10 +630,10 @@ public function assertCorrectSnapshot($bakeName, $result) * @param string $needle The filename pattern to find. * @return string */ - public function getGeneratedMigrationName($configDir, $needle) + public function getGeneratedMigrationName(string $configDir, string $needle): string { $files = glob($configDir . $needle); - $this->assertNotEmpty($files, "Could not find any files matching `{$needle}` in `{$configDir}`"); + $this->assertNotEmpty($files, sprintf('Could not find any files matching `%s` in `%s`', $needle, $configDir)); // Record the generated file so we can cleanup if the test fails. $this->generatedFiles[] = $files[0]; diff --git a/tests/TestCase/Command/BakeMigrationSnapshotCommandTest.php b/tests/TestCase/Command/BakeMigrationSnapshotCommandTest.php index d90980c7c..ac28573bb 100644 --- a/tests/TestCase/Command/BakeMigrationSnapshotCommandTest.php +++ b/tests/TestCase/Command/BakeMigrationSnapshotCommandTest.php @@ -52,7 +52,7 @@ class BakeMigrationSnapshotCommandTest extends TestCase * * @return void */ - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -68,7 +68,7 @@ public function setUp(): void * * @return void */ - public function tearDown(): void + protected function tearDown(): void { parent::tearDown(); ConnectionManager::drop('alternative'); @@ -85,7 +85,7 @@ public function tearDown(): void * * @return void */ - public function testNotEmptySnapshot() + public function testNotEmptySnapshot(): void { $this->runSnapshotTest('NotEmpty'); } @@ -95,10 +95,10 @@ public function testNotEmptySnapshot() * * @return void */ - public function testNotEmptySnapshotNoLock() + public function testNotEmptySnapshotNoLock(): void { $bakeName = $this->getBakeName('TestNotEmptySnapshot'); - $this->exec("bake migration_snapshot {$bakeName} -c test --no-lock"); + $this->exec(sprintf('bake migration_snapshot %s -c test --no-lock', $bakeName)); $generatedMigration = glob($this->migrationPath . '*_TestNotEmptySnapshot*.php'); $this->generatedFiles = $generatedMigration; @@ -115,14 +115,14 @@ public function testNotEmptySnapshotNoLock() * * @return void */ - public function testSnapshotGenerateOnly() + public function testSnapshotGenerateOnly(): void { if (file_exists($this->migrationPath . 'schema-dump-test.lock')) { unlink($this->migrationPath . 'schema-dump-test.lock'); } $bakeName = $this->getBakeName('TestGenerateOnlySnapshot'); - $this->exec("bake migration_snapshot {$bakeName} -c test --generate-only"); + $this->exec(sprintf('bake migration_snapshot %s -c test --generate-only', $bakeName)); $generatedMigration = glob($this->migrationPath . '*_TestGenerateOnlySnapshot*.php'); $this->generatedFiles = $generatedMigration; @@ -150,12 +150,12 @@ public function testSnapshotPostgresTimestampTzColumn(): void $scenario = 'PostgresTimestampTz'; - $bakeName = $this->getBakeName("TestSnapshot{$scenario}"); - $this->exec("bake migration_snapshot {$bakeName} -c test"); + $bakeName = $this->getBakeName('TestSnapshot' . $scenario); + $this->exec(sprintf('bake migration_snapshot %s -c test', $bakeName)); $connection->execute('DROP TABLE postgres_timestamp_tz'); - $generatedMigration = glob($this->migrationPath . "*_TestSnapshot{$scenario}*.php"); + $generatedMigration = glob($this->migrationPath . sprintf('*_TestSnapshot%s*.php', $scenario)); $this->generatedFiles = $generatedMigration; $this->generatedFiles[] = $this->migrationPath . 'schema-dump-test.lock'; @@ -172,7 +172,7 @@ public function testSnapshotPostgresTimestampTzColumn(): void * * @return void */ - public function testAutoIdDisabledSnapshot() + public function testAutoIdDisabledSnapshot(): void { $this->runSnapshotTest('AutoIdDisabled', '--disable-autoid'); } @@ -182,7 +182,7 @@ public function testAutoIdDisabledSnapshot() * * @return void */ - public function testSnapshotWithChange() + public function testSnapshotWithChange(): void { $this->runSnapshotTest('WithChange', '--change'); } @@ -247,7 +247,7 @@ public function testSnapshotDiffWithAutoIdIncompatibleUnsignedPrimaryKeys(): voi * * @return void */ - public function testPluginBlog() + public function testPluginBlog(): void { $this->loadPlugins(['TestBlog']); $this->migrationPath = ROOT . DS . 'Plugin' . DS . 'TestBlog' . DS . 'config' . DS . 'Migrations' . DS; @@ -263,13 +263,13 @@ public function testPluginBlog() * * @return void */ - public function testPluginWithCustomConnection() + public function testPluginWithCustomConnection(): void { $this->loadPlugins(['SimpleSnapshot']); $this->migrationPath = ROOT . DS . 'Plugin' . DS . 'SimpleSnapshot' . DS . 'config' . DS . 'Migrations' . DS; $bakeName = $this->getBakeName('TestSnapshotPluginCustomConnection'); - $this->exec("bake migration_snapshot {$bakeName} -c test -p SimpleSnapshot"); + $this->exec(sprintf('bake migration_snapshot %s -c test -p SimpleSnapshot', $bakeName)); $generatedMigration = glob($this->migrationPath . '*_TestSnapshotPluginCustomConnection*.php'); $this->generatedFiles = $generatedMigration; @@ -286,13 +286,13 @@ public function testPluginWithCustomConnection() protected function runSnapshotTest(string $scenario, string $arguments = ''): void { if ($arguments) { - $arguments = " $arguments"; + $arguments = ' ' . $arguments; } - $bakeName = $this->getBakeName("TestSnapshot{$scenario}"); - $this->exec("bake migration_snapshot {$bakeName} -c test{$arguments}"); + $bakeName = $this->getBakeName('TestSnapshot' . $scenario); + $this->exec(sprintf('bake migration_snapshot %s -c test%s', $bakeName, $arguments)); - $generatedMigration = glob($this->migrationPath . "*_TestSnapshot{$scenario}*.php"); + $generatedMigration = glob($this->migrationPath . sprintf('*_TestSnapshot%s*.php', $scenario)); $this->generatedFiles = $generatedMigration; $this->generatedFiles[] = $this->migrationPath . 'schema-dump-test.lock'; @@ -310,7 +310,7 @@ protected function runSnapshotTest(string $scenario, string $arguments = ''): vo * @param string $name Name of the baked file, unaware of the DB environment * @return string Baked filename */ - public function getBakeName($name) + public function getBakeName(string $name) { $dbenv = getenv('DB'); if ($dbenv !== 'mysql') { @@ -348,6 +348,7 @@ public function assertSameAsFile(string $path, string $result): void // Normalize utf8mb3 to utf8 for MySQL 8.0.30+ compatibility $expected = str_replace('utf8mb3_', 'utf8_', $expected); + $result = str_replace('utf8mb3_', 'utf8_', $result); // Normalize unified table name to legacy for comparison @@ -363,7 +364,7 @@ public function assertSameAsFile(string $path, string $result): void * @param string $result Results generated by the test to be compared * @return void */ - public function assertCorrectSnapshot($bakeName, $result) + public function assertCorrectSnapshot($bakeName, string $result): void { $dbenv = getenv('DB'); $bakeName = Inflector::underscore($bakeName); diff --git a/tests/TestCase/Command/BakeSeedCommandTest.php b/tests/TestCase/Command/BakeSeedCommandTest.php index a44d2c514..f28285ee6 100644 --- a/tests/TestCase/Command/BakeSeedCommandTest.php +++ b/tests/TestCase/Command/BakeSeedCommandTest.php @@ -46,7 +46,7 @@ class BakeSeedCommandTest extends TestCase * * @return void */ - public function setUp(): void + protected function setUp(): void { parent::setUp(); $this->_compareBasePath = Plugin::path('Migrations') . 'tests' . DS . 'comparisons' . DS . 'Seeds' . DS; @@ -57,7 +57,7 @@ public function setUp(): void * * @return void */ - public function testBasicBaking() + public function testBasicBaking(): void { $this->generatedFile = ROOT . DS . 'config/Seeds/ArticlesSeed.php'; $this->exec('bake seed Articles --connection test'); @@ -72,7 +72,7 @@ public function testBasicBaking() * * @return void */ - public function testBakeWithApplicationTemplate() + public function testBakeWithApplicationTemplate(): void { copy( ROOT . '/App/Template/plugin/Migrations/bake/Seed/custom-seed.twig', @@ -93,13 +93,13 @@ public function testBakeWithApplicationTemplate() * * @return void */ - public function testWithData() + public function testWithData(): void { $this->generatedFile = ROOT . DS . 'config/Seeds/EventsSeed.php'; $this->exec('bake seed Events --connection test --data'); $path = __FUNCTION__ . '.php'; - if (in_array(getenv('DB'), ['pgsql', 'sqlserver'])) { + if (in_array(getenv('DB'), ['pgsql', 'sqlserver'], true)) { $path = getenv('DB') . DS . $path; } elseif (PHP_VERSION_ID >= 80100) { $path = 'php81' . DS . $path; @@ -115,7 +115,7 @@ public function testWithData() * * @return void */ - public function testWithDataAndFields() + public function testWithDataAndFields(): void { $this->generatedFile = ROOT . DS . 'config/Seeds/EventsSeed.php'; $this->exec('bake seed Events --connection test --data --fields title,description'); @@ -130,13 +130,13 @@ public function testWithDataAndFields() * * @return void */ - public function testWithDataAndLimit() + public function testWithDataAndLimit(): void { $this->generatedFile = ROOT . DS . 'config/Seeds/EventsSeed.php'; $this->exec('bake seed Events --connection test --data --limit 2'); $path = __FUNCTION__ . '.php'; - if (in_array(getenv('DB'), ['pgsql', 'sqlserver'])) { + if (in_array(getenv('DB'), ['pgsql', 'sqlserver'], true)) { $path = getenv('DB') . DS . $path; } elseif (PHP_VERSION_ID >= 80100) { $path = 'php81' . DS . $path; @@ -152,7 +152,7 @@ public function testWithDataAndLimit() * * @return void */ - public function testPrettifyArray() + public function testPrettifyArray(): void { $this->generatedFile = ROOT . DS . 'config/Seeds/TextsSeed.php'; $this->exec('bake seed Texts --connection test --data'); @@ -167,7 +167,7 @@ public function testPrettifyArray() * * @return void */ - public function testAnonymousStyleWithConfigure() + public function testAnonymousStyleWithConfigure(): void { Configure::write('Migrations.style', 'anonymous'); diff --git a/tests/TestCase/Command/CompletionTest.php b/tests/TestCase/Command/CompletionTest.php index b05f0a4da..94cf1f9cd 100644 --- a/tests/TestCase/Command/CompletionTest.php +++ b/tests/TestCase/Command/CompletionTest.php @@ -24,12 +24,14 @@ class CompletionTest extends TestCase { use ConsoleIntegrationTestTrait; + public $Shell; + /** * tearDown * * @return void */ - public function tearDown(): void + protected function tearDown(): void { parent::tearDown(); unset($this->Shell); @@ -41,7 +43,7 @@ public function tearDown(): void * * @return void */ - public function testMigrationsSubcommands() + public function testMigrationsSubcommands(): void { $this->exec('completion subcommands migrations.migrations'); // Upgrade command is hidden when legacyTables is disabled @@ -64,7 +66,7 @@ public function testMigrationsSubcommands() * * @return void */ - public function testMigrationsOptionsMarkMigrated() + public function testMigrationsOptionsMarkMigrated(): void { $this->exec('completion options migrations.migrations mark_migrated'); $this->assertCount(1, $this->_out->messages()); @@ -85,7 +87,7 @@ public function testMigrationsOptionsMarkMigrated() * * @return void */ - public function testMigrationsOptionsMigrate() + public function testMigrationsOptionsMigrate(): void { $this->exec('completion options migrations.migrations migrate'); $this->assertCount(1, $this->_out->messages()); @@ -106,7 +108,7 @@ public function testMigrationsOptionsMigrate() * * @return void */ - public function testMigrationsOptionsRollback() + public function testMigrationsOptionsRollback(): void { $this->exec('completion options migrations.migrations rollback'); $this->assertCount(1, $this->_out->messages()); @@ -127,7 +129,7 @@ public function testMigrationsOptionsRollback() * * @return void */ - public function testMigrationsOptionsStatus() + public function testMigrationsOptionsStatus(): void { $this->exec('completion options migrations.migrations status'); $this->assertCount(1, $this->_out->messages()); diff --git a/tests/TestCase/Command/DumpCommandTest.php b/tests/TestCase/Command/DumpCommandTest.php index fe19b4072..a666415c6 100644 --- a/tests/TestCase/Command/DumpCommandTest.php +++ b/tests/TestCase/Command/DumpCommandTest.php @@ -14,10 +14,12 @@ class DumpCommandTest extends TestCase { protected Connection $connection; + protected string $_compareBasePath; + protected string $dumpFile; - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -32,7 +34,7 @@ public function setUp(): void $this->dumpFile = ROOT . DS . 'config/TestsMigrations/schema-dump-test.lock'; } - public function tearDown(): void + protected function tearDown(): void { parent::tearDown(); diff --git a/tests/TestCase/Command/EntryCommandTest.php b/tests/TestCase/Command/EntryCommandTest.php index 112a78454..d63aed559 100644 --- a/tests/TestCase/Command/EntryCommandTest.php +++ b/tests/TestCase/Command/EntryCommandTest.php @@ -26,7 +26,7 @@ class EntryCommandTest extends TestCase { use ConsoleIntegrationTestTrait; - public function setUp(): void + protected function setUp(): void { parent::setUp(); } @@ -36,7 +36,7 @@ public function setUp(): void * * @return void */ - public function testExecuteHelp() + public function testExecuteHelp(): void { $this->exec('migrations --help'); @@ -51,7 +51,7 @@ public function testExecuteHelp() * * @return void */ - public function testExecuteMissingCommand() + public function testExecuteMissingCommand(): void { $this->exec('migrations derp'); diff --git a/tests/TestCase/Command/MarkMigratedTest.php b/tests/TestCase/Command/MarkMigratedTest.php index 669f19327..a417a2908 100644 --- a/tests/TestCase/Command/MarkMigratedTest.php +++ b/tests/TestCase/Command/MarkMigratedTest.php @@ -34,7 +34,7 @@ class MarkMigratedTest extends TestCase * * @return void */ - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -51,7 +51,7 @@ public function setUp(): void * * @return void */ - public function tearDown(): void + protected function tearDown(): void { parent::tearDown(); $this->connection->execute('DROP TABLE IF EXISTS migrator_phinxlog'); @@ -65,7 +65,7 @@ public function tearDown(): void * * @return void */ - public function testExecute() + public function testExecute(): void { $this->exec('migrations mark_migrated --connection=test --source=TestsMigrations'); @@ -102,7 +102,7 @@ public function testExecute() $this->assertEquals(4, $result->fetchColumn(0)); } - public function testExecuteTarget() + public function testExecuteTarget(): void { $this->exec('migrations mark_migrated --connection=test --source=TestsMigrations --target=20150704160200'); $this->assertExitSuccess(); @@ -157,7 +157,7 @@ public function testTargetNotFound(): void ); } - public function testExecuteTargetWithExclude() + public function testExecuteTargetWithExclude(): void { $this->exec('migrations mark_migrated --connection=test --source=TestsMigrations --target=20150724233100 --exclude'); $this->assertExitSuccess(); @@ -206,7 +206,7 @@ public function testExecuteTargetWithExcludeNotFound(): void ); } - public function testExecuteTargetWithOnly() + public function testExecuteTargetWithOnly(): void { $this->exec('migrations mark_migrated --connection=test --source=TestsMigrations --target=20150724233100 --only'); $this->assertExitSuccess(); @@ -252,7 +252,7 @@ public function testExecuteTargetWithOnlyNotFound(): void ); } - public function testExecuteInvalidUseOfExclude() + public function testExecuteInvalidUseOfExclude(): void { $this->exec('migrations mark_migrated --connection=test --source=TestsMigrations --exclude'); @@ -287,7 +287,7 @@ public function testExecutePluginInvalid(): void try { $this->exec('migrations mark_migrated -c test --plugin NotThere'); $this->fail('Should raise an error or exit with an error'); - } catch (MissingPluginException $e) { + } catch (MissingPluginException) { $this->assertTrue(true); } /** @var \Cake\Database\Connection $connection */ diff --git a/tests/TestCase/Command/MigrateCommandTest.php b/tests/TestCase/Command/MigrateCommandTest.php index 8b063afc6..5b2dca1e8 100644 --- a/tests/TestCase/Command/MigrateCommandTest.php +++ b/tests/TestCase/Command/MigrateCommandTest.php @@ -13,7 +13,7 @@ class MigrateCommandTest extends TestCase { protected array $createdFiles = []; - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -21,7 +21,7 @@ public function setUp(): void $this->clearMigrationRecords('test', 'Migrator'); } - public function tearDown(): void + protected function tearDown(): void { parent::tearDown(); foreach ($this->createdFiles as $file) { @@ -30,7 +30,7 @@ public function tearDown(): void ConnectionManager::drop('invalid'); } - public function testHelp() + public function testHelp(): void { $this->exec('migrations migrate --help'); @@ -127,7 +127,7 @@ public function testMigrateWithSourceMigration(): void /** * Test dry-run */ - public function testMigrateDryRun() + public function testMigrateDryRun(): void { $migrationPath = ROOT . DS . 'config' . DS . 'Migrations'; $this->exec('migrations migrate -c test --dry-run'); @@ -146,7 +146,7 @@ public function testMigrateDryRun() /** * Test that migrations only run to a certain date */ - public function testMigrateDate() + public function testMigrateDate(): void { $migrationPath = ROOT . DS . 'config' . DS . 'Migrations'; $this->exec('migrations migrate -c test --date 2020-01-01'); @@ -162,7 +162,7 @@ public function testMigrateDate() /** * Test output for dates with no matching migrations */ - public function testMigrateDateNotFound() + public function testMigrateDateNotFound(): void { $migrationPath = ROOT . DS . 'config' . DS . 'Migrations'; $this->exec('migrations migrate -c test --date 2000-01-01'); @@ -179,7 +179,7 @@ public function testMigrateDateNotFound() /** * Test advancing migrations with an offset. */ - public function testMigrateTarget() + public function testMigrateTarget(): void { $migrationPath = ROOT . DS . 'config' . DS . 'Migrations'; $this->exec('migrations migrate -c test --target 20150416223600'); @@ -196,7 +196,7 @@ public function testMigrateTarget() $this->assertFileExists($dumpFile); } - public function testMigrateTargetNotFound() + public function testMigrateTargetNotFound(): void { $migrationPath = ROOT . DS . 'config' . DS . 'Migrations'; $this->exec('migrations migrate -c test --target 99'); @@ -214,7 +214,7 @@ public function testMigrateTargetNotFound() $this->assertFileExists($dumpFile); } - public function testMigrateFakeAll() + public function testMigrateFakeAll(): void { $migrationPath = ROOT . DS . 'config' . DS . 'Migrations'; $this->exec('migrations migrate -c test --fake'); @@ -232,7 +232,7 @@ public function testMigrateFakeAll() $this->assertFileExists($dumpFile); } - public function testMigratePlugin() + public function testMigratePlugin(): void { $this->loadPlugins(['Migrator']); $migrationPath = ROOT . DS . 'Plugin' . DS . 'Migrator' . DS . 'config' . DS . 'Migrations'; @@ -250,12 +250,12 @@ public function testMigratePlugin() $this->assertFileExists($dumpFile); } - public function testMigratePluginInvalid() + public function testMigratePluginInvalid(): void { try { $this->exec('migrations migrate -c test --plugin NotThere'); $this->fail('Should raise an error or exit with an error'); - } catch (MissingPluginException $e) { + } catch (MissingPluginException) { $this->assertTrue(true); } @@ -270,7 +270,7 @@ public function testMigratePluginInvalid() * * @return void */ - public function testMigrateWithNoLock() + public function testMigrateWithNoLock(): void { $migrationPath = ROOT . DS . 'config' . DS . 'Migrations'; $this->exec('migrations migrate -c test --no-lock'); diff --git a/tests/TestCase/Command/RollbackCommandTest.php b/tests/TestCase/Command/RollbackCommandTest.php index da94d200c..e24fdc250 100644 --- a/tests/TestCase/Command/RollbackCommandTest.php +++ b/tests/TestCase/Command/RollbackCommandTest.php @@ -3,6 +3,7 @@ namespace Migrations\Test\TestCase\Command; +use Cake\Console\TestSuite\StubConsoleOutput; use Cake\Datasource\ConnectionManager; use Cake\Event\EventInterface; use Cake\Event\EventManager; @@ -14,7 +15,7 @@ class RollbackCommandTest extends TestCase { protected array $createdFiles = []; - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -22,7 +23,7 @@ public function setUp(): void $this->clearMigrationRecords('test', 'Migrator'); } - public function tearDown(): void + protected function tearDown(): void { parent::tearDown(); foreach ($this->createdFiles as $file) { @@ -32,7 +33,7 @@ public function tearDown(): void protected function resetOutput(): void { - if ($this->_out) { + if ($this->_out instanceof StubConsoleOutput) { $property = new ReflectionProperty($this->_out, '_out'); $property->setValue($this->_out, []); } diff --git a/tests/TestCase/Command/SeedCommandTest.php b/tests/TestCase/Command/SeedCommandTest.php index e401e460b..f98e691d8 100644 --- a/tests/TestCase/Command/SeedCommandTest.php +++ b/tests/TestCase/Command/SeedCommandTest.php @@ -11,14 +11,14 @@ class SeedCommandTest extends TestCase { - public function setUp(): void + protected function setUp(): void { parent::setUp(); $this->clearMigrationRecords('test'); } - public function tearDown(): void + protected function tearDown(): void { parent::tearDown(); /** @var \Cake\Database\Connection $connection */ @@ -543,7 +543,7 @@ public function testIdempotentSeed(): void $this->assertEquals(2, $query->fetchColumn(0)); // Verify the seed WAS tracked in cake_seeds table (only one record, updated each run) - $seedLog = $connection->execute('SELECT COUNT(*) FROM cake_seeds WHERE seed_name = \'IdempotentTestSeed\''); + $seedLog = $connection->execute("SELECT COUNT(*) FROM cake_seeds WHERE seed_name = 'IdempotentTestSeed'"); $this->assertEquals(1, $seedLog->fetchColumn(0), 'Idempotent seeds should track last execution'); } @@ -560,7 +560,7 @@ public function testNonIdempotentSeedIsTracked(): void $connection = ConnectionManager::get('test'); // Verify the seed WAS tracked in cake_seeds table - $seedLog = $connection->execute('SELECT COUNT(*) FROM cake_seeds WHERE seed_name = \'NumbersSeed\''); + $seedLog = $connection->execute("SELECT COUNT(*) FROM cake_seeds WHERE seed_name = 'NumbersSeed'"); $this->assertEquals(1, $seedLog->fetchColumn(0), 'Regular seeds should be tracked'); // Run again - should be silently skipped @@ -589,7 +589,7 @@ public function testFakeSeedMarksAsExecuted(): void $this->assertEquals(0, $query->fetchColumn(0), 'Fake seed should not insert data'); // Verify the seed WAS tracked in cake_seeds table - $seedLog = $connection->execute('SELECT COUNT(*) FROM cake_seeds WHERE seed_name = \'NumbersSeed\''); + $seedLog = $connection->execute("SELECT COUNT(*) FROM cake_seeds WHERE seed_name = 'NumbersSeed'"); $this->assertEquals(1, $seedLog->fetchColumn(0), 'Fake seeds should be tracked'); // Running again should be silently skipped @@ -610,7 +610,7 @@ public function testFakeSeedWithForce(): void $this->assertExitSuccess(); // Verify seed is tracked - $seedLog = $connection->execute('SELECT COUNT(*) FROM cake_seeds WHERE seed_name = \'NumbersSeed\''); + $seedLog = $connection->execute("SELECT COUNT(*) FROM cake_seeds WHERE seed_name = 'NumbersSeed'"); $this->assertEquals(1, $seedLog->fetchColumn(0)); // Run with --force to actually execute it @@ -638,10 +638,10 @@ public function testResetSpecificSeed(): void $this->assertExitSuccess(); // Verify both are tracked - $numbersLog = $connection->execute('SELECT COUNT(*) FROM cake_seeds WHERE seed_name = \'NumbersSeed\''); + $numbersLog = $connection->execute("SELECT COUNT(*) FROM cake_seeds WHERE seed_name = 'NumbersSeed'"); $this->assertEquals(1, $numbersLog->fetchColumn(0)); - $storesLog = $connection->execute('SELECT COUNT(*) FROM cake_seeds WHERE seed_name = \'StoresSeed\''); + $storesLog = $connection->execute("SELECT COUNT(*) FROM cake_seeds WHERE seed_name = 'StoresSeed'"); $this->assertEquals(1, $storesLog->fetchColumn(0)); // Reset only Numbers seed @@ -651,10 +651,10 @@ public function testResetSpecificSeed(): void $this->assertOutputNotContains('All seeds will be reset:'); // Verify Numbers is reset but Stores is still tracked - $numbersLog = $connection->execute('SELECT COUNT(*) FROM cake_seeds WHERE seed_name = \'NumbersSeed\''); + $numbersLog = $connection->execute("SELECT COUNT(*) FROM cake_seeds WHERE seed_name = 'NumbersSeed'"); $this->assertEquals(0, $numbersLog->fetchColumn(0), 'Numbers seed should be reset'); - $storesLog = $connection->execute('SELECT COUNT(*) FROM cake_seeds WHERE seed_name = \'StoresSeed\''); + $storesLog = $connection->execute("SELECT COUNT(*) FROM cake_seeds WHERE seed_name = 'StoresSeed'"); $this->assertEquals(1, $storesLog->fetchColumn(0), 'Stores seed should still be tracked'); } @@ -674,10 +674,10 @@ public function testResetMultipleSpecificSeeds(): void $this->assertExitSuccess(); // Verify both are reset - $numbersLog = $connection->execute('SELECT COUNT(*) FROM cake_seeds WHERE seed_name = \'NumbersSeed\''); + $numbersLog = $connection->execute("SELECT COUNT(*) FROM cake_seeds WHERE seed_name = 'NumbersSeed'"); $this->assertEquals(0, $numbersLog->fetchColumn(0)); - $storesLog = $connection->execute('SELECT COUNT(*) FROM cake_seeds WHERE seed_name = \'StoresSeed\''); + $storesLog = $connection->execute("SELECT COUNT(*) FROM cake_seeds WHERE seed_name = 'StoresSeed'"); $this->assertEquals(0, $storesLog->fetchColumn(0)); } @@ -708,7 +708,7 @@ public function testFakeIdempotentSeedIsTracked(): void $this->assertEquals(0, $query->fetchColumn(0), 'Fake seed should not insert data'); // Verify the seed WAS tracked - $seedLog = $connection->execute('SELECT COUNT(*) FROM cake_seeds WHERE seed_name = \'IdempotentTestSeed\''); + $seedLog = $connection->execute("SELECT COUNT(*) FROM cake_seeds WHERE seed_name = 'IdempotentTestSeed'"); $this->assertEquals(1, $seedLog->fetchColumn(0), 'Idempotent seeds should be tracked when faked'); } } diff --git a/tests/TestCase/Command/StatusCommandTest.php b/tests/TestCase/Command/StatusCommandTest.php index 48acaf229..6b3b2f7e1 100644 --- a/tests/TestCase/Command/StatusCommandTest.php +++ b/tests/TestCase/Command/StatusCommandTest.php @@ -3,13 +3,14 @@ namespace Migrations\Test\TestCase\Command; +use Cake\Console\TestSuite\StubConsoleOutput; use Cake\Core\Exception\MissingPluginException; use Migrations\Test\TestCase\TestCase; use RuntimeException; class StatusCommandTest extends TestCase { - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -41,7 +42,7 @@ public function testExecuteSimpleJson(): void $this->exec('migrations status -c test --format json'); $this->assertExitSuccess(); - assert(isset($this->_out)); + assert($this->_out instanceof StubConsoleOutput); $output = $this->_out->messages(); $parsed = json_decode($output[0], true); $this->assertTrue(is_array($parsed)); diff --git a/tests/TestCase/Command/UpgradeCommandTest.php b/tests/TestCase/Command/UpgradeCommandTest.php index c7900bd7a..3a3890229 100644 --- a/tests/TestCase/Command/UpgradeCommandTest.php +++ b/tests/TestCase/Command/UpgradeCommandTest.php @@ -12,7 +12,7 @@ class UpgradeCommandTest extends TestCase { - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -23,7 +23,7 @@ public function setUp(): void $connection->execute('DROP TABLE IF EXISTS cake_migrations'); } - public function tearDown(): void + protected function tearDown(): void { $this->clearMigrationRecords('test'); @@ -48,7 +48,7 @@ protected function getAdapter(): AdapterInterface public function testHelp(): void { - Configure::write('Migrations.legacyTables', null); + Configure::write('Migrations.legacyTables'); $this->exec('migrations upgrade --help'); $this->assertExitSuccess(); @@ -61,7 +61,7 @@ public function testExecuteSimpleDryRun(): void Configure::write('Migrations.legacyTables', true); try { $this->getAdapter()->createSchemaTable(); - } catch (Exception $e) { + } catch (Exception) { // Table probably exists } @@ -85,7 +85,7 @@ public function testExecuteSimpleExecute(): void $adapter = $environment->getAdapter(); try { $adapter->createSchemaTable(); - } catch (Exception $e) { + } catch (Exception) { // Table probably exists } @@ -113,7 +113,7 @@ public function testExecuteSimpleExecuteDropTables(): void $adapter = $environment->getAdapter(); try { $adapter->createSchemaTable(); - } catch (Exception $e) { + } catch (Exception) { // Table probably exists } @@ -135,7 +135,7 @@ public function testExecuteWithMigrations(): void Configure::write('Migrations.legacyTables', true); try { $this->getAdapter()->createSchemaTable(); - } catch (Exception $e) { + } catch (Exception) { // Table probably exists } @@ -185,7 +185,7 @@ public function testExecuteWithSlashInPluginName(): void $adapter = $environment->getAdapter(); try { $adapter->createSchemaTable(); - } catch (Exception $e) { + } catch (Exception) { // Table probably exists } diff --git a/tests/TestCase/Config/ConfigMigrationPathsTest.php b/tests/TestCase/Config/ConfigMigrationPathsTest.php index 8a1165ba8..a849eb7c9 100644 --- a/tests/TestCase/Config/ConfigMigrationPathsTest.php +++ b/tests/TestCase/Config/ConfigMigrationPathsTest.php @@ -10,7 +10,7 @@ */ class ConfigMigrationPathsTest extends AbstractConfigTestCase { - public function testGetMigrationPathsThrowsExceptionForNoPath() + public function testGetMigrationPathsThrowsExceptionForNoPath(): void { $config = new Config([]); @@ -22,7 +22,7 @@ public function testGetMigrationPathsThrowsExceptionForNoPath() /** * Normal behavior */ - public function testGetMigrationPaths() + public function testGetMigrationPaths(): void { $config = new Config($this->getConfigArray()); $this->assertEquals($this->getMigrationPath(), $config->getMigrationPath()); diff --git a/tests/TestCase/Config/ConfigSeedPathsTest.php b/tests/TestCase/Config/ConfigSeedPathsTest.php index 8697979bf..164c8404b 100644 --- a/tests/TestCase/Config/ConfigSeedPathsTest.php +++ b/tests/TestCase/Config/ConfigSeedPathsTest.php @@ -10,7 +10,7 @@ */ class ConfigSeedPathsTest extends AbstractConfigTestCase { - public function testGetSeedPathsThrowsExceptionForNoPath() + public function testGetSeedPathsThrowsExceptionForNoPath(): void { $config = new Config([]); @@ -22,13 +22,13 @@ public function testGetSeedPathsThrowsExceptionForNoPath() /** * Normal behavior */ - public function testGetSeedPaths() + public function testGetSeedPaths(): void { $config = new Config($this->getConfigArray()); $this->assertEquals($this->getSeedPath(), $config->getSeedPath()); } - public function testGetSeedPathConvertsStringToArray() + public function testGetSeedPathConvertsStringToArray(): void { $values = [ 'paths' => [ diff --git a/tests/TestCase/Config/ConfigTest.php b/tests/TestCase/Config/ConfigTest.php index 9197956be..5bd0ba4c7 100644 --- a/tests/TestCase/Config/ConfigTest.php +++ b/tests/TestCase/Config/ConfigTest.php @@ -12,14 +12,14 @@ */ class ConfigTest extends AbstractConfigTestCase { - public function testGetEnvironmentMethod() + public function testGetEnvironmentMethod(): void { $config = new Config($this->getConfigArray()); $db = $config->getEnvironment(); $this->assertArrayHasKey('adapter', $db); } - public function testEnvironmentHasMigrationTable() + public function testEnvironmentHasMigrationTable(): void { $configArray = $this->getConfigArray(); $configArray['environment']['migration_table'] = 'test_table'; @@ -28,7 +28,7 @@ public function testEnvironmentHasMigrationTable() $this->assertSame('test_table', $config->getEnvironment()['migration_table']); } - public function testArrayAccessMethods() + public function testArrayAccessMethods(): void { $config = new Config([]); $config['foo'] = 'bar'; @@ -38,7 +38,7 @@ public function testArrayAccessMethods() $this->assertArrayNotHasKey('foo', $config); } - public function testUndefinedArrayAccess() + public function testUndefinedArrayAccess(): void { $config = new Config([]); @@ -48,7 +48,7 @@ public function testUndefinedArrayAccess() $config['foo']; } - public function testGetSeedPath() + public function testGetSeedPath(): void { $config = new Config(['paths' => ['seeds' => 'db/seeds']]); $this->assertEquals('db/seeds', $config->getSeedPath()); @@ -57,7 +57,7 @@ public function testGetSeedPath() $this->assertEquals('db/seeds1', $config->getSeedPath()); } - public function testGetSeedPathThrowsException() + public function testGetSeedPathThrowsException(): void { $config = new Config([]); @@ -67,7 +67,7 @@ public function testGetSeedPathThrowsException() $config->getSeedPath(); } - public function testGetVersionOrder() + public function testGetVersionOrder(): void { $config = new Config([]); $config['version_order'] = Config::VERSION_ORDER_EXECUTION_TIME; @@ -75,7 +75,7 @@ public function testGetVersionOrder() } #[DataProvider('isVersionOrderCreationTimeDataProvider')] - public function testIsVersionOrderCreationTime($versionOrder, $expected) + public function testIsVersionOrderCreationTime(string $versionOrder, bool $expected): void { // get config stub $configStub = $this->getMockBuilder(Config::class) @@ -90,7 +90,7 @@ public function testIsVersionOrderCreationTime($versionOrder, $expected) $this->assertEquals($expected, $configStub->isVersionOrderCreationTime()); } - public static function isVersionOrderCreationTimeDataProvider() + public static function isVersionOrderCreationTimeDataProvider(): array { return [ 'With Creation Time Version Order' => diff --git a/tests/TestCase/Db/Adapter/AbstractAdapterTest.php b/tests/TestCase/Db/Adapter/AbstractAdapterTest.php index 425d5281d..5279b0705 100644 --- a/tests/TestCase/Db/Adapter/AbstractAdapterTest.php +++ b/tests/TestCase/Db/Adapter/AbstractAdapterTest.php @@ -18,10 +18,7 @@ class AbstractAdapterTest extends TestCase { - /** - * @var \Migrations\Db\Adapter\AbstractAdapter|\PHPUnit\Framework\MockObject\MockObject - */ - private $adapter; + private AbstractAdapter $adapter; protected function setUp(): void { @@ -35,14 +32,14 @@ protected function tearDown(): void unset($this->adapter); } - public function testOptions() + public function testOptions(): void { $options = $this->adapter->getOptions(); $this->assertArrayHasKey('foo', $options); $this->assertEquals('bar', $options['foo']); } - public function testOptionsSetSchemaTableName() + public function testOptionsSetSchemaTableName(): void { // When unified table mode is enabled, getSchemaTableName() returns cake_migrations $expectedDefault = Configure::read('Migrations.legacyTables') === false @@ -58,7 +55,7 @@ public function testOptionsSetSchemaTableName() $this->assertEquals($expectedAfterSet, $this->adapter->getSchemaTableName()); } - public function testSchemaTableName() + public function testSchemaTableName(): void { $expectedDefault = Configure::read('Migrations.legacyTables') === false ? UnifiedMigrationsTableStorage::TABLE_NAME @@ -71,7 +68,7 @@ public function testSchemaTableName() $this->assertEquals($expectedAfterSet, $this->adapter->getSchemaTableName()); } - public function testGetVersionLogInvalidVersionOrderKO() + public function testGetVersionLogInvalidVersionOrderKO(): void { $this->expectExceptionMessage('Invalid version_order configuration option'); $adapter = new class (['version_order' => 'invalid']) extends AbstractAdapter { @@ -83,7 +80,7 @@ public function testGetVersionLogInvalidVersionOrderKO() $adapter->getVersionLog(); } - public function testGetVersionLongDryRun() + public function testGetVersionLongDryRun(): void { $adapter = new class (['version_order' => Config::VERSION_ORDER_CREATION_TIME]) extends AbstractAdapter { use DefaultAdapterTrait; @@ -122,7 +119,7 @@ public function fetchAll(string $sql): array * @see https://github.com/cakephp/phinx/issues/1891 */ #[DataProvider('currentTimestampDefaultValueProvider')] - public function testCurrentTimestampDefaultValueQuoting($default, $columnType, $expected) + public function testCurrentTimestampDefaultValueQuoting(string|Literal|bool $default, ?string $columnType, string $expected): void { $adapter = new class (['version_order' => Config::VERSION_ORDER_CREATION_TIME]) extends AbstractAdapter { use DefaultAdapterTrait; diff --git a/tests/TestCase/Db/Adapter/AdapterFactoryTest.php b/tests/TestCase/Db/Adapter/AdapterFactoryTest.php index 8db24f3bf..e1fd15594 100644 --- a/tests/TestCase/Db/Adapter/AdapterFactoryTest.php +++ b/tests/TestCase/Db/Adapter/AdapterFactoryTest.php @@ -5,17 +5,18 @@ use Migrations\Db\Adapter\AbstractAdapter; use Migrations\Db\Adapter\AdapterFactory; +use Migrations\Db\Adapter\AdapterInterface; +use Migrations\Db\Adapter\MysqlAdapter; +use Migrations\Db\Adapter\TimedOutputAdapter; use Migrations\Test\TestCase\Db\Adapter\DefaultAdapterTrait; +use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use ReflectionMethod; use RuntimeException; class AdapterFactoryTest extends TestCase { - /** - * @var \Migrations\Db\Adapter\AdapterFactory - */ - private $factory; + private AdapterFactory $factory; protected function setUp(): void { @@ -27,17 +28,17 @@ protected function tearDown(): void unset($this->factory); } - public function testInstanceIsFactory() + public function testInstanceIsFactory(): void { $this->assertInstanceOf(AdapterFactory::class, $this->factory); } - public function testRegisterAdapter() + public function testRegisterAdapter(): void { $pdo = new class (['foo' => 'bar']) extends AbstractAdapter { use DefaultAdapterTrait; }; - $this->factory->registerAdapter('test', function (array $options) use ($pdo) { + $this->factory->registerAdapter('test', function (array $options) use ($pdo): object { $this->assertEquals('value', $options['key']); return $pdo; @@ -46,7 +47,7 @@ public function testRegisterAdapter() $this->assertEquals($pdo, $this->factory->getAdapter('test', ['key' => 'value'])); } - public function testRegisterAdapterFailure() + public function testRegisterAdapterFailure(): void { $adapter = static::class; @@ -56,14 +57,14 @@ public function testRegisterAdapterFailure() $this->factory->registerAdapter('test', $adapter); } - public function testGetAdapter() + public function testGetAdapter(): void { $adapter = $this->factory->getAdapter('mysql', []); - $this->assertInstanceOf('Migrations\Db\Adapter\MysqlAdapter', $adapter); + $this->assertInstanceOf(MysqlAdapter::class, $adapter); } - public function testGetAdapterFailure() + public function testGetAdapterFailure(): void { $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Adapter "bad" has not been registered'); @@ -71,12 +72,11 @@ public function testGetAdapterFailure() $this->factory->getAdapter('bad', []); } - public function testRegisterWrapper() + public function testRegisterWrapper(): void { // WrapperFactory::getClass is protected, work around it to avoid // creating unnecessary instances and making the test more complex. - $method = new ReflectionMethod(get_class($this->factory), 'getWrapperClass'); - $method->setAccessible(true); + $method = new ReflectionMethod($this->factory::class, 'getWrapperClass'); $wrapper = $method->invoke($this->factory, 'record'); $this->factory->registerWrapper('test', $wrapper); @@ -84,7 +84,7 @@ public function testRegisterWrapper() $this->assertEquals($wrapper, $method->invoke($this->factory, 'test')); } - public function testRegisterWrapperFailure() + public function testRegisterWrapperFailure(): void { $wrapper = static::class; @@ -94,19 +94,19 @@ public function testRegisterWrapperFailure() $this->factory->registerWrapper('test', $wrapper); } - private function getAdapterMock() + private function getAdapterMock(): MockObject { - return $this->getMockBuilder('Migrations\Db\Adapter\AdapterInterface')->getMock(); + return $this->getMockBuilder(AdapterInterface::class)->getMock(); } - public function testGetWrapper() + public function testGetWrapper(): void { $wrapper = $this->factory->getWrapper('timed', $this->getAdapterMock()); - $this->assertInstanceOf('Migrations\Db\Adapter\TimedOutputAdapter', $wrapper); + $this->assertInstanceOf(TimedOutputAdapter::class, $wrapper); } - public function testGetWrapperFailure() + public function testGetWrapperFailure(): void { $this->expectException(RuntimeException::class); $this->expectExceptionMessage('Wrapper "nope" has not been registered'); diff --git a/tests/TestCase/Db/Adapter/MysqlAdapterTest.php b/tests/TestCase/Db/Adapter/MysqlAdapterTest.php index 94202d83b..93f05d046 100644 --- a/tests/TestCase/Db/Adapter/MysqlAdapterTest.php +++ b/tests/TestCase/Db/Adapter/MysqlAdapterTest.php @@ -29,16 +29,12 @@ class MysqlAdapterTest extends TestCase { - /** - * @var \Migrations\Db\Adapter\MysqlAdapter - */ - private $adapter; + private MysqlAdapter $adapter; + + private array $config; - /** - * @var array - */ - private $config; private StubConsoleOutput $out; + private ConsoleIo $io; protected function setUp(): void @@ -102,12 +98,12 @@ private function usingMariaDbWithUuid(): bool return version_compare($version, '10.7.0', '>='); } - public function testConnection() + public function testConnection(): void { $this->assertInstanceOf(Connection::class, $this->adapter->getConnection()); } - public function testCreatingTheSchemaTableOnConnect() + public function testCreatingTheSchemaTableOnConnect(): void { $this->adapter->connect(); $this->assertTrue($this->adapter->hasTable($this->adapter->getSchemaTableName())); @@ -118,7 +114,7 @@ public function testCreatingTheSchemaTableOnConnect() $this->assertTrue($this->adapter->hasTable($this->adapter->getSchemaTableName())); } - public function testSchemaTableIsCreatedWithPrimaryKey() + public function testSchemaTableIsCreatedWithPrimaryKey(): void { // Skip for unified table mode since schema structure is different if (Configure::read('Migrations.legacyTables') === false) { @@ -130,7 +126,7 @@ public function testSchemaTableIsCreatedWithPrimaryKey() $this->assertTrue($this->adapter->hasIndex($this->adapter->getSchemaTableName(), ['version'])); } - public function testDatabaseNameWithEscapedCharacter() + public function testDatabaseNameWithEscapedCharacter(): void { $this->adapter->dropDatabase($this->config['database'] . '-test'); $this->adapter->createDatabase($this->config['database'] . '-test', ['charset' => 'utf8mb4']); @@ -138,24 +134,24 @@ public function testDatabaseNameWithEscapedCharacter() $this->adapter->dropDatabase($this->config['database'] . '-test'); } - public function testQuoteTableName() + public function testQuoteTableName(): void { $this->assertEquals('`test_table`', $this->adapter->quoteTableName('test_table')); } - public function testQuoteColumnName() + public function testQuoteColumnName(): void { $this->assertEquals('`test_column`', $this->adapter->quoteColumnName('test_column')); } - public function testHasTableUnderstandsSchemaNotation() + public function testHasTableUnderstandsSchemaNotation(): void { $this->assertTrue($this->adapter->hasTable('performance_schema.threads'), 'Failed asserting hasTable understands tables in another schema.'); $this->assertFalse($this->adapter->hasTable('performance_schema.unknown_table')); $this->assertFalse($this->adapter->hasTable('unknown_schema.phinxlog')); } - public function testCreateTable() + public function testCreateTable(): void { $table = new Table('ntable', [], $this->adapter); $table->addColumn('realname', 'string') @@ -173,7 +169,7 @@ public function testCreateTable() $this->assertFalse($columns[0]->isSigned()); } - public function testCreateTableWithComment() + public function testCreateTableWithComment(): void { $tableComment = 'Table comment'; $table = new Table('ntable', ['comment' => $tableComment], $this->adapter); @@ -193,7 +189,7 @@ public function testCreateTableWithComment() $this->assertEquals($tableComment, $comment['TABLE_COMMENT'], 'Dont set table comment correctly'); } - public function testCreateTableWithForeignKeys() + public function testCreateTableWithForeignKeys(): void { $tag_table = new Table('ntable_tag', [], $this->adapter); $tag_table->addColumn('realname', 'string') @@ -224,7 +220,7 @@ public function testCreateTableWithForeignKeys() $this->assertEquals($foreignKey['REFERENCED_COLUMN_NAME'], 'id'); } - public function testCreateTableCustomIdColumn() + public function testCreateTableCustomIdColumn(): void { $table = new Table('ntable', ['id' => 'custom_id'], $this->adapter); $table->addColumn('realname', 'string') @@ -237,7 +233,7 @@ public function testCreateTableCustomIdColumn() $this->assertFalse($this->adapter->hasColumn('ntable', 'address')); } - public function testCreateTableWithNoPrimaryKey() + public function testCreateTableWithNoPrimaryKey(): void { $options = [ 'id' => false, @@ -248,7 +244,7 @@ public function testCreateTableWithNoPrimaryKey() $this->assertFalse($this->adapter->hasColumn('atable', 'id')); } - public function testCreateTableWithConflictingPrimaryKeys() + public function testCreateTableWithConflictingPrimaryKeys(): void { $options = [ 'primary_key' => 'user_id', @@ -260,7 +256,7 @@ public function testCreateTableWithConflictingPrimaryKeys() $table->addColumn('user_id', 'integer')->save(); } - public function testCreateTableWithPrimaryKeySetToImplicitId() + public function testCreateTableWithPrimaryKeySetToImplicitId(): void { $options = [ 'primary_key' => 'id', @@ -272,7 +268,7 @@ public function testCreateTableWithPrimaryKeySetToImplicitId() $this->assertTrue($this->adapter->hasColumn('ztable', 'user_id')); } - public function testCreateTableWithPrimaryKeyArraySetToImplicitId() + public function testCreateTableWithPrimaryKeyArraySetToImplicitId(): void { $options = [ 'primary_key' => ['id'], @@ -284,7 +280,7 @@ public function testCreateTableWithPrimaryKeyArraySetToImplicitId() $this->assertTrue($this->adapter->hasColumn('ztable', 'user_id')); } - public function testCreateTableWithMultiplePrimaryKeyArraySetToImplicitId() + public function testCreateTableWithMultiplePrimaryKeyArraySetToImplicitId(): void { $options = [ 'primary_key' => ['id', 'user_id'], @@ -295,7 +291,7 @@ public function testCreateTableWithMultiplePrimaryKeyArraySetToImplicitId() $table->addColumn('user_id', 'integer')->save(); } - public function testCreateTableWithMultiplePrimaryKeys() + public function testCreateTableWithMultiplePrimaryKeys(): void { $options = [ 'id' => false, @@ -314,7 +310,7 @@ public function testCreateTableWithMultiplePrimaryKeys() /** * @return void */ - public function testCreateTableWithPrimaryKeyAsUuid() + public function testCreateTableWithPrimaryKeyAsUuid(): void { $options = [ 'id' => false, @@ -331,7 +327,7 @@ public function testCreateTableWithPrimaryKeyAsUuid() /** * @return void */ - public function testCreateTableWithPrimaryKeyAsBinaryUuid() + public function testCreateTableWithPrimaryKeyAsBinaryUuid(): void { $options = [ 'id' => false, @@ -345,7 +341,7 @@ public function testCreateTableWithPrimaryKeyAsBinaryUuid() $this->assertTrue($this->adapter->hasColumn('ztable', 'user_id')); } - public function testCreateTableBinaryLengthWithIndex() + public function testCreateTableBinaryLengthWithIndex(): void { $table = new Table('ntable', [], $this->adapter); $table @@ -369,7 +365,7 @@ public function testCreateTableBinaryLengthWithIndex() /** * @return void */ - public function testCreateTableWithPrimaryKeyAsNativeUuid() + public function testCreateTableWithPrimaryKeyAsNativeUuid(): void { if (!$this->usingMariaDbWithUuid()) { $this->markTestSkipped('Database does not have a native uuid type'); @@ -387,7 +383,7 @@ public function testCreateTableWithPrimaryKeyAsNativeUuid() $this->assertTrue($this->adapter->hasColumn('ztable', 'user_id')); } - public function testCreateTableWithMultipleIndexes() + public function testCreateTableWithMultipleIndexes(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -401,7 +397,7 @@ public function testCreateTableWithMultipleIndexes() $this->assertFalse($this->adapter->hasIndex('table1', ['email', 'user_name'])); } - public function testCreateTableWithUniqueIndexes() + public function testCreateTableWithUniqueIndexes(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string', ['limit' => 191]) @@ -411,7 +407,7 @@ public function testCreateTableWithUniqueIndexes() $this->assertFalse($this->adapter->hasIndex('table1', ['email', 'user_email'])); } - public function testCreateTableWithFullTextIndex() + public function testCreateTableWithFullTextIndex(): void { $table = new Table('table1', ['engine' => 'MyISAM'], $this->adapter); $table->addColumn('email', 'string') @@ -421,7 +417,7 @@ public function testCreateTableWithFullTextIndex() $this->assertFalse($this->adapter->hasIndex('table1', ['email', 'user_email'])); } - public function testCreateTableWithNamedIndex() + public function testCreateTableWithNamedIndex(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -432,7 +428,7 @@ public function testCreateTableWithNamedIndex() $this->assertTrue($this->adapter->hasIndexByName('table1', 'myemailindex')); } - public function testCreateTableWithMyISAMEngine() + public function testCreateTableWithMyISAMEngine(): void { $table = new Table('ntable', ['engine' => 'MyISAM'], $this->adapter); $table->addColumn('realname', 'string') @@ -442,7 +438,7 @@ public function testCreateTableWithMyISAMEngine() $this->assertEquals('MyISAM', $row['Engine']); } - public function testCreateTableAndInheritDefaultCollation() + public function testCreateTableAndInheritDefaultCollation(): void { $options = $this->config + [ 'charset' => 'utf8mb4', @@ -458,7 +454,7 @@ public function testCreateTableAndInheritDefaultCollation() $this->assertContains($row['Collation'], ['utf8mb4_general_ci', 'utf8mb4_0900_ai_ci', 'utf8mb4_uca1400_ai_ci', 'utf8mb4_unicode_ci']); } - public function testCreateTableWithLatin1Collate() + public function testCreateTableWithLatin1Collate(): void { $table = new Table('latin1_table', ['collation' => 'latin1_general_ci'], $this->adapter); $table->addColumn('name', 'string') @@ -468,7 +464,7 @@ public function testCreateTableWithLatin1Collate() $this->assertEquals('latin1_general_ci', $row['Collation']); } - public function testCreateTableWithSignedPK() + public function testCreateTableWithSignedPK(): void { $table = new Table('ntable', ['signed' => true], $this->adapter); $table->addColumn('realname', 'string') @@ -487,7 +483,7 @@ public function testCreateTableWithSignedPK() } } - public function testCreateTableWithUnsignedPK() + public function testCreateTableWithUnsignedPK(): void { $table = new Table('ntable', ['signed' => false], $this->adapter); $table->addColumn('realname', 'string') @@ -506,7 +502,7 @@ public function testCreateTableWithUnsignedPK() } } - public function testCreateTableWithUnsignedNamedPK() + public function testCreateTableWithUnsignedNamedPK(): void { $table = new Table('ntable', ['id' => 'named_id', 'signed' => false], $this->adapter); $table->addColumn('realname', 'string') @@ -525,7 +521,7 @@ public function testCreateTableWithUnsignedNamedPK() $this->assertFalse($this->adapter->hasColumn('ntable', 'address')); } - public function testCreateTableWithSetEnumTypes() + public function testCreateTableWithSetEnumTypes(): void { $table = new Table('enum_test', [], $this->adapter); $table->addColumn('status', 'enum', ['values' => ['pending', 'active', 'archived']]) @@ -538,7 +534,7 @@ public function testCreateTableWithSetEnumTypes() } #[RunInSeparateProcess] - public function testUnsignedPksFeatureFlag() + public function testUnsignedPksFeatureFlag(): void { $this->adapter->connect(); @@ -554,7 +550,7 @@ public function testUnsignedPksFeatureFlag() } #[RunInSeparateProcess] - public function testAddTimestampsFeatureFlag() + public function testAddTimestampsFeatureFlag(): void { Configure::write('Migrations.add_timestamps_use_datetime', true); $this->adapter->connect(); @@ -581,7 +577,7 @@ public function testAddTimestampsFeatureFlag() $this->assertNull($columns[2]->getDefault()); } - public function testCreateTableWithSchema() + public function testCreateTableWithSchema(): void { $table = new Table($this->config['database'] . '.ntable', [], $this->adapter); $table->addColumn('realname', 'string') @@ -590,7 +586,7 @@ public function testCreateTableWithSchema() $this->assertTrue($this->adapter->hasTable('ntable')); } - public function testAddPrimarykey() + public function testAddPrimarykey(): void { $table = new Table('table1', ['id' => false], $this->adapter); $table @@ -604,7 +600,7 @@ public function testAddPrimarykey() $this->assertTrue($this->adapter->hasPrimaryKey('table1', ['column1'])); } - public function testChangePrimaryKey() + public function testChangePrimaryKey(): void { $table = new Table('table1', ['id' => false, 'primary_key' => 'column1'], $this->adapter); $table @@ -621,7 +617,7 @@ public function testChangePrimaryKey() $this->assertTrue($this->adapter->hasPrimaryKey('table1', ['column2', 'column3'])); } - public function testDropPrimaryKey() + public function testDropPrimaryKey(): void { $table = new Table('table1', ['id' => false, 'primary_key' => 'column1'], $this->adapter); $table @@ -635,7 +631,7 @@ public function testDropPrimaryKey() $this->assertFalse($this->adapter->hasPrimaryKey('table1', ['column1'])); } - public function testAddComment() + public function testAddComment(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -657,7 +653,7 @@ public function testAddComment() $this->assertEquals('comment1', $rows[0]['TABLE_COMMENT']); } - public function testChangeComment() + public function testChangeComment(): void { $table = new Table('table1', ['comment' => 'comment1'], $this->adapter); $table->save(); @@ -679,7 +675,7 @@ public function testChangeComment() $this->assertEquals('comment2', $rows[0]['TABLE_COMMENT']); } - public function testDropComment() + public function testDropComment(): void { $table = new Table('table1', ['comment' => 'comment1'], $this->adapter); $table->save(); @@ -701,7 +697,7 @@ public function testDropComment() $this->assertEquals('', $rows[0]['TABLE_COMMENT']); } - public function testRenameTable() + public function testRenameTable(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -713,7 +709,7 @@ public function testRenameTable() $this->assertTrue($this->adapter->hasTable('table2')); } - public function testAddColumn() + public function testAddColumn(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -727,7 +723,7 @@ public function testAddColumn() $this->assertEquals('realname', $rows[1]['Field']); } - public function testAddColumnWithDefaultValue() + public function testAddColumnWithDefaultValue(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -737,7 +733,7 @@ public function testAddColumnWithDefaultValue() $this->assertEquals('test', $rows[1]['Default']); } - public function testAddColumnWithDefaultZero() + public function testAddColumnWithDefaultZero(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -748,7 +744,7 @@ public function testAddColumnWithDefaultZero() $this->assertEquals('0', $rows[1]['Default']); } - public function testAddColumnWithDefaultEmptyString() + public function testAddColumnWithDefaultEmptyString(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -758,7 +754,7 @@ public function testAddColumnWithDefaultEmptyString() $this->assertEquals('', $rows[1]['Default']); } - public function testAddColumnWithDefaultBoolean() + public function testAddColumnWithDefaultBoolean(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -772,7 +768,7 @@ public function testAddColumnWithDefaultBoolean() $this->assertNull($rows[3]['Default']); } - public function testAddColumnWithDefaultLiteral() + public function testAddColumnWithDefaultLiteral(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -786,7 +782,7 @@ public function testAddColumnWithDefaultLiteral() $this->assertTrue($rows[2]['Default'] === 'oh hi'); } - public function testAddColumnFirst() + public function testAddColumnFirst(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -796,7 +792,7 @@ public function testAddColumnFirst() $this->assertSame('new_id', $rows[0]['Field']); } - public static function integerDataProvider() + public static function integerDataProvider(): array { return [ ['integer', [], 'int', '11', ''], @@ -811,7 +807,7 @@ public static function integerDataProvider() } #[DataProvider('integerDataProvider')] - public function testIntegerColumnTypes($phinx_type, $options, $sql_type, $width, $extra) + public function testIntegerColumnTypes(string $phinx_type, array $options, string $sql_type, string $width, string $extra): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -897,7 +893,7 @@ public function testRenameColumnWithDefaultGeneratedExtra(): void $this->assertTrue($this->adapter->hasColumn('t', 'last_changed2')); } - public function testRenamingANonExistentColumn() + public function testRenamingANonExistentColumn(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -910,13 +906,13 @@ public function testRenamingANonExistentColumn() $this->assertInstanceOf( 'InvalidArgumentException', $e, - 'Expected exception of type InvalidArgumentException, got ' . get_class($e), + 'Expected exception of type InvalidArgumentException, got ' . $e::class, ); - $this->assertEquals('The specified column doesn\'t exist: column2', $e->getMessage()); + $this->assertEquals("The specified column doesn't exist: column2", $e->getMessage()); } } - public function testChangeColumn() + public function testChangeColumn(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -933,7 +929,7 @@ public function testChangeColumn() $this->assertTrue($this->adapter->hasColumn('t', 'column2')); } - public function testChangeColumnDefaultValue() + public function testChangeColumnDefaultValue(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['default' => 'test']) @@ -948,7 +944,7 @@ public function testChangeColumnDefaultValue() $this->assertEquals('test1', $rows[1]['Default']); } - public function testChangeColumnDefaultToZero() + public function testChangeColumnDefaultToZero(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'integer') @@ -963,7 +959,7 @@ public function testChangeColumnDefaultToZero() $this->assertEquals('0', $rows[1]['Default']); } - public function testChangeColumnDefaultToNull() + public function testChangeColumnDefaultToNull(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['default' => 'test']) @@ -977,7 +973,7 @@ public function testChangeColumnDefaultToNull() $this->assertNull($rows[1]['Default']); } - public function testChangeColumnPreservesDefaultValue() + public function testChangeColumnPreservesDefaultValue(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['default' => 'original_default', 'null' => false, 'limit' => 100]) @@ -992,7 +988,7 @@ public function testChangeColumnPreservesDefaultValue() $this->assertEquals('varchar(100)', $rows[1]['Type']); } - public function testChangeColumnPreservesDefaultValueWithDifferentType() + public function testChangeColumnPreservesDefaultValueWithDifferentType(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'integer', ['default' => 42, 'null' => false]) @@ -1006,7 +1002,7 @@ public function testChangeColumnPreservesDefaultValueWithDifferentType() $this->assertEquals('NO', $rows[1]['Null']); } - public function testChangeColumnCanExplicitlyOverrideDefault() + public function testChangeColumnCanExplicitlyOverrideDefault(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['default' => 'original_default']) @@ -1019,7 +1015,7 @@ public function testChangeColumnCanExplicitlyOverrideDefault() $this->assertEquals('new_default', $rows[1]['Default']); } - public function testChangeColumnCanDisablePreserveUnspecified() + public function testChangeColumnCanDisablePreserveUnspecified(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['default' => 'original_default', 'limit' => 100]) @@ -1032,7 +1028,7 @@ public function testChangeColumnCanDisablePreserveUnspecified() $this->assertNull($rows[1]['Default']); } - public function testChangeColumnWithNullTypePreservesType() + public function testChangeColumnWithNullTypePreservesType(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['default' => 'test', 'limit' => 100]) @@ -1047,7 +1043,7 @@ public function testChangeColumnWithNullTypePreservesType() $this->assertEquals('YES', $rows[1]['Null']); } - public function testChangeColumnWithNullTypeOnNonExistentColumnThrows() + public function testChangeColumnWithNullTypeOnNonExistentColumnThrows(): void { $this->expectException(RuntimeException::class); $this->expectExceptionMessage("Cannot preserve column type for 'nonexistent'"); @@ -1059,7 +1055,7 @@ public function testChangeColumnWithNullTypeOnNonExistentColumnThrows() $table->changeColumn('nonexistent', null, ['null' => true])->save(); } - public function testUpdateColumnPreservesAttributes() + public function testUpdateColumnPreservesAttributes(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['default' => 'test', 'limit' => 100, 'null' => false]) @@ -1074,7 +1070,7 @@ public function testUpdateColumnPreservesAttributes() $this->assertEquals('YES', $rows[1]['Null']); } - public function testChangeColumnDoesNotPreserveByDefault() + public function testChangeColumnDoesNotPreserveByDefault(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['default' => 'test', 'limit' => 100]) @@ -1089,7 +1085,7 @@ public function testChangeColumnDoesNotPreserveByDefault() $this->assertEquals('YES', $rows[1]['Null']); } - public function testChangeColumnWithPreserveUnspecifiedTrue() + public function testChangeColumnWithPreserveUnspecifiedTrue(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['default' => 'test', 'limit' => 100]) @@ -1104,7 +1100,7 @@ public function testChangeColumnWithPreserveUnspecifiedTrue() $this->assertEquals('YES', $rows[1]['Null']); } - public function testUpdateColumnWithColumnObject() + public function testUpdateColumnWithColumnObject(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['default' => 'test', 'limit' => 100, 'null' => false]) @@ -1123,7 +1119,7 @@ public function testUpdateColumnWithColumnObject() $this->assertEquals('YES', $rows[1]['Null']); } - public function testUpdateColumnWithColumnObjectAndOptionsThrows() + public function testUpdateColumnWithColumnObjectAndOptionsThrows(): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Cannot specify options array when passing a Column object'); @@ -1141,7 +1137,7 @@ public function testUpdateColumnWithColumnObjectAndOptionsThrows() $table->updateColumn('column1', $newColumn, ['limit' => 500]); } - public function testUpdateColumnWithTypeChangeToText() + public function testUpdateColumnWithTypeChangeToText(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['limit' => 100, 'default' => 'test']) @@ -1161,7 +1157,7 @@ public function testUpdateColumnWithTypeChangeToText() $this->assertStringContainsString('test', $rows[1]['Default']); // Default should be preserved } - public function testUpdateColumnCanRemoveLengthConstraintWithoutChangingType() + public function testUpdateColumnCanRemoveLengthConstraintWithoutChangingType(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['limit' => 100, 'default' => 'test']) @@ -1181,7 +1177,7 @@ public function testUpdateColumnCanRemoveLengthConstraintWithoutChangingType() $this->assertEquals('test', $rows[1]['Default']); // Default should be preserved } - public function testUpdateColumnCanRemoveScaleAndPrecision() + public function testUpdateColumnCanRemoveScaleAndPrecision(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'decimal', ['precision' => 10, 'scale' => 2, 'default' => '123.45']) @@ -1200,7 +1196,7 @@ public function testUpdateColumnCanRemoveScaleAndPrecision() $this->assertEquals('123', $rows[1]['Default']); // Default should be preserved (truncated to integer) } - public function testUpdateColumnCanRemoveComment() + public function testUpdateColumnCanRemoveComment(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['limit' => 100, 'comment' => 'Original comment', 'default' => 'test']) @@ -1220,7 +1216,7 @@ public function testUpdateColumnCanRemoveComment() $this->assertEquals('test', $rows[1]['Default']); } - public function testChangeColumnEnum() + public function testChangeColumnEnum(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -1235,7 +1231,7 @@ public function testChangeColumnEnum() $this->assertEquals("enum('a','b')", $rows[1]['Type']); } - public static function binaryToBlobAutomaticConversionData() + public static function binaryToBlobAutomaticConversionData(): array { return [ // When creating binary with limit > 255, MySQL auto-converts to BLOB @@ -1255,7 +1251,7 @@ public static function binaryToBlobAutomaticConversionData() } #[DataProvider('binaryToBlobAutomaticConversionData')] - public function testBinaryToBlobAutomaticConversion(?int $limit, string $expectedType, ?int $expectedLimit) + public function testBinaryToBlobAutomaticConversion(?int $limit, string $expectedType, ?int $expectedLimit): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'binary', ['limit' => $limit]) @@ -1265,7 +1261,7 @@ public function testBinaryToBlobAutomaticConversion(?int $limit, string $expecte $this->assertSame($expectedLimit, $columns[1]->getLimit()); } - public static function varbinaryToBlobAutomaticConversionData() + public static function varbinaryToBlobAutomaticConversionData(): array { return [ // When creating varbinary with limit > 255, MySQL auto-converts to BLOB @@ -1285,7 +1281,7 @@ public static function varbinaryToBlobAutomaticConversionData() } #[DataProvider('varbinaryToBlobAutomaticConversionData')] - public function testVarbinaryToBlobAutomaticConversion(?int $limit, string $expectedType, ?int $expectedLimit) + public function testVarbinaryToBlobAutomaticConversion(?int $limit, string $expectedType, ?int $expectedLimit): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'varbinary', ['limit' => $limit]) @@ -1295,7 +1291,7 @@ public function testVarbinaryToBlobAutomaticConversion(?int $limit, string $expe $this->assertSame($expectedLimit, $columns[1]->getLimit()); } - public static function blobColumnsData() + public static function blobColumnsData(): array { return [ // BLOB columns with various limits - MySQL auto-selects appropriate BLOB subtype @@ -1328,7 +1324,7 @@ public static function blobColumnsData() } #[DataProvider('blobColumnsData')] - public function testblobColumns(string $type, string $expectedType, ?int $limit, ?int $expectedLimit) + public function testblobColumns(string $type, string $expectedType, ?int $limit, ?int $expectedLimit): void { $table = new Table('t', [], $this->adapter); $table->addColumn('blob_col', $type, ['limit' => $limit]) @@ -1338,7 +1334,7 @@ public function testblobColumns(string $type, string $expectedType, ?int $limit, $this->assertSame($expectedLimit, $columns[1]->getLimit()); } - public static function blobRoundTripData() + public static function blobRoundTripData(): array { return [ // type, limit, expected type after round-trip, expected limit after round-trip @@ -1351,7 +1347,7 @@ public static function blobRoundTripData() } #[DataProvider('blobRoundTripData')] - public function testBlobRoundTrip(string $type, ?int $limit, string $expectedType, int $expectedLimit) + public function testBlobRoundTrip(string $type, ?int $limit, string $expectedType, int $expectedLimit): void { // Create a table with a BLOB column $table = new Table('blob_round_trip_test', [], $this->adapter); @@ -1370,7 +1366,7 @@ public function testBlobRoundTrip(string $type, ?int $limit, string $expectedTyp $this->adapter->dropTable('blob_round_trip_test'); } - public static function textRoundTripData() + public static function textRoundTripData(): array { return [ // type, limit, expected type after round-trip, expected limit after round-trip @@ -1385,7 +1381,7 @@ public static function textRoundTripData() } #[DataProvider('textRoundTripData')] - public function testTextRoundTrip(string $type, ?int $limit, string $expectedType, ?int $expectedLimit) + public function testTextRoundTrip(string $type, ?int $limit, string $expectedType, ?int $expectedLimit): void { // Create a table with a TEXT column $table = new Table('text_round_trip_test', [], $this->adapter); @@ -1404,7 +1400,7 @@ public function testTextRoundTrip(string $type, ?int $limit, string $expectedTyp $this->adapter->dropTable('text_round_trip_test'); } - public function testTimestampInvalidLimit() + public function testTimestampInvalidLimit(): void { $this->adapter->connect(); $version = $this->adapter->getConnection()->getDriver()->version(); @@ -1418,7 +1414,7 @@ public function testTimestampInvalidLimit() $table->addColumn('column1', 'timestamp', ['limit' => 7])->save(); } - public function testDropColumn() + public function testDropColumn(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -1429,7 +1425,7 @@ public function testDropColumn() $this->assertFalse($this->adapter->hasColumn('t', 'column1')); } - public static function columnsProvider() + public static function columnsProvider(): array { return [ ['column1', 'string', []], @@ -1459,7 +1455,7 @@ public static function columnsProvider() } #[DataProvider('columnsProvider')] - public function testGetColumns($colName, $type, $options) + public function testGetColumns(string $colName, string $type, array $options): void { $table = new Table('t', [], $this->adapter); $table->addColumn($colName, $type, $options)->save(); @@ -1490,7 +1486,7 @@ public function testGetColumns($colName, $type, $options) } } - public function testGetColumnsInteger() + public function testGetColumnsInteger(): void { $colName = 'column15'; $type = 'integer'; @@ -1506,7 +1502,7 @@ public function testGetColumnsInteger() $this->assertNull($columns[1]->getLimit()); } - public function testGetColumnsReservedTableName() + public function testGetColumnsReservedTableName(): void { $table = new Table('group', [], $this->adapter); $table->addColumn('column1', 'string')->save(); @@ -1514,7 +1510,7 @@ public function testGetColumnsReservedTableName() $this->assertCount(2, $columns); } - public function testAddIndex() + public function testAddIndex(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -1525,7 +1521,7 @@ public function testAddIndex() $this->assertTrue($table->hasIndex('email')); } - public function testAddIndexWithSort() + public function testAddIndexWithSort(): void { $this->adapter->connect(); if (!$this->usingMysql8()) { @@ -1548,7 +1544,7 @@ public function testAddIndexWithSort() $this->assertEquals($emailOrder, 'A'); } - public function testAddMultipleFulltextIndex() + public function testAddMultipleFulltextIndex(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -1569,7 +1565,7 @@ public function testAddMultipleFulltextIndex() $this->assertTrue($table->hasIndex(['email', 'bio'])); } - public function testAddIndexWithLimit() + public function testAddIndexWithLimit(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -1586,7 +1582,7 @@ public function testAddIndexWithLimit() $this->assertEquals($expected_limit, 50); } - public function testAddMultiIndexesWithLimitSpecifier() + public function testAddMultiIndexesWithLimitSpecifier(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -1610,7 +1606,7 @@ public function testAddMultiIndexesWithLimitSpecifier() $this->assertEquals($expected_limit, 2); } - public function testAddSingleIndexesWithLimitSpecifier() + public function testAddSingleIndexesWithLimitSpecifier(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -1628,7 +1624,7 @@ public function testAddSingleIndexesWithLimitSpecifier() $this->assertEquals($expected_limit, 3); } - public function testDropIndex() + public function testDropIndex(): void { // single column index $table = new Table('table1', [], $this->adapter); @@ -1678,7 +1674,7 @@ public function testDropIndex() try { $table2->removeIndex(['fname'])->save(); - } catch (InvalidArgumentException $e) { + } catch (InvalidArgumentException) { } $this->assertTrue($table2->hasIndex(['fname', 'lname'])); @@ -1693,13 +1689,13 @@ public function testDropIndex() try { $table4->removeIndex(['fname'])->save(); - } catch (InvalidArgumentException $e) { + } catch (InvalidArgumentException) { } $this->assertTrue($table4->hasIndex(['fname', 'lname'])); } - public function testDropIndexByName() + public function testDropIndexByName(): void { // single column index $table = new Table('table1', [], $this->adapter); @@ -1721,7 +1717,7 @@ public function testDropIndexByName() $this->assertFalse($table2->hasIndex(['fname', 'lname'])); } - public function testAddForeignKey() + public function testAddForeignKey(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -1735,7 +1731,7 @@ public function testAddForeignKey() $this->assertTrue($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'])); } - public function testAddForeignKeyForTableWithSignedPK() + public function testAddForeignKeyForTableWithSignedPK(): void { $refTable = new Table('ref_table', ['signed' => true], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -1749,7 +1745,7 @@ public function testAddForeignKeyForTableWithSignedPK() $this->assertTrue($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'])); } - public function testDropForeignKey() + public function testDropForeignKey(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -1764,7 +1760,7 @@ public function testDropForeignKey() $this->assertFalse($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'])); } - public function testDropForeignKeyWithMultipleColumns() + public function testDropForeignKeyWithMultipleColumns(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable @@ -1814,7 +1810,7 @@ public function testDropForeignKeyWithMultipleColumns() $this->assertFalse($this->adapter->hasForeignKey($table->getName(), ['ref_table_field1', 'ref_table_id'])); } - public function testDropForeignKeyWithIdenticalMultipleColumns() + public function testDropForeignKeyWithIdenticalMultipleColumns(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable @@ -1862,11 +1858,8 @@ public static function nonExistentForeignKeyColumnsProvider(): array ]; } - /** - * @param array $columns - */ #[DataProvider('nonExistentForeignKeyColumnsProvider')] - public function testDropForeignKeyByNonExistentKeyColumns(array $columns) + public function testDropForeignKeyByNonExistentKeyColumns(array $columns): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable @@ -1894,7 +1887,7 @@ public function testDropForeignKeyByNonExistentKeyColumns(array $columns) $this->adapter->dropForeignKey($table->getName(), $columns); } - public function testDropForeignKeyCaseInsensitivity() + public function testDropForeignKeyCaseInsensitivity(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->save(); @@ -1909,7 +1902,7 @@ public function testDropForeignKeyCaseInsensitivity() $this->assertFalse($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'])); } - public function testDropForeignKeyByName() + public function testDropForeignKeyByName(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->save(); @@ -1929,7 +1922,7 @@ public function testDropForeignKeyByName() $this->assertFalse($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'])); } - public function testDropForeignKeyForTableWithSignedPK() + public function testDropForeignKeyForTableWithSignedPK(): void { $refTable = new Table('ref_table', ['signed' => true], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -1944,7 +1937,7 @@ public function testDropForeignKeyForTableWithSignedPK() $this->assertFalse($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'])); } - public function testDropForeignKeyAsString() + public function testDropForeignKeyAsString(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -1960,7 +1953,7 @@ public function testDropForeignKeyAsString() } #[DataProvider('provideForeignKeysToCheck')] - public function testHasForeignKey($tableDef, $key, $exp) + public function testHasForeignKey(string $tableDef, string|array $key, bool $exp): void { $conn = $this->adapter->getConnection(); $conn->execute('CREATE TABLE other(a int, b int, c int, key(a), key(b), key(a,b), key(a,b,c));'); @@ -1968,7 +1961,7 @@ public function testHasForeignKey($tableDef, $key, $exp) $this->assertSame($exp, $this->adapter->hasForeignKey('t', $key)); } - public static function provideForeignKeysToCheck() + public static function provideForeignKeysToCheck(): array { return [ ['create table t(a int)', 'a', false], @@ -1994,7 +1987,7 @@ public static function provideForeignKeysToCheck() ]; } - public function testHasForeignKeyAsString() + public function testHasForeignKeyAsString(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -2009,7 +2002,7 @@ public function testHasForeignKeyAsString() $this->assertFalse($this->adapter->hasForeignKey($table->getName(), 'ref_table_id2')); } - public function testHasNamedForeignKey() + public function testHasNamedForeignKey(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -2032,7 +2025,7 @@ public function testHasNamedForeignKey() $this->assertFalse($this->adapter->hasForeignKey($table->getName(), [], 'my_constraint2')); } - public function testHasForeignKeyWithConstraintForTableWithSignedPK() + public function testHasForeignKeyWithConstraintForTableWithSignedPK(): void { $refTable = new Table('ref_table', ['signed' => true], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -2052,7 +2045,7 @@ public function testHasForeignKeyWithConstraintForTableWithSignedPK() $this->assertFalse($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'], 'my_constraint2')); } - public function testsHasForeignKeyWithSchemaDotTableName() + public function testsHasForeignKeyWithSchemaDotTableName(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -2067,13 +2060,13 @@ public function testsHasForeignKeyWithSchemaDotTableName() $this->assertFalse($this->adapter->hasForeignKey($this->config['database'] . '.' . $table->getName(), ['ref_table_id2'])); } - public function testHasDatabase() + public function testHasDatabase(): void { $this->assertFalse($this->adapter->hasDatabase('fake_database_name')); $this->assertTrue($this->adapter->hasDatabase($this->config['database'])); } - public function testDropDatabase() + public function testDropDatabase(): void { $this->assertFalse($this->adapter->hasDatabase('phinx_temp_database')); $this->adapter->createDatabase('phinx_temp_database'); @@ -2081,7 +2074,7 @@ public function testDropDatabase() $this->adapter->dropDatabase('phinx_temp_database'); } - public function testAddColumnWithComment() + public function testAddColumnWithComment(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('column1', 'string', ['comment' => $comment = 'Comments from "column1"']) @@ -2100,7 +2093,7 @@ public function testAddColumnWithComment() $this->assertEquals($comment, $columnWithComment['COLUMN_COMMENT'], "Didn't set column comment correctly"); } - public function testAddColumnEnum() + public function testAddColumnEnum(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -2134,7 +2127,7 @@ public function testAddColumnEnum() $this->assertEquals($comment, $columnWithComment['COLUMN_COMMENT'], "Didn't set column comment correctly"); } - public function testAddGeoSpatialColumns() + public function testAddGeoSpatialColumns(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -2145,7 +2138,7 @@ public function testAddGeoSpatialColumns() $this->assertEquals('geometry', $rows[1]['Type']); } - public function testHasColumn() + public function testHasColumn(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('column1', 'string') @@ -2155,7 +2148,7 @@ public function testHasColumn() $this->assertTrue($table->hasColumn('column1')); } - public function testHasColumnReservedName() + public function testHasColumnReservedName(): void { $tableQuoted = new Table('group', [], $this->adapter); $tableQuoted->addColumn('value', 'string') @@ -2165,7 +2158,7 @@ public function testHasColumnReservedName() $this->assertTrue($tableQuoted->hasColumn('value')); } - public function testBulkInsertData() + public function testBulkInsertData(): void { $data = [ [ @@ -2199,7 +2192,7 @@ public function testBulkInsertData() $this->assertEquals('test', $rows[2]['column3']); } - public function testBulkInsertLiteral() + public function testBulkInsertLiteral(): void { $data = [ [ @@ -2225,12 +2218,12 @@ public function testBulkInsertLiteral() $this->assertEquals('value1', $rows[0]['column1']); $this->assertEquals('value2', $rows[1]['column1']); $this->assertEquals('value3', $rows[2]['column1']); - $this->assertMatchesRegularExpression('/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/', $rows[0]['column2']); + $this->assertMatchesRegularExpression('/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $rows[0]['column2']); $this->assertEquals('2024-01-01 00:00:00', $rows[1]['column2']); $this->assertEquals('2025-01-01 00:00:00', $rows[2]['column2']); } - public function testInsertData() + public function testInsertData(): void { $data = [ [ @@ -2265,7 +2258,7 @@ public function testInsertData() $this->assertEquals('foo', $rows[2]['column3']); } - public function testInsertLiteral() + public function testInsertLiteral(): void { $data = [ [ @@ -2296,12 +2289,12 @@ public function testInsertLiteral() $this->assertEquals('test', $rows[0]['column2']); $this->assertEquals('test', $rows[1]['column2']); $this->assertEquals('foo', $rows[2]['column2']); - $this->assertMatchesRegularExpression('/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/', $rows[0]['column3']); + $this->assertMatchesRegularExpression('/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $rows[0]['column3']); $this->assertEquals('2024-01-01 00:00:00', $rows[1]['column3']); $this->assertEquals('2025-01-01 00:00:00', $rows[2]['column3']); } - public function testDumpCreateTable() + public function testDumpCreateTable(): void { $options = $this->adapter->getOptions(); $options['dryrun'] = true; @@ -2314,7 +2307,7 @@ public function testDumpCreateTable() ->addColumn('column3', 'string', ['default' => 'test', 'null' => false]) ->save(); - $actualOutput = join("\n", $this->out->messages()); + $actualOutput = implode("\n", $this->out->messages()); // MySQL version affects default collation (8.0.0+ uses utf8mb4_0900_ai_ci, older uses utf8mb4_general_ci) // MariaDB 11.8 uses: utf8mb4_uca1400_ai_ci $this->assertMatchesRegularExpression( @@ -2329,7 +2322,7 @@ public function testDumpCreateTable() * Then enables dry run mode and inserts a record. * Asserts that the insert statement is output and doesn't insert a record. */ - public function testDumpInsert() + public function testDumpInsert(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('string_col', 'string') @@ -2354,13 +2347,13 @@ public function testDumpInsert() INSERT INTO `table1` (`string_col`) VALUES (null); INSERT INTO `table1` (`int_col`) VALUES (23); OUTPUT; - $actualOutput = join("\n", $this->out->messages()); + $actualOutput = implode("\n", $this->out->messages()); // Add this to be LF - CR/LF systems independent $expectedOutput = preg_replace('~\R~u', '', $expectedOutput); $actualOutput = preg_replace('~\R~u', '', $actualOutput); - $this->assertStringContainsString($expectedOutput, trim($actualOutput), 'Passing the --dry-run option doesn\'t dump the insert to the output'); + $this->assertStringContainsString($expectedOutput, trim((string)$actualOutput), "Passing the --dry-run option doesn't dump the insert to the output"); $countQuery = $this->adapter->query('SELECT COUNT(*) FROM table1'); $this->assertTrue($countQuery->execute()); @@ -2373,7 +2366,7 @@ public function testDumpInsert() * Then enables dry run mode and inserts some records. * Asserts that output contains the insert statement and doesn't insert any record. */ - public function testDumpBulkinsert() + public function testDumpBulkinsert(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('string_col', 'string') @@ -2395,8 +2388,8 @@ public function testDumpBulkinsert() $expectedOutput = <<<'OUTPUT' INSERT INTO `table1` (`string_col`, `int_col`) VALUES ('test_data1', 23), (null, 42); OUTPUT; - $actualOutput = join("\n", $this->out->messages()); - $this->assertStringContainsString($expectedOutput, $actualOutput, 'Passing the --dry-run option doesn\'t dump the bulkinsert to the output'); + $actualOutput = implode("\n", $this->out->messages()); + $this->assertStringContainsString($expectedOutput, $actualOutput, "Passing the --dry-run option doesn't dump the bulkinsert to the output"); $countQuery = $this->adapter->query('SELECT COUNT(*) FROM table1'); $this->assertTrue($countQuery->execute()); @@ -2404,7 +2397,7 @@ public function testDumpBulkinsert() $this->assertEquals(0, $res[0]['COUNT(*)']); } - public function testDumpCreateTableAndThenInsert() + public function testDumpCreateTableAndThenInsert(): void { $options = $this->adapter->getOptions(); $options['dryrun'] = true; @@ -2422,7 +2415,7 @@ public function testDumpCreateTableAndThenInsert() 'column2' => 1, ])->save(); - $actualOutput = join("\n", $this->out->messages()); + $actualOutput = implode("\n", $this->out->messages()); // Add this to be LF - CR/LF systems independent $actualOutput = preg_replace('~\R~u', '', $actualOutput); // MySQL version affects default collation (8.0.0+ uses utf8mb4_0900_ai_ci, older uses utf8mb4_general_ci) @@ -2436,7 +2429,7 @@ public function testDumpCreateTableAndThenInsert() /** * Tests interaction with the query builder */ - public function testQueryBuilder() + public function testQueryBuilder(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('string_col', 'string') @@ -2475,7 +2468,7 @@ public function testQueryBuilder() $this->assertEquals(1, $stm->rowCount()); } - public function testQueryWithParams() + public function testQueryWithParams(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('string_col', 'string') @@ -2506,7 +2499,7 @@ public function testQueryWithParams() $this->assertEquals(3, $res[0]['c']); } - public static function geometryTypeProvider() + public static function geometryTypeProvider(): array { return [ [MysqlAdapter::TYPE_GEOMETRY, 'POINT(0 0)'], @@ -2516,12 +2509,8 @@ public static function geometryTypeProvider() ]; } - /** - * @param string $type - * @param string $geom - */ #[DataProvider('geometryTypeProvider')] - public function testGeometrySridSupport($type, $geom) + public function testGeometrySridSupport(string $type, string $geom): void { $this->adapter->connect(); if (!$this->usingMysql8()) { @@ -2533,19 +2522,15 @@ public function testGeometrySridSupport($type, $geom) ->addColumn('geom', $type, ['srid' => 4326]) ->save(); - $this->adapter->execute("INSERT INTO table1 (`geom`) VALUES (ST_GeomFromText('{$geom}', 4326))"); + $this->adapter->execute(sprintf("INSERT INTO table1 (`geom`) VALUES (ST_GeomFromText('%s', 4326))", $geom)); $rows = $this->adapter->fetchAll('SELECT ST_AsWKT(geom) as wkt, ST_SRID(geom) as srid FROM table1'); $this->assertCount(1, $rows); $this->assertSame($geom, $rows[0]['wkt']); $this->assertSame(4326, (int)$rows[0]['srid']); } - /** - * @param string $type - * @param string $geom - */ #[DataProvider('geometryTypeProvider')] - public function testGeometrySridThrowsInsertDifferentSrid($type, $geom) + public function testGeometrySridThrowsInsertDifferentSrid(string $type, string $geom): void { $this->adapter->connect(); if (!$this->usingMysql8()) { @@ -2559,10 +2544,10 @@ public function testGeometrySridThrowsInsertDifferentSrid($type, $geom) $this->expectException(PDOException::class); $this->expectExceptionMessage("SQLSTATE[HY000]: General error: 3643 The SRID of the geometry does not match the SRID of the column 'geom'. The SRID of the geometry is 4322, but the SRID of the column is 4326. Consider changing the SRID of the geometry or the SRID property of the column."); - $this->adapter->execute("INSERT INTO table1 (`geom`) VALUES (ST_GeomFromText('{$geom}', 4322))"); + $this->adapter->execute(sprintf("INSERT INTO table1 (`geom`) VALUES (ST_GeomFromText('%s', 4322))", $geom)); } - public static function defaultsCastAsExpressions() + public static function defaultsCastAsExpressions(): array { return [ [MysqlAdapter::TYPE_JSON, '{"a": true}'], @@ -2577,20 +2562,21 @@ public static function defaultsCastAsExpressions() /** * MySQL 8 added support for specifying defaults for the BLOB, TEXT, GEOMETRY, and JSON data types, * however requiring that they be wrapped in expressions. - * - * @param string $type - * @param string $default */ #[DataProvider('defaultsCastAsExpressions')] public function testDefaultsCastAsExpressionsForCertainTypes(string $type, string $default): void { if ( - $this->usingMariaDb() && in_array($type, [ - MysqlAdapter::TYPE_GEOMETRY, - MysqlAdapter::TYPE_POINT, - MysqlAdapter::TYPE_LINESTRING, - MysqlAdapter::TYPE_POLYGON, - ]) + $this->usingMariaDb() && in_array( + $type, + [ + MysqlAdapter::TYPE_GEOMETRY, + MysqlAdapter::TYPE_POINT, + MysqlAdapter::TYPE_LINESTRING, + MysqlAdapter::TYPE_POLYGON, + ], + true, + ) ) { $this->markTestSkipped('GIS is broken with MariaDB'); } @@ -2612,13 +2598,13 @@ public function testDefaultsCastAsExpressionsForCertainTypes(string $type, strin $actualDefault = $columns[0]->getDefault(); // Normalize quote handling - both MariaDB and MySQL 8.0.13+ may return defaults with quotes - if (str_starts_with($actualDefault, "'") && str_ends_with($actualDefault, "'")) { - $actualDefault = substr($actualDefault, 1, -1); + if (str_starts_with((string)$actualDefault, "'") && str_ends_with((string)$actualDefault, "'")) { + $actualDefault = substr((string)$actualDefault, 1, -1); } $this->assertSame($default, $actualDefault); } - public function testCreateTableWithPrecisionCurrentTimestamp() + public function testCreateTableWithPrecisionCurrentTimestamp(): void { $this->adapter->connect(); (new Table('exampleCurrentTimestamp3', ['id' => false], $this->adapter)) @@ -2637,7 +2623,7 @@ public function testCreateTableWithPrecisionCurrentTimestamp() $this->assertEqualsIgnoringCase('CURRENT_TIMESTAMP(3)', $colDef['COLUMN_DEFAULT']); } - public function testAddCheckConstraint() + public function testAddCheckConstraint(): void { $table = new Table('check_table', [], $this->adapter); $table->addColumn('price', 'decimal', ['precision' => 10, 'scale' => 2]) @@ -2649,7 +2635,7 @@ public function testAddCheckConstraint() $this->assertTrue($this->adapter->hasCheckConstraint('check_table', 'price_positive')); } - public function testAddCheckConstraintWithAutoGeneratedName() + public function testAddCheckConstraintWithAutoGeneratedName(): void { $table = new Table('check_table2', [], $this->adapter); $table->addColumn('age', 'integer') @@ -2669,7 +2655,7 @@ public function testAddCheckConstraintWithAutoGeneratedName() $this->assertStringContainsString($expected, $constraints[0]['name']); } - public function testHasCheckConstraint() + public function testHasCheckConstraint(): void { $table = new Table('check_table3', [], $this->adapter); $table->addColumn('quantity', 'integer') @@ -2683,7 +2669,7 @@ public function testHasCheckConstraint() $this->assertTrue($this->adapter->hasCheckConstraint('check_table3', 'quantity_positive')); } - public function testDropCheckConstraint() + public function testDropCheckConstraint(): void { $table = new Table('check_table4', [], $this->adapter); $table->addColumn('price', 'decimal', ['precision' => 10, 'scale' => 2]) @@ -2697,7 +2683,7 @@ public function testDropCheckConstraint() $this->assertFalse($this->adapter->hasCheckConstraint('check_table4', 'price_check')); } - public function testCheckConstraintWithComplexExpression() + public function testCheckConstraintWithComplexExpression(): void { $table = new Table('check_table5', [], $this->adapter); $table->addColumn('email', 'string', ['limit' => 255]) @@ -2714,7 +2700,7 @@ public function testCheckConstraintWithComplexExpression() // Verify the constraint is actually enforced $quotedTableName = $this->adapter->getConnection()->getDriver()->quoteIdentifier('check_table5'); $this->expectException(PDOException::class); - $this->adapter->execute("INSERT INTO {$quotedTableName} (email, status) VALUES ('test@example.com', 'invalid')"); + $this->adapter->execute(sprintf("INSERT INTO %s (email, status) VALUES ('test@example.com', 'invalid')", $quotedTableName)); } /** @@ -2727,7 +2713,7 @@ public function testCheckConstraintWithComplexExpression() * The 5.x branch uses CakePHP's database layer instead of phinx, * so we need to verify it handles scale=0 correctly. */ - public function testDecimalWithScaleZero() + public function testDecimalWithScaleZero(): void { // Create table with DECIMAL(65,0) $table = new Table('decimal_scale_zero_test', [], $this->adapter); @@ -2761,7 +2747,7 @@ public function testDecimalWithScaleZero() ); } - public function testInsertOrSkipWithDuplicates() + public function testInsertOrSkipWithDuplicates(): void { $table = new Table('users', [], $this->adapter); $table->addColumn('email', 'string', ['limit' => 255]) @@ -2784,7 +2770,7 @@ public function testInsertOrSkipWithDuplicates() $this->assertEquals('John', $rows[0]['name']); } - public function testInsertModeResetsAfterInsertOrSkip() + public function testInsertModeResetsAfterInsertOrSkip(): void { $table = new Table('users', [], $this->adapter); $table->addColumn('email', 'string', ['limit' => 255]) @@ -2804,7 +2790,7 @@ public function testInsertModeResetsAfterInsertOrSkip() ])->save(); } - public function testBulkinsertOrSkipWithDuplicates() + public function testBulkinsertOrSkipWithDuplicates(): void { $table = new Table('products', [], $this->adapter); $table->addColumn('sku', 'string', ['limit' => 50]) @@ -2831,7 +2817,7 @@ public function testBulkinsertOrSkipWithDuplicates() $this->assertEquals('30.00', $rows[2]['price']); } - public function testInsertOrSkipWithoutDuplicates() + public function testInsertOrSkipWithoutDuplicates(): void { $table = new Table('categories', [], $this->adapter); $table->addColumn('name', 'string') @@ -2847,7 +2833,7 @@ public function testInsertOrSkipWithoutDuplicates() $this->assertCount(2, $rows); } - public function testAddColumnWithAlgorithmInstant() + public function testAddColumnWithAlgorithmInstant(): void { $table = new Table('users', [], $this->adapter); $table->addColumn('email', 'string') @@ -2861,7 +2847,7 @@ public function testAddColumnWithAlgorithmInstant() $this->assertTrue($this->adapter->hasColumn('users', 'status')); } - public function testAddColumnWithAlgorithmAndLock() + public function testAddColumnWithAlgorithmAndLock(): void { $table = new Table('products', [], $this->adapter); $table->addColumn('name', 'string') @@ -2879,7 +2865,7 @@ public function testAddColumnWithAlgorithmAndLock() $this->assertTrue($this->adapter->hasColumn('products', 'price')); } - public function testChangeColumnWithAlgorithm() + public function testChangeColumnWithAlgorithm(): void { $table = new Table('items', [], $this->adapter); $table->addColumn('description', 'string', ['limit' => 100]) @@ -2899,7 +2885,7 @@ public function testChangeColumnWithAlgorithm() } } - public function testBatchedOperationsWithSameAlgorithm() + public function testBatchedOperationsWithSameAlgorithm(): void { $table = new Table('batch_test', [], $this->adapter); $table->addColumn('col1', 'string') @@ -2919,7 +2905,7 @@ public function testBatchedOperationsWithSameAlgorithm() $this->assertTrue($this->adapter->hasColumn('batch_test', 'col3')); } - public function testBatchedOperationsWithConflictingAlgorithmsThrowsException() + public function testBatchedOperationsWithConflictingAlgorithmsThrowsException(): void { $table = new Table('conflict_test', [], $this->adapter); $table->addColumn('col1', 'string') @@ -2939,7 +2925,7 @@ public function testBatchedOperationsWithConflictingAlgorithmsThrowsException() ->update(); } - public function testBatchedOperationsWithConflictingLocksThrowsException() + public function testBatchedOperationsWithConflictingLocksThrowsException(): void { $table = new Table('lock_conflict_test', [], $this->adapter); $table->addColumn('col1', 'string') @@ -2961,7 +2947,7 @@ public function testBatchedOperationsWithConflictingLocksThrowsException() ->update(); } - public function testInvalidAlgorithmThrowsException() + public function testInvalidAlgorithmThrowsException(): void { $table = new Table('invalid_algo', [], $this->adapter); $table->addColumn('col1', 'string') @@ -2975,7 +2961,7 @@ public function testInvalidAlgorithmThrowsException() ])->update(); } - public function testInvalidLockThrowsException() + public function testInvalidLockThrowsException(): void { $table = new Table('invalid_lock', [], $this->adapter); $table->addColumn('col1', 'string') @@ -2989,7 +2975,7 @@ public function testInvalidLockThrowsException() ])->update(); } - public function testAlgorithmInstantWithExplicitLockThrowsException() + public function testAlgorithmInstantWithExplicitLockThrowsException(): void { $table = new Table('instant_lock_test', [], $this->adapter); $table->addColumn('col1', 'string') @@ -3005,7 +2991,7 @@ public function testAlgorithmInstantWithExplicitLockThrowsException() ])->update(); } - public function testAlgorithmConstantsAreDefined() + public function testAlgorithmConstantsAreDefined(): void { $this->assertEquals('DEFAULT', MysqlAdapter::ALGORITHM_DEFAULT); $this->assertEquals('INSTANT', MysqlAdapter::ALGORITHM_INSTANT); @@ -3013,7 +2999,7 @@ public function testAlgorithmConstantsAreDefined() $this->assertEquals('COPY', MysqlAdapter::ALGORITHM_COPY); } - public function testLockConstantsAreDefined() + public function testLockConstantsAreDefined(): void { $this->assertEquals('DEFAULT', MysqlAdapter::LOCK_DEFAULT); $this->assertEquals('NONE', MysqlAdapter::LOCK_NONE); @@ -3021,7 +3007,7 @@ public function testLockConstantsAreDefined() $this->assertEquals('EXCLUSIVE', MysqlAdapter::LOCK_EXCLUSIVE); } - public function testAlgorithmWithMixedCase() + public function testAlgorithmWithMixedCase(): void { $table = new Table('mixed_case', [], $this->adapter); $table->addColumn('col1', 'string') @@ -3037,7 +3023,7 @@ public function testAlgorithmWithMixedCase() $this->assertTrue($this->adapter->hasColumn('mixed_case', 'col2')); } - public function testInsertOrUpdateWithDuplicates() + public function testInsertOrUpdateWithDuplicates(): void { $table = new Table('currencies', [], $this->adapter); $table->addColumn('code', 'string', ['limit' => 3]) @@ -3070,7 +3056,7 @@ public function testInsertOrUpdateWithDuplicates() $this->assertEquals('1.0500', $rows[2]['rate']); // USD updated } - public function testInsertOrUpdateWithMultipleUpdateColumns() + public function testInsertOrUpdateWithMultipleUpdateColumns(): void { $table = new Table('products', [], $this->adapter); $table->addColumn('sku', 'string', ['limit' => 50]) @@ -3095,7 +3081,7 @@ public function testInsertOrUpdateWithMultipleUpdateColumns() $this->assertEquals(50, $rows[0]['stock']); } - public function testInsertOrUpdateModeResetsAfterSave() + public function testInsertOrUpdateModeResetsAfterSave(): void { $table = new Table('items', [], $this->adapter); $table->addColumn('code', 'string', ['limit' => 10]) @@ -3115,7 +3101,7 @@ public function testInsertOrUpdateModeResetsAfterSave() ])->save(); } - public function testInsertOrUpdateWithEmptyConflictColumnsDoesNotWarn() + public function testInsertOrUpdateWithEmptyConflictColumnsDoesNotWarn(): void { $table = new Table('currencies', [], $this->adapter); $table->addColumn('code', 'string', ['limit' => 3]) @@ -3124,7 +3110,7 @@ public function testInsertOrUpdateWithEmptyConflictColumnsDoesNotWarn() ->create(); $warning = null; - set_error_handler(function (int $errno, string $errstr) use (&$warning) { + set_error_handler(function (int $errno, string $errstr) use (&$warning): true { $warning = $errstr; return true; @@ -3147,7 +3133,7 @@ public function testInsertOrUpdateWithEmptyConflictColumnsDoesNotWarn() $this->assertEquals('1.0000', $rows[1]['rate']); } - public function testCreateTableWithRangeColumnsPartitioning() + public function testCreateTableWithRangeColumnsPartitioning(): void { // MySQL requires RANGE COLUMNS for DATE columns $table = new Table('partitioned_orders', ['id' => false, 'primary_key' => ['id', 'order_date']], $this->adapter); @@ -3165,7 +3151,7 @@ public function testCreateTableWithRangeColumnsPartitioning() $this->assertTrue($this->adapter->hasColumn('partitioned_orders', 'order_date')); } - public function testCreateTableWithListColumnsPartitioning() + public function testCreateTableWithListColumnsPartitioning(): void { // MySQL requires LIST COLUMNS for STRING columns $table = new Table('partitioned_customers', ['id' => false, 'primary_key' => ['id', 'region']], $this->adapter); @@ -3180,7 +3166,7 @@ public function testCreateTableWithListColumnsPartitioning() $this->assertTrue($this->adapter->hasTable('partitioned_customers')); } - public function testCreateTableWithHashPartitioning() + public function testCreateTableWithHashPartitioning(): void { // MySQL requires partition column in primary key $table = new Table('partitioned_sessions', ['id' => false, 'primary_key' => ['id', 'user_id']], $this->adapter); @@ -3193,7 +3179,7 @@ public function testCreateTableWithHashPartitioning() $this->assertTrue($this->adapter->hasTable('partitioned_sessions')); } - public function testCreateTableWithKeyPartitioning() + public function testCreateTableWithKeyPartitioning(): void { $table = new Table('partitioned_cache', ['id' => false, 'primary_key' => ['cache_key']], $this->adapter); $table->addColumn('cache_key', 'string', ['limit' => 255]) @@ -3204,7 +3190,7 @@ public function testCreateTableWithKeyPartitioning() $this->assertTrue($this->adapter->hasTable('partitioned_cache')); } - public function testCreateTableWithRangePartitioningByInteger() + public function testCreateTableWithRangePartitioningByInteger(): void { $table = new Table('partitioned_logs', ['id' => false, 'primary_key' => ['id']], $this->adapter); $table->addColumn('id', 'biginteger') @@ -3218,7 +3204,7 @@ public function testCreateTableWithRangePartitioningByInteger() $this->assertTrue($this->adapter->hasTable('partitioned_logs')); } - public function testCreateTableWithExpressionPartitioning() + public function testCreateTableWithExpressionPartitioning(): void { $table = new Table('partitioned_events', ['id' => false, 'primary_key' => ['id', 'created_at']], $this->adapter); $table->addColumn('id', 'integer') @@ -3232,7 +3218,7 @@ public function testCreateTableWithExpressionPartitioning() $this->assertTrue($this->adapter->hasTable('partitioned_events')); } - public function testAddSinglePartitionToExistingTable() + public function testAddSinglePartitionToExistingTable(): void { // Create a partitioned table with room to add more partitions $table = new Table('partitioned_orders', ['id' => false, 'primary_key' => ['id', 'order_date']], $this->adapter); @@ -3260,7 +3246,7 @@ public function testAddSinglePartitionToExistingTable() $this->assertCount(1, $rows); } - public function testAddMultiplePartitionsToExistingTable() + public function testAddMultiplePartitionsToExistingTable(): void { // Create a partitioned table with room to add more partitions $table = new Table('partitioned_sales', ['id' => false, 'primary_key' => ['id', 'sale_date']], $this->adapter); @@ -3297,7 +3283,7 @@ public function testAddMultiplePartitionsToExistingTable() $this->assertCount(3, $rows); } - public function testDropSinglePartitionFromExistingTable() + public function testDropSinglePartitionFromExistingTable(): void { // Create a partitioned table with multiple partitions $table = new Table('partitioned_logs', ['id' => false, 'primary_key' => ['id']], $this->adapter); @@ -3334,7 +3320,7 @@ public function testDropSinglePartitionFromExistingTable() $this->assertCount(1, $rows); } - public function testDropMultiplePartitionsFromExistingTable() + public function testDropMultiplePartitionsFromExistingTable(): void { // Create a partitioned table with multiple partitions $table = new Table('partitioned_archive', ['id' => false, 'primary_key' => ['id']], $this->adapter); @@ -3377,7 +3363,7 @@ public function testDropMultiplePartitionsFromExistingTable() $this->assertCount(1, $rows); } - public function testAddMultipleListPartitionsToExistingTable() + public function testAddMultipleListPartitionsToExistingTable(): void { // Create a LIST partitioned table $table = new Table('partitioned_regions', ['id' => false, 'primary_key' => ['id', 'region_id']], $this->adapter); @@ -3409,7 +3395,7 @@ public function testAddMultipleListPartitionsToExistingTable() $this->assertCount(2, $rows); } - public function testAddPartitionsWithMaxvalue() + public function testAddPartitionsWithMaxvalue(): void { // Create a partitioned table without MAXVALUE partition $table = new Table('partitioned_data', ['id' => false, 'primary_key' => ['id']], $this->adapter); diff --git a/tests/TestCase/Db/Adapter/PostgresAdapterTest.php b/tests/TestCase/Db/Adapter/PostgresAdapterTest.php index 58c03871e..22ce3bf91 100644 --- a/tests/TestCase/Db/Adapter/PostgresAdapterTest.php +++ b/tests/TestCase/Db/Adapter/PostgresAdapterTest.php @@ -27,13 +27,12 @@ class PostgresAdapterTest extends TestCase { - /** - * @var \Migrations\Db\Adapter\PostgresAdapter - */ - private $adapter; + private PostgresAdapter $adapter; private array $config; + private StubConsoleOutput $out; + private ConsoleIo $io; /** @@ -41,7 +40,7 @@ class PostgresAdapterTest extends TestCase * * @return bool */ - private static function isPostgresAvailable() + private function isPostgresAvailable() { static $available; @@ -67,7 +66,7 @@ protected function setUp(): void 'database' => $config['database'], ]; - if (!self::isPostgresAvailable()) { + if (!$this->isPostgresAvailable()) { $this->markTestSkipped('Postgres is not available. Please install php-pdo-pgsql or equivalent package.'); } @@ -110,17 +109,17 @@ private function usingPostgres10(): bool return version_compare($version, '10.0.0', '>='); } - public function testAdapterType() + public function testAdapterType(): void { $this->assertEquals('pgsql', $this->adapter->getAdapterType()); } - public function testConnection() + public function testConnection(): void { $this->assertInstanceOf(Connection::class, $this->adapter->getConnection()); } - public function testCreatingTheSchemaTableOnConnect() + public function testCreatingTheSchemaTableOnConnect(): void { $this->adapter->connect(); $this->assertTrue($this->adapter->hasTable($this->adapter->getSchemaTableName())); @@ -131,21 +130,21 @@ public function testCreatingTheSchemaTableOnConnect() $this->assertTrue($this->adapter->hasTable($this->adapter->getSchemaTableName())); } - public function testSchemaTableIsCreatedWithPrimaryKey() + public function testSchemaTableIsCreatedWithPrimaryKey(): void { $this->adapter->connect(); new Table($this->adapter->getSchemaTableName(), [], $this->adapter); $this->assertTrue($this->adapter->hasIndex($this->adapter->getSchemaTableName(), ['version'])); } - public function testQuoteSchemaName() + public function testQuoteSchemaName(): void { $this->assertEquals('"schema"', $this->adapter->quoteSchemaName('schema')); // No . is supported in schema name. $this->assertEquals('"schema"."schema"', $this->adapter->quoteSchemaName('schema.schema')); } - public function testGetGlobalSchemaName() + public function testGetGlobalSchemaName(): void { $config = ConnectionManager::getConfig('test'); $config['schema'] = 'test_schema'; @@ -169,20 +168,20 @@ public function testGetGlobalSchemaName() ConnectionManager::drop('test-schema'); } - public function testQuoteTableName() + public function testQuoteTableName(): void { $this->assertEquals('"public"."table"', $this->adapter->quoteTableName('table')); $this->assertEquals('"table"."table"', $this->adapter->quoteTableName('table.table')); } - public function testQuoteColumnName() + public function testQuoteColumnName(): void { $this->assertEquals('"string"', $this->adapter->quoteColumnName('string')); // No . is supported in column name. $this->assertEquals('"string"."string"', $this->adapter->quoteColumnName('string.string')); } - public function testCreateTable() + public function testCreateTable(): void { $table = new Table('ntable', [], $this->adapter); $table->addColumn('realname', 'string') @@ -195,7 +194,7 @@ public function testCreateTable() $this->assertFalse($this->adapter->hasColumn('ntable', 'address')); } - public function testCreateTableWithSchema() + public function testCreateTableWithSchema(): void { $this->adapter->createSchema('nschema'); @@ -212,7 +211,7 @@ public function testCreateTableWithSchema() $this->adapter->dropSchema('nschema'); } - public function testCreateTableCustomIdColumn() + public function testCreateTableCustomIdColumn(): void { $table = new Table('ntable', ['id' => 'custom_id'], $this->adapter); $table->addColumn('realname', 'string') @@ -225,7 +224,7 @@ public function testCreateTableCustomIdColumn() $this->assertFalse($this->adapter->hasColumn('ntable', 'address')); } - public function testCreateTableWithNoPrimaryKey() + public function testCreateTableWithNoPrimaryKey(): void { $options = [ 'id' => false, @@ -236,7 +235,7 @@ public function testCreateTableWithNoPrimaryKey() $this->assertFalse($this->adapter->hasColumn('atable', 'id')); } - public function testCreateTableWithConflictingPrimaryKeys() + public function testCreateTableWithConflictingPrimaryKeys(): void { $options = [ 'primary_key' => 'user_id', @@ -248,7 +247,7 @@ public function testCreateTableWithConflictingPrimaryKeys() $table->addColumn('user_id', 'integer')->save(); } - public function testCreateTableWithPrimaryKeySetToImplicitId() + public function testCreateTableWithPrimaryKeySetToImplicitId(): void { $options = [ 'primary_key' => 'id', @@ -260,7 +259,7 @@ public function testCreateTableWithPrimaryKeySetToImplicitId() $this->assertTrue($this->adapter->hasColumn('ztable', 'user_id')); } - public function testCreateTableWithPrimaryKeyArraySetToImplicitId() + public function testCreateTableWithPrimaryKeyArraySetToImplicitId(): void { $options = [ 'primary_key' => ['id'], @@ -272,7 +271,7 @@ public function testCreateTableWithPrimaryKeyArraySetToImplicitId() $this->assertTrue($this->adapter->hasColumn('ztable', 'user_id')); } - public function testCreateTableWithMultiplePrimaryKeyArraySetToImplicitId() + public function testCreateTableWithMultiplePrimaryKeyArraySetToImplicitId(): void { $options = [ 'primary_key' => ['id', 'user_id'], @@ -283,7 +282,7 @@ public function testCreateTableWithMultiplePrimaryKeyArraySetToImplicitId() $table->addColumn('user_id', 'integer')->save(); } - public function testCreateTableWithMultiplePrimaryKeys() + public function testCreateTableWithMultiplePrimaryKeys(): void { $options = [ 'id' => false, @@ -298,7 +297,7 @@ public function testCreateTableWithMultiplePrimaryKeys() $this->assertFalse($this->adapter->hasIndex('table1', ['tag_id', 'user_email'])); } - public function testCreateTableWithMultiplePrimaryKeysWithSchema() + public function testCreateTableWithMultiplePrimaryKeysWithSchema(): void { $this->adapter->createSchema('schema1'); @@ -320,7 +319,7 @@ public function testCreateTableWithMultiplePrimaryKeysWithSchema() /** * @return void */ - public function testCreateTableWithPrimaryKeyAsUuid() + public function testCreateTableWithPrimaryKeyAsUuid(): void { $options = [ 'id' => false, @@ -337,7 +336,7 @@ public function testCreateTableWithPrimaryKeyAsUuid() /** * @return void */ - public function testCreateTableWithPrimaryKeyAsBinaryUuid() + public function testCreateTableWithPrimaryKeyAsBinaryUuid(): void { $options = [ 'id' => false, @@ -354,7 +353,7 @@ public function testCreateTableWithPrimaryKeyAsBinaryUuid() /** * @return void */ - public function testCreateTableWithPrimaryKeyAsNativeUuid() + public function testCreateTableWithPrimaryKeyAsNativeUuid(): void { $options = [ 'id' => false, @@ -368,7 +367,7 @@ public function testCreateTableWithPrimaryKeyAsNativeUuid() $this->assertTrue($this->adapter->hasColumn('ztable', 'user_id')); } - public function testCreateTableWithMultipleIndexes() + public function testCreateTableWithMultipleIndexes(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -382,7 +381,7 @@ public function testCreateTableWithMultipleIndexes() $this->assertFalse($this->adapter->hasIndex('table1', ['email', 'user_name'])); } - public function testCreateTableWithUniqueIndexes() + public function testCreateTableWithUniqueIndexes(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -392,7 +391,7 @@ public function testCreateTableWithUniqueIndexes() $this->assertFalse($this->adapter->hasIndex('table1', ['email', 'user_email'])); } - public function testCreateTableWithNamedIndexes() + public function testCreateTableWithNamedIndexes(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -465,7 +464,7 @@ public function testCreateTableIndexWithWhere(): void $this->assertStringContainsString('("email") WHERE is_verified = true', $indexQuery); } - public function testAddPrimaryKey() + public function testAddPrimaryKey(): void { $table = new Table('table1', ['id' => false], $this->adapter); $table @@ -479,7 +478,7 @@ public function testAddPrimaryKey() $this->assertTrue($this->adapter->hasPrimaryKey('table1', ['column1'])); } - public function testChangePrimaryKey() + public function testChangePrimaryKey(): void { $table = new Table('table1', ['id' => false, 'primary_key' => 'column1'], $this->adapter); $table @@ -496,7 +495,7 @@ public function testChangePrimaryKey() $this->assertTrue($this->adapter->hasPrimaryKey('table1', ['column2', 'column3'])); } - public function testDropPrimaryKey() + public function testDropPrimaryKey(): void { $table = new Table('table1', ['id' => false, 'primary_key' => 'column1'], $this->adapter); $table @@ -510,7 +509,7 @@ public function testDropPrimaryKey() $this->assertFalse($this->adapter->hasPrimaryKey('table1', ['column1'])); } - public function testAddComment() + public function testAddComment(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -531,7 +530,7 @@ public function testAddComment() $this->assertEquals('comment1', $rows[0]['description']); } - public function testChangeComment() + public function testChangeComment(): void { $table = new Table('table1', ['comment' => 'comment1'], $this->adapter); $table->save(); @@ -552,7 +551,7 @@ public function testChangeComment() $this->assertEquals('comment2', $rows[0]['description']); } - public function testDropComment() + public function testDropComment(): void { $table = new Table('table1', ['comment' => 'comment1'], $this->adapter); $table->save(); @@ -573,7 +572,7 @@ public function testDropComment() $this->assertEmpty($rows); } - public function testRenameTable() + public function testRenameTable(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -585,7 +584,7 @@ public function testRenameTable() $this->assertTrue($this->adapter->hasTable('table2')); } - public function testRenameTableWithSchema() + public function testRenameTableWithSchema(): void { $this->adapter->createSchema('schema1'); @@ -600,7 +599,7 @@ public function testRenameTableWithSchema() $this->adapter->dropSchema('schema1'); } - public function testAddColumn() + public function testAddColumn(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -610,7 +609,7 @@ public function testAddColumn() $this->assertTrue($table->hasColumn('email')); } - public function testAddColumnWithDefaultValue() + public function testAddColumnWithDefaultValue(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -624,7 +623,7 @@ public function testAddColumnWithDefaultValue() } } - public function testAddColumnWithDefaultZero() + public function testAddColumnWithDefaultZero(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -639,13 +638,14 @@ public function testAddColumnWithDefaultZero() } } - public function testAddColumnWithAutoIdentity() + public function testAddColumnWithAutoIdentity(): void { if (!$this->usingPostgres10()) { $this->markTestSkipped('Test Skipped because of PostgreSQL version is < 10.0'); } $table = new Table('table1', [], $this->adapter); $table->save(); + $columns = $this->adapter->getColumns('table1'); foreach ($columns as $column) { if ($column->getName() === 'id') { @@ -658,7 +658,7 @@ public function testAddColumnWithAutoIdentity() /** * Test that shims from PHINX_TYPE_JSONB to 'json' type work. */ - public function testAddColumnJsonbCompat() + public function testAddColumnJsonbCompat(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -678,15 +678,16 @@ public static function providerAddColumnIdentity(): array } #[DataProvider('providerAddColumnIdentity')] - public function testAddColumnIdentity($generated, $addToColumn) + public function testAddColumnIdentity(string $generated, bool $addToColumn): void { if (!$this->usingPostgres10()) { $this->markTestSkipped('Test Skipped because of PostgreSQL version is < 10.0'); } $table = new Table('table1', ['id' => false], $this->adapter); $table->save(); + $options = ['identity' => true]; - if ($addToColumn !== false) { + if ($addToColumn) { $options['generated'] = $generated; } $table->addColumn('id', 'integer', $options) @@ -700,7 +701,7 @@ public function testAddColumnIdentity($generated, $addToColumn) } } - public function testAddColumnWithDefaultBoolean() + public function testAddColumnWithDefaultBoolean(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -724,7 +725,7 @@ public function testAddColumnWithDefaultBoolean() } } - public function testAddColumnWithBooleanIgnoreLimitCastDefault() + public function testAddColumnWithBooleanIgnoreLimitCastDefault(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -758,7 +759,7 @@ public function testAddColumnWithBooleanIgnoreLimitCastDefault() $this->assertNull($column->getLimit()); } - public function testAddColumnWithComment() + public function testAddColumnWithComment(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -788,7 +789,7 @@ public function testAddColumnWithComment() ); } - public function testAddStringWithLimit() + public function testAddStringWithLimit(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -807,7 +808,7 @@ public function testAddStringWithLimit() } } - public function testAddDecimalWithPrecisionAndScale() + public function testAddDecimalWithPrecisionAndScale(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -829,7 +830,7 @@ public function testAddDecimalWithPrecisionAndScale() } } - public function testAddTimestampWithPrecision() + public function testAddTimestampWithPrecision(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -853,7 +854,7 @@ public function testAddTimestampWithPrecision() } } - public function testRenameColumn() + public function testRenameColumn(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -865,7 +866,7 @@ public function testRenameColumn() $this->assertTrue($this->adapter->hasColumn('t', 'column2')); } - public function testRenameColumnIsCaseSensitive() + public function testRenameColumnIsCaseSensitive(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('columnOne', 'string') @@ -877,7 +878,7 @@ public function testRenameColumnIsCaseSensitive() $this->assertTrue($this->adapter->hasColumn('t', 'columnTwo')); } - public function testRenamingANonExistentColumn() + public function testRenamingANonExistentColumn(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -890,13 +891,13 @@ public function testRenamingANonExistentColumn() $this->assertInstanceOf( 'InvalidArgumentException', $e, - 'Expected exception of type InvalidArgumentException, got ' . get_class($e), + 'Expected exception of type InvalidArgumentException, got ' . $e::class, ); $this->assertEquals('The specified column does not exist: column2', $e->getMessage()); } } - public function testChangeColumn() + public function testChangeColumn(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -922,7 +923,7 @@ public static function providerChangeColumnIdentity(): array } #[DataProvider('providerChangeColumnIdentity')] - public function testChangeColumnIdentity($generated) + public function testChangeColumnIdentity(string $generated): void { if (!$this->usingPostgres10()) { $this->markTestSkipped('Test Skipped because of PostgreSQL version is < 10.0'); @@ -933,6 +934,7 @@ public function testChangeColumnIdentity($generated) $table->changeColumn('column1', 'integer', ['identity' => true, 'generated' => PostgresAdapter::GENERATED_ALWAYS]); $table->save(); + $columns = $this->adapter->getColumns('table1'); foreach ($columns as $column) { if ($column->getName() === 'column1') { @@ -942,7 +944,7 @@ public function testChangeColumnIdentity($generated) } } - public function testChangeColumnDropIdentity() + public function testChangeColumnDropIdentity(): void { if (!$this->usingPostgres10()) { $this->markTestSkipped('Test Skipped because of PostgreSQL version is < 10.0'); @@ -951,6 +953,7 @@ public function testChangeColumnDropIdentity() $table->save(); $table->changeColumn('id', 'integer', ['identity' => false]); $table->save(); + $columns = $this->adapter->getColumns('table1'); foreach ($columns as $column) { if ($column->getName() === 'id') { @@ -959,7 +962,7 @@ public function testChangeColumnDropIdentity() } } - public function testChangeColumnChangeIdentity() + public function testChangeColumnChangeIdentity(): void { if (!$this->usingPostgres10()) { $this->markTestSkipped('Test Skipped because of PostgreSQL version is < 10.0'); @@ -968,6 +971,7 @@ public function testChangeColumnChangeIdentity() $table->save(); $table->changeColumn('id', 'integer', ['identity' => true, 'generated' => PostgresAdapter::GENERATED_BY_DEFAULT]); $table->save(); + $columns = $this->adapter->getColumns('table1'); foreach ($columns as $column) { if ($column->getName() === 'id') { @@ -977,7 +981,7 @@ public function testChangeColumnChangeIdentity() } } - public static function integersProvider() + public static function integersProvider(): array { return [ ['smallinteger', 32767], @@ -987,7 +991,7 @@ public static function integersProvider() } #[DataProvider('integersProvider')] - public function testChangeColumnFromTextToInteger($type, $value) + public function testChangeColumnFromTextToInteger(string $type, int $value): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'text') @@ -1002,7 +1006,7 @@ public function testChangeColumnFromTextToInteger($type, $value) $this->assertSame($value, $row['column1']); } - public function testChangeBooleanOptions() + public function testChangeBooleanOptions(): void { $table = new Table('t', ['id' => false], $this->adapter); $table->addColumn('my_bool', 'boolean', ['default' => true, 'null' => true]) @@ -1020,12 +1024,12 @@ public function testChangeBooleanOptions() $rows = $this->adapter->fetchAll('SELECT * FROM t'); $this->assertCount(3, $rows); - $this->assertSame([true, false, null], array_map(function ($row) { + $this->assertSame([true, false, null], array_map(function (array $row) { return $row['my_bool']; }, $rows)); } - public function testChangeColumnFromIntegerToBoolean() + public function testChangeColumnFromIntegerToBoolean(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'integer', ['default' => 0]) @@ -1041,7 +1045,7 @@ public function testChangeColumnFromIntegerToBoolean() } } - public function testChangeColumnCharToUuid() + public function testChangeColumnCharToUuid(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'char', ['default' => null, 'limit' => 36]) @@ -1059,7 +1063,7 @@ public function testChangeColumnCharToUuid() } } - public function testChangeColumnCharToNativeUuid() + public function testChangeColumnCharToNativeUuid(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'char', ['default' => null, 'limit' => 36]) @@ -1077,7 +1081,7 @@ public function testChangeColumnCharToNativeUuid() } } - public function testChangeColumnWithDefault() + public function testChangeColumnWithDefault(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -1100,7 +1104,7 @@ public function testChangeColumnWithDefault() } } - public function testChangeColumnWithDropDefault() + public function testChangeColumnWithDropDefault(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['default' => 'Test']) @@ -1127,7 +1131,7 @@ public function testChangeColumnWithDropDefault() } } - public function testDropColumn() + public function testDropColumn(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -1138,7 +1142,7 @@ public function testDropColumn() $this->assertFalse($this->adapter->hasColumn('t', 'column1')); } - public static function columnsProvider() + public static function columnsProvider(): array { return [ ['column1', 'string', []], @@ -1161,7 +1165,7 @@ public static function columnsProvider() } #[DataProvider('columnsProvider')] - public function testGetColumns($colName, $type, $options, $actualType = null) + public function testGetColumns(string $colName, string $type, array $options, ?string $actualType = null): void { $table = new Table('t', [], $this->adapter); $table->addColumn($colName, $type, $options)->save(); @@ -1182,7 +1186,7 @@ public function testGetColumns($colName, $type, $options, $actualType = null) } #[DataProvider('columnsProvider')] - public function testGetColumnsWithSchema($colName, $type, $options, $actualType = null) + public function testGetColumnsWithSchema(string $colName, string $type, array $options, ?string $actualType = null): void { $this->adapter->createSchema('tschema'); @@ -1206,7 +1210,7 @@ public function testGetColumnsWithSchema($colName, $type, $options, $actualType $this->adapter->dropSchema('tschema'); } - public function testAddIndex() + public function testAddIndex(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -1217,7 +1221,7 @@ public function testAddIndex() $this->assertTrue($table->hasIndex('email')); } - public function testAddIndexWithSort() + public function testAddIndexWithSort(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -1259,7 +1263,7 @@ public function testAddIndexWithSort() $this->assertEquals($emailOrder['sort_order'], 'ASC'); } - public function testAddIndexWithIncludeColumns() + public function testAddIndexWithIncludeColumns(): void { if (!version_compare($this->adapter->fetchAll('SHOW server_version;')[0]['server_version'], '11.0.0', '>=')) { $this->markTestSkipped('Cannot test index include collumns (non-key columns) on postgresql versions less than 11'); @@ -1312,7 +1316,7 @@ public function testAddIndexWithIncludeColumns() $this->assertEquals($indexColumn['index_column'], 'INCLUDED'); } - public function testAddIndexWithSchema() + public function testAddIndexWithSchema(): void { $this->adapter->createSchema('schema1'); @@ -1327,7 +1331,7 @@ public function testAddIndexWithSchema() $this->adapter->dropSchema('schema1'); } - public function testAddIndexWithNameWithSchema() + public function testAddIndexWithNameWithSchema(): void { $this->adapter->createSchema('schema1'); @@ -1342,7 +1346,7 @@ public function testAddIndexWithNameWithSchema() $this->adapter->dropSchema('schema1'); } - public function testAddIndexIsCaseSensitive() + public function testAddIndexIsCaseSensitive(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('theEmail', 'string') @@ -1353,7 +1357,7 @@ public function testAddIndexIsCaseSensitive() $this->assertTrue($table->hasIndex('theEmail')); } - public function testDropIndex() + public function testDropIndex(): void { // single column index $table = new Table('table1', [], $this->adapter); @@ -1394,7 +1398,7 @@ public function testDropIndex() $this->assertFalse($table4->hasIndex(['fname', 'lname'])); } - public function testDropIndexWithSchema() + public function testDropIndexWithSchema(): void { $this->adapter->createSchema('schema1'); @@ -1439,7 +1443,7 @@ public function testDropIndexWithSchema() $this->adapter->dropSchema('schema1'); } - public function testDropIndexByName() + public function testDropIndexByName(): void { // single column index $table = new Table('table1', [], $this->adapter); @@ -1464,7 +1468,7 @@ public function testDropIndexByName() $this->assertFalse($table2->hasIndex(['fname', 'lname'])); } - public function testDropIndexByNameWithSchema() + public function testDropIndexByNameWithSchema(): void { $this->adapter->createSchema('schema1'); @@ -1493,7 +1497,7 @@ public function testDropIndexByNameWithSchema() $this->adapter->dropSchema('schema1'); } - public function testAddForeignKey() + public function testAddForeignKey(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -1507,7 +1511,7 @@ public function testAddForeignKey() $this->assertTrue($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'])); } - public function testAddForeignKeyWithSchema() + public function testAddForeignKeyWithSchema(): void { $this->adapter->createSchema('schema1'); $this->adapter->createSchema('schema2'); @@ -1527,7 +1531,7 @@ public function testAddForeignKeyWithSchema() $this->adapter->dropSchema('schema2'); } - public function testAddForeignKeyDeferrable() + public function testAddForeignKeyDeferrable(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -1548,7 +1552,7 @@ public function testAddForeignKeyDeferrable() $this->assertTrue($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'])); } - public function testDropForeignKey() + public function testDropForeignKey(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -1563,7 +1567,7 @@ public function testDropForeignKey() $this->assertFalse($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'])); } - public function testDropForeignKeyWithMultipleColumns() + public function testDropForeignKeyWithMultipleColumns(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable @@ -1614,7 +1618,7 @@ public function testDropForeignKeyWithMultipleColumns() $this->assertFalse($this->adapter->hasForeignKey($table->getName(), ['ref_table_field1', 'ref_table_id'])); } - public function testDropForeignKeyWithIdenticalMultipleColumns() + public function testDropForeignKeyWithIdenticalMultipleColumns(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable @@ -1662,11 +1666,8 @@ public static function nonExistentForeignKeyColumnsProvider(): array ]; } - /** - * @param array $columns - */ #[DataProvider('nonExistentForeignKeyColumnsProvider')] - public function testDropForeignKeyByNonExistentKeyColumns(array $columns) + public function testDropForeignKeyByNonExistentKeyColumns(array $columns): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable @@ -1694,7 +1695,7 @@ public function testDropForeignKeyByNonExistentKeyColumns(array $columns) $this->adapter->dropForeignKey($table->getName(), $columns); } - public function testDropForeignKeyCaseSensitivity() + public function testDropForeignKeyCaseSensitivity(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->save(); @@ -1716,7 +1717,7 @@ public function testDropForeignKeyCaseSensitivity() $this->adapter->dropForeignKey($table->getName(), ['ref_table_id']); } - public function testDropForeignKeyByName() + public function testDropForeignKeyByName(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->save(); @@ -1737,7 +1738,7 @@ public function testDropForeignKeyByName() } #[DataProvider('provideForeignKeysToCheck')] - public function testHasForeignKey($tableDef, $key, $exp) + public function testHasForeignKey(string $tableDef, string|array $key, bool $exp): void { $conn = $this->adapter->getConnection(); $conn->execute('CREATE TABLE other(a int, b int, c int, unique(a), unique(b), unique(a,b), unique(a,b,c));'); @@ -1745,7 +1746,7 @@ public function testHasForeignKey($tableDef, $key, $exp) $this->assertSame($exp, $this->adapter->hasForeignKey('t', $key)); } - public static function provideForeignKeysToCheck() + public static function provideForeignKeysToCheck(): array { return [ ['create table t(a int)', 'a', false], @@ -1771,7 +1772,7 @@ public static function provideForeignKeysToCheck() ]; } - public function testHasNamedForeignKey() + public function testHasNamedForeignKey(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->save(); @@ -1794,7 +1795,7 @@ public function testHasNamedForeignKey() $this->assertFalse($this->adapter->hasForeignKey($table->getName(), [], 'my_constraint2')); } - public function testDropForeignKeyWithSchema() + public function testDropForeignKeyWithSchema(): void { $this->adapter->createSchema('schema1'); $this->adapter->createSchema('schema2'); @@ -1815,7 +1816,7 @@ public function testDropForeignKeyWithSchema() $this->adapter->dropSchema('schema2'); } - public function testDropForeignKeyNotDroppingPrimaryKey() + public function testDropForeignKeyNotDroppingPrimaryKey(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -1833,13 +1834,13 @@ public function testDropForeignKeyNotDroppingPrimaryKey() $this->assertTrue($this->adapter->hasIndexByName('table', 'table_pkey')); } - public function testHasDatabase() + public function testHasDatabase(): void { $this->assertFalse($this->adapter->hasDatabase('fake_database_name')); $this->assertTrue($this->adapter->hasDatabase($this->config['database'])); } - public function testDropDatabase() + public function testDropDatabase(): void { $this->assertFalse($this->adapter->hasDatabase('phinx_temp_database')); $this->adapter->createDatabase('phinx_temp_database'); @@ -1847,13 +1848,13 @@ public function testDropDatabase() $this->adapter->dropDatabase('phinx_temp_database'); } - public function testCreateSchema() + public function testCreateSchema(): void { $this->adapter->createSchema('foo'); $this->assertTrue($this->adapter->hasSchema('foo')); } - public function testDropSchema() + public function testDropSchema(): void { $this->adapter->createSchema('foo'); $this->assertTrue($this->adapter->hasSchema('foo')); @@ -1861,7 +1862,7 @@ public function testDropSchema() $this->assertFalse($this->adapter->hasSchema('foo')); } - public function testDropAllSchemas() + public function testDropAllSchemas(): void { $this->adapter->createSchema('foo'); $this->adapter->createSchema('bar'); @@ -1873,7 +1874,7 @@ public function testDropAllSchemas() $this->assertFalse($this->adapter->hasSchema('bar')); } - public function testCreateTableWithComment() + public function testCreateTableWithComment(): void { $tableComment = 'Table comment'; $table = new Table('ntable', ['comment' => $tableComment], $this->adapter); @@ -1895,7 +1896,7 @@ public function testCreateTableWithComment() $this->assertEquals($tableComment, $rows[0]['description'], 'Dont set table comment correctly'); } - public function testCanAddColumnComment() + public function testCanAddColumnComment(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn( @@ -1918,7 +1919,7 @@ public function testCanAddColumnComment() $this->assertEquals($comment, $row['column_comment'], 'Dont set column comment correctly'); } - public function testCanAddCommentForColumnWithReservedName() + public function testCanAddCommentForColumnWithReservedName(): void { $table = new Table('user', [], $this->adapter); $table->addColumn('index', 'string', ['comment' => $comment = 'Comments from column "index"']) @@ -1943,7 +1944,7 @@ public function testCanAddCommentForColumnWithReservedName() } #[Depends('testCanAddColumnComment')] - public function testCanChangeColumnComment() + public function testCanChangeColumnComment(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('field1', 'string', ['comment' => 'Comments from column "field1"']) @@ -1970,7 +1971,7 @@ public function testCanChangeColumnComment() } #[Depends('testCanAddColumnComment')] - public function testCanRemoveColumnComment() + public function testCanRemoveColumnComment(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('field1', 'string', ['comment' => 'Comments from column "field1"']) @@ -1994,7 +1995,7 @@ public function testCanRemoveColumnComment() } #[Depends('testCanAddColumnComment')] - public function testCanAddMultipleCommentsToOneTable() + public function testCanAddMultipleCommentsToOneTable(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('comment1', 'string', [ @@ -2033,7 +2034,7 @@ public function testCanAddMultipleCommentsToOneTable() } #[Depends('testCanAddColumnComment')] - public function testColumnsAreResetBetweenTables() + public function testColumnsAreResetBetweenTables(): void { $table = new Table('widgets', [], $this->adapter); $table->addColumn('transport', 'string', [ @@ -2062,7 +2063,7 @@ public function testColumnsAreResetBetweenTables() /** * Test that column names are properly escaped when creating Foreign Keys */ - public function testForeignKeysAreProperlyEscaped() + public function testForeignKeysAreProperlyEscaped(): void { $userId = 'user'; $sessionId = 'session'; @@ -2082,7 +2083,7 @@ public function testForeignKeysAreProperlyEscaped() $this->assertTrue($foreign->hasForeignKey('user')); } - public function testForeignKeysAreProperlyEscapedWithSchema() + public function testForeignKeysAreProperlyEscapedWithSchema(): void { $this->adapter->createSchema('schema_users'); @@ -2110,7 +2111,7 @@ public function testForeignKeysAreProperlyEscapedWithSchema() $this->adapter->dropSchema('schema_users'); } - public function testForeignKeysAreProperlyEscapedWithSchema2() + public function testForeignKeysAreProperlyEscapedWithSchema2(): void { $this->adapter->createSchema('schema_users'); $this->adapter->createSchema('schema_sessions'); @@ -2140,7 +2141,7 @@ public function testForeignKeysAreProperlyEscapedWithSchema2() $this->adapter->dropSchema('schema_sessions'); } - public function testTimestampWithTimezone() + public function testTimestampWithTimezone(): void { $table = new Table('tztable', ['id' => false], $this->adapter); $table @@ -2154,7 +2155,7 @@ public function testTimestampWithTimezone() $columns = $this->adapter->getColumns('tztable'); foreach ($columns as $column) { - if (substr($column->getName(), -4) === 'notz') { + if (str_ends_with((string)$column->getName(), 'notz')) { $this->assertFalse($column->isTimezone(), 'column: ' . $column->getName()); } else { $this->assertTrue($column->isTimezone(), 'column: ' . $column->getName()); @@ -2162,7 +2163,7 @@ public function testTimestampWithTimezone() } } - public function testTimestampWithTimezoneWithSchema() + public function testTimestampWithTimezoneWithSchema(): void { $this->adapter->createSchema('tzschema'); @@ -2178,7 +2179,7 @@ public function testTimestampWithTimezoneWithSchema() $columns = $this->adapter->getColumns('tzschema.tztable'); foreach ($columns as $column) { - if (substr($column->getName(), -4) === 'notz') { + if (str_ends_with((string)$column->getName(), 'notz')) { $this->assertFalse($column->isTimezone(), 'column: ' . $column->getName()); } else { $this->assertTrue($column->isTimezone(), 'column: ' . $column->getName()); @@ -2188,7 +2189,7 @@ public function testTimestampWithTimezoneWithSchema() $this->adapter->dropSchema('tzschema'); } - public function testBulkInsertData() + public function testBulkInsertData(): void { $data = [ [ @@ -2222,7 +2223,7 @@ public function testBulkInsertData() $this->assertEquals('test', $rows[2]['column3']); } - public function testBulkInsertBoolean() + public function testBulkInsertBoolean(): void { $data = [ [ @@ -2246,7 +2247,7 @@ public function testBulkInsertBoolean() $this->assertNull($rows[2]['column1']); } - public function testBulkInsertLiteral() + public function testBulkInsertLiteral(): void { $data = [ [ @@ -2272,12 +2273,12 @@ public function testBulkInsertLiteral() $this->assertEquals('value1', $rows[0]['column1']); $this->assertEquals('value2', $rows[1]['column1']); $this->assertEquals('value3', $rows[2]['column1']); - $this->assertMatchesRegularExpression('/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/', $rows[0]['column2']); + $this->assertMatchesRegularExpression('/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $rows[0]['column2']); $this->assertEquals('2024-01-01 00:00:00', $rows[1]['column2']); $this->assertEquals('2025-01-01 00:00:00', $rows[2]['column2']); } - public function testInsertData() + public function testInsertData(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('column1', 'string') @@ -2301,7 +2302,7 @@ public function testInsertData() $this->assertEquals(2, $rows[1]['column2']); } - public function testInsertLiteral() + public function testInsertLiteral(): void { $data = [ [ @@ -2332,12 +2333,12 @@ public function testInsertLiteral() $this->assertEquals('test', $rows[0]['column2']); $this->assertEquals('test', $rows[1]['column2']); $this->assertEquals('foo', $rows[2]['column2']); - $this->assertMatchesRegularExpression('/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/', $rows[0]['column3']); + $this->assertMatchesRegularExpression('/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $rows[0]['column3']); $this->assertEquals('2024-01-01 00:00:00', $rows[1]['column3']); $this->assertEquals('2025-01-01 00:00:00', $rows[2]['column3']); } - public function testInsertBoolean() + public function testInsertBoolean(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('column1', 'boolean', ['null' => true]) @@ -2362,7 +2363,7 @@ public function testInsertBoolean() $this->assertNull($rows[2]['column1']); } - public function testInsertDataWithSchema() + public function testInsertDataWithSchema(): void { $this->adapter->createSchema('schema1'); @@ -2390,7 +2391,7 @@ public function testInsertDataWithSchema() $this->adapter->dropSchema('schema1'); } - public function testTruncateTable() + public function testTruncateTable(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('column1', 'string') @@ -2414,7 +2415,7 @@ public function testTruncateTable() $this->assertCount(0, $rows); } - public function testTruncateTableWithSchema() + public function testTruncateTableWithSchema(): void { $this->adapter->createSchema('schema1'); @@ -2442,7 +2443,7 @@ public function testTruncateTableWithSchema() $this->adapter->dropSchema('schema1'); } - public function testDumpCreateTable() + public function testDumpCreateTable(): void { $options = $this->adapter->getOptions(); $options['dryrun'] = true; @@ -2455,7 +2456,7 @@ public function testDumpCreateTable() ->addColumn('column3', 'string', ['default' => 'test', 'null' => false]) ->save(); - $actualOutput = join("\n", $this->out->messages()); + $actualOutput = implode("\n", $this->out->messages()); // Check for key parts of the CREATE TABLE statement // The identity column syntax varies between CakePHP/database versions $this->assertStringContainsString( @@ -2469,7 +2470,7 @@ public function testDumpCreateTable() $this->assertStringContainsString('CONSTRAINT "table1_pkey" PRIMARY KEY ("id")', $actualOutput); } - public function testDumpCreateTableWithSchema() + public function testDumpCreateTableWithSchema(): void { $options = $this->adapter->getOptions(); $options['dryrun'] = true; @@ -2482,7 +2483,7 @@ public function testDumpCreateTableWithSchema() ->addColumn('column3', 'string', ['default' => 'test', 'null' => false]) ->save(); - $actualOutput = join("\n", $this->out->messages()); + $actualOutput = implode("\n", $this->out->messages()); // Check for key parts of the CREATE TABLE statement // The identity column syntax varies between CakePHP/database versions $this->assertStringContainsString( @@ -2501,7 +2502,7 @@ public function testDumpCreateTableWithSchema() * Then enables dry run mode and inserts a record. * Asserts that output contains the insert statement and doesn't insert a record. */ - public function testDumpInsert() + public function testDumpInsert(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('string_col', 'string') @@ -2538,11 +2539,11 @@ public function testDumpInsert() OUTPUT; } - $actualOutput = join("\n", $this->out->messages()); + $actualOutput = implode("\n", $this->out->messages()); $this->assertStringContainsString( $expectedOutput, $actualOutput, - 'Passing the --dry-run option doesn\'t dump the insert to the output', + "Passing the --dry-run option doesn't dump the insert to the output", ); $countQuery = $this->adapter->query('SELECT COUNT(*) FROM table1'); @@ -2556,7 +2557,7 @@ public function testDumpInsert() * Then enables dry run mode and inserts some records. * Asserts that output contains the insert statement and doesn't insert any record. */ - public function testDumpBulkinsert() + public function testDumpBulkinsert(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('string_col', 'string') @@ -2588,11 +2589,11 @@ public function testDumpBulkinsert() OUTPUT; } - $actualOutput = join("\n", $this->out->messages()); + $actualOutput = implode("\n", $this->out->messages()); $this->assertStringContainsString( $expectedOutput, $actualOutput, - 'Passing the --dry-run option doesn\'t dump the bulkinsert to the output', + "Passing the --dry-run option doesn't dump the bulkinsert to the output", ); $countQuery = $this->adapter->query('SELECT COUNT(*) FROM table1'); @@ -2601,7 +2602,7 @@ public function testDumpBulkinsert() $this->assertEquals(0, $res[0]['count']); } - public function testDumpCreateTableAndThenInsert() + public function testDumpCreateTableAndThenInsert(): void { $options = $this->adapter->getOptions(); $options['dryrun'] = true; @@ -2630,14 +2631,14 @@ public function testDumpCreateTableAndThenInsert() OUTPUT; } - $actualOutput = join("\n", $this->out->messages()); + $actualOutput = implode("\n", $this->out->messages()); $this->assertStringContainsString($expectedOutput, $actualOutput, 'Passing the --dry-run option does not dump create and then insert table queries to the output'); } /** * Tests interaction with the query builder */ - public function testQueryBuilder() + public function testQueryBuilder(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('string_col', 'string') @@ -2676,7 +2677,7 @@ public function testQueryBuilder() $this->assertEquals(1, $stm->rowCount()); } - public function testQueryWithParams() + public function testQueryWithParams(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('string_col', 'string') @@ -2707,7 +2708,7 @@ public function testQueryWithParams() $this->assertEquals(3, $res[0]['c']); } - public function testRenameMixedCaseTableAndColumns() + public function testRenameMixedCaseTableAndColumns(): void { $table = new Table('OrganizationSettings', [], $this->adapter); $table->addColumn('SettingType', 'string') @@ -2752,7 +2753,7 @@ public function testSerialAliases(string $columnType): void $this->assertFalse($column->isNull()); } - public function testAddCheckConstraint() + public function testAddCheckConstraint(): void { $table = new Table('check_table', [], $this->adapter); $table->addColumn('price', 'decimal', ['precision' => 10, 'scale' => 2]) @@ -2764,7 +2765,7 @@ public function testAddCheckConstraint() $this->assertTrue($this->adapter->hasCheckConstraint('check_table', 'price_positive')); } - public function testHasCheckConstraint() + public function testHasCheckConstraint(): void { $table = new Table('check_table3', [], $this->adapter); $table->addColumn('quantity', 'integer') @@ -2778,7 +2779,7 @@ public function testHasCheckConstraint() $this->assertTrue($this->adapter->hasCheckConstraint('check_table3', 'quantity_positive')); } - public function testDropCheckConstraint() + public function testDropCheckConstraint(): void { $table = new Table('check_table4', [], $this->adapter); $table->addColumn('price', 'decimal', ['precision' => 10, 'scale' => 2]) @@ -2792,7 +2793,7 @@ public function testDropCheckConstraint() $this->assertFalse($this->adapter->hasCheckConstraint('check_table4', 'price_check')); } - public function testCheckConstraintWithComplexExpression() + public function testCheckConstraintWithComplexExpression(): void { $table = new Table('check_table5', [], $this->adapter); $table->addColumn('email', 'string', ['limit' => 255]) @@ -2809,10 +2810,10 @@ public function testCheckConstraintWithComplexExpression() // Verify the constraint is actually enforced $quotedTableName = $this->adapter->getConnection()->getDriver()->quoteIdentifier('check_table5'); $this->expectException(PDOException::class); - $this->adapter->execute("INSERT INTO {$quotedTableName} (email, status) VALUES ('test@example.com', 'invalid')"); + $this->adapter->execute(sprintf("INSERT INTO %s (email, status) VALUES ('test@example.com', 'invalid')", $quotedTableName)); } - public function testInsertOrSkipWithDuplicates() + public function testInsertOrSkipWithDuplicates(): void { $table = new Table('users', [], $this->adapter); $table->addColumn('email', 'string', ['limit' => 255]) @@ -2835,7 +2836,7 @@ public function testInsertOrSkipWithDuplicates() $this->assertEquals('John', $rows[0]['name']); } - public function testInsertModeResetsAfterInsertOrSkip() + public function testInsertModeResetsAfterInsertOrSkip(): void { $table = new Table('users', [], $this->adapter); $table->addColumn('email', 'string', ['limit' => 255]) @@ -2855,7 +2856,7 @@ public function testInsertModeResetsAfterInsertOrSkip() ])->save(); } - public function testBulkinsertOrSkipWithDuplicates() + public function testBulkinsertOrSkipWithDuplicates(): void { $table = new Table('products', [], $this->adapter); $table->addColumn('sku', 'string', ['limit' => 50]) @@ -2882,7 +2883,7 @@ public function testBulkinsertOrSkipWithDuplicates() $this->assertEquals('30.00', $rows[2]['price']); } - public function testInsertOrSkipWithoutDuplicates() + public function testInsertOrSkipWithoutDuplicates(): void { $table = new Table('categories', [], $this->adapter); $table->addColumn('name', 'string') @@ -2898,7 +2899,7 @@ public function testInsertOrSkipWithoutDuplicates() $this->assertCount(2, $rows); } - public function testInsertOrUpdateWithDuplicates() + public function testInsertOrUpdateWithDuplicates(): void { $table = new Table('currencies', [], $this->adapter); $table->addColumn('code', 'string', ['limit' => 3]) @@ -2931,7 +2932,7 @@ public function testInsertOrUpdateWithDuplicates() $this->assertEquals('1.0500', $rows[2]['rate']); // USD updated } - public function testInsertOrUpdateWithMultipleUpdateColumns() + public function testInsertOrUpdateWithMultipleUpdateColumns(): void { $table = new Table('products', [], $this->adapter); $table->addColumn('sku', 'string', ['limit' => 50]) @@ -2956,7 +2957,7 @@ public function testInsertOrUpdateWithMultipleUpdateColumns() $this->assertEquals(50, $rows[0]['stock']); } - public function testInsertOrUpdateModeResetsAfterSave() + public function testInsertOrUpdateModeResetsAfterSave(): void { $table = new Table('items', [], $this->adapter); $table->addColumn('code', 'string', ['limit' => 10]) @@ -2976,7 +2977,7 @@ public function testInsertOrUpdateModeResetsAfterSave() ])->save(); } - public function testInsertOrUpdateRequiresConflictColumns() + public function testInsertOrUpdateRequiresConflictColumns(): void { $table = new Table('currencies', [], $this->adapter); $table->addColumn('code', 'string', ['limit' => 3]) @@ -2992,7 +2993,7 @@ public function testInsertOrUpdateRequiresConflictColumns() ], ['rate'], [])->save(); } - public function testAddSinglePartitionToExistingTable() + public function testAddSinglePartitionToExistingTable(): void { // Create a partitioned table with room to add more partitions $table = new Table('partitioned_orders', ['id' => false, 'primary_key' => ['id', 'order_date']], $this->adapter); @@ -3023,7 +3024,7 @@ public function testAddSinglePartitionToExistingTable() $this->adapter->dropTable('partitioned_orders'); } - public function testAddMultiplePartitionsToExistingTable() + public function testAddMultiplePartitionsToExistingTable(): void { // Create a partitioned table $table = new Table('partitioned_sales', ['id' => false, 'primary_key' => ['id', 'sale_date']], $this->adapter); @@ -3061,7 +3062,7 @@ public function testAddMultiplePartitionsToExistingTable() $this->adapter->dropTable('partitioned_sales'); } - public function testDropSinglePartitionFromExistingTable() + public function testDropSinglePartitionFromExistingTable(): void { // Create a partitioned table with multiple partitions $table = new Table('partitioned_logs', ['id' => false, 'primary_key' => ['id']], $this->adapter); @@ -3103,7 +3104,7 @@ public function testDropSinglePartitionFromExistingTable() $this->adapter->dropTable('partitioned_logs'); } - public function testDropMultiplePartitionsFromExistingTable() + public function testDropMultiplePartitionsFromExistingTable(): void { // Create a partitioned table with multiple partitions $table = new Table('partitioned_archive', ['id' => false, 'primary_key' => ['id']], $this->adapter); diff --git a/tests/TestCase/Db/Adapter/RecordingAdapterTest.php b/tests/TestCase/Db/Adapter/RecordingAdapterTest.php index c5a684323..260979e9e 100644 --- a/tests/TestCase/Db/Adapter/RecordingAdapterTest.php +++ b/tests/TestCase/Db/Adapter/RecordingAdapterTest.php @@ -3,6 +3,12 @@ namespace Migrations\Test\Db\Adapter; +use Migrations\Db\Action\DropForeignKey; +use Migrations\Db\Action\DropIndex; +use Migrations\Db\Action\DropTable; +use Migrations\Db\Action\RemoveColumn; +use Migrations\Db\Action\RenameColumn; +use Migrations\Db\Action\RenameTable; use Migrations\Db\Adapter\AbstractAdapter; use Migrations\Db\Adapter\RecordingAdapter; use Migrations\Db\Table; @@ -12,10 +18,7 @@ class RecordingAdapterTest extends TestCase { - /** - * @var \Migrations\Db\Adapter\RecordingAdapter - */ - private $adapter; + private RecordingAdapter $adapter; protected function setUp(): void { @@ -35,30 +38,30 @@ protected function tearDown(): void unset($this->adapter); } - public function testRecordingAdapterCanInvertCreateTable() + public function testRecordingAdapterCanInvertCreateTable(): void { $table = new Table('atable', [], $this->adapter); $table->addColumn('column1', 'string') ->save(); $commands = $this->adapter->getInvertedCommands()->getActions(); - $this->assertInstanceOf('Migrations\Db\Action\DropTable', $commands[0]); + $this->assertInstanceOf(DropTable::class, $commands[0]); $this->assertEquals('atable', $commands[0]->getTable()->getName()); } - public function testRecordingAdapterCanInvertRenameTable() + public function testRecordingAdapterCanInvertRenameTable(): void { $table = new Table('oldname', [], $this->adapter); $table->rename('newname') ->save(); $commands = $this->adapter->getInvertedCommands()->getActions(); - $this->assertInstanceOf('Migrations\Db\Action\RenameTable', $commands[0]); + $this->assertInstanceOf(RenameTable::class, $commands[0]); $this->assertEquals('newname', $commands[0]->getTable()->getName()); $this->assertEquals('oldname', $commands[0]->getNewName()); } - public function testRecordingAdapterCanInvertAddColumn() + public function testRecordingAdapterCanInvertAddColumn(): void { $this->adapter ->getAdapter() @@ -82,12 +85,12 @@ public function testRecordingAdapterCanInvertAddColumn() ->save(); $commands = $this->adapter->getInvertedCommands()->getActions(); - $this->assertInstanceOf('Migrations\Db\Action\RemoveColumn', $commands[0]); + $this->assertInstanceOf(RemoveColumn::class, $commands[0]); $this->assertEquals('atable', $commands[0]->getTable()->getName()); $this->assertEquals('acolumn', $commands[0]->getColumn()->getName()); } - public function testRecordingAdapterCanInvertRenameColumn() + public function testRecordingAdapterCanInvertRenameColumn(): void { $this->adapter ->getAdapter() @@ -100,12 +103,12 @@ public function testRecordingAdapterCanInvertRenameColumn() ->save(); $commands = $this->adapter->getInvertedCommands()->getActions(); - $this->assertInstanceOf('Migrations\Db\Action\RenameColumn', $commands[0]); + $this->assertInstanceOf(RenameColumn::class, $commands[0]); $this->assertEquals('newname', $commands[0]->getColumn()->getName()); $this->assertEquals('oldname', $commands[0]->getNewName()); } - public function testRecordingAdapterCanInvertAddIndex() + public function testRecordingAdapterCanInvertAddIndex(): void { $this->adapter ->getAdapter() @@ -118,12 +121,12 @@ public function testRecordingAdapterCanInvertAddIndex() ->save(); $commands = $this->adapter->getInvertedCommands()->getActions(); - $this->assertInstanceOf('Migrations\Db\Action\DropIndex', $commands[0]); + $this->assertInstanceOf(DropIndex::class, $commands[0]); $this->assertEquals('atable', $commands[0]->getTable()->getName()); $this->assertEquals(['email'], $commands[0]->getIndex()->getColumns()); } - public function testRecordingAdapterCanInvertAddForeignKey() + public function testRecordingAdapterCanInvertAddForeignKey(): void { $this->adapter ->getAdapter() @@ -136,12 +139,12 @@ public function testRecordingAdapterCanInvertAddForeignKey() ->save(); $commands = $this->adapter->getInvertedCommands()->getActions(); - $this->assertInstanceOf('Migrations\Db\Action\DropForeignKey', $commands[0]); + $this->assertInstanceOf(DropForeignKey::class, $commands[0]); $this->assertEquals('atable', $commands[0]->getTable()->getName()); $this->assertEquals(['ref_table_id'], $commands[0]->getForeignKey()->getColumns()); } - public function testGetInvertedCommandsThrowsExceptionForIrreversibleCommand() + public function testGetInvertedCommandsThrowsExceptionForIrreversibleCommand(): void { $this->adapter ->getAdapter() diff --git a/tests/TestCase/Db/Adapter/SqliteAdapterTest.php b/tests/TestCase/Db/Adapter/SqliteAdapterTest.php index 2fd54a9bd..a66031d52 100644 --- a/tests/TestCase/Db/Adapter/SqliteAdapterTest.php +++ b/tests/TestCase/Db/Adapter/SqliteAdapterTest.php @@ -27,13 +27,12 @@ class SqliteAdapterTest extends TestCase { private array $config; + private StubConsoleOutput $out; + private ConsoleIo $io; - /** - * @var \Migrations\Db\Adapter\SqliteAdapter - */ - private $adapter; + private SqliteAdapter $adapter; protected function setUp(): void { @@ -78,17 +77,17 @@ protected function tearDown(): void unset($this->adapter, $this->out, $this->io); } - public function testGetConnection() + public function testGetConnection(): void { error_reporting(E_ALL); - $this->deprecated(function () { + $this->deprecated(function (): void { $connection = $this->adapter->getConnection(); $this->assertInstanceOf(Connection::class, $connection); $this->assertSame($connection, $this->adapter->getDecoratedConnection()); }); } - public function testBeginTransaction() + public function testBeginTransaction(): void { $this->adapter->beginTransaction(); @@ -98,7 +97,7 @@ public function testBeginTransaction() ); } - public function testRollbackTransaction() + public function testRollbackTransaction(): void { $this->adapter->beginTransaction(); $this->adapter->rollbackTransaction(); @@ -109,7 +108,7 @@ public function testRollbackTransaction() ); } - public function testCommitTransactionTransaction() + public function testCommitTransactionTransaction(): void { $this->adapter->beginTransaction(); $this->adapter->commitTransaction(); @@ -120,7 +119,7 @@ public function testCommitTransactionTransaction() ); } - public function testCreatingTheSchemaTableOnConnect() + public function testCreatingTheSchemaTableOnConnect(): void { $this->adapter->connect(); $this->assertTrue($this->adapter->hasTable($this->adapter->getSchemaTableName())); @@ -131,24 +130,24 @@ public function testCreatingTheSchemaTableOnConnect() $this->assertTrue($this->adapter->hasTable($this->adapter->getSchemaTableName())); } - public function testSchemaTableIsCreatedWithPrimaryKey() + public function testSchemaTableIsCreatedWithPrimaryKey(): void { $this->adapter->connect(); new Table($this->adapter->getSchemaTableName(), [], $this->adapter); $this->assertTrue($this->adapter->hasIndex($this->adapter->getSchemaTableName(), ['version'])); } - public function testQuoteTableName() + public function testQuoteTableName(): void { $this->assertEquals('"test_table"', $this->adapter->quoteTableName('test_table')); } - public function testQuoteColumnName() + public function testQuoteColumnName(): void { $this->assertEquals('"test_column"', $this->adapter->quoteColumnName('test_column')); } - public function testCreateTable() + public function testCreateTable(): void { $table = new Table('ntable', [], $this->adapter); $table->addColumn('realname', 'string') @@ -161,7 +160,7 @@ public function testCreateTable() $this->assertFalse($this->adapter->hasColumn('ntable', 'address')); } - public function testCreateTableCustomIdColumn() + public function testCreateTableCustomIdColumn(): void { $table = new Table('ntable', ['id' => 'custom_id'], $this->adapter); $table->addColumn('realname', 'string') @@ -181,7 +180,7 @@ public function testCreateTableCustomIdColumn() $this->assertFalse($idColumn->isNull()); } - public function testCreateTableIdentityIdColumn() + public function testCreateTableIdentityIdColumn(): void { $table = new Table('ntable', ['id' => false, 'primary_key' => ['custom_id']], $this->adapter); $table->addColumn('custom_id', 'integer', ['identity' => true]) @@ -195,7 +194,7 @@ public function testCreateTableIdentityIdColumn() $this->assertTrue($idColumn->getIdentity()); } - public function testCreateTableWithNoPrimaryKey() + public function testCreateTableWithNoPrimaryKey(): void { $options = [ 'id' => false, @@ -206,7 +205,7 @@ public function testCreateTableWithNoPrimaryKey() $this->assertFalse($this->adapter->hasColumn('atable', 'id')); } - public function testCreateTableWithMultiplePrimaryKeys() + public function testCreateTableWithMultiplePrimaryKeys(): void { $options = [ 'id' => false, @@ -226,7 +225,7 @@ public function testCreateTableWithMultiplePrimaryKeys() /** * @return void */ - public function testCreateTableWithPrimaryKeyAsUuid() + public function testCreateTableWithPrimaryKeyAsUuid(): void { $options = [ 'id' => false, @@ -241,7 +240,7 @@ public function testCreateTableWithPrimaryKeyAsUuid() /** * @return void */ - public function testCreateTableWithPrimaryKeyAsBinaryUuid() + public function testCreateTableWithPrimaryKeyAsBinaryUuid(): void { $options = [ 'id' => false, @@ -253,7 +252,7 @@ public function testCreateTableWithPrimaryKeyAsBinaryUuid() $this->assertTrue($this->adapter->hasIndex('ztable', 'id')); } - public function testCreateTableWithMultipleIndexes() + public function testCreateTableWithMultipleIndexes(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -267,7 +266,7 @@ public function testCreateTableWithMultipleIndexes() $this->assertFalse($this->adapter->hasIndex('table1', ['email', 'user_name'])); } - public function testCreateTableWithUniqueIndexes() + public function testCreateTableWithUniqueIndexes(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -277,7 +276,7 @@ public function testCreateTableWithUniqueIndexes() $this->assertFalse($this->adapter->hasIndex('table1', ['email', 'user_email'])); } - public function testCreateTableWithNamedIndexes() + public function testCreateTableWithNamedIndexes(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -288,7 +287,7 @@ public function testCreateTableWithNamedIndexes() $this->assertTrue($this->adapter->hasIndexByName('table1', 'myemailindex')); } - public function testCreateTableWithForeignKey() + public function testCreateTableWithForeignKey(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -302,7 +301,7 @@ public function testCreateTableWithForeignKey() $this->assertTrue($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'])); } - public function testCreateTableWithIndexesAndForeignKey() + public function testCreateTableWithIndexesAndForeignKey(): void { $refTable = new Table('tbl_master', [], $this->adapter); $refTable->create(); @@ -335,7 +334,7 @@ public function testCreateTableWithIndexesAndForeignKey() ); } - public function testCreateTableWithoutAutoIncrementingPrimaryKeyAndWithForeignKey() + public function testCreateTableWithoutAutoIncrementingPrimaryKeyAndWithForeignKey(): void { $refTable = (new Table('tbl_master', ['id' => false, 'primary_key' => 'id'], $this->adapter)) ->addColumn('id', 'text'); @@ -384,7 +383,7 @@ public function testCreateTableIndexWithWhere(): void $this->assertStringContainsString('("email" ASC) WHERE is_verified = true', $indexQuery); } - public function testAddPrimaryKey() + public function testAddPrimaryKey(): void { $table = new Table('table1', [], $this->adapter); $table @@ -396,7 +395,7 @@ public function testAddPrimaryKey() $this->assertTrue($this->adapter->hasPrimaryKey('table1', ['id'])); } - public function testChangePrimaryKey() + public function testChangePrimaryKey(): void { $table = new Table('table1', ['id' => false, 'primary_key' => 'column1'], $this->adapter); $table @@ -412,7 +411,7 @@ public function testChangePrimaryKey() $this->assertTrue($this->adapter->hasPrimaryKey('table1', ['column2'])); } - public function testChangePrimaryKeyNonInteger() + public function testChangePrimaryKeyNonInteger(): void { $table = new Table('table1', ['id' => false, 'primary_key' => 'column1'], $this->adapter); $table @@ -428,7 +427,7 @@ public function testChangePrimaryKeyNonInteger() $this->assertTrue($this->adapter->hasPrimaryKey('table1', ['column2'])); } - public function testChangePrimaryKeyWithoutAutoIncrement() + public function testChangePrimaryKeyWithoutAutoIncrement(): void { // Create table with id_1 as PK without AUTOINCREMENT keyword $this->adapter->execute('CREATE TABLE table1 (id_1 INTEGER NOT NULL PRIMARY KEY, id_2 INTEGER NOT NULL)'); @@ -450,7 +449,7 @@ public function testChangePrimaryKeyWithoutAutoIncrement() $this->assertStringNotContainsString('AUTOINCREMENT', $result['sql'], 'AUTOINCREMENT should not be added when changing PK to a column that did not have it'); } - public function testChangePrimaryKeyFromAutoIncrementColumn() + public function testChangePrimaryKeyFromAutoIncrementColumn(): void { // Create table with id_1 as PK with AUTOINCREMENT $this->adapter->execute('CREATE TABLE table1 (id_1 INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, id_2 INTEGER NOT NULL)'); @@ -473,7 +472,7 @@ public function testChangePrimaryKeyFromAutoIncrementColumn() $this->assertStringNotContainsString('AUTOINCREMENT', $result['sql'], 'AUTOINCREMENT should not be added when changing PK to a column that never had it'); } - public function testDropPrimaryKey() + public function testDropPrimaryKey(): void { $table = new Table('table1', ['id' => false, 'primary_key' => 'column1'], $this->adapter); $table @@ -488,7 +487,7 @@ public function testDropPrimaryKey() $this->assertFalse($this->adapter->hasPrimaryKey('table1', ['column1'])); } - public function testAddMultipleColumnPrimaryKeyFails() + public function testAddMultipleColumnPrimaryKeyFails(): void { $table = new Table('table1', [], $this->adapter); $table @@ -503,7 +502,7 @@ public function testAddMultipleColumnPrimaryKeyFails() ->save(); } - public function testChangeCommentFails() + public function testChangeCommentFails(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -515,7 +514,7 @@ public function testChangeCommentFails() ->save(); } - public function testRenameTable() + public function testRenameTable(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -526,7 +525,7 @@ public function testRenameTable() $this->assertTrue($this->adapter->hasTable('table2')); } - public function testAddColumn() + public function testAddColumn(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -541,7 +540,7 @@ public function testAddColumn() // $this->assertEquals('realname', $rows[1]['Field']); } - public function testAddColumnWithDefaultValue() + public function testAddColumnWithDefaultValue(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -551,7 +550,7 @@ public function testAddColumnWithDefaultValue() $this->assertEquals("'test'", $rows[1]['dflt_value']); } - public function testAddColumnWithDefaultZero() + public function testAddColumnWithDefaultZero(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -562,7 +561,7 @@ public function testAddColumnWithDefaultZero() $this->assertEquals('0', $rows[1]['dflt_value']); } - public function testAddColumnWithDefaultEmptyString() + public function testAddColumnWithDefaultEmptyString(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -572,7 +571,7 @@ public function testAddColumnWithDefaultEmptyString() $this->assertEquals("''", $rows[1]['dflt_value']); } - public function testAddDecimalWithPrecisionAndScale() + public function testAddDecimalWithPrecisionAndScale(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -620,7 +619,7 @@ public function testAddColumnToIrregularCreateTableStatements(string $createTabl } } - public function testRenameColumn() + public function testRenameColumn(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -631,7 +630,7 @@ public function testRenameColumn() $this->assertTrue($this->adapter->hasColumn('t', 'column2')); } - public function testRenamingANonExistentColumn() + public function testRenamingANonExistentColumn(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -642,7 +641,7 @@ public function testRenamingANonExistentColumn() $this->adapter->renameColumn('t', 'column2', 'column1'); } - public function testRenameColumnWithIndex() + public function testRenameColumnWithIndex(): void { $table = new Table('t', [], $this->adapter); $table @@ -659,7 +658,7 @@ public function testRenameColumnWithIndex() $this->assertTrue($this->adapter->hasIndex($table->getName(), 'newindexcol')); } - public function testRenameColumnWithUniqueIndex() + public function testRenameColumnWithUniqueIndex(): void { $table = new Table('t', [], $this->adapter); $table @@ -676,7 +675,7 @@ public function testRenameColumnWithUniqueIndex() $this->assertTrue($this->adapter->hasIndex($table->getName(), 'newindexcol')); } - public function testRenameColumnWithCompositeIndex() + public function testRenameColumnWithCompositeIndex(): void { $table = new Table('t', [], $this->adapter); $table @@ -698,7 +697,7 @@ public function testRenameColumnWithCompositeIndex() * Tests that rewriting the index SQL does not accidentally change * the table name in case it matches the column name. */ - public function testRenameColumnWithIndexMatchingTheTableName() + public function testRenameColumnWithIndexMatchingTheTableName(): void { $table = new Table('indexcol', [], $this->adapter); $table @@ -719,7 +718,7 @@ public function testRenameColumnWithIndexMatchingTheTableName() * Tests that rewriting the index SQL does not accidentally change * column names that partially match the column to rename. */ - public function testRenameColumnWithIndexColumnPartialMatch() + public function testRenameColumnWithIndexColumnPartialMatch(): void { $table = new Table('t', [], $this->adapter); $table @@ -738,7 +737,7 @@ public function testRenameColumnWithIndexColumnPartialMatch() $this->assertTrue($this->adapter->hasIndex($table->getName(), ['indexcolumn', 'newindexcol'])); } - public function testRenameColumnWithIndexColumnRequiringQuoting() + public function testRenameColumnWithIndexColumnRequiringQuoting(): void { $table = new Table('t', [], $this->adapter); $table @@ -758,7 +757,7 @@ public function testRenameColumnWithIndexColumnRequiringQuoting() /** * Indices that are using expressions are not being updated. */ - public function testRenameColumnWithExpressionIndex() + public function testRenameColumnWithExpressionIndex(): void { $table = new Table('t', [], $this->adapter); $table @@ -847,7 +846,7 @@ public static function customIndexSQLDataProvider(): array * @param string $newIndexSQL Expected new index creation SQL */ #[DataProvider('customIndexSQLDataProvider')] - public function testRenameColumnWithCustomIndex(string $indexSQL, string $newIndexSQL) + public function testRenameColumnWithCustomIndex(string $indexSQL, string $newIndexSQL): void { $table = new Table('t', [], $this->adapter); $table @@ -946,7 +945,7 @@ public static function customCompositeIndexSQLDataProvider(): array * @param string $newIndexSQL Expected new index creation SQL */ #[DataProvider('customCompositeIndexSQLDataProvider')] - public function testRenameColumnWithCustomCompositeIndex(string $indexSQL, string $newIndexSQL) + public function testRenameColumnWithCustomCompositeIndex(string $indexSQL, string $newIndexSQL): void { $table = new Table('t', [], $this->adapter); $table @@ -969,7 +968,7 @@ public function testRenameColumnWithCustomCompositeIndex(string $indexSQL, strin $this->assertSame($index['sql'], $newIndexSQL); } - public function testChangeColumn() + public function testChangeColumn(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -978,6 +977,7 @@ public function testChangeColumn() $newColumn1 = new Column(); $newColumn1->setName('column1'); $newColumn1->setType('string'); + $table->changeColumn('column1', $newColumn1); $this->assertTrue($this->adapter->hasColumn('t', 'column1')); $newColumn2 = new Column(); @@ -988,7 +988,7 @@ public function testChangeColumn() $this->assertTrue($this->adapter->hasColumn('t', 'column2')); } - public function testChangeColumnDefaultValue() + public function testChangeColumnDefaultValue(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['default' => 'test']) @@ -1004,7 +1004,7 @@ public function testChangeColumnDefaultValue() $this->assertEquals("'test1'", $rows[1]['dflt_value']); } - public function testChangeColumnWithForeignKey() + public function testChangeColumnWithForeignKey(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -1022,7 +1022,7 @@ public function testChangeColumnWithForeignKey() $this->assertTrue($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'])); } - public function testChangeColumnWithIndex() + public function testChangeColumnWithIndex(): void { $table = new Table('t', [], $this->adapter); $table @@ -1040,7 +1040,7 @@ public function testChangeColumnWithIndex() $this->assertTrue($this->adapter->hasIndex($table->getName(), 'indexcol')); } - public function testChangeColumnWithTrigger() + public function testChangeColumnWithTrigger(): void { $table = new Table('t', [], $this->adapter); $table @@ -1075,7 +1075,7 @@ public function testChangeColumnWithTrigger() $this->assertEquals($triggerSQL, $rows[0]['sql']); } - public function testChangeColumnDefaultToZero() + public function testChangeColumnDefaultToZero(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'integer') @@ -1089,7 +1089,7 @@ public function testChangeColumnDefaultToZero() $this->assertEquals('0', $rows[1]['dflt_value']); } - public function testChangeColumnDefaultToNull() + public function testChangeColumnDefaultToNull(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['default' => 'test']) @@ -1103,7 +1103,7 @@ public function testChangeColumnDefaultToNull() $this->assertNull($rows[1]['dflt_value']); } - public function testChangeColumnWithCommasInCommentsOrDefaultValue() + public function testChangeColumnWithCommasInCommentsOrDefaultValue(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['default' => 'one, two or three', 'comment' => 'three, two or one']) @@ -1119,11 +1119,11 @@ public function testChangeColumnWithCommasInCommentsOrDefaultValue() } #[DataProvider('columnCreationArgumentProvider')] - public function testDropColumn($columnCreationArgs) + public function testDropColumn(array $columnCreationArgs): void { $table = new Table('t', [], $this->adapter); $columnName = $columnCreationArgs[0]; - call_user_func_array([$table, 'addColumn'], $columnCreationArgs); + $table->addColumn(...$columnCreationArgs); $table->save(); $this->assertTrue($this->adapter->hasColumn('t', $columnName)); @@ -1132,7 +1132,7 @@ public function testDropColumn($columnCreationArgs) $this->assertFalse($this->adapter->hasColumn('t', $columnName)); } - public function testDropColumnWithIndex() + public function testDropColumnWithIndex(): void { $table = new Table('t', [], $this->adapter); $table @@ -1147,7 +1147,7 @@ public function testDropColumnWithIndex() $this->assertFalse($this->adapter->hasIndex($table->getName(), 'indexcol')); } - public function testDropColumnWithUniqueIndex() + public function testDropColumnWithUniqueIndex(): void { $table = new Table('t', [], $this->adapter); $table @@ -1162,7 +1162,7 @@ public function testDropColumnWithUniqueIndex() $this->assertFalse($this->adapter->hasIndex($table->getName(), 'indexcol')); } - public function testDropColumnWithCompositeIndex() + public function testDropColumnWithCompositeIndex(): void { $table = new Table('t', [], $this->adapter); $table @@ -1182,7 +1182,7 @@ public function testDropColumnWithCompositeIndex() * Tests that removing columns does not accidentally drop indices * on table names that match the column to remove. */ - public function testDropColumnWithIndexMatchingTheTableName() + public function testDropColumnWithIndexMatchingTheTableName(): void { $table = new Table('indexcol', [], $this->adapter); $table @@ -1202,7 +1202,7 @@ public function testDropColumnWithIndexMatchingTheTableName() * Tests that removing columns does not accidentally drop indices * that contain column names that partially match the column to remove. */ - public function testDropColumnWithIndexColumnPartialMatch() + public function testDropColumnWithIndexColumnPartialMatch(): void { $table = new Table('t', [], $this->adapter); $table @@ -1222,7 +1222,7 @@ public function testDropColumnWithIndexColumnPartialMatch() /** * Indices with expressions are not being removed. */ - public function testDropColumnWithExpressionIndex() + public function testDropColumnWithExpressionIndex(): void { $table = new Table('t', [], $this->adapter); $table @@ -1244,7 +1244,7 @@ public function testDropColumnWithExpressionIndex() * @param string $newIndexSQL Expected new index creation SQL */ #[DataProvider('customIndexSQLDataProvider')] - public function testDropColumnWithCustomIndex(string $indexSQL, string $newIndexSQL) + public function testDropColumnWithCustomIndex(string $indexSQL, string $newIndexSQL): void { $table = new Table('t', [], $this->adapter); $table @@ -1265,7 +1265,7 @@ public function testDropColumnWithCustomIndex(string $indexSQL, string $newIndex * @param string $newIndexSQL Expected new index creation SQL */ #[DataProvider('customCompositeIndexSQLDataProvider')] - public function testDropColumnWithCustomCompositeIndex(string $indexSQL, string $newIndexSQL) + public function testDropColumnWithCustomCompositeIndex(string $indexSQL, string $newIndexSQL): void { $table = new Table('t', [], $this->adapter); $table @@ -1285,7 +1285,7 @@ public function testDropColumnWithCustomCompositeIndex(string $indexSQL, string $this->assertFalse($this->adapter->hasIndex($table->getName(), ['indexcol1', 'indexcol3'])); } - public static function columnCreationArgumentProvider() + public static function columnCreationArgumentProvider(): array { return [ [['column1', 'string']], @@ -1293,7 +1293,7 @@ public static function columnCreationArgumentProvider() ]; } - public static function columnsProvider() + public static function columnsProvider(): array { return [ ['column1', 'string', []], @@ -1313,7 +1313,7 @@ public static function columnsProvider() ]; } - public function testAddIndex() + public function testAddIndex(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -1324,7 +1324,7 @@ public function testAddIndex() $this->assertTrue($table->hasIndex('email')); } - public function testDropIndex() + public function testDropIndex(): void { // single column index $table = new Table('table1', [], $this->adapter); @@ -1365,7 +1365,7 @@ public function testDropIndex() $this->assertFalse($table4->hasIndex(['fname', 'lname'])); } - public function testDropIndexByName() + public function testDropIndexByName(): void { // single column index $table = new Table('table1', [], $this->adapter); @@ -1387,7 +1387,7 @@ public function testDropIndexByName() $this->assertFalse($table2->hasIndex(['fname', 'lname'])); } - public function testAddForeignKey() + public function testAddForeignKey(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -1401,7 +1401,7 @@ public function testAddForeignKey() $this->assertTrue($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'])); } - public function testDropForeignKey() + public function testDropForeignKey(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string') @@ -1431,7 +1431,7 @@ public function testDropForeignKey() $this->assertTrue($this->adapter->hasTable($table->getName())); } - public function testDropForeignKeyWithQuoteVariants() + public function testDropForeignKeyWithQuoteVariants(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string') @@ -1465,7 +1465,7 @@ public function testDropForeignKeyWithQuoteVariants() $this->assertFalse($this->adapter->hasForeignKey('table', ['ref_lots_of_space', 'ref_lots_of_space'])); } - public function testDropForeignKeyWithMultipleColumns() + public function testDropForeignKeyWithMultipleColumns(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable @@ -1525,11 +1525,8 @@ public static function nonExistentForeignKeyColumnsProvider(): array ]; } - /** - * @param array $columns - */ #[DataProvider('nonExistentForeignKeyColumnsProvider')] - public function testDropForeignKeyByNonExistentKeyColumns(array $columns) + public function testDropForeignKeyByNonExistentKeyColumns(array $columns): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable @@ -1557,7 +1554,7 @@ public function testDropForeignKeyByNonExistentKeyColumns(array $columns) $this->adapter->dropForeignKey($table->getName(), $columns); } - public function testDropForeignKeyCaseInsensitivity() + public function testDropForeignKeyCaseInsensitivity(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->save(); @@ -1572,7 +1569,7 @@ public function testDropForeignKeyCaseInsensitivity() $this->assertFalse($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'])); } - public function testDropForeignKeyByName() + public function testDropForeignKeyByName(): void { $this->expectExceptionMessage('SQLite does not have named foreign keys'); $this->expectException(BadMethodCallException::class); @@ -1594,7 +1591,7 @@ public function testDropForeignKeyByName() $this->adapter->dropForeignKey($table->getName(), [], 'my_constraint'); } - public function testHasDatabase() + public function testHasDatabase(): void { if ($this->config['database'] === ':memory:') { $this->markTestSkipped('Skipping hasDatabase() when testing in-memory db.'); @@ -1603,7 +1600,7 @@ public function testHasDatabase() $this->assertTrue($this->adapter->hasDatabase($this->config['database'])); } - public function testDropDatabase() + public function testDropDatabase(): void { $this->assertFalse($this->adapter->hasDatabase('phinx_temp_database')); $this->adapter->createDatabase('phinx_temp_database'); @@ -1611,7 +1608,7 @@ public function testDropDatabase() $this->adapter->dropDatabase('phinx_temp_database'); } - public function testAddColumnWithComment() + public function testAddColumnWithComment(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('column1', 'string', ['comment' => 'Comments from "column1"']) @@ -1628,7 +1625,7 @@ public function testAddColumnWithComment() $this->assertMatchesRegularExpression('/\/\* Comments from "column1" \*\//', $sql); } - public function testAddColumnTableWithConstraint() + public function testAddColumnTableWithConstraint(): void { $this->adapter->execute('PRAGMA foreign_keys = ON'); $roles = new Table('constraint_roles', [], $this->adapter); @@ -1648,13 +1645,13 @@ public function testAddColumnTableWithConstraint() $updatedRoles ->addColumn('description', 'string', ['default' => 'short desc']) ->update(); - $res = $this->adapter->fetchAll('select * from sqlite_master where type = \'table\''); + $res = $this->adapter->fetchAll("select * from sqlite_master where type = 'table'"); $res = $this->adapter->fetchRow('select * from constraint_roles LIMIT 1'); $this->assertArrayHasKey('description', $res, 'Should have new column in output'); $this->assertEquals('short desc', $res['description']); } - public function testAddIndexTwoTablesSameIndex() + public function testAddIndexTwoTablesSameIndex(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -1675,7 +1672,7 @@ public function testAddIndexTwoTablesSameIndex() $this->assertTrue($table2->hasIndex('email')); } - public function testBulkInsertData() + public function testBulkInsertData(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('column1', 'string') @@ -1698,7 +1695,7 @@ public function testBulkInsertData() ) ->insert( [ - 'column1' => '\'value4\'', + 'column1' => "'value4'", 'column2' => null, ], ) @@ -1708,14 +1705,14 @@ public function testBulkInsertData() $this->assertEquals('value1', $rows[0]['column1']); $this->assertEquals('value2', $rows[1]['column1']); $this->assertEquals('value3', $rows[2]['column1']); - $this->assertEquals('\'value4\'', $rows[3]['column1']); + $this->assertEquals("'value4'", $rows[3]['column1']); $this->assertEquals(1, $rows[0]['column2']); $this->assertEquals(2, $rows[1]['column2']); $this->assertEquals(3, $rows[2]['column2']); $this->assertNull($rows[3]['column2']); } - public function testBulkInsertLiteral() + public function testBulkInsertLiteral(): void { $data = [ [ @@ -1741,12 +1738,12 @@ public function testBulkInsertLiteral() $this->assertEquals('value1', $rows[0]['column1']); $this->assertEquals('value2', $rows[1]['column1']); $this->assertEquals('value3', $rows[2]['column1']); - $this->assertMatchesRegularExpression('/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/', $rows[0]['column2']); + $this->assertMatchesRegularExpression('/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $rows[0]['column2']); $this->assertEquals('2024-01-01 00:00:00', $rows[1]['column2']); $this->assertEquals('2025-01-01 00:00:00', $rows[2]['column2']); } - public function testInsertData() + public function testInsertData(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('column1', 'string') @@ -1769,7 +1766,7 @@ public function testInsertData() ) ->insert( [ - 'column1' => '\'value4\'', + 'column1' => "'value4'", 'column2' => null, ], ) @@ -1780,14 +1777,14 @@ public function testInsertData() $this->assertEquals('value1', $rows[0]['column1']); $this->assertEquals('value2', $rows[1]['column1']); $this->assertEquals('value3', $rows[2]['column1']); - $this->assertEquals('\'value4\'', $rows[3]['column1']); + $this->assertEquals("'value4'", $rows[3]['column1']); $this->assertEquals(1, $rows[0]['column2']); $this->assertEquals(2, $rows[1]['column2']); $this->assertEquals(3, $rows[2]['column2']); $this->assertNull($rows[3]['column2']); } - public function testInsertLiteral() + public function testInsertLiteral(): void { $data = [ [ @@ -1818,12 +1815,12 @@ public function testInsertLiteral() $this->assertEquals('test', $rows[0]['column2']); $this->assertEquals('test', $rows[1]['column2']); $this->assertEquals('foo', $rows[2]['column2']); - $this->assertMatchesRegularExpression('/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/', $rows[0]['column3']); + $this->assertMatchesRegularExpression('/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $rows[0]['column3']); $this->assertEquals('2024-01-01 00:00:00', $rows[1]['column3']); $this->assertEquals('2025-01-01 00:00:00', $rows[2]['column3']); } - public function testBulkInsertDataEnum() + public function testBulkInsertDataEnum(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('column1', 'string') @@ -1841,7 +1838,7 @@ public function testBulkInsertDataEnum() $this->assertEquals('c', $rows[0]['column3']); } - public function testNullWithoutDefaultValue() + public function testNullWithoutDefaultValue(): void { // construct table with default/null combinations $table = new Table('table1', [], $this->adapter); @@ -1878,7 +1875,7 @@ public function testNullWithoutDefaultValue() $this->assertEquals('some2', $dd->getDefault()); } - public function testDumpCreateTable() + public function testDumpCreateTable(): void { $this->adapter->setOptions($this->adapter->getOptions() + ['dryrun' => true]); $table = new Table('table1', [], $this->adapter); @@ -1891,7 +1888,7 @@ public function testDumpCreateTable() $expectedOutput = <<<'OUTPUT' CREATE TABLE "table1" ("id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, "column1" VARCHAR NOT NULL, "column2" INTEGER, "column3" VARCHAR DEFAULT 'test'); OUTPUT; - $actualOutput = join("\n", $this->out->messages()); + $actualOutput = implode("\n", $this->out->messages()); $this->assertStringContainsString($expectedOutput, $actualOutput, 'Passing the --dry-run option does not dump create table query to the output'); } @@ -1900,7 +1897,7 @@ public function testDumpCreateTable() * Then sets phinx to dry run mode and inserts a record. * Asserts that phinx outputs the insert statement and doesn't insert a record. */ - public function testDumpInsert() + public function testDumpInsert(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('string_col', 'string') @@ -1925,9 +1922,9 @@ public function testDumpInsert() INSERT INTO "table1" ("string_col") VALUES (null); INSERT INTO "table1" ("int_col") VALUES (23); OUTPUT; - $actualOutput = join("\n", $this->out->messages()); + $actualOutput = implode("\n", $this->out->messages()); $actualOutput = preg_replace("/\r\n|\r/", "\n", $actualOutput); // normalize line endings for Windows - $this->assertStringContainsString($expectedOutput, $actualOutput, 'Passing the --dry-run option doesn\'t dump the insert to the output'); + $this->assertStringContainsString($expectedOutput, $actualOutput, "Passing the --dry-run option doesn't dump the insert to the output"); $countQuery = $this->adapter->query('SELECT COUNT(*) FROM table1'); $this->assertTrue($countQuery->execute()); @@ -1940,7 +1937,7 @@ public function testDumpInsert() * Then sets phinx to dry run mode and inserts some records. * Asserts that phinx outputs the insert statement and doesn't insert any record. */ - public function testDumpBulkinsert() + public function testDumpBulkinsert(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('string_col', 'string') @@ -1962,8 +1959,8 @@ public function testDumpBulkinsert() $expectedOutput = <<<'OUTPUT' INSERT INTO "table1" ("string_col", "int_col") VALUES ('test_data1', 23), (null, 42); OUTPUT; - $actualOutput = join("\n", $this->out->messages()); - $this->assertStringContainsString($expectedOutput, $actualOutput, 'Passing the --dry-run option doesn\'t dump the bulkinsert to the output'); + $actualOutput = implode("\n", $this->out->messages()); + $this->assertStringContainsString($expectedOutput, $actualOutput, "Passing the --dry-run option doesn't dump the bulkinsert to the output"); $countQuery = $this->adapter->query('SELECT COUNT(*) FROM table1'); $this->assertTrue($countQuery->execute()); @@ -1971,7 +1968,7 @@ public function testDumpBulkinsert() $this->assertEquals(0, $res[0][0]); } - public function testDumpCreateTableAndThenInsert() + public function testDumpCreateTableAndThenInsert(): void { $this->adapter->setOptions($this->adapter->getOptions() + ['dryrun' => true]); $table = new Table('table1', ['id' => false, 'primary_key' => ['column1']], $this->adapter); @@ -1992,7 +1989,7 @@ public function testDumpCreateTableAndThenInsert() CREATE TABLE "table1" ("column1" VARCHAR NOT NULL, "column2" INTEGER, PRIMARY KEY ("column1")); INSERT INTO "table1" ("column1", "column2") VALUES ('id1', 1); OUTPUT; - $actualOutput = join("\n", $this->out->messages()); + $actualOutput = implode("\n", $this->out->messages()); $actualOutput = preg_replace("/\r\n|\r/", "\n", $actualOutput); // normalize line endings for Windows $this->assertStringContainsString($expectedOutput, $actualOutput, 'Passing the --dry-run option does not dump create and then insert table queries to the output'); } @@ -2000,7 +1997,7 @@ public function testDumpCreateTableAndThenInsert() /** * Tests interaction with the query builder */ - public function testQueryBuilder() + public function testQueryBuilder(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('string_col', 'string') @@ -2039,7 +2036,7 @@ public function testQueryBuilder() $this->assertEquals(1, $stm->rowCount()); } - public function testQueryWithParams() + public function testQueryWithParams(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('string_col', 'string') @@ -2074,7 +2071,7 @@ public function testQueryWithParams() * Tests adding more than one column to a table * that already exists due to adapters having different add column instructions */ - public function testAlterTableColumnAdd() + public function testAlterTableColumnAdd(): void { $table = new Table('table1', [], $this->adapter); $table->create(); @@ -2099,14 +2096,14 @@ public function testAlterTableColumnAdd() $columnCount = count($columns); for ($i = 0; $i < $columnCount; $i++) { - $this->assertSame($expected[$i]['name'], $columns[$i]->getName(), "Wrong name for {$expected[$i]['name']}"); - $this->assertSame($expected[$i]['type'], $columns[$i]->getType(), "Wrong type for {$expected[$i]['name']}"); - $this->assertSame($expected[$i]['default'], $columns[$i]->getDefault() instanceof Literal ? (string)$columns[$i]->getDefault() : $columns[$i]->getDefault(), "Wrong default for {$expected[$i]['name']}"); - $this->assertSame($expected[$i]['null'], $columns[$i]->getNull(), "Wrong null for {$expected[$i]['name']}"); + $this->assertSame($expected[$i]['name'], $columns[$i]->getName(), 'Wrong name for ' . $expected[$i]['name']); + $this->assertSame($expected[$i]['type'], $columns[$i]->getType(), 'Wrong type for ' . $expected[$i]['name']); + $this->assertSame($expected[$i]['default'], $columns[$i]->getDefault() instanceof Literal ? (string)$columns[$i]->getDefault() : $columns[$i]->getDefault(), 'Wrong default for ' . $expected[$i]['name']); + $this->assertSame($expected[$i]['null'], $columns[$i]->getNull(), 'Wrong null for ' . $expected[$i]['name']); } } - public function testAlterTableWithConstraints() + public function testAlterTableWithConstraints(): void { $table = new Table('table1', [], $this->adapter); $table->create(); @@ -2135,10 +2132,10 @@ public function testAlterTableWithConstraints() $columnCount = count($columns); for ($i = 0; $i < $columnCount; $i++) { - $this->assertSame($expected[$i]['name'], $columns[$i]->getName(), "Wrong name for {$expected[$i]['name']}"); - $this->assertSame($expected[$i]['type'], $columns[$i]->getType(), "Wrong type for {$expected[$i]['name']}"); - $this->assertSame($expected[$i]['default'], $columns[$i]->getDefault() instanceof Literal ? (string)$columns[$i]->getDefault() : $columns[$i]->getDefault(), "Wrong default for {$expected[$i]['name']}"); - $this->assertSame($expected[$i]['null'], $columns[$i]->getNull(), "Wrong null for {$expected[$i]['name']}"); + $this->assertSame($expected[$i]['name'], $columns[$i]->getName(), 'Wrong name for ' . $expected[$i]['name']); + $this->assertSame($expected[$i]['type'], $columns[$i]->getType(), 'Wrong type for ' . $expected[$i]['name']); + $this->assertSame($expected[$i]['default'], $columns[$i]->getDefault() instanceof Literal ? (string)$columns[$i]->getDefault() : $columns[$i]->getDefault(), 'Wrong default for ' . $expected[$i]['name']); + $this->assertSame($expected[$i]['null'], $columns[$i]->getNull(), 'Wrong null for ' . $expected[$i]['name']); } } @@ -2146,7 +2143,7 @@ public function testAlterTableWithConstraints() * Tests that operations that trigger implicit table drops will not cause * a foreign key constraint violation error. */ - public function testAlterTableDoesNotViolateRestrictedForeignKeyConstraint() + public function testAlterTableDoesNotViolateRestrictedForeignKeyConstraint(): void { $this->adapter->execute('PRAGMA foreign_keys = ON'); @@ -2213,7 +2210,7 @@ public function testAlterTableDoesNotViolateRestrictedForeignKeyConstraint() * alteration process (being it implicitly by the process itself or by the user) * will trigger an error accordingly. */ - public function testAlterTableDoesViolateForeignKeyConstraintOnTargetTableChange() + public function testAlterTableDoesViolateForeignKeyConstraintOnTargetTableChange(): void { $articlesTable = new Table('articles', [], $this->adapter); $articlesTable @@ -2249,7 +2246,7 @@ public function testAlterTableDoesViolateForeignKeyConstraintOnTargetTableChange * alteration process (being it implicitly by the process itself or by the user) * will trigger an error accordingly. */ - public function testAlterTableDoesViolateForeignKeyConstraintOnSourceTableChange() + public function testAlterTableDoesViolateForeignKeyConstraintOnSourceTableChange(): void { $adapter = $this ->getMockBuilder(SqliteAdapter::class) @@ -2302,7 +2299,7 @@ public function testAlterTableDoesViolateForeignKeyConstraintOnSourceTableChange * Tests that the adapter's foreign key validation does not apply when * the `foreign_keys` pragma is set to `OFF`. */ - public function testAlterTableForeignKeyConstraintValidationNotRunningWithDisabledForeignKeys() + public function testAlterTableForeignKeyConstraintValidationNotRunningWithDisabledForeignKeys(): void { $articlesTable = new Table('articles', [], $this->adapter); $articlesTable @@ -2345,7 +2342,7 @@ public function testAlterTableForeignKeyConstraintValidationNotRunningWithDisabl ->update(); } - public function testLiteralSupport() + public function testLiteralSupport(): void { $createQuery = <<<'INPUT' CREATE TABLE `test` (`real_col` DECIMAL) @@ -2358,23 +2355,23 @@ public function testLiteralSupport() } #[DataProvider('provideTableNamesForPresenceCheck')] - public function testHasTable($createName, $tableName, $exp) + public function testHasTable(string $createName, string $tableName, bool $exp): void { // Test case for issue #1535 $conn = $this->adapter->getConnection(); - $conn->execute('ATTACH DATABASE \':memory:\' as etc'); + $conn->execute("ATTACH DATABASE ':memory:' as etc"); $conn->execute('ATTACH DATABASE \':memory:\' as "main.db"'); $conn->execute(sprintf('DROP TABLE IF EXISTS %s', $createName)); $this->assertFalse($this->adapter->hasTable($tableName), sprintf('Adapter claims table %s exists when it does not', $tableName)); $conn->execute(sprintf('CREATE TABLE %s (a text)', $createName)); - if ($exp == true) { + if ($exp) { $this->assertTrue($this->adapter->hasTable($tableName), sprintf('Adapter claims table %s does not exist when it does', $tableName)); } else { $this->assertFalse($this->adapter->hasTable($tableName), sprintf('Adapter claims table %s exists when it does not', $tableName)); } } - public static function provideTableNamesForPresenceCheck() + public static function provideTableNamesForPresenceCheck(): array { return [ 'Ordinary table' => ['t', 't', true], @@ -2386,8 +2383,8 @@ public static function provideTableNamesForPresenceCheck() 'Wrong schema 1' => ['t', 'etc.t', false], 'Wrong schema 2' => ['t', 'temp.t', false], 'Missing schema' => ['t', 'not_attached.t', false], - 'Malicious table' => ['"\'"', '\'', true], - 'Malicious missing table' => ['t', '\'', false], + 'Malicious table' => ['"\'"', "'", true], + 'Malicious missing table' => ['t', "'", false], 'Table name case 1' => ['t', 'T', true], 'Table name case 2' => ['T', 't', true], 'Schema name case 1' => ['main.t', 'MAIN.t', true], @@ -2424,10 +2421,10 @@ public function testHasTableAfterExecuteDrop(): void } #[DataProvider('provideIndexColumnsToCheck')] - public function testHasIndex($tableDef, $cols, $exp) + public function testHasIndex(string $tableDef, string|array $cols, bool $exp): void { $conn = $this->adapter->getConnection(); - if (strpos($tableDef, ';') !== false) { + if (str_contains($tableDef, ';')) { $queries = explode(';', $tableDef); foreach ($queries as $query) { $stmt = $conn->execute($query); @@ -2441,7 +2438,7 @@ public function testHasIndex($tableDef, $cols, $exp) $this->assertEquals($exp, $this->adapter->hasIndex('t', $cols)); } - public static function provideIndexColumnsToCheck() + public static function provideIndexColumnsToCheck(): array { return [ ['create table t(a text)', 'a', false], @@ -2464,10 +2461,10 @@ public static function provideIndexColumnsToCheck() } #[DataProvider('provideIndexNamesToCheck')] - public function testHasIndexByName($tableDef, $index, $exp) + public function testHasIndexByName(string $tableDef, string $index, bool $exp): void { $conn = $this->adapter->getConnection(); - if (strpos($tableDef, ';') !== false) { + if (str_contains($tableDef, ';')) { $queries = explode(';', $tableDef); foreach ($queries as $query) { $stmt = $conn->execute($query); @@ -2480,7 +2477,7 @@ public function testHasIndexByName($tableDef, $index, $exp) $this->assertEquals($exp, $this->adapter->hasIndexByName('t', $index)); } - public static function provideIndexNamesToCheck() + public static function provideIndexNamesToCheck(): array { return [ ['create table t(a text)', 'test', false], @@ -2496,11 +2493,11 @@ public static function provideIndexNamesToCheck() } #[DataProvider('providePrimaryKeysToCheck')] - public function testHasPrimaryKey($tableDef, $key, $exp) + public function testHasPrimaryKey(string $tableDef, string|array $key, bool $exp): void { $this->assertFalse($this->adapter->hasTable('t'), 'Dirty test fixture'); $conn = $this->adapter->getConnection(); - if (strpos($tableDef, ';') !== false) { + if (str_contains($tableDef, ';')) { $queries = explode(';', $tableDef); foreach ($queries as $query) { $stmt = $conn->execute($query); @@ -2513,7 +2510,7 @@ public function testHasPrimaryKey($tableDef, $key, $exp) $this->assertSame($exp, $this->adapter->hasPrimaryKey('t', $key)); } - public static function providePrimaryKeysToCheck() + public static function providePrimaryKeysToCheck(): array { return [ ['create table t(a integer)', 'a', false], @@ -2525,7 +2522,7 @@ public static function providePrimaryKeysToCheck() ['create table t("a" integer PRIMARY KEY)', 'a', true], ['create table t([a] integer PRIMARY KEY)', 'a', true], ['create table t(`a` integer PRIMARY KEY)', 'a', true], - ['create table t(\'a\' integer PRIMARY KEY)', 'a', true], + ["create table t('a' integer PRIMARY KEY)", 'a', true], ['create table t(`a.a` integer PRIMARY KEY)', 'a.a', true], ['create table t(a integer primary key)', ['a'], true], ['create table t(a integer primary key)', ['a', 'b'], false], @@ -2555,7 +2552,7 @@ public static function providePrimaryKeysToCheck() ]; } - public function testHasNamedPrimaryKey() + public function testHasNamedPrimaryKey(): void { $this->expectException(InvalidArgumentException::class); @@ -2563,11 +2560,11 @@ public function testHasNamedPrimaryKey() } #[DataProvider('provideForeignKeysToCheck')] - public function testHasForeignKey($tableDef, $key, $exp) + public function testHasForeignKey(string $tableDef, string|array $key, bool $exp): void { $conn = $this->adapter->getConnection(); $conn->execute('CREATE TABLE other(a integer, b integer, c integer)'); - if (strpos($tableDef, ';') !== false) { + if (str_contains($tableDef, ';')) { $queries = explode(';', $tableDef); foreach ($queries as $query) { $stmt = $conn->execute($query); @@ -2581,7 +2578,7 @@ public function testHasForeignKey($tableDef, $key, $exp) $this->assertSame($exp, $this->adapter->hasForeignKey('t', $key)); } - public static function provideForeignKeysToCheck() + public static function provideForeignKeysToCheck(): array { return [ ['create table t(a integer)', 'a', false], @@ -2723,13 +2720,13 @@ public static function hasNamedForeignKeyProvider(): array } #[DataProvider('provideColumnTypesForValidation')] - public function testIsValidColumnType($phinxType, $exp) + public function testIsValidColumnType(string $phinxType, bool $exp): void { $col = (new Column())->setType($phinxType); $this->assertSame($exp, $this->adapter->isValidColumnType($col)); } - public static function provideColumnTypesForValidation() + public static function provideColumnTypesForValidation(): array { return [ [SqliteAdapter::TYPE_BIGINTEGER, true], @@ -2761,12 +2758,12 @@ public static function provideColumnTypesForValidation() } #[DataProvider('provideDatabaseVersionStrings')] - public function testDatabaseVersionAtLeast($ver, $exp) + public function testDatabaseVersionAtLeast(string $ver, bool $exp): void { $this->assertSame($exp, $this->adapter->databaseVersionAtLeast($ver)); } - public static function provideDatabaseVersionStrings() + public static function provideDatabaseVersionStrings(): array { return [ ['2', true], @@ -2780,10 +2777,10 @@ public static function provideDatabaseVersionStrings() } #[DataProvider('provideColumnNamesToCheck')] - public function testHasColumn($tableDef, $col, $exp) + public function testHasColumn(string $tableDef, string $col, bool $exp): void { $conn = $this->adapter->getConnection(); - if (strpos($tableDef, ';') !== false) { + if (str_contains($tableDef, ';')) { $queries = explode(';', $tableDef); foreach ($queries as $query) { $stmt = $conn->execute($query); @@ -2797,7 +2794,7 @@ public function testHasColumn($tableDef, $col, $exp) $this->assertEquals($exp, $this->adapter->hasColumn('t', $col)); } - public static function provideColumnNamesToCheck() + public static function provideColumnNamesToCheck(): array { return [ ['create table t(a text)', 'a', true], @@ -2805,7 +2802,7 @@ public static function provideColumnNamesToCheck() ['create table t(A text)', 'A', true], ['create table t("a" text)', 'a', true], ['create table t([a] text)', 'a', true], - ['create table t(\'a\' text)', 'a', true], + ["create table t('a' text)", 'a', true], ['create table t("A" text)', 'A', true], ['create table t(a text)', 'a', true], ['create table t(b text)', 'a', false], @@ -2818,10 +2815,11 @@ public static function provideColumnNamesToCheck() ]; } - public function testGetColumns() + public function testGetColumns(): void { $conn = $this->adapter->getConnection(); $conn->execute('create table t(a integer, b text, c char(5), d integer(12,6), e integer not null, f integer null)'); + $exp = [ ['name' => 'a', 'type' => 'integer', 'null' => true, 'limit' => null, 'precision' => null, 'scale' => null], ['name' => 'b', 'type' => 'text', 'null' => true, 'limit' => null, 'precision' => null, 'scale' => null], @@ -2836,16 +2834,17 @@ public function testGetColumns() $this->assertInstanceOf(Column::class, $act[$index]); foreach ($data as $key => $value) { $m = 'get' . ucfirst($key); - $this->assertEquals($value, $act[$index]->$m(), "Parameter '$key' of column at index $index did not match expectations."); + $this->assertEquals($value, $act[$index]->$m(), sprintf("Parameter '%s' of column at index %s did not match expectations.", $key, $index)); } } } #[DataProvider('provideIdentityCandidates')] - public function testGetColumnsForIdentity($tableDef, $exp) + public function testGetColumnsForIdentity(string $tableDef, ?string $exp): void { $conn = $this->adapter->getConnection(); $conn->execute($tableDef); + $cols = $this->adapter->getColumns('t'); $act = []; foreach ($cols as $col) { @@ -2856,7 +2855,7 @@ public function testGetColumnsForIdentity($tableDef, $exp) $this->assertEquals((array)$exp, $act); } - public static function provideIdentityCandidates() + public static function provideIdentityCandidates(): array { return [ ['create table t(a text)', null], @@ -2871,7 +2870,7 @@ public static function provideIdentityCandidates() } #[DataProvider('provideDefaultValues')] - public function testGetColumnsForDefaults($tableDef, $exp) + public function testGetColumnsForDefaults(string $tableDef, string|Literal|int|float|Expression|null $exp): void { $conn = $this->adapter->getConnection(); $conn->execute($tableDef); @@ -2884,7 +2883,7 @@ public function testGetColumnsForDefaults($tableDef, $exp) } } - public static function provideDefaultValues() + public static function provideDefaultValues(): array { return [ 'Implicit null' => ['create table t(a integer)', null], @@ -2905,12 +2904,12 @@ public static function provideDefaultValues() 'Current timestamp LC' => ['create table t(a datetime default current_timestamp)', 'CURRENT_TIMESTAMP'], 'Current timestamp UC' => ['create table t(a datetime default CURRENT_TIMESTAMP)', 'CURRENT_TIMESTAMP'], 'Current timestamp MC' => ['create table t(a datetime default CURRENT_timestamp)', 'CURRENT_TIMESTAMP'], - 'String 1' => ['create table t(a text default \'\')', Literal::from('')], - 'String 2' => ['create table t(a text default \'value!\')', Literal::from('value!')], - 'String 3' => ['create table t(a text default \'O\'\'Brien\')', Literal::from('O\'Brien')], - 'String 4' => ['create table t(a text default \'CURRENT_TIMESTAMP\')', Literal::from('CURRENT_TIMESTAMP')], - 'String 5' => ['create table t(a text default \'current_timestamp\')', Literal::from('current_timestamp')], - 'String 6' => ['create table t(a text default \'\' /* comment */)', Literal::from('')], + 'String 1' => ["create table t(a text default '')", Literal::from('')], + 'String 2' => ["create table t(a text default 'value!')", Literal::from('value!')], + 'String 3' => ["create table t(a text default 'O''Brien')", Literal::from("O'Brien")], + 'String 4' => ["create table t(a text default 'CURRENT_TIMESTAMP')", Literal::from('CURRENT_TIMESTAMP')], + 'String 5' => ["create table t(a text default 'current_timestamp')", Literal::from('current_timestamp')], + 'String 6' => ["create table t(a text default '' /* comment */)", Literal::from('')], 'Hexadecimal LC' => ['create table t(a integer default 0xff)', 255], 'Hexadecimal UC' => ['create table t(a integer default 0XFF)', 255], 'Hexadecimal MC' => ['create table t(a integer default 0x1F)', 31], @@ -2934,26 +2933,27 @@ public static function provideDefaultValues() 'Float 9' => ['create table t(a float default 1e+1)', 10.0], 'Float 10' => ['create table t(a float default 1e-1)', 0.1], 'Float 11' => ['create table t(a float default 1E-1)', 0.1], - 'Blob literal 1' => ['create table t(a float default x\'ff\')', Expression::from('x\'ff\'')], - 'Blob literal 2' => ['create table t(a float default X\'FF\')', Expression::from('X\'FF\'')], + 'Blob literal 1' => ["create table t(a float default x'ff')", Expression::from("x'ff'")], + 'Blob literal 2' => ["create table t(a float default X'FF')", Expression::from("X'FF'")], 'Arbitrary expression' => ['create table t(a float default ((2) + (2)))', Expression::from('(2) + (2)')], - 'Pathological case 1' => ['create table t(a float default (\'/*\' || \'*/\'))', Expression::from('/*\' || \'*/')], + 'Pathological case 1' => ["create table t(a float default ('/*' || '*/'))", Expression::from("/*' || '*/")], ]; } #[DataProvider('provideBooleanDefaultValues')] - public function testGetColumnsForBooleanDefaults($tableDef, $exp) + public function testGetColumnsForBooleanDefaults(string $tableDef, int $exp): void { if (!$this->adapter->databaseVersionAtLeast('3.24')) { $this->markTestSkipped('SQLite 3.24.0 or later is required for this test.'); } $conn = $this->adapter->getConnection(); $conn->execute($tableDef); + $act = $this->adapter->getColumns('t')[0]->getDefault(); $this->assertSame($exp, $act); } - public static function provideBooleanDefaultValues() + public static function provideBooleanDefaultValues(): array { return [ 'True LC' => ['create table t(a boolean default true)', 1], @@ -2966,26 +2966,26 @@ public static function provideBooleanDefaultValues() } #[DataProvider('provideTablesForTruncation')] - public function testTruncateTable($tableDef, $tableName, $tableId) + public function testTruncateTable(string $tableDef, string $tableName, string $tableId): void { $conn = $this->adapter->getConnection(); $conn->execute($tableDef); - $conn->execute("INSERT INTO $tableId default values"); - $conn->execute("INSERT INTO $tableId default values"); - $conn->execute("INSERT INTO $tableId default values"); - $this->assertEquals(3, $conn->execute("select count(*) from $tableId")->fetchColumn(0), 'Broken fixture: data were not inserted properly'); - $this->assertEquals(3, $conn->execute("select max(id) from $tableId")->fetchColumn(0), 'Broken fixture: data were not inserted properly'); + $conn->execute(sprintf('INSERT INTO %s default values', $tableId)); + $conn->execute(sprintf('INSERT INTO %s default values', $tableId)); + $conn->execute(sprintf('INSERT INTO %s default values', $tableId)); + $this->assertEquals(3, $conn->execute('select count(*) from ' . $tableId)->fetchColumn(0), 'Broken fixture: data were not inserted properly'); + $this->assertEquals(3, $conn->execute('select max(id) from ' . $tableId)->fetchColumn(0), 'Broken fixture: data were not inserted properly'); $this->adapter->truncateTable($tableName); - $this->assertEquals(0, $conn->execute("select count(*) from $tableId")->fetchColumn(0), 'Table was not truncated'); - $conn->execute("INSERT INTO $tableId default values"); - $this->assertEquals(1, $conn->execute("select max(id) from $tableId")->fetchColumn(0), 'Autoincrement was not reset'); - $conn->execute("DROP TABLE $tableId"); + $this->assertEquals(0, $conn->execute('select count(*) from ' . $tableId)->fetchColumn(0), 'Table was not truncated'); + $conn->execute(sprintf('INSERT INTO %s default values', $tableId)); + $this->assertEquals(1, $conn->execute('select max(id) from ' . $tableId)->fetchColumn(0), 'Autoincrement was not reset'); + $conn->execute('DROP TABLE ' . $tableId); } /** * @return array */ - public static function provideTablesForTruncation() + public static function provideTablesForTruncation(): array { return [ ['create table t(id integer primary key)', 't', 't'], @@ -3003,7 +3003,7 @@ public static function provideTablesForTruncation() ]; } - public function testForeignKeyReferenceCorrectAfterRenameColumn() + public function testForeignKeyReferenceCorrectAfterRenameColumn(): void { $refTableColumnId = 'ref_table_id'; $refTableColumnToRename = 'columnToRename'; @@ -3019,7 +3019,7 @@ public function testForeignKeyReferenceCorrectAfterRenameColumn() $refTable->renameColumn($refTableColumnToRename, $refTableRenamedColumn)->save(); $this->assertTrue($this->adapter->hasForeignKey($table->getName(), [$refTableColumnId])); - $this->assertFalse($this->adapter->hasTable("tmp_{$refTable->getName()}")); + $this->assertFalse($this->adapter->hasTable('tmp_' . $refTable->getName())); $this->assertTrue($this->adapter->hasColumn($refTable->getName(), $refTableRenamedColumn)); $rows = $this->adapter->fetchAll('select * from sqlite_master where "type" = \'table\''); @@ -3028,10 +3028,10 @@ public function testForeignKeyReferenceCorrectAfterRenameColumn() $sql = $row['sql']; } } - $this->assertStringContainsString("REFERENCES \"{$refTable->getName()}\" (\"id\")", $sql); + $this->assertStringContainsString(sprintf('REFERENCES "%s" ("id")', $refTable->getName()), $sql); } - public function testForeignKeyReferenceCorrectAfterChangeColumn() + public function testForeignKeyReferenceCorrectAfterChangeColumn(): void { $refTableColumnId = 'ref_table_id'; $refTableColumnToChange = 'columnToChange'; @@ -3046,7 +3046,7 @@ public function testForeignKeyReferenceCorrectAfterChangeColumn() $refTable->changeColumn($refTableColumnToChange, 'text')->save(); $this->assertTrue($this->adapter->hasForeignKey($table->getName(), [$refTableColumnId])); - $this->assertFalse($this->adapter->hasTable("tmp_{$refTable->getName()}")); + $this->assertFalse($this->adapter->hasTable('tmp_' . $refTable->getName())); $this->assertEquals('text', $this->adapter->getColumns($refTable->getName())[1]->getType()); $rows = $this->adapter->fetchAll('select * from sqlite_master where "type" = \'table\''); @@ -3055,10 +3055,10 @@ public function testForeignKeyReferenceCorrectAfterChangeColumn() $sql = $row['sql']; } } - $this->assertStringContainsString("REFERENCES \"{$refTable->getName()}\" (\"id\")", $sql); + $this->assertStringContainsString(sprintf('REFERENCES "%s" ("id")', $refTable->getName()), $sql); } - public function testForeignKeyReferenceCorrectAfterRemoveColumn() + public function testForeignKeyReferenceCorrectAfterRemoveColumn(): void { $refTableColumnId = 'ref_table_id'; $refTableColumnToRemove = 'columnToRemove'; @@ -3073,7 +3073,7 @@ public function testForeignKeyReferenceCorrectAfterRemoveColumn() $refTable->removeColumn($refTableColumnToRemove)->save(); $this->assertTrue($this->adapter->hasForeignKey($table->getName(), [$refTableColumnId])); - $this->assertFalse($this->adapter->hasTable("tmp_{$refTable->getName()}")); + $this->assertFalse($this->adapter->hasTable('tmp_' . $refTable->getName())); $this->assertFalse($this->adapter->hasColumn($refTable->getName(), $refTableColumnToRemove)); $rows = $this->adapter->fetchAll('select * from sqlite_master where "type" = \'table\''); @@ -3082,10 +3082,10 @@ public function testForeignKeyReferenceCorrectAfterRemoveColumn() $sql = $row['sql']; } } - $this->assertStringContainsString("REFERENCES \"{$refTable->getName()}\" (\"id\")", $sql); + $this->assertStringContainsString(sprintf('REFERENCES "%s" ("id")', $refTable->getName()), $sql); } - public function testForeignKeyReferenceCorrectAfterChangePrimaryKey() + public function testForeignKeyReferenceCorrectAfterChangePrimaryKey(): void { $refTableColumnAdditionalId = 'additional_id'; $refTableColumnId = 'ref_table_id'; @@ -3103,7 +3103,7 @@ public function testForeignKeyReferenceCorrectAfterChangePrimaryKey() ->save(); $this->assertTrue($this->adapter->hasForeignKey($table->getName(), [$refTableColumnId])); - $this->assertFalse($this->adapter->hasTable("tmp_{$refTable->getName()}")); + $this->assertFalse($this->adapter->hasTable('tmp_' . $refTable->getName())); $this->assertTrue($this->adapter->getColumns($refTable->getName())[1]->getIdentity()); $rows = $this->adapter->fetchAll('select * from sqlite_master where "type" = \'table\''); @@ -3112,10 +3112,10 @@ public function testForeignKeyReferenceCorrectAfterChangePrimaryKey() $sql = $row['sql']; } } - $this->assertStringContainsString("REFERENCES \"{$refTable->getName()}\" (\"id\")", $sql); + $this->assertStringContainsString(sprintf('REFERENCES "%s" ("id")', $refTable->getName()), $sql); } - public function testForeignKeyReferenceCorrectAfterDropForeignKey() + public function testForeignKeyReferenceCorrectAfterDropForeignKey(): void { $refTableAdditionalColumnId = 'ref_table_additional_id'; $refTableAdditional = new Table('ref_table_additional', [], $this->adapter); @@ -3135,7 +3135,7 @@ public function testForeignKeyReferenceCorrectAfterDropForeignKey() $refTable->dropForeignKey($refTableAdditionalColumnId)->save(); $this->assertTrue($this->adapter->hasForeignKey($table->getName(), [$refTableColumnId])); - $this->assertFalse($this->adapter->hasTable("tmp_{$refTable->getName()}")); + $this->assertFalse($this->adapter->hasTable('tmp_' . $refTable->getName())); $this->assertFalse($this->adapter->hasForeignKey($refTable->getName(), [$refTableAdditionalColumnId])); $rows = $this->adapter->fetchAll('select * from sqlite_master where "type" = \'table\''); @@ -3144,17 +3144,17 @@ public function testForeignKeyReferenceCorrectAfterDropForeignKey() $sql = $row['sql']; } } - $this->assertStringContainsString("REFERENCES \"{$refTable->getName()}\" (\"id\")", $sql); + $this->assertStringContainsString(sprintf('REFERENCES "%s" ("id")', $refTable->getName()), $sql); } - public function testPdoExceptionUpdateNonExistingTable() + public function testPdoExceptionUpdateNonExistingTable(): void { $this->expectException(PDOException::class); $table = new Table('non_existing_table', [], $this->adapter); $table->addColumn('column', 'string')->update(); } - public function testAddCheckConstraint() + public function testAddCheckConstraint(): void { $table = new Table('check_table', [], $this->adapter); $table->addColumn('price', 'decimal', ['precision' => 10, 'scale' => 2]) @@ -3166,7 +3166,7 @@ public function testAddCheckConstraint() $this->assertTrue($this->adapter->hasCheckConstraint('check_table', 'price_positive')); } - public function testHasCheckConstraint() + public function testHasCheckConstraint(): void { $table = new Table('check_table3', [], $this->adapter); $table->addColumn('quantity', 'integer') @@ -3180,7 +3180,7 @@ public function testHasCheckConstraint() $this->assertTrue($this->adapter->hasCheckConstraint('check_table3', 'quantity_positive')); } - public function testDropCheckConstraint() + public function testDropCheckConstraint(): void { $table = new Table('check_table4', [], $this->adapter); $table->addColumn('price', 'decimal', ['precision' => 10, 'scale' => 2]) @@ -3194,7 +3194,7 @@ public function testDropCheckConstraint() $this->assertFalse($this->adapter->hasCheckConstraint('check_table4', 'price_check')); } - public function testCheckConstraintWithComplexExpression() + public function testCheckConstraintWithComplexExpression(): void { $table = new Table('check_table5', [], $this->adapter); $table->addColumn('email', 'string', ['limit' => 255]) @@ -3211,10 +3211,10 @@ public function testCheckConstraintWithComplexExpression() // Verify the constraint is actually enforced $quotedTableName = $this->adapter->getConnection()->getDriver()->quoteIdentifier('check_table5'); $this->expectException(PDOException::class); - $this->adapter->execute("INSERT INTO {$quotedTableName} (email, status) VALUES ('test@example.com', 'invalid')"); + $this->adapter->execute(sprintf("INSERT INTO %s (email, status) VALUES ('test@example.com', 'invalid')", $quotedTableName)); } - public function testInsertOrSkipWithDuplicates() + public function testInsertOrSkipWithDuplicates(): void { $table = new Table('users', [], $this->adapter); $table->addColumn('email', 'string', ['limit' => 255]) @@ -3237,7 +3237,7 @@ public function testInsertOrSkipWithDuplicates() $this->assertEquals('John', $rows[0]['name']); } - public function testInsertModeResetsAfterInsertOrSkip() + public function testInsertModeResetsAfterInsertOrSkip(): void { $table = new Table('users', [], $this->adapter); $table->addColumn('email', 'string', ['limit' => 255]) @@ -3257,7 +3257,7 @@ public function testInsertModeResetsAfterInsertOrSkip() ])->save(); } - public function testBulkinsertOrSkipWithDuplicates() + public function testBulkinsertOrSkipWithDuplicates(): void { $table = new Table('products', [], $this->adapter); $table->addColumn('sku', 'string', ['limit' => 50]) @@ -3284,7 +3284,7 @@ public function testBulkinsertOrSkipWithDuplicates() $this->assertEquals('30.00', $rows[2]['price']); } - public function testInsertOrSkipWithoutDuplicates() + public function testInsertOrSkipWithoutDuplicates(): void { $table = new Table('categories', [], $this->adapter); $table->addColumn('name', 'string') @@ -3300,7 +3300,7 @@ public function testInsertOrSkipWithoutDuplicates() $this->assertCount(2, $rows); } - public function testInsertOrUpdateWithDuplicates() + public function testInsertOrUpdateWithDuplicates(): void { $table = new Table('currencies', [], $this->adapter); $table->addColumn('code', 'string', ['limit' => 3]) @@ -3333,7 +3333,7 @@ public function testInsertOrUpdateWithDuplicates() $this->assertEquals('1.0500', $rows[2]['rate']); // USD updated } - public function testInsertOrUpdateWithMultipleUpdateColumns() + public function testInsertOrUpdateWithMultipleUpdateColumns(): void { $table = new Table('products', [], $this->adapter); $table->addColumn('sku', 'string', ['limit' => 50]) @@ -3358,7 +3358,7 @@ public function testInsertOrUpdateWithMultipleUpdateColumns() $this->assertEquals(50, $rows[0]['stock']); } - public function testInsertOrUpdateModeResetsAfterSave() + public function testInsertOrUpdateModeResetsAfterSave(): void { $table = new Table('items', [], $this->adapter); $table->addColumn('code', 'string', ['limit' => 10]) @@ -3378,7 +3378,7 @@ public function testInsertOrUpdateModeResetsAfterSave() ])->save(); } - public function testInsertOrUpdateRequiresConflictColumns() + public function testInsertOrUpdateRequiresConflictColumns(): void { $table = new Table('currencies', [], $this->adapter); $table->addColumn('code', 'string', ['limit' => 3]) diff --git a/tests/TestCase/Db/Adapter/SqlserverAdapterTest.php b/tests/TestCase/Db/Adapter/SqlserverAdapterTest.php index f494d45d2..91dc7d0ae 100644 --- a/tests/TestCase/Db/Adapter/SqlserverAdapterTest.php +++ b/tests/TestCase/Db/Adapter/SqlserverAdapterTest.php @@ -22,13 +22,12 @@ class SqlserverAdapterTest extends TestCase { - /** - * @var \Migrations\Db\Adapter\SqlServerAdapter - */ - private $adapter; + private SqlserverAdapter $adapter; private array $config; + private StubConsoleOutput $out; + private ConsoleIo $io; protected function setUp(): void @@ -73,12 +72,12 @@ protected function getConsoleIo(): ConsoleIo return $this->io; } - public function testConnection() + public function testConnection(): void { $this->assertInstanceOf(Connection::class, $this->adapter->getConnection()); } - public function testCreatingTheSchemaTableOnConnect() + public function testCreatingTheSchemaTableOnConnect(): void { $this->adapter->connect(); $this->assertTrue($this->adapter->hasTable($this->adapter->getSchemaTableName())); @@ -89,25 +88,25 @@ public function testCreatingTheSchemaTableOnConnect() $this->assertTrue($this->adapter->hasTable($this->adapter->getSchemaTableName())); } - public function testSchemaTableIsCreatedWithPrimaryKey() + public function testSchemaTableIsCreatedWithPrimaryKey(): void { $this->adapter->connect(); new Table($this->adapter->getSchemaTableName(), [], $this->adapter); $this->assertTrue($this->adapter->hasIndex($this->adapter->getSchemaTableName(), ['version'])); } - public function testQuoteTableName() + public function testQuoteTableName(): void { $this->assertEquals('[dbo].[test_table]', $this->adapter->quoteTableName('test_table')); $this->assertEquals('[schema].[table]', $this->adapter->quoteTableName('schema.table')); } - public function testQuoteColumnName() + public function testQuoteColumnName(): void { $this->assertEquals('[test_column]', $this->adapter->quoteColumnName('test_column')); } - public function testCreateTable() + public function testCreateTable(): void { $table = new Table('ntable', [], $this->adapter); $table->addColumn('realname', 'string') @@ -120,7 +119,7 @@ public function testCreateTable() $this->assertFalse($this->adapter->hasColumn('ntable', 'address')); } - public function testCreateTableWithSchema() + public function testCreateTableWithSchema(): void { $this->adapter->createSchema('nschema'); @@ -138,7 +137,7 @@ public function testCreateTableWithSchema() $this->adapter->dropSchema('nschema'); } - public function testCreateTableCustomIdColumn() + public function testCreateTableCustomIdColumn(): void { $table = new Table('ntable', ['id' => 'custom_id'], $this->adapter); $table->addColumn('realname', 'string') @@ -151,7 +150,7 @@ public function testCreateTableCustomIdColumn() $this->assertFalse($this->adapter->hasColumn('ntable', 'address')); } - public function testCreateTableIdentityColumn() + public function testCreateTableIdentityColumn(): void { $table = new Table('ntable', ['id' => false, 'primary_key' => 'id'], $this->adapter); $table->addColumn('id', 'integer', ['identity' => true]) @@ -160,7 +159,7 @@ public function testCreateTableIdentityColumn() $this->assertTrue($this->adapter->hasColumn('ntable', 'id')); } - public function testCreateTableWithNoPrimaryKey() + public function testCreateTableWithNoPrimaryKey(): void { $options = [ 'id' => false, @@ -171,7 +170,7 @@ public function testCreateTableWithNoPrimaryKey() $this->assertFalse($this->adapter->hasColumn('atable', 'id')); } - public function testCreateTableWithConflictingPrimaryKeys() + public function testCreateTableWithConflictingPrimaryKeys(): void { $options = [ 'primary_key' => 'user_id', @@ -183,7 +182,7 @@ public function testCreateTableWithConflictingPrimaryKeys() $table->addColumn('user_id', 'integer')->save(); } - public function testCreateTableWithPrimaryKeySetToImplicitId() + public function testCreateTableWithPrimaryKeySetToImplicitId(): void { $options = [ 'primary_key' => 'id', @@ -195,7 +194,7 @@ public function testCreateTableWithPrimaryKeySetToImplicitId() $this->assertTrue($this->adapter->hasColumn('ztable', 'user_id')); } - public function testCreateTableWithPrimaryKeyArraySetToImplicitId() + public function testCreateTableWithPrimaryKeyArraySetToImplicitId(): void { $options = [ 'primary_key' => ['id'], @@ -207,7 +206,7 @@ public function testCreateTableWithPrimaryKeyArraySetToImplicitId() $this->assertTrue($this->adapter->hasColumn('ztable', 'user_id')); } - public function testCreateTableWithMultiplePrimaryKeyArraySetToImplicitId() + public function testCreateTableWithMultiplePrimaryKeyArraySetToImplicitId(): void { $options = [ 'primary_key' => ['id', 'user_id'], @@ -218,7 +217,7 @@ public function testCreateTableWithMultiplePrimaryKeyArraySetToImplicitId() $table->addColumn('user_id', 'integer')->save(); } - public function testCreateTableWithMultiplePrimaryKeys() + public function testCreateTableWithMultiplePrimaryKeys(): void { $options = [ 'id' => false, @@ -233,7 +232,7 @@ public function testCreateTableWithMultiplePrimaryKeys() $this->assertFalse($this->adapter->hasIndex('table1', ['tag_id', 'user_email'])); } - public function testCreateTableWithPrimaryKeyAsUuid() + public function testCreateTableWithPrimaryKeyAsUuid(): void { $options = [ 'id' => false, @@ -247,7 +246,7 @@ public function testCreateTableWithPrimaryKeyAsUuid() $this->assertTrue($this->adapter->hasColumn('ztable', 'user_id')); } - public function testCreateTableWithPrimaryKeyAsBinaryUuid() + public function testCreateTableWithPrimaryKeyAsBinaryUuid(): void { $options = [ 'id' => false, @@ -261,7 +260,7 @@ public function testCreateTableWithPrimaryKeyAsBinaryUuid() $this->assertTrue($this->adapter->hasColumn('ztable', 'user_id')); } - public function testCreateTableWithMultipleIndexes() + public function testCreateTableWithMultipleIndexes(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -275,7 +274,7 @@ public function testCreateTableWithMultipleIndexes() $this->assertFalse($this->adapter->hasIndex('table1', ['email', 'user_name'])); } - public function testCreateTableWithUniqueIndexes() + public function testCreateTableWithUniqueIndexes(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -285,7 +284,7 @@ public function testCreateTableWithUniqueIndexes() $this->assertFalse($this->adapter->hasIndex('table1', ['email', 'user_email'])); } - public function testCreateTableWithNamedIndexes() + public function testCreateTableWithNamedIndexes(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -319,7 +318,7 @@ public function testCreateTableIndexWithWhere(): void $this->assertStringContainsString('([email]) WHERE is_verified = true', $indexQuery); } - public function testAddPrimaryKey() + public function testAddPrimaryKey(): void { $table = new Table('table1', ['id' => false], $this->adapter); $table @@ -333,7 +332,7 @@ public function testAddPrimaryKey() $this->assertTrue($this->adapter->hasPrimaryKey('table1', ['column1'])); } - public function testChangePrimaryKey() + public function testChangePrimaryKey(): void { $table = new Table('table1', ['id' => false, 'primary_key' => 'column1'], $this->adapter); $table @@ -350,7 +349,7 @@ public function testChangePrimaryKey() $this->assertTrue($this->adapter->hasPrimaryKey('table1', ['column2', 'column3'])); } - public function testDropPrimaryKey() + public function testDropPrimaryKey(): void { $table = new Table('table1', ['id' => false, 'primary_key' => 'column1'], $this->adapter); $table @@ -364,7 +363,7 @@ public function testDropPrimaryKey() $this->assertFalse($this->adapter->hasPrimaryKey('table1', ['column1'])); } - public function testHasPrimaryKeyMultipleColumns() + public function testHasPrimaryKeyMultipleColumns(): void { $table = new Table('table1', ['id' => false, 'primary_key' => ['column1', 'column2', 'column3']], $this->adapter); $table @@ -378,7 +377,7 @@ public function testHasPrimaryKeyMultipleColumns() $this->assertFalse($table->hasPrimaryKey(['column1', 'column2', 'column3', 'column4'])); } - public function testHasPrimaryKeyCaseSensitivity() + public function testHasPrimaryKeyCaseSensitivity(): void { $table = new Table('table', ['id' => false, 'primary_key' => ['column1']], $this->adapter); $table @@ -389,7 +388,7 @@ public function testHasPrimaryKeyCaseSensitivity() $this->assertFalse($table->hasPrimaryKey('cOlUmN1')); } - public function testChangeCommentFails() + public function testChangeCommentFails(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -401,7 +400,7 @@ public function testChangeCommentFails() ->save(); } - public function testRenameTable() + public function testRenameTable(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -412,7 +411,7 @@ public function testRenameTable() $this->assertTrue($this->adapter->hasTable('table2')); } - public function testAddColumn() + public function testAddColumn(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -422,7 +421,7 @@ public function testAddColumn() $this->assertTrue($table->hasColumn('email')); } - public function testAddColumnWithDefaultValue() + public function testAddColumnWithDefaultValue(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -436,7 +435,7 @@ public function testAddColumnWithDefaultValue() } } - public function testAddColumnWithDefaultZero() + public function testAddColumnWithDefaultZero(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -451,7 +450,7 @@ public function testAddColumnWithDefaultZero() } } - public function testAddColumnWithDefaultNull() + public function testAddColumnWithDefaultNull(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -465,7 +464,7 @@ public function testAddColumnWithDefaultNull() } } - public function testAddColumnWithNotNullableNoDefault() + public function testAddColumnWithNotNullableNoDefault(): void { $table = new Table('table1', [], $this->adapter); $table @@ -480,7 +479,7 @@ public function testAddColumnWithNotNullableNoDefault() $this->assertNull($columns[1]->getDefault()); } - public function testAddColumnWithDefaultBool() + public function testAddColumnWithDefaultBool(): void { $table = new Table('table1', [], $this->adapter); $table->save(); @@ -499,7 +498,7 @@ public function testAddColumnWithDefaultBool() } } - public function testRenameColumn() + public function testRenameColumn(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -511,7 +510,7 @@ public function testRenameColumn() $this->assertTrue($this->adapter->hasColumn('t', 'column2')); } - public function testRenamingANonExistentColumn() + public function testRenamingANonExistentColumn(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -524,13 +523,13 @@ public function testRenamingANonExistentColumn() $this->assertInstanceOf( 'InvalidArgumentException', $e, - 'Expected exception of type InvalidArgumentException, got ' . get_class($e), + 'Expected exception of type InvalidArgumentException, got ' . $e::class, ); $this->assertEquals('The specified column does not exist: column2', $e->getMessage()); } } - public function testChangeColumnType() + public function testChangeColumnType(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -549,7 +548,7 @@ public function testChangeColumnType() } } - public function testChangeColumnNameAndNull() + public function testChangeColumnNameAndNull(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['null' => false]) @@ -569,7 +568,7 @@ public function testChangeColumnNameAndNull() } } - public function testChangeColumnDefaults() + public function testChangeColumnDefaults(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['default' => 'test']) @@ -591,7 +590,7 @@ public function testChangeColumnDefaults() $this->assertSame('another test', $columns[1]->getDefault()); } - public function testChangeColumnDefaultToNull() + public function testChangeColumnDefaultToNull(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string', ['null' => true, 'default' => 'test']) @@ -606,7 +605,7 @@ public function testChangeColumnDefaultToNull() $this->assertNull($columns[1]->getDefault()); } - public function testChangeColumnDefaultToZero() + public function testChangeColumnDefaultToZero(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'integer') @@ -621,7 +620,7 @@ public function testChangeColumnDefaultToZero() $this->assertSame(0, $columns[1]->getDefault()); } - public function testDropColumn() + public function testDropColumn(): void { $table = new Table('t', [], $this->adapter); $table->addColumn('column1', 'string') @@ -631,7 +630,7 @@ public function testDropColumn() $this->assertFalse($this->adapter->hasColumn('t', 'column1')); } - public static function columnsProvider() + public static function columnsProvider(): array { return [ ['column1', 'string', ['null' => true, 'default' => null]], @@ -655,7 +654,7 @@ public static function columnsProvider() } #[DataProvider('columnsProvider')] - public function testGetColumns($colName, $type, $options, $actualType = null) + public function testGetColumns(string $colName, string $type, array $options, ?string $actualType = null): void { $table = new Table('t', [], $this->adapter); $table @@ -671,7 +670,7 @@ public function testGetColumns($colName, $type, $options, $actualType = null) $this->assertEquals($actualType ?? $type, $columns[1]->getType()); } - public function testAddIndex() + public function testAddIndex(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -682,7 +681,7 @@ public function testAddIndex() $this->assertTrue($table->hasIndex('email')); } - public function testAddIndexWithSort() + public function testAddIndexWithSort(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -710,7 +709,7 @@ public function testAddIndexWithSort() $this->assertEquals($emailOrder['sort_order'], 'ASC'); } - public function testAddIndexWithIncludeColumns() + public function testAddIndexWithIncludeColumns(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('email', 'string') @@ -747,7 +746,7 @@ public function testAddIndexWithIncludeColumns() $this->assertEquals($emailOrder['included'], 1); } - public function testGetIndexes() + public function testGetIndexes(): void { // single column index $table = new Table('table1', [], $this->adapter); @@ -771,7 +770,7 @@ public function testGetIndexes() $this->assertEquals(['email', 'username'], $indexes[2]['columns']); } - public function testDropIndex() + public function testDropIndex(): void { // single column index $table = new Table('table1', [], $this->adapter); @@ -812,7 +811,7 @@ public function testDropIndex() $this->assertFalse($table4->hasIndex(['fname', 'lname'])); } - public function testDropIndexByName() + public function testDropIndexByName(): void { // single column index $table = new Table('table1', [], $this->adapter); @@ -838,7 +837,7 @@ public function testDropIndexByName() $this->assertFalse($table2->hasIndex(['fname', 'lname'])); } - public function testAddForeignKey() + public function testAddForeignKey(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -856,7 +855,7 @@ public function testAddForeignKey() $this->assertTrue($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'], 'fk1')); } - public function testDropForeignKey() + public function testDropForeignKey(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->addColumn('field1', 'string')->save(); @@ -872,7 +871,7 @@ public function testDropForeignKey() $this->assertFalse($this->adapter->hasForeignKey($table->getName(), ['ref_table_id'])); } - public function testDropForeignKeyWithMultipleColumns() + public function testDropForeignKeyWithMultipleColumns(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable @@ -922,7 +921,7 @@ public function testDropForeignKeyWithMultipleColumns() $this->assertFalse($this->adapter->hasForeignKey($table->getName(), ['ref_table_field1', 'ref_table_id'])); } - public function testDropForeignKeyWithIdenticalMultipleColumns() + public function testDropForeignKeyWithIdenticalMultipleColumns(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable @@ -969,11 +968,8 @@ public static function nonExistentForeignKeyColumnsProvider(): array ]; } - /** - * @param array $columns - */ #[DataProvider('nonExistentForeignKeyColumnsProvider')] - public function testDropForeignKeyByNonExistentKeyColumns(array $columns) + public function testDropForeignKeyByNonExistentKeyColumns(array $columns): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable @@ -1001,7 +997,7 @@ public function testDropForeignKeyByNonExistentKeyColumns(array $columns) $this->adapter->dropForeignKey($table->getName(), $columns); } - public function testDropForeignKeyCaseSensitivity() + public function testDropForeignKeyCaseSensitivity(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->save(); @@ -1023,7 +1019,7 @@ public function testDropForeignKeyCaseSensitivity() $this->adapter->dropForeignKey($table->getName(), ['ref_table_id']); } - public function testDropForeignKeyByName() + public function testDropForeignKeyByName(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->save(); @@ -1044,7 +1040,7 @@ public function testDropForeignKeyByName() } #[DataProvider('provideForeignKeysToCheck')] - public function testHasForeignKey($tableDef, $key, $exp) + public function testHasForeignKey(string $tableDef, string|array $key, bool $exp): void { $conn = $this->adapter->getConnection(); $conn->execute('CREATE TABLE other(a int, b int, c int, unique(a), unique(b), unique(a,b), unique(a,b,c));'); @@ -1052,7 +1048,7 @@ public function testHasForeignKey($tableDef, $key, $exp) $this->assertSame($exp, $this->adapter->hasForeignKey('t', $key)); } - public static function provideForeignKeysToCheck() + public static function provideForeignKeysToCheck(): array { return [ ['create table t(a int)', 'a', false], @@ -1079,7 +1075,7 @@ public static function provideForeignKeysToCheck() ]; } - public function testHasNamedForeignKey() + public function testHasNamedForeignKey(): void { $refTable = new Table('ref_table', [], $this->adapter); $refTable->save(); @@ -1102,13 +1098,13 @@ public function testHasNamedForeignKey() $this->assertFalse($this->adapter->hasForeignKey($table->getName(), [], 'my_constraint2')); } - public function testHasDatabase() + public function testHasDatabase(): void { $this->assertFalse($this->adapter->hasDatabase('fake_database_name')); $this->assertTrue($this->adapter->hasDatabase($this->config['database'])); } - public function testDropDatabase() + public function testDropDatabase(): void { $this->assertFalse($this->adapter->hasDatabase('phinx_temp_database')); $this->adapter->createDatabase('phinx_temp_database'); @@ -1116,13 +1112,13 @@ public function testDropDatabase() $this->adapter->dropDatabase('phinx_temp_database'); } - public function testCreateSchema() + public function testCreateSchema(): void { $this->adapter->createSchema('foo'); $this->assertTrue($this->adapter->hasSchema('foo')); } - public function testDropSchema() + public function testDropSchema(): void { $this->adapter->createSchema('foo'); $this->assertTrue($this->adapter->hasSchema('foo')); @@ -1130,7 +1126,7 @@ public function testDropSchema() $this->assertFalse($this->adapter->hasSchema('foo')); } - public function testDropAllSchemas() + public function testDropAllSchemas(): void { $this->adapter->createSchema('foo'); $this->adapter->createSchema('bar'); @@ -1142,14 +1138,14 @@ public function testDropAllSchemas() $this->assertFalse($this->adapter->hasSchema('bar')); } - public function testQuoteSchemaName() + public function testQuoteSchemaName(): void { $this->assertEquals('[schema]', $this->adapter->quoteSchemaName('schema')); // Dotted schema names are not supported $this->assertEquals('[schema].[schema]', $this->adapter->quoteSchemaName('schema.schema')); } - public function testAddColumnComment() + public function testAddColumnComment(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('field1', 'string', ['comment' => $comment = 'Comments from column "field1"']) @@ -1161,7 +1157,7 @@ public function testAddColumnComment() } #[Depends('testAddColumnComment')] - public function testChangeColumnComment() + public function testChangeColumnComment(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('field1', 'string', ['comment' => 'Comments from column "field1"']) @@ -1176,7 +1172,7 @@ public function testChangeColumnComment() } #[Depends('testAddColumnComment')] - public function testRemoveColumnComment() + public function testRemoveColumnComment(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('field1', 'string', ['comment' => 'Comments from column "field1"']) @@ -1193,7 +1189,7 @@ public function testRemoveColumnComment() /** * Test that column names are properly escaped when creating Foreign Keys */ - public function testForignKeysArePropertlyEscaped() + public function testForignKeysArePropertlyEscaped(): void { $userId = 'user'; $sessionId = 'session'; @@ -1209,7 +1205,7 @@ public function testForignKeysArePropertlyEscaped() $this->assertTrue($foreign->hasForeignKey('user')); } - public function testBulkInsertData() + public function testBulkInsertData(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('column1', 'string') @@ -1245,7 +1241,7 @@ public function testBulkInsertData() $this->assertEquals(3, $rows[2]['column2']); } - public function testBulkInsertLiteral() + public function testBulkInsertLiteral(): void { $data = [ [ @@ -1271,12 +1267,12 @@ public function testBulkInsertLiteral() $this->assertEquals('value1', $rows[0]['column1']); $this->assertEquals('value2', $rows[1]['column1']); $this->assertEquals('value3', $rows[2]['column1']); - $this->assertMatchesRegularExpression('/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/', $rows[0]['column2']); + $this->assertMatchesRegularExpression('/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $rows[0]['column2']); $this->assertEquals('2024-01-01 00:00:00.0000000', $rows[1]['column2']); $this->assertEquals('2025-01-01 00:00:00.0000000', $rows[2]['column2']); } - public function testInsertData() + public function testInsertData(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('column1', 'string') @@ -1309,7 +1305,7 @@ public function testInsertData() $this->assertEquals(3, $rows[2]['column2']); } - public function testInsertLiteral() + public function testInsertLiteral(): void { $data = [ [ @@ -1340,12 +1336,12 @@ public function testInsertLiteral() $this->assertEquals('test', $rows[0]['column2']); $this->assertEquals('test', $rows[1]['column2']); $this->assertEquals('foo', $rows[2]['column2']); - $this->assertMatchesRegularExpression('/[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}/', $rows[0]['column3']); + $this->assertMatchesRegularExpression('/\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/', $rows[0]['column3']); $this->assertEquals('2024-01-01 00:00:00.0000000', $rows[1]['column3']); $this->assertEquals('2025-01-01 00:00:00.0000000', $rows[2]['column3']); } - public function testTruncateTable() + public function testTruncateTable(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('column1', 'string') @@ -1369,7 +1365,7 @@ public function testTruncateTable() $this->assertCount(0, $rows); } - public function testDumpCreateTableAndThenInsert() + public function testDumpCreateTableAndThenInsert(): void { $options = $this->adapter->getOptions(); $options['dryrun'] = true; @@ -1393,7 +1389,7 @@ public function testDumpCreateTableAndThenInsert() CREATE TABLE [dbo].[table1] ([column1] NVARCHAR(255) NOT NULL, [column2] INTEGER DEFAULT NULL, CONSTRAINT PK_table1 PRIMARY KEY ([column1])); INSERT INTO [dbo].[table1] ([column1], [column2]) VALUES ('id1', 1); OUTPUT; - $output = join("\n", $this->out->messages()); + $output = implode("\n", $this->out->messages()); $actualOutput = str_replace("\r\n", "\n", $output); $this->assertStringContainsString($expectedOutput, $actualOutput, 'Passing the --dry-run option does not dump create and then insert table queries to the output'); } @@ -1401,7 +1397,7 @@ public function testDumpCreateTableAndThenInsert() /** * Tests interaction with the query builder */ - public function testQueryBuilder() + public function testQueryBuilder(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('string_col', 'string') @@ -1442,7 +1438,7 @@ public function testQueryBuilder() $stm->closeCursor(); } - public function testQueryWithParams() + public function testQueryWithParams(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('string_col', 'string') @@ -1473,7 +1469,7 @@ public function testQueryWithParams() $this->assertEquals(3, $res[0]['c']); } - public function testIdentityInsert() + public function testIdentityInsert(): void { $table = new Table('table1', [], $this->adapter); $table->addColumn('name', 'string') @@ -1500,7 +1496,7 @@ public function testIdentityInsert() $this->assertEquals(50, $res[1]['id']); } - public function testInsertOrSkipThrowsException() + public function testInsertOrSkipThrowsException(): void { $table = new Table('users', [], $this->adapter); $table->addColumn('email', 'string', ['limit' => 255]) diff --git a/tests/TestCase/Db/Adapter/UnifiedMigrationsTableStorageTest.php b/tests/TestCase/Db/Adapter/UnifiedMigrationsTableStorageTest.php index d7b30fc83..223609ad5 100644 --- a/tests/TestCase/Db/Adapter/UnifiedMigrationsTableStorageTest.php +++ b/tests/TestCase/Db/Adapter/UnifiedMigrationsTableStorageTest.php @@ -21,12 +21,7 @@ */ class UnifiedMigrationsTableStorageTest extends TestCase { - /** - * @var bool - */ - private bool $tableCreated = false; - - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -37,7 +32,7 @@ public function setUp(): void $this->cleanupTable(); } - public function tearDown(): void + protected function tearDown(): void { // Always clean up the table $this->cleanupTable(); @@ -74,7 +69,7 @@ private function cleanupTable(): void // Also drop any phinxlog tables that might exist $connection->execute('DROP TABLE IF EXISTS phinxlog'); $connection->execute('DROP TABLE IF EXISTS migrator_phinxlog'); - } catch (Exception $e) { + } catch (Exception) { // Ignore cleanup errors } } @@ -96,7 +91,6 @@ public function testMigrateCreatesUnifiedTable(): void $dialect = $connection->getDriver()->schemaDialect(); $this->assertTrue($dialect->hasTable(UnifiedMigrationsTableStorage::TABLE_NAME)); - $this->tableCreated = true; // Verify records were inserted with null plugin (app migrations) $result = $connection->selectQuery() @@ -120,7 +114,6 @@ public function testMigratePluginUsesUnifiedTable(): void // Run app migrations first to create the table $this->exec('migrations migrate -c test --source Migrations --no-lock'); $this->assertExitSuccess(); - $this->tableCreated = true; // Clear the migration records for app (but keep the table) $this->clearMigrationRecords('test'); @@ -148,7 +141,6 @@ public function testRollbackWithUnifiedTable(): void // Run migrations $this->exec('migrations migrate -c test --source Migrations --no-lock'); $this->assertExitSuccess(); - $this->tableCreated = true; // Verify we have records $initialCount = $this->getMigrationRecordCount('test'); @@ -168,7 +160,6 @@ public function testStatusWithUnifiedTable(): void // Run migrations $this->exec('migrations migrate -c test --source Migrations --no-lock'); $this->assertExitSuccess(); - $this->tableCreated = true; // Check status $this->exec('migrations status -c test --source Migrations'); @@ -183,7 +174,6 @@ public function testAppAndPluginMigrationsAreSeparated(): void // Run app migrations $this->exec('migrations migrate -c test --source Migrations --no-lock'); $this->assertExitSuccess(); - $this->tableCreated = true; // Run plugin migrations $this->exec('migrations migrate -c test --plugin Migrator --no-lock'); diff --git a/tests/TestCase/Db/LiteralTest.php b/tests/TestCase/Db/LiteralTest.php index e8c55fdb5..1ff0c617a 100644 --- a/tests/TestCase/Db/LiteralTest.php +++ b/tests/TestCase/Db/LiteralTest.php @@ -8,18 +8,18 @@ class LiteralTest extends TestCase { - public function testToString() + public function testToString(): void { $str = 'test1'; $instance = new Literal($str); $this->assertEquals($str, (string)$instance); } - public function testFrom() + public function testFrom(): void { $str = 'test1'; $instance = Literal::from($str); - $this->assertInstanceOf('\Migrations\Db\Literal', $instance); + $this->assertInstanceOf(Literal::class, $instance); $this->assertEquals($str, (string)$instance); } } diff --git a/tests/TestCase/Db/Table/ColumnTest.php b/tests/TestCase/Db/Table/ColumnTest.php index 2d5ccd1ae..045cf21ce 100644 --- a/tests/TestCase/Db/Table/ColumnTest.php +++ b/tests/TestCase/Db/Table/ColumnTest.php @@ -22,7 +22,7 @@ protected function tearDown(): void Configure::delete('Migrations.unsigned_ints'); } - public function testNullConstructorParameter() + public function testNullConstructorParameter(): void { $column = new Column(name: 'title'); $this->assertTrue($column->isNull()); @@ -38,7 +38,7 @@ public function testNullConstructorParameter() $this->assertTrue($column->isNull()); } - public function testSetOptionThrowsExceptionIfOptionIsNotString() + public function testSetOptionThrowsExceptionIfOptionIsNotString(): void { $column = new Column(); @@ -48,7 +48,7 @@ public function testSetOptionThrowsExceptionIfOptionIsNotString() $column->setOptions(['identity']); } - public function testSetOptionsIdentity() + public function testSetOptionsIdentity(): void { $column = new Column(); $this->assertTrue($column->isNull()); @@ -59,7 +59,7 @@ public function testSetOptionsIdentity() $this->assertTrue($column->isIdentity()); } - public function testColumnNullFeatureFlag() + public function testColumnNullFeatureFlag(): void { $column = new Column(); $this->assertTrue($column->isNull()); diff --git a/tests/TestCase/Db/Table/ForeignKeyTest.php b/tests/TestCase/Db/Table/ForeignKeyTest.php index c2fce98ab..4c9fc179e 100644 --- a/tests/TestCase/Db/Table/ForeignKeyTest.php +++ b/tests/TestCase/Db/Table/ForeignKeyTest.php @@ -11,10 +11,7 @@ class ForeignKeyTest extends TestCase { - /** - * @var ForeignKey - */ - private $fk; + private ForeignKey $fk; protected function setUp(): void { @@ -38,7 +35,7 @@ public function testReferencedColumns(): void $this->assertEquals(['user_id', 'tenant_id'], $this->fk->getReferencedColumns()); } - public function testOnDeleteSetNullCanBeSetThroughOptions() + public function testOnDeleteSetNullCanBeSetThroughOptions(): void { $this->assertEquals( ForeignKey::SET_NULL, @@ -46,30 +43,22 @@ public function testOnDeleteSetNullCanBeSetThroughOptions() ); } - public function testInitiallyActionsEmpty() + public function testInitiallyActionsEmpty(): void { $this->assertSame(ForeignKey::NO_ACTION, $this->fk->getOnDelete()); $this->assertSame(ForeignKey::NO_ACTION, $this->fk->getOnUpdate()); } - /** - * @param string $dirtyValue - * @param string $valueOfConstant - */ #[DataProvider('actionsProvider')] - public function testBothActionsCanBeSetThroughSetters($dirtyValue, $valueOfConstant) + public function testBothActionsCanBeSetThroughSetters(string $dirtyValue, string $valueOfConstant): void { $this->fk->setOnDelete($dirtyValue)->setOnUpdate($dirtyValue); $this->assertEquals($valueOfConstant, $this->fk->getOnDelete()); $this->assertEquals($valueOfConstant, $this->fk->getOnUpdate()); } - /** - * @param string $dirtyValue - * @param string $valueOfConstant - */ #[DataProvider('actionsProvider')] - public function testBothActionsCanBeSetThroughOptions($dirtyValue, $valueOfConstant) + public function testBothActionsCanBeSetThroughOptions(string $dirtyValue, string $valueOfConstant): void { $this->fk->setOptions([ 'delete' => $dirtyValue, @@ -79,21 +68,21 @@ public function testBothActionsCanBeSetThroughOptions($dirtyValue, $valueOfConst $this->assertEquals($valueOfConstant, $this->fk->getOnUpdate()); } - public function testUnknownActionsNotAllowedThroughSetter() + public function testUnknownActionsNotAllowedThroughSetter(): void { $this->expectException(InvalidArgumentException::class); $this->fk->setOnDelete('i m dump'); } - public function testUnknownActionsNotAllowedThroughOptions() + public function testUnknownActionsNotAllowedThroughOptions(): void { $this->expectException(InvalidArgumentException::class); $this->fk->setOptions(['update' => 'no yu a dumb']); } - public static function actionsProvider() + public static function actionsProvider(): array { return [ [ForeignKey::CASCADE, ForeignKey::CASCADE], @@ -107,7 +96,7 @@ public static function actionsProvider() ]; } - public function testSetOptionThrowsExceptionIfOptionIsNotString() + public function testSetOptionThrowsExceptionIfOptionIsNotString(): void { $this->expectException(RuntimeException::class); $this->expectExceptionMessage('"0" is not a valid foreign key option'); diff --git a/tests/TestCase/Db/Table/IndexTest.php b/tests/TestCase/Db/Table/IndexTest.php index 6c9011c20..b42c3e136 100644 --- a/tests/TestCase/Db/Table/IndexTest.php +++ b/tests/TestCase/Db/Table/IndexTest.php @@ -9,7 +9,7 @@ class IndexTest extends TestCase { - public function testSetOptionThrowsExceptionIfOptionIsNotString() + public function testSetOptionThrowsExceptionIfOptionIsNotString(): void { $column = new Index(); diff --git a/tests/TestCase/Db/Table/TableTest.php b/tests/TestCase/Db/Table/TableTest.php index 463e9aa86..3bd3e5cba 100644 --- a/tests/TestCase/Db/Table/TableTest.php +++ b/tests/TestCase/Db/Table/TableTest.php @@ -49,7 +49,7 @@ public static function provideTimestampColumnNames(): array return $result; } - public function testAddColumnWithAnInvalidColumnType() + public function testAddColumnWithAnInvalidColumnType(): void { try { $adapter = new MysqlAdapter([]); @@ -61,13 +61,13 @@ public function testAddColumnWithAnInvalidColumnType() $this->assertInstanceOf( 'InvalidArgumentException', $e, - 'Expected exception of type InvalidArgumentException, got ' . get_class($e), + 'Expected exception of type InvalidArgumentException, got ' . $e::class, ); $this->assertStringStartsWith('An invalid column type ', $e->getMessage()); } } - public function testAddColumnWithColumnObject() + public function testAddColumnWithColumnObject(): void { $adapter = new MysqlAdapter([]); $column = new Column(); @@ -75,12 +75,13 @@ public function testAddColumnWithColumnObject() ->setType('integer'); $table = new Table('ntable', [], $adapter); $table->addColumn($column); + $actions = $this->getPendingActions($table); $this->assertInstanceOf(AddColumn::class, $actions[0]); $this->assertSame($column, $actions[0]->getColumn()); } - public function testAddColumnWithNoAdapterSpecified() + public function testAddColumnWithNoAdapterSpecified(): void { try { $table = new Table('ntable'); @@ -90,12 +91,12 @@ public function testAddColumnWithNoAdapterSpecified() $this->assertInstanceOf( 'RuntimeException', $e, - 'Expected exception of type RuntimeException, got ' . get_class($e), + 'Expected exception of type RuntimeException, got ' . $e::class, ); } } - public function testAddComment() + public function testAddComment(): void { $adapter = new MysqlAdapter([]); $table = new Table('ntable', ['comment' => 'test comment'], $adapter); @@ -103,7 +104,7 @@ public function testAddComment() $this->assertEquals('test comment', $options['comment']); } - public function testAddIndexWithIndexObject() + public function testAddIndexWithIndexObject(): void { $adapter = new MysqlAdapter([]); $index = new Index(); @@ -111,6 +112,7 @@ public function testAddIndexWithIndexObject() ->setColumns(['email']); $table = new Table('ntable', [], $adapter); $table->addIndex($index); + $actions = $this->getPendingActions($table); $this->assertInstanceOf(AddIndex::class, $actions[0]); $this->assertSame($index, $actions[0]->getIndex()); @@ -158,7 +160,6 @@ public function testAddForeignKeyWithObject(): void } /** - * @param AdapterInterface $adapter * @param string|null $createdAtColumnName * @param string|null $updatedAtColumnName * @param string $expectedCreatedAtColumnName @@ -168,14 +169,15 @@ public function testAddForeignKeyWithObject(): void #[DataProvider('provideTimestampColumnNames')] public function testAddTimestamps( AdapterInterface $adapter, - $createdAtColumnName, - $updatedAtColumnName, + string|bool|null $createdAtColumnName, + string|bool|null $updatedAtColumnName, $expectedCreatedAtColumnName, $expectedUpdatedAtColumnName, $withTimezone, ): void { $table = new Table('ntable', [], $adapter); $table->addTimestamps($createdAtColumnName, $updatedAtColumnName, $withTimezone); + $actions = $this->getPendingActions($table); $columns = []; @@ -198,14 +200,12 @@ public function testAddTimestamps( $this->assertNull($columns[1]->getDefault()); } - /** - * @param AdapterInterface $adapter - */ #[DataProvider('provideAdapters')] - public function testAddTimestampsNoUpdated(AdapterInterface $adapter) + public function testAddTimestampsNoUpdated(AdapterInterface $adapter): void { $table = new Table('ntable', [], $adapter); $table->addTimestamps(null, false); + $actions = $this->getPendingActions($table); $columns = []; @@ -223,14 +223,12 @@ public function testAddTimestampsNoUpdated(AdapterInterface $adapter) $this->assertSame('', $columns[0]->getUpdate()); } - /** - * @param AdapterInterface $adapter - */ #[DataProvider('provideAdapters')] - public function testAddTimestampsNoCreated(AdapterInterface $adapter) + public function testAddTimestampsNoCreated(AdapterInterface $adapter): void { $table = new Table('ntable', [], $adapter); $table->addTimestamps(false, null); + $actions = $this->getPendingActions($table); $columns = []; @@ -249,11 +247,8 @@ public function testAddTimestampsNoCreated(AdapterInterface $adapter) $this->assertNull($columns[0]->getDefault()); } - /** - * @param AdapterInterface $adapter - */ #[DataProvider('provideAdapters')] - public function testAddTimestampsThrowsOnBothFalse(AdapterInterface $adapter) + public function testAddTimestampsThrowsOnBothFalse(AdapterInterface $adapter): void { $table = new Table('ntable', [], $adapter); $this->expectException(RuntimeException::class); @@ -262,7 +257,6 @@ public function testAddTimestampsThrowsOnBothFalse(AdapterInterface $adapter) } /** - * @param AdapterInterface $adapter * @param string|null $createdAtColumnName * @param string|null $updatedAtColumnName * @param string $expectedCreatedAtColumnName @@ -272,14 +266,15 @@ public function testAddTimestampsThrowsOnBothFalse(AdapterInterface $adapter) #[DataProvider('provideTimestampColumnNames')] public function testAddTimestampsWithTimezone( AdapterInterface $adapter, - $createdAtColumnName, - $updatedAtColumnName, + string|bool|null $createdAtColumnName, + string|bool|null $updatedAtColumnName, $expectedCreatedAtColumnName, $expectedUpdatedAtColumnName, $withTimezone, ): void { $table = new Table('ntable', [], $adapter); $table->addTimestampsWithTimezone($createdAtColumnName, $updatedAtColumnName); + $actions = $this->getPendingActions($table); $columns = []; @@ -302,7 +297,7 @@ public function testAddTimestampsWithTimezone( $this->assertNull($columns[1]->getDefault()); } - public function testInsert() + public function testInsert(): void { $adapterStub = $this->getMockBuilder(MysqlAdapter::class) ->setConstructorArgs([[]]) @@ -319,7 +314,7 @@ public function testInsert() $this->assertEquals($expectedData, $table->getData()); } - public function testInsertMultipleRowsWithoutZeroKey() + public function testInsertMultipleRowsWithoutZeroKey(): void { $adapterStub = $this->getMockBuilder(MysqlAdapter::class) ->setConstructorArgs([[]]) @@ -340,7 +335,7 @@ public function testInsertMultipleRowsWithoutZeroKey() $this->assertEquals($expectedData, $table->getData()); } - public function testInsertSaveEmptyData() + public function testInsertSaveEmptyData(): void { $adapterStub = $this->getMockBuilder(MysqlAdapter::class) ->setConstructorArgs([[]]) @@ -352,7 +347,7 @@ public function testInsertSaveEmptyData() $table->insert([])->save(); } - public function testInsertSaveData() + public function testInsertSaveData(): void { $adapterStub = $this->getMockBuilder(MysqlAdapter::class) ->setConstructorArgs([[]]) @@ -385,7 +380,7 @@ public function testInsertSaveData() ->save(); } - public function testSaveAfterSaveData() + public function testSaveAfterSaveData(): void { $adapterStub = $this->getMockBuilder(MysqlAdapter::class) ->setConstructorArgs([[]]) @@ -418,31 +413,29 @@ public function testSaveAfterSaveData() ->save(); } - public function testResetAfterAddingData() + public function testResetAfterAddingData(): void { $adapterStub = $this->getMockBuilder(MysqlAdapter::class) ->setConstructorArgs([[]]) ->getMock(); $table = new Table('ntable', [], $adapterStub); $columns = ['column1']; - $data = [['value1']]; - $table->insert($columns, $data)->save(); + $table->insert($columns)->save(); $this->assertEquals([], $table->getData()); } - public function testPendingAfterAddingData() + public function testPendingAfterAddingData(): void { $adapterStub = $this->getMockBuilder(MysqlAdapter::class) ->setConstructorArgs([[]]) ->getMock(); $table = new Table('ntable', [], $adapterStub); $columns = ['column1']; - $data = [['value1']]; - $table->insert($columns, $data); + $table->insert($columns); $this->assertTrue($table->hasPendingActions()); } - public function testPendingAfterAddingColumn() + public function testPendingAfterAddingColumn(): void { $adapterStub = $this->getMockBuilder(MysqlAdapter::class) ->setConstructorArgs([[]]) @@ -455,7 +448,7 @@ public function testPendingAfterAddingColumn() $this->assertTrue($table->hasPendingActions()); } - public function testGetColumn() + public function testGetColumn(): void { $adapterStub = $this->getMockBuilder(MysqlAdapter::class) ->setConstructorArgs([[]]) @@ -477,23 +470,22 @@ public function testGetColumn() /** * @param string $indexIdentifier - * @param Index $index */ #[DataProvider('removeIndexDataprovider')] - public function testRemoveIndex($indexIdentifier, Index $index) + public function testRemoveIndex(string|array $indexIdentifier, Index $index): void { $adapter = new MysqlAdapter([]); $table = new Table('table', [], $adapter); $table->removeIndex($indexIdentifier); - $indexes = array_map(function (DropIndex $action) { + $indexes = array_map(function (DropIndex $action): Index { return $action->getIndex(); }, $this->getPendingActions($table)); $this->assertEquals([$index], $indexes); } - public static function removeIndexDataprovider() + public static function removeIndexDataprovider(): array { return [ [ @@ -513,8 +505,7 @@ public static function removeIndexDataprovider() protected function getPendingActions($table) { - $prop = new ReflectionProperty(get_class($table), 'actions'); - $prop->setAccessible(true); + $prop = new ReflectionProperty($table::class, 'actions'); return $prop->getValue($table)->getActions(); } diff --git a/tests/TestCase/Middleware/PendingMigrationsMiddlewareTest.php b/tests/TestCase/Middleware/PendingMigrationsMiddlewareTest.php index 9db05c0cc..e13e6f485 100644 --- a/tests/TestCase/Middleware/PendingMigrationsMiddlewareTest.php +++ b/tests/TestCase/Middleware/PendingMigrationsMiddlewareTest.php @@ -37,7 +37,7 @@ class PendingMigrationsMiddlewareTest extends TestCase * * @return void */ - public function setUp(): void + protected function setUp(): void { parent::setUp(); $connection = ConnectionManager::get('test'); @@ -51,7 +51,7 @@ public function setUp(): void ); } - public function tearDown(): void + protected function tearDown(): void { parent::tearDown(); ConnectionManager::drop('custom'); @@ -66,7 +66,7 @@ public function testAppMigrationsFail(): void $middleware = new PendingMigrationsMiddleware(); $request = new ServerRequest(); - $handler = new TestRequestHandler(function ($req) { + $handler = new TestRequestHandler(function ($req): Response { return new Response(); }); @@ -95,11 +95,12 @@ public function testAppMigrationsSuccess(): void ], ]; $config = new Config($config); + $manager = new Manager($config, $this->io); $manager->migrate(null, true); $request = new ServerRequest(); - $handler = new TestRequestHandler(function ($req) { + $handler = new TestRequestHandler(function ($req): Response { return new Response(); }); $result = $middleware->process($request, $handler); @@ -118,7 +119,7 @@ public function testAppAndPluginsMigrationsFail(): void ]); $request = new ServerRequest(); - $handler = new TestRequestHandler(function ($req) { + $handler = new TestRequestHandler(function ($req): Response { return new Response(); }); @@ -151,11 +152,12 @@ public function testAppAndPluginsMigrationsSuccess(): void ], ]; $config = new Config($config); + $manager = new Manager($config, $this->io); $manager->migrate(null, true); $request = new ServerRequest(); - $handler = new TestRequestHandler(function ($req) { + $handler = new TestRequestHandler(function ($req): Response { return new Response(); }); diff --git a/tests/TestCase/Migration/EnvironmentTest.php b/tests/TestCase/Migration/EnvironmentTest.php index 84d060582..633c20f8b 100644 --- a/tests/TestCase/Migration/EnvironmentTest.php +++ b/tests/TestCase/Migration/EnvironmentTest.php @@ -26,26 +26,26 @@ protected function setUp(): void $this->environment = new Environment('test', []); } - public function testConstructorWorksAsExpected() + public function testConstructorWorksAsExpected(): void { $env = new Environment('testenv', ['foo' => 'bar']); $this->assertEquals('testenv', $env->getName()); $this->assertArrayHasKey('foo', $env->getOptions()); } - public function testSettingTheName() + public function testSettingTheName(): void { $this->environment->setName('prod123'); $this->assertEquals('prod123', $this->environment->getName()); } - public function testSettingOptions() + public function testSettingOptions(): void { $this->environment->setOptions(['foo' => 'bar']); $this->assertArrayHasKey('foo', $this->environment->getOptions()); } - public function testInvalidAdapter() + public function testInvalidAdapter(): void { $this->environment->setOptions(['adapter' => 'fakeadapter']); @@ -55,14 +55,14 @@ public function testInvalidAdapter() $this->environment->getAdapter(); } - public function testNoAdapter() + public function testNoAdapter(): void { $this->expectException(RuntimeException::class); $this->environment->getAdapter(); } - public function testGetAdapterWithBadConnectionName() + public function testGetAdapterWithBadConnectionName(): void { $this->environment->setOptions(['connection' => 'lolnope']); @@ -72,7 +72,7 @@ public function testGetAdapterWithBadConnectionName() $this->environment->getAdapter(); } - public function testGetAdapter() + public function testGetAdapter(): void { /** @var array $config */ $config = ConnectionManager::getConfig('test'); @@ -86,7 +86,7 @@ public function testGetAdapter() $this->assertInstanceOf(AdapterWrapper::class, $adapter); } - public function testSchemaName() + public function testSchemaName(): void { $this->assertEquals('phinxlog', $this->environment->getSchemaTableName()); @@ -94,7 +94,7 @@ public function testSchemaName() $this->assertEquals('changelog', $this->environment->getSchemaTableName()); } - public function testCurrentVersion() + public function testCurrentVersion(): void { $stub = $this->getMockBuilder(AbstractAdapter::class) ->setConstructorArgs([[]]) @@ -108,7 +108,7 @@ public function testCurrentVersion() $this->assertEquals(20110301080000, $this->environment->getCurrentVersion()); } - public function testExecutingAMigrationUp() + public function testExecutingAMigrationUp(): void { // stub adapter $adapterStub = $this->getMockBuilder(AbstractAdapter::class) @@ -123,6 +123,7 @@ public function testExecutingAMigrationUp() // up $upMigration = new class (20110301080000) extends BaseMigration { public bool $executed = false; + public function up(): void { $this->executed = true; @@ -133,7 +134,7 @@ public function up(): void $this->assertTrue($upMigration->executed); } - public function testExecutingAMigrationDown() + public function testExecutingAMigrationDown(): void { // stub adapter $adapterStub = $this->getMockBuilder(AbstractAdapter::class) @@ -148,6 +149,7 @@ public function testExecutingAMigrationDown() // down $downMigration = new class (20110301080000) extends BaseMigration { public bool $executed = false; + public function down(): void { $this->executed = true; @@ -158,7 +160,7 @@ public function down(): void $this->assertTrue($downMigration->executed); } - public function testExecutingAMigrationWithTransactions() + public function testExecutingAMigrationWithTransactions(): void { // stub adapter $adapterStub = $this->getMockBuilder(AbstractAdapter::class) @@ -179,6 +181,7 @@ public function testExecutingAMigrationWithTransactions() // migrate $migration = new class (20110301080000) extends BaseMigration { public bool $executed = false; + public function up(): void { $this->executed = true; @@ -189,7 +192,7 @@ public function up(): void $this->assertTrue($migration->executed); } - public function testExecutingAMigrationWithUseTransactions() + public function testExecutingAMigrationWithUseTransactions(): void { // stub adapter $adapterStub = $this->getMockBuilder(AbstractAdapter::class) @@ -226,7 +229,7 @@ public function up(): void $this->assertTrue($migration->executed); } - public function testExecutingAChangeMigrationUp() + public function testExecutingAChangeMigrationUp(): void { // stub adapter $adapterStub = $this->getMockBuilder(AbstractAdapter::class) @@ -241,6 +244,7 @@ public function testExecutingAChangeMigrationUp() // migration $migration = new class (20130301080000) extends BaseMigration { public bool $executed = false; + public function change(): void { $this->executed = true; @@ -251,7 +255,7 @@ public function change(): void $this->assertTrue($migration->executed); } - public function testExecutingAChangeMigrationDown() + public function testExecutingAChangeMigrationDown(): void { // stub adapter $adapterStub = $this->getMockBuilder(AbstractAdapter::class) @@ -266,6 +270,7 @@ public function testExecutingAChangeMigrationDown() // migration $migration = new class (20130301080000) extends BaseMigration { public bool $executed = false; + public function change(): void { $this->executed = true; @@ -276,7 +281,7 @@ public function change(): void $this->assertTrue($migration->executed); } - public function testExecutingAFakeMigration() + public function testExecutingAFakeMigration(): void { // stub adapter $adapterStub = $this->getMockBuilder(AbstractAdapter::class) @@ -291,6 +296,7 @@ public function testExecutingAFakeMigration() // migration $migration = new class (20130301080000) extends BaseMigration { public bool $executed = false; + public function change(): void { $this->executed = true; @@ -301,7 +307,7 @@ public function change(): void $this->assertFalse($migration->executed); } - public function testGettingInputObject() + public function testGettingInputObject(): void { $mock = $this->getMockBuilder(ConsoleIo::class)->getMock(); $this->environment->setIo($mock); @@ -309,7 +315,7 @@ public function testGettingInputObject() $this->assertInstanceOf(ConsoleIo::class, $inputObject); } - public function testExecuteMigrationCallsInit() + public function testExecuteMigrationCallsInit(): void { // stub adapter $adapterStub = $this->getMockBuilder(AbstractAdapter::class) @@ -324,6 +330,7 @@ public function testExecuteMigrationCallsInit() // up $upMigration = new class (20110301080000) extends BaseMigration { public bool $initExecuted = false; + public bool $upExecuted = false; public function init(): void @@ -341,7 +348,7 @@ public function up(): void $this->assertTrue($upMigration->upExecuted); } - public function testExecuteSeedInit() + public function testExecuteSeedInit(): void { // stub adapter $adapterStub = $this->getMockBuilder(AbstractAdapter::class) @@ -352,6 +359,7 @@ public function testExecuteSeedInit() $seed = new class (20110301080000) extends BaseSeed { public bool $initExecuted = false; + public bool $runExecuted = false; public function init(): void diff --git a/tests/TestCase/Migration/ManagerFactoryTest.php b/tests/TestCase/Migration/ManagerFactoryTest.php index 0352e887f..12bdd2dbf 100644 --- a/tests/TestCase/Migration/ManagerFactoryTest.php +++ b/tests/TestCase/Migration/ManagerFactoryTest.php @@ -6,6 +6,8 @@ use Cake\Console\ConsoleIo; use Cake\Console\TestSuite\StubConsoleInput; use Cake\Console\TestSuite\StubConsoleOutput; +use Cake\Database\Connection; +use Cake\Database\Driver\Mysql; use Cake\Datasource\ConnectionManager; use Migrations\Migration\ManagerFactory; use PHPUnit\Framework\TestCase; @@ -16,6 +18,7 @@ public function testConnection(): void { $out = new StubConsoleOutput(); $out->setOutputAs(StubConsoleOutput::PLAIN); + $in = new StubConsoleInput([]); $io = new ConsoleIo($out, $out, $in); @@ -41,6 +44,7 @@ public function testDsnConnection(): void { $out = new StubConsoleOutput(); $out->setOutputAs(StubConsoleOutput::PLAIN); + $in = new StubConsoleInput([]); $io = new ConsoleIo($out, $out, $in); @@ -53,9 +57,9 @@ public function testDsnConnection(): void 'scheme' => 'mysql', 'username' => 'root', 'host' => '127.0.0.1', - 'className' => 'Cake\Database\Connection', + 'className' => Connection::class, 'database' => 'db_tmp', - 'driver' => 'Cake\Database\Driver\Mysql', + 'driver' => Mysql::class, 'name' => 'tmp', ]; $this->assertEquals($expected, ConnectionManager::getConfig('tmp')); diff --git a/tests/TestCase/Migration/ManagerTest.php b/tests/TestCase/Migration/ManagerTest.php index 4efcf70c2..3d7ce3d44 100644 --- a/tests/TestCase/Migration/ManagerTest.php +++ b/tests/TestCase/Migration/ManagerTest.php @@ -13,6 +13,7 @@ use Migrations\Db\Adapter\AdapterInterface; use Migrations\Migration\Environment; use Migrations\Migration\Manager; +use Migrations\MigrationInterface; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use ReflectionClass; @@ -40,10 +41,7 @@ class ManagerTest extends TestCase */ protected $in; - /** - * @var Manager - */ - private $manager; + private ?Manager $manager = null; protected function setUp(): void { @@ -51,6 +49,7 @@ protected function setUp(): void $this->out = new StubConsoleOutput(); $this->out->setOutputAs(StubConsoleOutput::PLAIN); + $this->in = new StubConsoleInput([]); $this->io = new ConsoleIo($this->out, $this->out, $this->in); @@ -70,9 +69,9 @@ protected static function getDriverType(): string protected function getOutput(): string { $lines = $this->out->messages(); - $lines = array_map(fn($line) => strip_tags($line), $lines); + $lines = array_map(strip_tags(...), $lines); - return join("\n", $lines); + return implode("\n", $lines); } protected function tearDown(): void @@ -80,11 +79,6 @@ protected function tearDown(): void $this->manager = null; } - private static function getCorrectedPath(string $path): string - { - return str_replace('/', DIRECTORY_SEPARATOR, $path); - } - /** * Returns a sample configuration array for use with the unit tests. * @@ -306,7 +300,7 @@ public function testPrintStatusMethodWithBreakpointSet(): void $this->assertEquals($expected, $return); } - public function testPrintStatusMethodWithNoMigrations() + public function testPrintStatusMethodWithNoMigrations(): void { // stub environment $envStub = $this->getMockBuilder(Environment::class) @@ -325,7 +319,7 @@ public function testPrintStatusMethodWithNoMigrations() $this->assertEquals([], $return); } - public function testPrintStatusMethodWithMissingMigrations() + public function testPrintStatusMethodWithMissingMigrations(): void { // stub environment $envStub = $this->getMockBuilder(Environment::class) @@ -384,7 +378,7 @@ public function testPrintStatusMethodWithMissingMigrations() $this->assertEquals($expected, $return); } - public function testPrintStatusMethodWithMissingLastMigration() + public function testPrintStatusMethodWithMissingLastMigration(): void { // stub environment $envStub = $this->getMockBuilder(Environment::class) @@ -445,7 +439,7 @@ public function testPrintStatusMethodWithMissingLastMigration() $this->assertEquals($expected, $return); } - public function testPrintStatusMethodWithMissingMigrationsAndBreakpointSet() + public function testPrintStatusMethodWithMissingMigrationsAndBreakpointSet(): void { // stub environment $envStub = $this->getMockBuilder(Environment::class) @@ -504,7 +498,7 @@ public function testPrintStatusMethodWithMissingMigrationsAndBreakpointSet() $this->assertEquals($expected, $return); } - public function testPrintStatusMethodWithDownMigrations() + public function testPrintStatusMethodWithDownMigrations(): void { // stub environment $envStub = $this->getMockBuilder(Environment::class) @@ -540,7 +534,7 @@ public function testPrintStatusMethodWithDownMigrations() $this->assertEquals($expected, $return); } - public function testPrintStatusMethodWithMissingAndDownMigrations() + public function testPrintStatusMethodWithMissingAndDownMigrations(): void { // stub environment $envStub = $this->getMockBuilder(Environment::class) @@ -605,7 +599,7 @@ public function testPrintStatusMethodWithMissingAndDownMigrations() $this->assertEquals($expected, $return); } - public function testGetMigrationsWithDuplicateMigrationVersions() + public function testGetMigrationsWithDuplicateMigrationVersions(): void { $config = new Config(['paths' => ['migrations' => ROOT . '/config/Duplicateversions']]); $manager = new Manager($config, $this->io); @@ -616,7 +610,7 @@ public function testGetMigrationsWithDuplicateMigrationVersions() $manager->getMigrations(); } - public function testGetMigrationsWithDuplicateMigrationNames() + public function testGetMigrationsWithDuplicateMigrationNames(): void { $config = new Config(['paths' => ['migrations' => ROOT . '/config/Duplicatenames']]); $manager = new Manager($config, $this->io); @@ -627,7 +621,7 @@ public function testGetMigrationsWithDuplicateMigrationNames() $manager->getMigrations(); } - public function testGetMigrationsWithInvalidMigrationClassName() + public function testGetMigrationsWithInvalidMigrationClassName(): void { $config = new Config(['paths' => ['migrations' => ROOT . '/config/Invalidclassname']]); $manager = new Manager($config, $this->io); @@ -651,7 +645,7 @@ public function testGetMigrationsWithLegacyAbstractMigrationClass(): void $manager->getMigrations(); } - public function testGetMigrationsWithAnonymousClass() + public function testGetMigrationsWithAnonymousClass(): void { $config = new Config(['paths' => ['migrations' => ROOT . '/config/AnonymousMigrations']]); $manager = new Manager($config, $this->io); @@ -665,13 +659,13 @@ public function testGetMigrationsWithAnonymousClass() $migration = reset($migrations); // Check that it's a valid migration object - $this->assertInstanceOf('\Migrations\MigrationInterface', $migration); + $this->assertInstanceOf(MigrationInterface::class, $migration); // Check the version was set correctly (2024_12_08_150000 => 20241208150000) $this->assertEquals(20241208150000, $migration->getVersion()); } - public function testGettingAValidEnvironment() + public function testGettingAValidEnvironment(): void { $this->assertInstanceOf( Environment::class, @@ -684,12 +678,9 @@ public function testGettingAValidEnvironment() * migration to point to. * * @param string[] $availableMigrations - * @param string $dateString - * @param string $expectedMigration - * @param string $message */ #[DataProvider('migrateDateDataProvider')] - public function testMigrationsByDate(array $availableMigrations, $dateString, $expectedMigration, $message) + public function testMigrationsByDate(array $availableMigrations, string $dateString, string $expectedMigration, string $message): void { // stub environment $envStub = $this->getMockBuilder(Environment::class) @@ -719,12 +710,10 @@ public function testMigrationsByDate(array $availableMigrations, $dateString, $e * migration to point to. * * @param string[] $availableMigrations - * @param int $count * @param string $expectedMigration - * @param string $message */ #[DataProvider('migrateByCountDataProvider')] - public function testMigrationsByCount(array $availableMigrations, $count, $expectedMigration, $message) + public function testMigrationsByCount(array $availableMigrations, int $count, ?string $expectedMigration, string $message): void { // stub environment $envStub = $this->getMockBuilder(Environment::class) @@ -744,7 +733,7 @@ public function testMigrationsByCount(array $availableMigrations, $count, $expec // Mock getMigrations to return the available migrations $migrations = []; foreach ($availableMigrations as $version) { - $migration = $this->getMockBuilder('\Migrations\MigrationInterface') + $migration = $this->getMockBuilder(MigrationInterface::class) ->getMock(); $migration->expects($this->any()) ->method('getVersion') @@ -758,11 +747,11 @@ public function testMigrationsByCount(array $availableMigrations, $count, $expec // Use reflection to set the migrations property $reflection = new ReflectionClass($this->manager); $migrationsProperty = $reflection->getProperty('migrations'); - $migrationsProperty->setAccessible(true); $migrationsProperty->setValue($this->manager, $migrations); $this->manager->setEnvironment($envStub); $this->manager->migrate(null, false, $count); + $output = $this->getOutput(); if (is_null($expectedMigration)) { $this->assertEmpty($output, $message); @@ -776,7 +765,7 @@ public function testMigrationsByCount(array $availableMigrations, $count, $expec * migration to point to. */ #[DataProvider('rollbackToVersionDataProvider')] - public function testRollbackToVersion($availableRollbacks, $version, $expectedOutput) + public function testRollbackToVersion(array $availableRollbacks, ?string $version, string|array|null $expectedOutput): void { // stub environment $envStub = $this->getMockBuilder(Environment::class) @@ -788,6 +777,7 @@ public function testRollbackToVersion($availableRollbacks, $version, $expectedOu $this->manager->setEnvironment($envStub); $this->manager->rollback($version); + $output = $this->getOutput(); if (is_null($expectedOutput)) { $output = explode("\n", $output); @@ -808,7 +798,7 @@ public function testRollbackToVersion($availableRollbacks, $version, $expectedOu * migration to point to. */ #[DataProvider('rollbackToDateDataProvider')] - public function testRollbackToDate($availableRollbacks, $version, $expectedOutput) + public function testRollbackToDate(array $availableRollbacks, string $version, string|array|null $expectedOutput): void { // stub environment $envStub = $this->getMockBuilder(Environment::class) @@ -820,6 +810,7 @@ public function testRollbackToDate($availableRollbacks, $version, $expectedOutpu $this->manager->setEnvironment($envStub); $this->manager->rollback($version, false, false); + $output = $this->getOutput(); if (is_null($expectedOutput)) { $output = explode("\n", $output); @@ -839,7 +830,7 @@ public function testRollbackToDate($availableRollbacks, $version, $expectedOutpu * Test that rollbacking with count stops at the right migration. */ #[DataProvider('rollbackByCountDataProvider')] - public function testRollbackByCount($availableRollbacks, $count, $expectedOutput) + public function testRollbackByCount(array $availableRollbacks, int $count, string|array|null $expectedOutput): void { // stub environment $envStub = $this->getMockBuilder(Environment::class) @@ -852,7 +843,7 @@ public function testRollbackByCount($availableRollbacks, $count, $expectedOutput // Mock getMigrations to return migrations matching the version log $migrations = []; foreach ($availableRollbacks as $version => $details) { - $migration = $this->getMockBuilder('\Migrations\MigrationInterface') + $migration = $this->getMockBuilder(MigrationInterface::class) ->getMock(); $migration->expects($this->any()) ->method('getVersion') @@ -869,11 +860,11 @@ public function testRollbackByCount($availableRollbacks, $count, $expectedOutput // Use reflection to set the migrations property $reflection = new ReflectionClass($this->manager); $migrationsProperty = $reflection->getProperty('migrations'); - $migrationsProperty->setAccessible(true); $migrationsProperty->setValue($this->manager, $migrations); $this->manager->setEnvironment($envStub); $this->manager->rollbackByCount($count); + $output = $this->getOutput(); if (is_null($expectedOutput)) { $output = explode("\n", $output); @@ -894,7 +885,7 @@ public function testRollbackByCount($availableRollbacks, $count, $expectedOutput * migration to point to. */ #[DataProvider('rollbackToVersionByExecutionTimeDataProvider')] - public function testRollbackToVersionByExecutionTime($availableRollbacks, $version, $expectedOutput) + public function testRollbackToVersionByExecutionTime(array $availableRollbacks, ?string $version, string|array $expectedOutput): void { // stub environment $envStub = $this->getMockBuilder(Environment::class) @@ -912,6 +903,7 @@ public function testRollbackToVersionByExecutionTime($availableRollbacks, $versi $this->manager = new Manager($config, $this->io); $this->manager->setEnvironment($envStub); $this->manager->rollback($version); + $output = $this->getOutput(); if (is_null($expectedOutput)) { @@ -932,7 +924,7 @@ public function testRollbackToVersionByExecutionTime($availableRollbacks, $versi * migration to point to. */ #[DataProvider('rollbackToVersionByExecutionTimeDataProvider')] - public function testRollbackToVersionByName($availableRollbacks, $version, $expectedOutput) + public function testRollbackToVersionByName(array $availableRollbacks, ?string $version, string|array $expectedOutput): void { // stub environment $envStub = $this->getMockBuilder(Environment::class) @@ -950,6 +942,7 @@ public function testRollbackToVersionByName($availableRollbacks, $version, $expe $this->manager = new Manager($config, $this->io); $this->manager->setEnvironment($envStub); $this->manager->rollback($availableRollbacks[$version]['migration_name'] ?? $version); + $output = $this->getOutput(); if (is_null($expectedOutput)) { @@ -970,7 +963,7 @@ public function testRollbackToVersionByName($availableRollbacks, $version, $expe * migration to point to. */ #[DataProvider('rollbackToDateByExecutionTimeDataProvider')] - public function testRollbackToDateByExecutionTime($availableRollbacks, $date, $expectedOutput) + public function testRollbackToDateByExecutionTime(array $availableRollbacks, ?string $date, string|array|null $expectedOutput): void { // stub environment $envStub = $this->getMockBuilder(Environment::class) @@ -988,6 +981,7 @@ public function testRollbackToDateByExecutionTime($availableRollbacks, $date, $e $this->manager = new Manager($config, $this->io); $this->manager->setEnvironment($envStub); $this->manager->rollback($date, false, false); + $output = $this->getOutput(); if (is_null($expectedOutput)) { @@ -1021,6 +1015,7 @@ public function testRollbackToVersionWithSingleMigrationDoesNotFail(): void $this->manager->setEnvironment($envStub); $this->manager->rollback(); + $output = $this->getOutput(); $this->assertStringContainsString('== 20120111235330 TestMigration: reverting', $output); @@ -1054,6 +1049,7 @@ public function testRollbackToVersionWithTwoMigrations(): void $this->manager->setEnvironment($envStub); $this->manager->rollback(); + $output = $this->getOutput(); $this->assertStringNotContainsString('== 20120111235330 TestMigration: reverting', $output); @@ -1080,7 +1076,8 @@ public function testRollbackLast(array $availableRolbacks, string $versionOrder, $this->manager = new Manager($config, $this->io); $this->manager->setEnvironment($envStub); - $this->manager->rollback(null); + $this->manager->rollback(); + $output = $this->getOutput(); if (is_null($expectedOutput)) { $this->assertEquals('No migrations to rollback' . PHP_EOL, $output); @@ -2425,7 +2422,7 @@ public function testExecuteSeedWorksAsExpected(): void $this->manager->setEnvironment($envStub); $this->manager->seed(); - $output = join("\n", $this->out->messages()); + $output = implode("\n", $this->out->messages()); $this->assertStringContainsString('GSeeder', $output); $this->assertStringContainsString('PostSeeder', $output); $this->assertStringContainsString('UserSeeder', $output); @@ -2439,7 +2436,8 @@ public function testExecuteASingleSeedWorksAsExpected(): void ->getMock(); $this->manager->setEnvironment($envStub); $this->manager->seed('UserSeeder'); - $output = join("\n", $this->out->messages()); + + $output = implode("\n", $this->out->messages()); $this->assertStringContainsString('UserSeeder', $output); } @@ -2474,7 +2472,7 @@ public function testSeedWillNotBeExecuted(): void $this->manager->setEnvironment($envStub); $this->manager->seed('UserSeederNotExecuted'); - $output = join("\n", $this->out->messages()); + $output = implode("\n", $this->out->messages()); $this->assertStringContainsString('skipped', $output); } @@ -2962,7 +2960,7 @@ public function testInvalidVersionBreakpoint(): void $this->manager->setEnvironment($envStub); $this->manager->setBreakpoint(20120133235330); - $output = join("\n", $this->out->messages()); + $output = implode("\n", $this->out->messages()); $this->assertStringContainsString('warning 20120133235330 is not a valid version', $output); } diff --git a/tests/TestCase/MigrationsTest.php b/tests/TestCase/MigrationsTest.php index 2830b88c2..44bc6c4af 100644 --- a/tests/TestCase/MigrationsTest.php +++ b/tests/TestCase/MigrationsTest.php @@ -55,7 +55,7 @@ class MigrationsTest extends TestCase * * @return void */ - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -108,7 +108,7 @@ public function setUp(): void * * @return void */ - public function tearDown(): void + protected function tearDown(): void { parent::tearDown(); unset($this->Connection, $this->migrations); @@ -125,7 +125,7 @@ public function tearDown(): void * * @return void */ - public function testStatus() + public function testStatus(): void { $result = $this->migrations->status(); $expected = [ @@ -158,7 +158,7 @@ public function testStatus() * * @return void */ - public function testMigrateAndRollback() + public function testMigrateAndRollback(): void { if ($this->Connection->getDriver() instanceof Sqlserver) { // TODO This test currently fails in CI because numbers table @@ -252,7 +252,7 @@ public function testMigrateAndRollback() * * @return void */ - public function testCreateWithEncoding() + public function testCreateWithEncoding(): void { $this->skipIf(env('DB') !== 'mysql', 'Requires MySQL'); @@ -279,7 +279,7 @@ public function testCreateWithEncoding() * * @return void */ - public function testMarkMigratedAll() + public function testMarkMigratedAll(): void { $markMigrated = $this->migrations->markMigrated(); $this->assertTrue($markMigrated); @@ -316,7 +316,7 @@ public function testMarkMigratedAll() * * @return void */ - public function testMarkMigratedAllAsVersion() + public function testMarkMigratedAllAsVersion(): void { $markMigrated = $this->migrations->markMigrated('all'); $this->assertTrue($markMigrated); @@ -352,7 +352,7 @@ public function testMarkMigratedAllAsVersion() * * @return void */ - public function testMarkMigratedTarget() + public function testMarkMigratedTarget(): void { $markMigrated = $this->migrations->markMigrated(null, ['target' => '20150704160200']); $this->assertTrue($markMigrated); @@ -394,7 +394,7 @@ public function testMarkMigratedTarget() * * @return void */ - public function testMarkMigratedTargetError() + public function testMarkMigratedTargetError(): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('Migration `20150704160610` was not found !'); @@ -407,7 +407,7 @@ public function testMarkMigratedTargetError() * * @return void */ - public function testMarkMigratedTargetExclude() + public function testMarkMigratedTargetExclude(): void { $markMigrated = $this->migrations->markMigrated(null, ['target' => '20150704160200', 'exclude' => true]); $this->assertTrue($markMigrated); @@ -449,7 +449,7 @@ public function testMarkMigratedTargetExclude() * * @return void */ - public function testMarkMigratedTargetOnly() + public function testMarkMigratedTargetOnly(): void { $markMigrated = $this->migrations->markMigrated(null, ['target' => '20150724233100', 'only' => true]); $this->assertTrue($markMigrated); @@ -491,7 +491,7 @@ public function testMarkMigratedTargetOnly() * * @return void */ - public function testMarkMigratedTargetExcludeOnly() + public function testMarkMigratedTargetExcludeOnly(): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('You should use `exclude` OR `only` (not both) along with a `target` argument'); @@ -504,7 +504,7 @@ public function testMarkMigratedTargetExcludeOnly() * * @return void */ - public function testMarkMigratedVersion() + public function testMarkMigratedVersion(): void { $markMigrated = $this->migrations->markMigrated(20150704160200); $this->assertTrue($markMigrated); @@ -546,7 +546,7 @@ public function testMarkMigratedVersion() * * @return void */ - public function testOverrideOptions() + public function testOverrideOptions(): void { $result = $this->migrations->status(); $expectedStatus = [ @@ -614,7 +614,7 @@ public function testOverrideOptions() * * @return void */ - public function testMigrateDateOption() + public function testMigrateDateOption(): void { // If we want to migrate to a date before the first first migration date, // we should not migrate anything @@ -674,6 +674,7 @@ public function testMigrateDateOption() // If we want to migrate to a date after the last migration date, // we should migrate everything $this->migrations->migrate(['date' => '20150730']); + $expectedStatus = [ [ 'status' => 'up', @@ -790,7 +791,7 @@ public function testMigrateDateOption() * * @return void */ - public function testSeed() + public function testSeed(): void { $this->migrations->migrate(); $seed = $this->migrations->seed(['source' => 'Seeds']); @@ -866,7 +867,7 @@ public function testSeed() * * @return void */ - public function testSeedOneSeeder() + public function testSeedOneSeeder(): void { $this->migrations->migrate(); @@ -915,7 +916,7 @@ public function testSeedOneSeeder() * * @return void */ - public function testSeedOneSeederShortName() + public function testSeedOneSeederShortName(): void { $this->migrations->migrate(); @@ -964,7 +965,7 @@ public function testSeedOneSeederShortName() * * @return void */ - public function testSeedCallSeeder() + public function testSeedCallSeeder(): void { $this->migrations->migrate(); @@ -1025,7 +1026,7 @@ public function testSeedCallSeeder() * * @return void */ - public function testSeedWrongSeed() + public function testSeedWrongSeed(): void { $this->expectException(InvalidArgumentException::class); $this->expectExceptionMessage('The seed `DerpSeed` does not exist'); @@ -1086,7 +1087,7 @@ public function testMigrateSnapshots(string $basePath, string $filename, array $ 'parts', 'special_pks', 'special_tags', 'texts', 'users', ]; foreach ($cleanup as $item) { - $snapshotConn->execute("DROP TABLE IF EXISTS {$item}"); + $snapshotConn->execute('DROP TABLE IF EXISTS ' . $item); } $migrations = new Migrations([ @@ -1103,7 +1104,7 @@ public function testMigrateSnapshots(string $basePath, string $filename, array $ /** * Tests that migrating in case of error throws an exception */ - public function testMigrateErrors() + public function testMigrateErrors(): void { $this->expectException(Exception::class); $this->migrations->markMigrated(20150704160200); @@ -1113,7 +1114,7 @@ public function testMigrateErrors() /** * Tests that rolling back in case of error throws an exception */ - public function testRollbackErrors() + public function testRollbackErrors(): void { $this->expectException(Exception::class); $this->migrations->markMigrated('all'); @@ -1124,7 +1125,7 @@ public function testRollbackErrors() * Tests that marking migrated a non-existant migrations returns an error * and can return a error message */ - public function testMarkMigratedErrors() + public function testMarkMigratedErrors(): void { $this->expectException(Exception::class); $this->migrations->markMigrated(20150704000000); diff --git a/tests/TestCase/TestCase.php b/tests/TestCase/TestCase.php index 06b0f68ec..e9734f79c 100644 --- a/tests/TestCase/TestCase.php +++ b/tests/TestCase/TestCase.php @@ -39,7 +39,7 @@ abstract class TestCase extends BaseTestCase */ protected $generatedFiles = []; - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -47,7 +47,7 @@ public function setUp(): void $this->loadPlugins(['Cake/TwigView']); } - public function tearDown(): void + protected function tearDown(): void { parent::tearDown(); @@ -72,9 +72,9 @@ public function tearDown(): void * @param string $name plugin name to load * @return void */ - protected function _loadTestPlugin($name) + protected function _loadTestPlugin(string $name) { - $root = dirname(dirname(__FILE__)) . DS; + $root = dirname(__FILE__, 2) . DS; $path = $root . 'test_app' . DS . 'Plugin' . DS . $name . DS; $this->loadPlugins([ @@ -91,7 +91,7 @@ protected function _loadTestPlugin($name) * @param string $message The message to use if a check fails. * @return void */ - protected function assertFilesExist(array $files, $message = '') + protected function assertFilesExist(array $files, string $message = '') { foreach ($files as $file) { $this->assertFileExists($file, $message); @@ -106,7 +106,7 @@ protected function assertFilesExist(array $files, $message = '') * @param string $message The error message. * @return void */ - protected function assertFileContains($expected, $path, $message = '') + protected function assertFileContains(string $expected, string $path, string $message = '') { $this->assertFileExists($path, 'Cannot test contents, file does not exist.'); @@ -122,7 +122,7 @@ protected function assertFileContains($expected, $path, $message = '') * @param string $message The error message. * @return void */ - protected function assertFileNotContains($expected, $path, $message = '') + protected function assertFileNotContains(string $expected, string $path, string $message = '') { $this->assertFileExists($path, 'Cannot test contents, file does not exist.'); diff --git a/tests/TestCase/TestSuite/MigratorTest.php b/tests/TestCase/TestSuite/MigratorTest.php index de3baa975..9363dba40 100644 --- a/tests/TestCase/TestSuite/MigratorTest.php +++ b/tests/TestCase/TestSuite/MigratorTest.php @@ -55,7 +55,7 @@ protected function getMigratorWhereClause(): array : []; } - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -67,7 +67,7 @@ public function setUp(): void (new ConnectionHelper())->dropTables('test'); } - public function tearDown(): void + protected function tearDown(): void { parent::tearDown(); if ($this->restore) { @@ -185,7 +185,7 @@ public function testTruncateAfterMigrations(): void $this->assertCount(0, $connection->selectQuery()->select(['*'])->from('migrator')->execute()->fetchAll()); } - private function setMigrationEndDateToYesterday() + private function setMigrationEndDateToYesterday(): void { $query = ConnectionManager::get('test')->updateQuery() ->update($this->getMigratorTableName()) diff --git a/tests/TestCase/Util/ColumnParserTest.php b/tests/TestCase/Util/ColumnParserTest.php index d56d0616a..5fddc4799 100644 --- a/tests/TestCase/Util/ColumnParserTest.php +++ b/tests/TestCase/Util/ColumnParserTest.php @@ -31,13 +31,13 @@ class ColumnParserTest extends TestCase * * @return void */ - public function setUp(): void + protected function setUp(): void { parent::setUp(); $this->columnParser = new ColumnParser(); } - public function testParseFields() + public function testParseFields(): void { $this->assertEquals([ 'id' => [ @@ -227,7 +227,7 @@ public function testParseFields() $this->assertEquals($expected, $actual); } - public function testParseIndexes() + public function testParseIndexes(): void { $this->assertEquals(['UNIQUE_ID' => [ 'columns' => ['id'], @@ -247,7 +247,7 @@ public function testParseIndexes() ])); } - public function testParsePrimaryKey() + public function testParsePrimaryKey(): void { $this->assertEquals(['id'], $this->columnParser->parsePrimaryKey(['id:primary'])); $this->assertEquals(['id'], $this->columnParser->parsePrimaryKey(['id:integer:primary'])); @@ -258,7 +258,7 @@ public function testParsePrimaryKey() ); } - public function testValidArguments() + public function testValidArguments(): void { $this->assertEquals( ['id'], @@ -310,7 +310,7 @@ public function testValidArguments() ); } - public function testGetType() + public function testGetType(): void { $this->assertSame('integer', $this->columnParser->getType('id', null)); $this->assertSame('integer', $this->columnParser->getType('id', 'primary_key')); @@ -332,7 +332,7 @@ public function testGetType() $this->assertSame('decimal', $this->columnParser->getType('longitude', null)); } - public function testGetTypeAndLength() + public function testGetTypeAndLength(): void { $this->assertEquals(['string', 255], $this->columnParser->getTypeAndLength('name', 'string')); $this->assertEquals(['integer', 11], $this->columnParser->getTypeAndLength('counter', 'integer')); @@ -346,7 +346,7 @@ public function testGetTypeAndLength() $this->assertEquals(['decimal', [10, 6]], $this->columnParser->getTypeAndLength('latitude', 'decimal[10,6]')); } - public function testGetTypeAndLengthReturnsIntegerTypes() + public function testGetTypeAndLengthReturnsIntegerTypes(): void { // Test that lengths are returned as integers, not strings [, $length] = $this->columnParser->getTypeAndLength('name', 'string[128]'); @@ -376,7 +376,7 @@ public function testGetTypeAndLengthReturnsIntegerTypes() $this->assertSame(11, $length); } - public function testGetLength() + public function testGetLength(): void { $this->assertSame(255, $this->columnParser->getLength('string')); $this->assertSame(11, $this->columnParser->getLength('integer')); @@ -385,7 +385,7 @@ public function testGetLength() $this->assertNull($this->columnParser->getLength('text')); } - public function testGetIndexName() + public function testGetIndexName(): void { $this->assertSame('SOME_INDEX', $this->columnParser->getIndexName('id', null, 'SOME_INDEX', true)); $this->assertSame('SOME_INDEX', $this->columnParser->getIndexName('id', null, 'SOME_INDEX', false)); @@ -398,7 +398,7 @@ public function testGetIndexName() $this->assertSame('PRIMARY', $this->columnParser->getIndexName('id', 'primary', null, true)); } - public function testParseFieldsWithReferences() + public function testParseFieldsWithReferences(): void { // Test basic references - should convert to integer $expected = [ @@ -443,7 +443,7 @@ public function testParseFieldsWithReferences() $this->assertEquals($expected, $actual); } - public function testParseFieldsWithDefaultValues() + public function testParseFieldsWithDefaultValues(): void { // Test boolean default true $expected = [ @@ -557,7 +557,7 @@ public function testParseFieldsWithDefaultValues() $this->assertEquals($expected, $actual); } - public function testParseDefaultValue() + public function testParseDefaultValue(): void { // Test null and empty values $this->assertNull($this->columnParser->parseDefaultValue(null, 'string')); @@ -588,7 +588,7 @@ public function testParseDefaultValue() $this->assertSame('CURRENT_TIMESTAMP', $this->columnParser->parseDefaultValue('CURRENT_TIMESTAMP', 'datetime')); } - public function testParseIndexesWithDefaultValues() + public function testParseIndexesWithDefaultValues(): void { // Ensure indexes still work with default values in the definition $expected = [ @@ -611,7 +611,7 @@ public function testParseIndexesWithDefaultValues() $this->assertEquals($expected, $actual); } - public function testValidArgumentsWithDefaultValues() + public function testValidArgumentsWithDefaultValues(): void { $this->assertEquals( ['active:boolean:default[true]'], @@ -627,7 +627,7 @@ public function testValidArgumentsWithDefaultValues() ); } - public function testParseForeignKeys() + public function testParseForeignKeys(): void { // Test basic reference - infer table name from field $expected = [ diff --git a/tests/TestCase/Util/UtilTest.php b/tests/TestCase/Util/UtilTest.php index c017c7641..6c9aed720 100644 --- a/tests/TestCase/Util/UtilTest.php +++ b/tests/TestCase/Util/UtilTest.php @@ -12,12 +12,12 @@ class UtilTest extends TestCase { - private function getCorrectedPath($path) + private function getCorrectedPath(string $path): string { return str_replace('/', DIRECTORY_SEPARATOR, $path); } - public function testGetExistingMigrationClassNames() + public function testGetExistingMigrationClassNames(): void { $expectedResults = [ 'TestMigration', @@ -31,14 +31,14 @@ public function testGetExistingMigrationClassNames() } } - public function testGetExistingMigrationClassNamesWithFile() + public function testGetExistingMigrationClassNamesWithFile(): void { $file = $this->getCorrectedPath(__DIR__ . '/_files/migrations/20120111235330_test_migration.php'); $existingClassNames = Util::getExistingMigrationClassNames($file); $this->assertCount(0, $existingClassNames); } - public function testGetCurrentTimestamp() + public function testGetCurrentTimestamp(): void { $dt = new DateTime('now', new DateTimeZone('UTC')); $expected = $dt->format(Util::DATE_FORMAT); @@ -104,7 +104,7 @@ public static function providerMapFileName(): array } #[DataProvider('providerMapFileName')] - public function testMapFileNameToClassName(string $fileName, string $className) + public function testMapFileNameToClassName(string $fileName, string $className): void { $this->assertEquals($className, Util::mapFileNameToClassName($fileName)); } @@ -117,7 +117,7 @@ public function testMapReadableFileNameToClassName(): void $this->assertEquals('DropOrdersTable', Util::mapFileNameToClassName('2024_01_01_000000_DropOrdersTable.php')); } - public function testGlobPath() + public function testGlobPath(): void { $files = Util::glob(__DIR__ . '/_files/migrations/empty.txt'); $this->assertCount(1, $files); @@ -130,7 +130,7 @@ public function testGlobPath() $this->assertEquals('not_a_migration.php', basename($files[2])); } - public function testGlobAll() + public function testGlobAll(): void { $files = Util::globAll([ __DIR__ . '/_files/migrations/*.php', @@ -144,7 +144,7 @@ public function testGlobAll() $this->assertEquals('empty.txt', basename($files[3])); } - public function testGetFiles() + public function testGetFiles(): void { $files = Util::getFiles([ __DIR__ . '/_files/migrations', diff --git a/tests/TestCase/Util/_files/migrations/20120111235330_test_migration.php b/tests/TestCase/Util/_files/migrations/20120111235330_test_migration.php index fd8abe276..69edb0937 100644 --- a/tests/TestCase/Util/_files/migrations/20120111235330_test_migration.php +++ b/tests/TestCase/Util/_files/migrations/20120111235330_test_migration.php @@ -8,7 +8,7 @@ class TestMigration extends BaseMigration /** * Migrate Up. */ - public function up() + public function up(): void { // do nothing } @@ -16,7 +16,7 @@ public function up() /** * Migrate Down. */ - public function down() + public function down(): void { // do nothing } diff --git a/tests/TestCase/View/Helper/MigrationHelperTest.php b/tests/TestCase/View/Helper/MigrationHelperTest.php index 0f64e4dd0..ad1a5073b 100644 --- a/tests/TestCase/View/Helper/MigrationHelperTest.php +++ b/tests/TestCase/View/Helper/MigrationHelperTest.php @@ -76,7 +76,7 @@ class MigrationHelperTest extends TestCase * * @return void */ - public function setUp(): void + protected function setUp(): void { parent::setUp(); @@ -141,34 +141,34 @@ public function setUp(): void * * @return void */ - public function tearDown(): void + protected function tearDown(): void { parent::tearDown(); unset($this->helper, $this->view, $this->collection, $this->connection); } - public function testTableMethod() + public function testTableMethod(): void { $this->assertSame('drop', $this->helper->tableMethod('drop_table')); $this->assertSame('create', $this->helper->tableMethod('create_table')); $this->assertSame('update', $this->helper->tableMethod('other_method')); } - public function testIndexMethod() + public function testIndexMethod(): void { $this->assertSame('removeIndex', $this->helper->indexMethod('drop_field')); $this->assertSame('addIndex', $this->helper->indexMethod('add_field')); $this->assertSame('addIndex', $this->helper->indexMethod('alter_field')); } - public function testColumnMethod() + public function testColumnMethod(): void { $this->assertSame('removeColumn', $this->helper->columnMethod('drop_field')); $this->assertSame('addColumn', $this->helper->columnMethod('add_field')); $this->assertSame('changeColumn', $this->helper->columnMethod('alter_field')); } - public function testColumns() + public function testColumns(): void { $extra = []; if ($this->connection->getDriver() instanceof Sqlserver) { @@ -218,7 +218,7 @@ public function testColumns() ], $this->helper->columns('users')); } - public function testColumn() + public function testColumn(): void { $tableSchema = $this->collection->describe('users'); @@ -289,7 +289,7 @@ public function testColumn() ], $this->helper->column($tableSchema, 'updated')); } - public function testValue() + public function testValue(): void { $this->assertSame('null', $this->helper->value(null)); $this->assertSame('null', $this->helper->value('null')); @@ -309,7 +309,7 @@ public function testValue() $this->assertSame("'o\\\"ne'", $this->helper->value('o"ne')); } - public function testAttributes() + public function testAttributes(): void { $attributes = [ 'null' => false, @@ -381,7 +381,7 @@ public function testAttributes() $this->assertEquals($attributes, $result); } - public function testStringifyList() + public function testStringifyList(): void { $this->assertSame('', $this->helper->stringifyList([])); $this->assertSame(" diff --git a/tests/bootstrap.php b/tests/bootstrap.php index cf4caad6f..f92d9157b 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -24,10 +24,10 @@ use Migrator\MigratorPlugin; use function Cake\Core\env; -$findRoot = function ($root) { +$findRoot = function ($root): string { do { $lastRoot = $root; - $root = dirname($root); + $root = dirname((string)$root); if (is_dir($root . '/vendor/cakephp/cakephp')) { return $root; } @@ -38,7 +38,7 @@ unset($findRoot); chdir($root); -require_once 'vendor/autoload.php'; +require_once __DIR__ . '/../vendor/autoload.php'; if (!defined('DS')) { define('DS', DIRECTORY_SEPARATOR); diff --git a/tests/test_app/App/Http/TestRequestHandler.php b/tests/test_app/App/Http/TestRequestHandler.php index 2b376a4f5..dfe37dce3 100644 --- a/tests/test_app/App/Http/TestRequestHandler.php +++ b/tests/test_app/App/Http/TestRequestHandler.php @@ -10,11 +10,14 @@ class TestRequestHandler implements RequestHandlerInterface { + /** + * @var callable + */ public $callable; public function __construct(?callable $callable = null) { - $this->callable = $callable ?: function ($request) { + $this->callable = $callable ?: function ($request): Response { return new Response(); }; } diff --git a/tests/test_app/Plugin/Migrator/config/Migrations/20211001000000_migrator.php b/tests/test_app/Plugin/Migrator/config/Migrations/20211001000000_migrator.php index abc0aaa4f..c3051a35c 100644 --- a/tests/test_app/Plugin/Migrator/config/Migrations/20211001000000_migrator.php +++ b/tests/test_app/Plugin/Migrator/config/Migrations/20211001000000_migrator.php @@ -4,7 +4,7 @@ class Migrator extends BaseMigration { - public function up() + public function up(): void { $this->table('migrator')->addColumn('test', 'integer')->create(); $this->table('migrator')->insert(['test' => 1])->save(); diff --git a/tests/test_app/Plugin/Migrator/config/Migrations2/20211002000000_migrator2.php b/tests/test_app/Plugin/Migrator/config/Migrations2/20211002000000_migrator2.php index e06b74823..8cb055972 100644 --- a/tests/test_app/Plugin/Migrator/config/Migrations2/20211002000000_migrator2.php +++ b/tests/test_app/Plugin/Migrator/config/Migrations2/20211002000000_migrator2.php @@ -4,7 +4,7 @@ class Migrator2 extends BaseMigration { - public function up() + public function up(): void { $this->table('migrator')->insert(['test' => 2])->save(); } diff --git a/tests/test_app/config/DropColumnFkIndexRegression/20190928205056_first_fk_index_migration.php b/tests/test_app/config/DropColumnFkIndexRegression/20190928205056_first_fk_index_migration.php index a24c27de9..8f274973f 100644 --- a/tests/test_app/config/DropColumnFkIndexRegression/20190928205056_first_fk_index_migration.php +++ b/tests/test_app/config/DropColumnFkIndexRegression/20190928205056_first_fk_index_migration.php @@ -4,7 +4,7 @@ class FirstFkIndexMigration extends BaseMigration { - public function up() + public function up(): void { $this->table('table2', [ 'id' => false, @@ -87,7 +87,7 @@ public function up() ->create(); } - public function down() + public function down(): void { $this->table('table1', [ 'id' => false, diff --git a/tests/test_app/config/DropColumnFkIndexRegression/20190928205060_second_fk_index_migration.php b/tests/test_app/config/DropColumnFkIndexRegression/20190928205060_second_fk_index_migration.php index f6c7cb22e..2835b5b9f 100644 --- a/tests/test_app/config/DropColumnFkIndexRegression/20190928205060_second_fk_index_migration.php +++ b/tests/test_app/config/DropColumnFkIndexRegression/20190928205060_second_fk_index_migration.php @@ -4,7 +4,7 @@ class SecondFkIndexMigration extends BaseMigration { - public function up() + public function up(): void { $this->table('table1', [ 'id' => false, diff --git a/tests/test_app/config/DropIndexRegression/20121213232502_create_drop_fk_initial_schema.php b/tests/test_app/config/DropIndexRegression/20121213232502_create_drop_fk_initial_schema.php index 88f18e47d..f173b072a 100644 --- a/tests/test_app/config/DropIndexRegression/20121213232502_create_drop_fk_initial_schema.php +++ b/tests/test_app/config/DropIndexRegression/20121213232502_create_drop_fk_initial_schema.php @@ -7,7 +7,7 @@ class CreateDropFkInitialSchema extends BaseMigration /** * Change. */ - public function change() + public function change(): void { $this->table('my_table') ->addColumn('name', 'string') diff --git a/tests/test_app/config/DropIndexRegression/20121223011815_add_regression_drop_fk.php b/tests/test_app/config/DropIndexRegression/20121223011815_add_regression_drop_fk.php index 4b1a5a7c9..72f8d3827 100644 --- a/tests/test_app/config/DropIndexRegression/20121223011815_add_regression_drop_fk.php +++ b/tests/test_app/config/DropIndexRegression/20121223011815_add_regression_drop_fk.php @@ -7,7 +7,7 @@ class AddRegressionDropFk extends BaseMigration /** * Change. */ - public function change() + public function change(): void { $table = $this->table('my_table'); $table diff --git a/tests/test_app/config/DropIndexRegression/20121223011816_change_fk_regression.php b/tests/test_app/config/DropIndexRegression/20121223011816_change_fk_regression.php index b3ec6f21b..020e82b01 100644 --- a/tests/test_app/config/DropIndexRegression/20121223011816_change_fk_regression.php +++ b/tests/test_app/config/DropIndexRegression/20121223011816_change_fk_regression.php @@ -7,7 +7,7 @@ class ChangeFkRegression extends BaseMigration /** * Migrate Up. */ - public function up() + public function up(): void { $table = $this->table('my_table'); $table diff --git a/tests/test_app/config/DropIndexRegression/20121223011817_change_column_regression.php b/tests/test_app/config/DropIndexRegression/20121223011817_change_column_regression.php index abbd5a8ac..f95ce31e8 100644 --- a/tests/test_app/config/DropIndexRegression/20121223011817_change_column_regression.php +++ b/tests/test_app/config/DropIndexRegression/20121223011817_change_column_regression.php @@ -7,7 +7,7 @@ class ChangeColumnRegression extends BaseMigration /** * Migrate Up. */ - public function up() + public function up(): void { $table = $this->table('my_table'); $table diff --git a/tests/test_app/config/DropTableWithFkRegression/20190928205056_first_drop_fk_migration.php b/tests/test_app/config/DropTableWithFkRegression/20190928205056_first_drop_fk_migration.php index 376669a65..36f4be4a4 100644 --- a/tests/test_app/config/DropTableWithFkRegression/20190928205056_first_drop_fk_migration.php +++ b/tests/test_app/config/DropTableWithFkRegression/20190928205056_first_drop_fk_migration.php @@ -4,7 +4,7 @@ class FirstDropFkMigration extends BaseMigration { - public function change() + public function change(): void { $this->table('orders') ->addColumn('order_date', 'timestamp') diff --git a/tests/test_app/config/DropTableWithFkRegression/20190928205060_second_drop_fk_migration.php b/tests/test_app/config/DropTableWithFkRegression/20190928205060_second_drop_fk_migration.php index 2fc464337..f1161cb41 100644 --- a/tests/test_app/config/DropTableWithFkRegression/20190928205060_second_drop_fk_migration.php +++ b/tests/test_app/config/DropTableWithFkRegression/20190928205060_second_drop_fk_migration.php @@ -4,7 +4,7 @@ class SecondDropFkMigration extends BaseMigration { - public function change() + public function change(): void { $this->table('customers') ->addColumn('name', 'text') diff --git a/tests/test_app/config/Duplicatenames/20120111235330_duplicate_migration_name.php b/tests/test_app/config/Duplicatenames/20120111235330_duplicate_migration_name.php index 4a8dddeb4..d133d6c04 100644 --- a/tests/test_app/config/Duplicatenames/20120111235330_duplicate_migration_name.php +++ b/tests/test_app/config/Duplicatenames/20120111235330_duplicate_migration_name.php @@ -7,7 +7,7 @@ class DuplicateMigrationName extends BaseMigration /** * Migrate Up. */ - public function up() + public function up(): void { // do nothing } @@ -15,7 +15,7 @@ public function up() /** * Migrate Down. */ - public function down() + public function down(): void { // do nothing } diff --git a/tests/test_app/config/Duplicatenames/20120111235331_duplicate_migration_name.php b/tests/test_app/config/Duplicatenames/20120111235331_duplicate_migration_name.php index 4a8dddeb4..d133d6c04 100644 --- a/tests/test_app/config/Duplicatenames/20120111235331_duplicate_migration_name.php +++ b/tests/test_app/config/Duplicatenames/20120111235331_duplicate_migration_name.php @@ -7,7 +7,7 @@ class DuplicateMigrationName extends BaseMigration /** * Migrate Up. */ - public function up() + public function up(): void { // do nothing } @@ -15,7 +15,7 @@ public function up() /** * Migrate Down. */ - public function down() + public function down(): void { // do nothing } diff --git a/tests/test_app/config/Duplicateversions/20120111235330_duplicate_migration.php b/tests/test_app/config/Duplicateversions/20120111235330_duplicate_migration.php index 159962d0a..7f9a90ba4 100644 --- a/tests/test_app/config/Duplicateversions/20120111235330_duplicate_migration.php +++ b/tests/test_app/config/Duplicateversions/20120111235330_duplicate_migration.php @@ -7,7 +7,7 @@ class DuplicateMigration extends BaseMigration /** * Migrate Up. */ - public function up() + public function up(): void { // do nothing } @@ -15,7 +15,7 @@ public function up() /** * Migrate Down. */ - public function down() + public function down(): void { // do nothing } diff --git a/tests/test_app/config/Duplicateversions/20120111235330_duplicate_migration_2.php b/tests/test_app/config/Duplicateversions/20120111235330_duplicate_migration_2.php index 4f548649c..7e0bce59d 100644 --- a/tests/test_app/config/Duplicateversions/20120111235330_duplicate_migration_2.php +++ b/tests/test_app/config/Duplicateversions/20120111235330_duplicate_migration_2.php @@ -7,7 +7,7 @@ class DuplicateMigration2 extends BaseMigration /** * Migrate Up. */ - public function up() + public function up(): void { // do nothing } @@ -15,7 +15,7 @@ public function up() /** * Migrate Down. */ - public function down() + public function down(): void { // do nothing } diff --git a/tests/test_app/config/Invalidclassname/20120111235330_invalid_class.php b/tests/test_app/config/Invalidclassname/20120111235330_invalid_class.php index b147e2f92..942b856b6 100644 --- a/tests/test_app/config/Invalidclassname/20120111235330_invalid_class.php +++ b/tests/test_app/config/Invalidclassname/20120111235330_invalid_class.php @@ -7,7 +7,7 @@ class DifferentClassName extends BaseMigration /** * Migrate Up. */ - public function up() + public function up(): void { // do nothing } @@ -15,7 +15,7 @@ public function up() /** * Migrate Down. */ - public function down() + public function down(): void { // do nothing } diff --git a/tests/test_app/config/ManagerMigrations/20120111235330_test_migration.php b/tests/test_app/config/ManagerMigrations/20120111235330_test_migration.php index 8a4180048..863a9f375 100644 --- a/tests/test_app/config/ManagerMigrations/20120111235330_test_migration.php +++ b/tests/test_app/config/ManagerMigrations/20120111235330_test_migration.php @@ -7,7 +7,7 @@ class TestMigration extends BaseMigration /** * Migrate Up. */ - public function up() + public function up(): void { // do nothing } @@ -15,7 +15,7 @@ public function up() /** * Migrate Down. */ - public function down() + public function down(): void { // do nothing } diff --git a/tests/test_app/config/ManagerMigrations/20120116183504_test_migration_2.php b/tests/test_app/config/ManagerMigrations/20120116183504_test_migration_2.php index 70d0b0e06..c98b7fbf9 100644 --- a/tests/test_app/config/ManagerMigrations/20120116183504_test_migration_2.php +++ b/tests/test_app/config/ManagerMigrations/20120116183504_test_migration_2.php @@ -7,7 +7,7 @@ class TestMigration2 extends BaseMigration /** * Migrate Up. */ - public function up() + public function up(): void { // do nothing } @@ -15,7 +15,7 @@ public function up() /** * Migrate Down. */ - public function down() + public function down(): void { // do nothing } diff --git a/tests/test_app/config/Postgres/20180516025208_snapshot_pgsql.php b/tests/test_app/config/Postgres/20180516025208_snapshot_pgsql.php index 843c8fafb..e221f3368 100644 --- a/tests/test_app/config/Postgres/20180516025208_snapshot_pgsql.php +++ b/tests/test_app/config/Postgres/20180516025208_snapshot_pgsql.php @@ -4,7 +4,7 @@ class SnapshotPgsql extends BaseMigration { - public function up() + public function up(): void { $this->table('articles') ->addColumn('title', 'string', [ @@ -304,7 +304,7 @@ public function up() ->update(); } - public function down() + public function down(): void { $this->table('articles') ->dropForeignKey( diff --git a/tests/test_app/config/Reversiblemigrations/20121213232502_create_initial_schema.php b/tests/test_app/config/Reversiblemigrations/20121213232502_create_initial_schema.php index f27456ea0..4f94bfd69 100644 --- a/tests/test_app/config/Reversiblemigrations/20121213232502_create_initial_schema.php +++ b/tests/test_app/config/Reversiblemigrations/20121213232502_create_initial_schema.php @@ -8,7 +8,7 @@ class CreateInitialSchema extends BaseMigration /** * Change. */ - public function change() + public function change(): void { // users table $users = $this->table('users'); diff --git a/tests/test_app/config/Reversiblemigrations/20121223011815_update_info_table.php b/tests/test_app/config/Reversiblemigrations/20121223011815_update_info_table.php index 147fdfcf7..3b2a15e9f 100644 --- a/tests/test_app/config/Reversiblemigrations/20121223011815_update_info_table.php +++ b/tests/test_app/config/Reversiblemigrations/20121223011815_update_info_table.php @@ -8,7 +8,7 @@ class UpdateInfoTable extends BaseMigration /** * Change. */ - public function change() + public function change(): void { // info table $info = $this->table('info'); diff --git a/tests/test_app/config/Reversiblemigrations/20121224200649_rename_info_table_to_statuses_table.php b/tests/test_app/config/Reversiblemigrations/20121224200649_rename_info_table_to_statuses_table.php index 767a0f9c6..5e49f0383 100644 --- a/tests/test_app/config/Reversiblemigrations/20121224200649_rename_info_table_to_statuses_table.php +++ b/tests/test_app/config/Reversiblemigrations/20121224200649_rename_info_table_to_statuses_table.php @@ -7,7 +7,7 @@ class RenameInfoTableToStatusesTable extends BaseMigration /** * Change. */ - public function change() + public function change(): void { // users table $table = $this->table('info'); diff --git a/tests/test_app/config/Reversiblemigrations/20121224200739_rename_bio_to_biography.php b/tests/test_app/config/Reversiblemigrations/20121224200739_rename_bio_to_biography.php index 42423bafc..3e91fa180 100644 --- a/tests/test_app/config/Reversiblemigrations/20121224200739_rename_bio_to_biography.php +++ b/tests/test_app/config/Reversiblemigrations/20121224200739_rename_bio_to_biography.php @@ -7,7 +7,7 @@ class RenameBioToBiography extends BaseMigration /** * Change. */ - public function change() + public function change(): void { // users table $table = $this->table('users'); diff --git a/tests/test_app/config/Reversiblemigrations/20121224200852_create_user_logins_table.php b/tests/test_app/config/Reversiblemigrations/20121224200852_create_user_logins_table.php index 8e7ec6332..24dfdec76 100644 --- a/tests/test_app/config/Reversiblemigrations/20121224200852_create_user_logins_table.php +++ b/tests/test_app/config/Reversiblemigrations/20121224200852_create_user_logins_table.php @@ -8,7 +8,7 @@ class CreateUserLoginsTable extends BaseMigration /** * Change. */ - public function change() + public function change(): void { // user logins table $table = $this->table('user_logins'); diff --git a/tests/test_app/config/Reversiblemigrations/20170824134305_direction_aware_reversible_up.php b/tests/test_app/config/Reversiblemigrations/20170824134305_direction_aware_reversible_up.php index d87da33d2..12b49727e 100644 --- a/tests/test_app/config/Reversiblemigrations/20170824134305_direction_aware_reversible_up.php +++ b/tests/test_app/config/Reversiblemigrations/20170824134305_direction_aware_reversible_up.php @@ -5,7 +5,7 @@ class DirectionAwareReversibleUp extends BaseMigration { - public function change() + public function change(): void { $this->table('change_direction_test') ->addColumn('thing', Column::STRING, [ diff --git a/tests/test_app/config/Reversiblemigrations/20170831121929_direction_aware_reversible_down.php b/tests/test_app/config/Reversiblemigrations/20170831121929_direction_aware_reversible_down.php index 3455b2ded..3229cd498 100644 --- a/tests/test_app/config/Reversiblemigrations/20170831121929_direction_aware_reversible_down.php +++ b/tests/test_app/config/Reversiblemigrations/20170831121929_direction_aware_reversible_down.php @@ -6,7 +6,7 @@ class DirectionAwareReversibleDown extends BaseMigration { - public function change() + public function change(): void { $this->table('change_direction_test') ->addColumn('subthing', Column::STRING, [ diff --git a/tests/test_app/config/Reversiblemigrations/20180431121930_tricky_edge_case.php b/tests/test_app/config/Reversiblemigrations/20180431121930_tricky_edge_case.php index fdd8f32d6..00a80f3ba 100644 --- a/tests/test_app/config/Reversiblemigrations/20180431121930_tricky_edge_case.php +++ b/tests/test_app/config/Reversiblemigrations/20180431121930_tricky_edge_case.php @@ -5,7 +5,7 @@ class TrickyEdgeCase extends BaseMigration { - public function change() + public function change(): void { $table = $this->table('user_logins'); $table diff --git a/tests/test_app/config/Reversiblemigrations/20180516025208_create_test_index_limit_specifier_table.php b/tests/test_app/config/Reversiblemigrations/20180516025208_create_test_index_limit_specifier_table.php index d118bed6e..5af15e185 100644 --- a/tests/test_app/config/Reversiblemigrations/20180516025208_create_test_index_limit_specifier_table.php +++ b/tests/test_app/config/Reversiblemigrations/20180516025208_create_test_index_limit_specifier_table.php @@ -26,7 +26,7 @@ class CreateTestIndexLimitSpecifierTable extends BaseMigration * Remember to call "create()" or "update()" and NOT "save()" when working * with the Table class. */ - public function change() + public function change(): void { $table = $this->table('test_index_limit_specifier'); $table->addColumn('column1', Column::STRING) diff --git a/tests/test_app/config/Reversiblemigrations/20190928220334_add_column_index_fk.php b/tests/test_app/config/Reversiblemigrations/20190928220334_add_column_index_fk.php index 74b4b3238..45f3dad78 100644 --- a/tests/test_app/config/Reversiblemigrations/20190928220334_add_column_index_fk.php +++ b/tests/test_app/config/Reversiblemigrations/20190928220334_add_column_index_fk.php @@ -31,7 +31,7 @@ class AddColumnIndexFk extends BaseMigration * Remember to call "create()" or "update()" and NOT "save()" when working * with the Table class. */ - public function change() + public function change(): void { $table = $this->table('statuses') ->addColumn('user_id', Column::INTEGER, [ diff --git a/tests/test_app/config/ShouldExecute/20201207205056_should_not_execute_migration.php b/tests/test_app/config/ShouldExecute/20201207205056_should_not_execute_migration.php index 1e45f604e..d6c4da16e 100644 --- a/tests/test_app/config/ShouldExecute/20201207205056_should_not_execute_migration.php +++ b/tests/test_app/config/ShouldExecute/20201207205056_should_not_execute_migration.php @@ -5,7 +5,7 @@ class ShouldNotExecuteMigration extends BaseMigration { - public function change() + public function change(): void { // info table $this->table('info')->create(); diff --git a/tests/test_app/config/ShouldExecute/20201207205057_should_execute_migration.php b/tests/test_app/config/ShouldExecute/20201207205057_should_execute_migration.php index 7e34549b3..d35a45edd 100644 --- a/tests/test_app/config/ShouldExecute/20201207205057_should_execute_migration.php +++ b/tests/test_app/config/ShouldExecute/20201207205057_should_execute_migration.php @@ -5,7 +5,7 @@ class ShouldExecuteMigration extends BaseMigration { - public function change() + public function change(): void { // info table $this->table('info')->create();