Skip to content

Commit

Permalink
[11.x] Add the ability to skip migrations within tests (#54441)
Browse files Browse the repository at this point in the history
* introduce WithoutMigration

* helper function for running skipped migrations

* style

* allow for array of migrations

* revert RefreshDatabase changes

* add migrator test

* revert RefreshDatabase entirely

* test unsetting skipped migrations

* test with an array

* formatting

---------

Co-authored-by: Taylor Otwell <[email protected]>
  • Loading branch information
cosmastech and taylorotwell authored Feb 6, 2025
1 parent b29fa77 commit 578d24a
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 2 deletions.
4 changes: 3 additions & 1 deletion src/Illuminate/Database/Events/NoPendingMigrations.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

namespace Illuminate\Database\Events;

class NoPendingMigrations
use Illuminate\Contracts\Database\Events\MigrationEvent;

class NoPendingMigrations implements MigrationEvent
{
/**
* The migration method that was called.
Expand Down
37 changes: 36 additions & 1 deletion src/Illuminate/Database/Migrations/Migrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,13 @@ class Migrator
*/
protected $output;

/**
* The pending migrations to skip.
*
* @var list<string>
*/
protected static $withoutMigrations = [];

/**
* Create a new migrator instance.
*
Expand Down Expand Up @@ -142,12 +149,29 @@ public function run($paths = [], array $options = [])
*/
protected function pendingMigrations($files, $ran)
{
$migrationsToSkip = $this->migrationsToSkip();

return (new Collection($files))
->reject(fn ($file) => in_array($this->getMigrationName($file), $ran))
->reject(fn ($file) =>
in_array($migrationName = $this->getMigrationName($file), $ran) ||
in_array($migrationName, $migrationsToSkip)
)
->values()
->all();
}

/**
* Get list of pending migrations to skip.
*
* @return list<string>
*/
protected function migrationsToSkip()
{
return (new Collection(self::$withoutMigrations))
->map($this->getMigrationName(...))
->all();
}

/**
* Run an array of migrations.
*
Expand Down Expand Up @@ -598,6 +622,17 @@ public function paths()
return $this->paths;
}

/**
* Set the pending migrations to skip.
*
* @param list<string> $migrations
* @return void
*/
public static function withoutMigrations(array $migrations)
{
static::$withoutMigrations = $migrations;
}

/**
* Get the default connection name.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use Illuminate\Console\Application as Artisan;
use Illuminate\Cookie\Middleware\EncryptCookies;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Migrations\Migrator;
use Illuminate\Foundation\Bootstrap\HandleExceptions;
use Illuminate\Foundation\Bootstrap\RegisterProviders;
use Illuminate\Foundation\Console\AboutCommand;
Expand Down Expand Up @@ -170,6 +171,7 @@ protected function tearDownTheTestEnvironment(): void
ConvertEmptyStringsToNull::flushState();
EncryptCookies::flushState();
HandleExceptions::flushState();
Migrator::withoutMigrations([]);
Once::flush();
PreventRequestsDuringMaintenance::flushState();
Queue::createPayloadUsing(null);
Expand Down
25 changes: 25 additions & 0 deletions tests/Integration/Migration/MigratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace Illuminate\Tests\Integration\Migration;

use Illuminate\Database\Migrations\Migrator;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
Expand Down Expand Up @@ -29,6 +30,12 @@ protected function setUp(): void
$this->subject->getRepository()->createRepository();
}

protected function tearDown(): void
{
parent::tearDown();
Migrator::withoutMigrations([]);
}

public function testMigrate()
{
$this->expectInfo('Running migrations.');
Expand Down Expand Up @@ -58,6 +65,24 @@ public function testMigrateWithoutOutput()
$this->assertTrue(DB::getSchemaBuilder()->hasColumn('people', 'last_name'));
}

public function testWithSkippedMigrations()
{
$this->app->forgetInstance('migrator');
$this->subject = $this->app->make('migrator');

Migrator::withoutMigrations(['2015_10_04_000000_modify_people_table.php', '2016_10_04_000000_modify_people_table']);

$this->subject->run([__DIR__.'/fixtures']);
$this->assertTrue(DB::getSchemaBuilder()->hasTable('people'));
$this->assertFalse(DB::getSchemaBuilder()->hasColumn('people', 'first_name'));
$this->assertFalse(DB::getSchemaBuilder()->hasColumn('people', 'last_name'));

Migrator::withoutMigrations([]);
$this->subject->run([__DIR__.'/fixtures']);
$this->assertTrue(DB::getSchemaBuilder()->hasColumn('people', 'first_name'));
$this->assertTrue(DB::getSchemaBuilder()->hasColumn('people', 'last_name'));
}

public function testRollback()
{
$this->getConnection()->statement('CREATE TABLE people(id INT, first_name VARCHAR, last_name VARCHAR);');
Expand Down

0 comments on commit 578d24a

Please sign in to comment.