diff --git a/composer.json b/composer.json
index 07b7333..88b4a83 100644
--- a/composer.json
+++ b/composer.json
@@ -41,7 +41,7 @@
"infection/infection": "^0.26.6",
"mockery/mockery": "^1.5",
"phpunit/phpunit": "^9.5.20",
- "spiral/testing": "^2.0",
+ "spiral/testing": "^2.4",
"spiral/validator": "^1.2",
"vimeo/psalm": "^4.27"
},
diff --git a/src/Auth/TokenStorage.php b/src/Auth/TokenStorage.php
index 01262df..c837440 100644
--- a/src/Auth/TokenStorage.php
+++ b/src/Auth/TokenStorage.php
@@ -89,11 +89,13 @@ private function issueID(): string
{
$id = $this->randomHash(64);
+ /** @psalm-suppress InternalMethod */
$query = $this->orm->getSource(Token::class)
->getDatabase()
->select()
->from($this->orm->getSource(Token::class)->getTable());
+ /** @psalm-suppress InternalMethod */
while ((clone $query)->where('id', $id)->count('id') !== 0) {
$id = $this->randomHash(64);
}
diff --git a/src/Console/Command/CycleOrm/Generator/ShowChanges.php b/src/Console/Command/CycleOrm/Generator/ShowChanges.php
index f65292b..7591983 100644
--- a/src/Console/Command/CycleOrm/Generator/ShowChanges.php
+++ b/src/Console/Command/CycleOrm/Generator/ShowChanges.php
@@ -4,10 +4,10 @@
namespace Spiral\Cycle\Console\Command\CycleOrm\Generator;
+use Cycle\Database\Schema\ComparatorInterface;
use Cycle\Schema\GeneratorInterface;
use Cycle\Schema\Registry;
use Cycle\Database\Schema\AbstractTable;
-use Cycle\Database\Schema\Comparator;
use Symfony\Component\Console\Output\OutputInterface;
final class ShowChanges implements GeneratorInterface
@@ -15,20 +15,18 @@ final class ShowChanges implements GeneratorInterface
private array $changes = [];
public function __construct(
- private readonly OutputInterface $output
+ private readonly OutputInterface $output,
) {
}
public function run(Registry $registry): Registry
{
- $this->output->writeln('Detecting schema changes:');
-
$this->changes = [];
foreach ($registry->getIterator() as $e) {
if ($registry->hasTable($e)) {
$table = $registry->getTableSchema($e);
if ($table->getComparator()->hasChanges()) {
- $key = $registry->getDatabase($e).':'.$registry->getTable($e);
+ $key = $registry->getDatabase($e) . ':' . $registry->getTable($e);
$this->changes[$key] = [
'database' => $registry->getDatabase($e),
'table' => $registry->getTable($e),
@@ -44,6 +42,9 @@ public function run(Registry $registry): Registry
return $registry;
}
+
+ $this->output->writeln('Schema changes:');
+
foreach ($this->changes as $change) {
$this->output->write(\sprintf('• %s.%s', $change['database'], $change['table']));
$this->describeChanges($change['schema']);
@@ -63,14 +64,14 @@ protected function describeChanges(AbstractTable $table): void
$this->output->writeln(
\sprintf(
': %s change(s) detected',
- $this->numChanges($table)
- )
+ $this->numChanges($table),
+ ),
);
return;
}
- $this->output->write("\n");
+ $this->output->write("\n");
if (!$table->exists()) {
$this->output->writeln(' - create table');
@@ -88,7 +89,7 @@ protected function describeChanges(AbstractTable $table): void
$this->describeFKs($cmp);
}
- protected function describeColumns(Comparator $cmp): void
+ protected function describeColumns(ComparatorInterface $cmp): void
{
foreach ($cmp->addedColumns() as $column) {
$this->output->writeln(" - add column {$column->getName()}");
@@ -104,7 +105,7 @@ protected function describeColumns(Comparator $cmp): void
}
}
- protected function describeIndexes(Comparator $cmp): void
+ protected function describeIndexes(ComparatorInterface $cmp): void
{
foreach ($cmp->addedIndexes() as $index) {
$index = \implode(', ', $index->getColumns());
@@ -123,7 +124,7 @@ protected function describeIndexes(Comparator $cmp): void
}
}
- protected function describeFKs(Comparator $cmp): void
+ protected function describeFKs(ComparatorInterface $cmp): void
{
foreach ($cmp->addedForeignKeys() as $fk) {
$fkColumns = \implode(', ', $fk->getColumns());
diff --git a/src/Console/Command/CycleOrm/MigrateCommand.php b/src/Console/Command/CycleOrm/MigrateCommand.php
index 3ce1873..62c6c05 100644
--- a/src/Console/Command/CycleOrm/MigrateCommand.php
+++ b/src/Console/Command/CycleOrm/MigrateCommand.php
@@ -4,6 +4,9 @@
namespace Spiral\Cycle\Console\Command\CycleOrm;
+use Cycle\Schema\Generator\Migrations\Strategy\GeneratorStrategyInterface;
+use Cycle\Schema\Generator\Migrations\Strategy\MultipleFilesStrategy;
+use Spiral\Core\BinderInterface;
use Spiral\Cycle\Bootloader\SchemaBootloader;
use Spiral\Cycle\Config\CycleConfig;
use Spiral\Cycle\Console\Command\CycleOrm\Generator\ShowChanges;
@@ -22,6 +25,7 @@ final class MigrateCommand extends AbstractCommand
protected const NAME = 'cycle:migrate';
protected const DESCRIPTION = 'Generate ORM schema migrations';
protected const OPTIONS = [
+ ['split', 'p', InputOption::VALUE_NONE, 'Split generated migration into multiple files.'],
['run', 'r', InputOption::VALUE_NONE, 'Automatically run generated migration.'],
];
@@ -30,30 +34,44 @@ public function perform(
CycleConfig $config,
Registry $registry,
MemoryInterface $memory,
- GenerateMigrations $migrations,
Migrator $migrator,
- Console $console
+ Console $console,
): int {
$migrator->configure();
foreach ($migrator->getMigrations() as $migration) {
if ($migration->getState()->getStatus() !== State::STATUS_EXECUTED) {
- $this->writeln('Outstanding migrations found, run `migrate` first.');
- return self::SUCCESS;
+ $this->error('Outstanding migrations found.');
+
+ if ($this->isInteractive() && $this->output->confirm('Do you want to run `migrate` now?')) {
+ $console->run('migrate', [], $this->output);
+ } else {
+ $this->error('Please run `migrate` first.');
+ return self::SUCCESS;
+ }
}
}
+ $this->comment('Detecting schema changes...');
+
$schemaCompiler = Compiler::compile(
$registry,
\array_merge($bootloader->getGenerators($config), [
- $show = new ShowChanges($this->output)
+ $show = new ShowChanges($this->output),
]),
- $config->getSchemaDefaults()
+ $config->getSchemaDefaults(),
);
$schemaCompiler->toMemory($memory);
if ($show->hasChanges()) {
+ if ($this->option('split')) {
+ \assert($this->container instanceof BinderInterface);
+ $this->container->bind(GeneratorStrategyInterface::class, MultipleFilesStrategy::class);
+ }
+
+ $migrations = $this->container->get(GenerateMigrations::class);
+
(new \Cycle\Schema\Compiler())->compile($registry, [$migrations]);
if ($this->option('run')) {
diff --git a/src/Console/Command/CycleOrm/RenderCommand.php b/src/Console/Command/CycleOrm/RenderCommand.php
index a6527f3..5b0ecf3 100644
--- a/src/Console/Command/CycleOrm/RenderCommand.php
+++ b/src/Console/Command/CycleOrm/RenderCommand.php
@@ -15,7 +15,6 @@
final class RenderCommand extends AbstractCommand
{
protected const SIGNATURE = 'cycle:render {format=color : Output format}';
-
protected const DESCRIPTION = 'Render available CycleORM schemas';
public function perform(
diff --git a/src/Console/Command/CycleOrm/SyncCommand.php b/src/Console/Command/CycleOrm/SyncCommand.php
index 680cb89..12d0352 100644
--- a/src/Console/Command/CycleOrm/SyncCommand.php
+++ b/src/Console/Command/CycleOrm/SyncCommand.php
@@ -8,12 +8,12 @@
use Cycle\Schema\Generator\SyncTables;
use Cycle\Schema\Registry;
use Spiral\Boot\MemoryInterface;
-use Spiral\Console\Command;
use Spiral\Cycle\Config\CycleConfig;
use Spiral\Cycle\Console\Command\CycleOrm\Generator\ShowChanges;
+use Spiral\Cycle\Console\Command\Migrate\AbstractCommand;
use Spiral\Cycle\Schema\Compiler;
-final class SyncCommand extends Command
+final class SyncCommand extends AbstractCommand
{
protected const NAME = 'cycle:sync';
protected const DESCRIPTION = 'Sync Cycle ORM schema with database without intermediate migration (risk operation)';
@@ -22,19 +22,24 @@ public function perform(
SchemaBootloader $bootloader,
CycleConfig $config,
Registry $registry,
- MemoryInterface $memory
+ MemoryInterface $memory,
): int {
+ if (!$this->verifyEnvironment(message: 'This operation is not recommended for production environment.')) {
+ return self::FAILURE;
+ }
+
$show = new ShowChanges($this->output);
$schemaCompiler = Compiler::compile(
$registry,
\array_merge($bootloader->getGenerators($config), [$show, new SyncTables()]),
- $config->getSchemaDefaults()
+ $config->getSchemaDefaults(),
);
+
$schemaCompiler->toMemory($memory);
if ($show->hasChanges()) {
- $this->writeln("\nORM Schema has been synchronized");
+ $this->info('ORM Schema has been synchronized with database.');
}
return self::SUCCESS;
diff --git a/src/Console/Command/CycleOrm/UpdateCommand.php b/src/Console/Command/CycleOrm/UpdateCommand.php
index d5eb8c7..ef83522 100644
--- a/src/Console/Command/CycleOrm/UpdateCommand.php
+++ b/src/Console/Command/CycleOrm/UpdateCommand.php
@@ -20,17 +20,17 @@ public function perform(
SchemaBootloader $bootloader,
CycleConfig $config,
Registry $registry,
- MemoryInterface $memory
+ MemoryInterface $memory,
): int {
- $this->write('Updating ORM schema... ');
+ $this->info('Updating ORM schema... ');
Compiler::compile(
$registry,
$bootloader->getGenerators($config),
- $config->getSchemaDefaults()
+ $config->getSchemaDefaults(),
)->toMemory($memory);
- $this->writeln('done');
+ $this->info('Schema has been updated.');
return self::SUCCESS;
}
diff --git a/src/Console/Command/Migrate/AbstractCommand.php b/src/Console/Command/Migrate/AbstractCommand.php
index 271f8b0..853305d 100644
--- a/src/Console/Command/Migrate/AbstractCommand.php
+++ b/src/Console/Command/Migrate/AbstractCommand.php
@@ -15,7 +15,7 @@ abstract class AbstractCommand extends Command
{
public function __construct(
protected Migrator $migrator,
- protected MigrationConfig $config
+ protected MigrationConfig $config,
) {
parent::__construct();
}
@@ -24,7 +24,7 @@ protected function verifyConfigured(): bool
{
if (!$this->migrator->isConfigured()) {
$this->writeln(
- "Migrations are not configured yet, run 'migrate:init' first."
+ "Migrations are not configured yet, run 'migrate:init' first.",
);
return false;
@@ -36,17 +36,17 @@ protected function verifyConfigured(): bool
/**
* Check if current environment is safe to run migration.
*/
- protected function verifyEnvironment(): bool
+ protected function verifyEnvironment(string $message = 'Confirmation is required to run migrations!'): bool
{
- if ($this->option('force') || $this->config->isSafe()) {
+ if ($this->isForce() || $this->config->isSafe()) {
//Safe to run
return true;
}
- $this->writeln('Confirmation is required to run migrations!');
+ $this->error($message);
if (!$this->askConfirmation()) {
- $this->writeln('Cancelling operation...');
+ $this->comment('Cancelling operation...');
return false;
}
@@ -60,7 +60,8 @@ protected function defineOptions(): array
static::OPTIONS,
[
['force', 's', InputOption::VALUE_NONE, 'Skip safe environment check'],
- ]
+ ['no-interaction', 'n', InputOption::VALUE_NONE, 'Do not ask any interactive question'],
+ ],
);
}
@@ -71,7 +72,17 @@ protected function askConfirmation(): bool
return $question->ask(
$this->input,
$this->output,
- new ConfirmationQuestion('Would you like to continue? ')
+ new ConfirmationQuestion('Would you like to continue? ', false),
);
}
+
+ protected function isInteractive(): bool
+ {
+ return !$this->option('no-interaction');
+ }
+
+ protected function isForce(): bool
+ {
+ return $this->option('force');
+ }
}
diff --git a/src/Console/Command/Migrate/InitCommand.php b/src/Console/Command/Migrate/InitCommand.php
index 6faefec..e8c418c 100644
--- a/src/Console/Command/Migrate/InitCommand.php
+++ b/src/Console/Command/Migrate/InitCommand.php
@@ -7,7 +7,7 @@
final class InitCommand extends AbstractCommand
{
protected const NAME = 'migrate:init';
- protected const DESCRIPTION = 'Init migrations component (create migrations table)';
+ protected const DESCRIPTION = 'Create migrations table if not exists.';
/**
* Perform command.
@@ -15,7 +15,7 @@ final class InitCommand extends AbstractCommand
public function perform(): int
{
$this->migrator->configure();
- $this->writeln('Migrations table were successfully created');
+ $this->info('Migration table was successfully created.');
return self::SUCCESS;
}
diff --git a/src/Console/Command/Migrate/MigrateCommand.php b/src/Console/Command/Migrate/MigrateCommand.php
index c5884b7..8a2eb78 100644
--- a/src/Console/Command/Migrate/MigrateCommand.php
+++ b/src/Console/Command/Migrate/MigrateCommand.php
@@ -9,7 +9,7 @@
final class MigrateCommand extends AbstractCommand
{
protected const NAME = 'migrate';
- protected const DESCRIPTION = 'Perform one or all outstanding migrations';
+ protected const DESCRIPTION = 'Execute one or multiple migrations.';
protected const OPTIONS = [
['one', 'o', InputOption::VALUE_NONE, 'Execute only one (first) migration'],
];
@@ -34,12 +34,12 @@ public function perform(): int
$this->sprintf(
"Migration %s was successfully executed.\n",
- $migration->getState()->getName()
+ $migration->getState()->getName(),
);
}
if (!$found) {
- $this->writeln('No outstanding migrations were found.');
+ $this->error('No outstanding migrations were found.');
}
return self::SUCCESS;
diff --git a/src/Console/Command/Migrate/ReplayCommand.php b/src/Console/Command/Migrate/ReplayCommand.php
index 21c5f3e..eedd760 100644
--- a/src/Console/Command/Migrate/ReplayCommand.php
+++ b/src/Console/Command/Migrate/ReplayCommand.php
@@ -16,7 +16,6 @@ final class ReplayCommand extends AbstractCommand
];
/**
- * @param Console $console
* @throws \Throwable
*/
public function perform(Console $console): int
@@ -35,12 +34,12 @@ public function perform(Console $console): int
$migrate['--one'] = true;
}
- $this->writeln('Rolling back executed migration(s)...');
+ $this->warning('Rolling back executed migration(s)...');
$console->run('migrate:rollback', $rollback, $this->output);
$this->writeln('');
- $this->writeln('Executing outstanding migration(s)...');
+ $this->info('Executing outstanding migration(s)...');
$console->run('migrate', $migrate, $this->output);
return self::SUCCESS;
diff --git a/src/Console/Command/Migrate/RollbackCommand.php b/src/Console/Command/Migrate/RollbackCommand.php
index 4d9e429..2760419 100644
--- a/src/Console/Command/Migrate/RollbackCommand.php
+++ b/src/Console/Command/Migrate/RollbackCommand.php
@@ -17,7 +17,6 @@ final class RollbackCommand extends AbstractCommand
public function perform(): int
{
if (!$this->verifyEnvironment()) {
- //Making sure we can safely migrate in this environment
return self::FAILURE;
}
@@ -30,12 +29,12 @@ public function perform(): int
$count--;
$this->sprintf(
"Migration %s was successfully rolled back.\n",
- $migration->getState()->getName()
+ $migration->getState()->getName(),
);
}
if (!$found) {
- $this->writeln('No executed migrations were found.');
+ $this->error('No executed migrations were found.');
}
return self::SUCCESS;
diff --git a/src/Console/Command/Migrate/StatusCommand.php b/src/Console/Command/Migrate/StatusCommand.php
index 8f76647..13a79e3 100644
--- a/src/Console/Command/Migrate/StatusCommand.php
+++ b/src/Console/Command/Migrate/StatusCommand.php
@@ -7,12 +7,12 @@
use Cycle\Migrations\State;
/**
- * Show all available migrations and their statuses
+ * Get list of all available migrations and their statuses.
*/
final class StatusCommand extends AbstractCommand
{
protected const NAME = 'migrate:status';
- protected const DESCRIPTION = 'Get list of all available migrations and their statuses';
+ protected const DESCRIPTION = 'Get list of all available migrations and their statuses.';
protected const PENDING = 'not executed yet';
public function perform(): int
@@ -35,8 +35,8 @@ public function perform(): int
$state->getTimeCreated()->format('Y-m-d H:i:s'),
$state->getStatus() == State::STATUS_PENDING
? self::PENDING
- : ''.$state->getTimeExecuted()->format('Y-m-d H:i:s').'',
- ]
+ : '' . $state->getTimeExecuted()->format('Y-m-d H:i:s') . '',
+ ],
);
}
diff --git a/src/Console/Command/Scaffolder/EntityCommand.php b/src/Console/Command/Scaffolder/EntityCommand.php
index 3a44abc..929497f 100644
--- a/src/Console/Command/Scaffolder/EntityCommand.php
+++ b/src/Console/Command/Scaffolder/EntityCommand.php
@@ -19,12 +19,12 @@
class EntityCommand extends AbstractCommand
{
- protected const NAME = 'create:entity';
+ protected const NAME = 'create:entity';
protected const DESCRIPTION = 'Create entity declaration';
- protected const ARGUMENTS = [
+ protected const ARGUMENTS = [
['name', InputArgument::REQUIRED, 'Entity name'],
];
- protected const OPTIONS = [
+ protected const OPTIONS = [
[
'role',
'r',
diff --git a/src/Console/Command/Scaffolder/MigrationCommand.php b/src/Console/Command/Scaffolder/MigrationCommand.php
index 32bf488..8252ae2 100644
--- a/src/Console/Command/Scaffolder/MigrationCommand.php
+++ b/src/Console/Command/Scaffolder/MigrationCommand.php
@@ -13,12 +13,12 @@
class MigrationCommand extends AbstractCommand
{
- protected const NAME = 'create:migration';
+ protected const NAME = 'create:migration';
protected const DESCRIPTION = 'Create migration declaration';
- protected const ARGUMENTS = [
+ protected const ARGUMENTS = [
['name', InputArgument::REQUIRED, 'Migration name'],
];
- protected const OPTIONS = [
+ protected const OPTIONS = [
[
'table',
't',
@@ -66,12 +66,12 @@ public function perform(Migrator $migrator): int
$filename = $migrator->getRepository()->registerMigration(
(string)$this->argument('name'),
$declaration->getClass()->getName(),
- (string) $declaration->getFile()
+ (string)$declaration->getFile(),
);
$this->writeln(
"Declaration of '{$declaration->getClass()->getName()}' "
- . "has been successfully written into '{$filename}'."
+ . "has been successfully written into '{$filename}'.",
);
return self::SUCCESS;
diff --git a/tests/src/Console/Command/CycleOrm/MigrateCommandTest.php b/tests/src/Console/Command/CycleOrm/MigrateCommandTest.php
index 7961e3b..e43456d 100644
--- a/tests/src/Console/Command/CycleOrm/MigrateCommandTest.php
+++ b/tests/src/Console/Command/CycleOrm/MigrateCommandTest.php
@@ -4,8 +4,6 @@
namespace Spiral\Tests\Console\Command\CycleOrm;
-use Cycle\Annotated\Annotation\Column;
-use Cycle\Annotated\Annotation\Entity;
use Cycle\ORM\SchemaInterface;
use Spiral\Boot\MemoryInterface;
use Spiral\Cycle\Config\CycleConfig;
@@ -38,8 +36,15 @@ protected function setUp(): void
public function testMigrate(): void
{
+ // Create migration
$this->assertConsoleCommandOutputContainsStrings('cycle:migrate', [], self::USER_MIGRATION);
- $this->assertConsoleCommandOutputContainsStrings('cycle:migrate', [], 'Outstanding migrations found');
+
+ $this->assertConsoleCommandOutputContainsStrings('cycle:migrate', [], [
+ 'Outstanding migrations found',
+ 'Detecting schema changes...',
+ 'was successfully executed.',
+ 'no database changes has been detected',
+ ]);
}
public function testMigrateNoChanges(): void
@@ -55,9 +60,10 @@ public function testMigrationShouldBeCreatedWhenNewEntityAppeared(): void
$fs = new Files();
- $entityPatch = __DIR__.'/../../../../app/Entities/Tag.php';
+ $entityPatch = __DIR__ . '/../../../../app/Entities/Tag.php';
file_put_contents(
- $entityPatch, <<<'PHP'
+ $entityPatch,
+ <<<'PHP'
assertConsoleCommandOutputContainsStrings('cycle:migrate', ['-r' => true], [
@@ -89,8 +95,7 @@ public function testSchemaDefaultsShouldBePassedToCompiler(): void
{
$config['schema']['defaults'][SchemaInterface::TYPECAST_HANDLER][] = 'foo';
- $memory = new class implements MemoryInterface
- {
+ $memory = new class implements MemoryInterface {
private mixed $data;
public function loadData(string $section): mixed
diff --git a/tests/src/Console/Command/CycleOrm/SyncCommandTest.php b/tests/src/Console/Command/CycleOrm/SyncCommandTest.php
index aef66c6..dc674aa 100644
--- a/tests/src/Console/Command/CycleOrm/SyncCommandTest.php
+++ b/tests/src/Console/Command/CycleOrm/SyncCommandTest.php
@@ -8,15 +8,24 @@
use Spiral\App\Entities\User;
use Spiral\Boot\MemoryInterface;
use Spiral\Cycle\Config\CycleConfig;
+use Spiral\Testing\Attribute\Env;
use Spiral\Tests\ConsoleTest;
final class SyncCommandTest extends ConsoleTest
{
public const ENV = [
- 'SAFE_MIGRATIONS' => true,
'USE_MIGRATIONS' => true,
];
+ #[Env('SAFE_MIGRATIONS', 'false')]
+ public function testUnsafeSync(): void
+ {
+ $output = $this->runCommand('cycle:sync');
+ $this->assertStringContainsString('This operation is not recommended for production environment.', $output);
+ $this->assertStringContainsString('Cancelling operation...', $output);
+ }
+
+ #[Env('SAFE_MIGRATIONS', 'true')]
public function testSync(): void
{
$output = $this->runCommand('cycle:sync');
@@ -28,6 +37,7 @@ public function testSync(): void
$this->assertSame(1, $u->id);
}
+ #[Env('SAFE_MIGRATIONS', 'true')]
public function testSyncDebug(): void
{
$this->assertConsoleCommandOutputContainsStrings('cycle:sync', ['-vvv'], [
@@ -43,6 +53,7 @@ public function testSyncDebug(): void
$this->assertSame(1, $u->id);
}
+ #[Env('SAFE_MIGRATIONS', 'true')]
public function testSchemaDefaultsShouldBePassedToCompiler(): void
{
$config['schema']['defaults'][SchemaInterface::TYPECAST_HANDLER][] = 'foo';
diff --git a/tests/src/Console/Command/Migrate/MigrateCommandTest.php b/tests/src/Console/Command/Migrate/MigrateCommandTest.php
index 7a5eba8..df97c67 100644
--- a/tests/src/Console/Command/Migrate/MigrateCommandTest.php
+++ b/tests/src/Console/Command/Migrate/MigrateCommandTest.php
@@ -5,16 +5,46 @@
namespace Spiral\Tests\Console\Command\Migrate;
use Cycle\Database\DatabaseInterface;
+use Spiral\Testing\Attribute\Env;
use Spiral\Tests\ConsoleTest;
final class MigrateCommandTest extends ConsoleTest
{
public const ENV = [
- 'SAFE_MIGRATIONS' => true,
'USE_MIGRATIONS' => true,
];
+ #[Env('SAFE_MIGRATIONS', true)]
public function testMigrate(): void
+ {
+ $db = $this->initMigrations();
+ $this->runCommand('migrate');
+ $this->assertCount(4, $db->getTables());
+ }
+
+ #[Env('SAFE_MIGRATIONS', false)]
+ public function tesForceMigrate(): void
+ {
+ $db = $this->initMigrations();
+ $this->runCommand('migrate', ['--force' => true]);
+ $this->assertCount(4, $db->getTables());
+ }
+
+ #[Env('SAFE_MIGRATIONS', false)]
+ public function testUnsafeMigrate(): void
+ {
+ $db = $this->initMigrations();
+ $output = $this->runCommand('migrate');
+ $this->assertStringContainsString('Confirmation is required to run migrations!', $output);
+ $this->assertStringContainsString('Cancelling operation...', $output);
+ $this->assertCount(1, $db->getTables());
+ }
+
+ /**
+ * @return void
+ * @throws \Throwable
+ */
+ public function initMigrations(): DatabaseInterface
{
/** @var DatabaseInterface $db */
$db = $this->getContainer()->get(DatabaseInterface::class);
@@ -25,7 +55,6 @@ public function testMigrate(): void
$this->assertCount(1, $db->getTables());
- $this->runCommand('migrate');
- $this->assertCount(4, $db->getTables());
+ return $db;
}
}