2018-01-16 21:26:59 +01:00
|
|
|
<?php
|
|
|
|
|
2023-02-03 20:41:59 +01:00
|
|
|
declare(strict_types=1);
|
|
|
|
|
2020-04-19 20:41:38 +02:00
|
|
|
namespace Engelsystem\Test\Unit\Database\Migration;
|
2018-01-16 21:26:59 +01:00
|
|
|
|
|
|
|
use Engelsystem\Application;
|
|
|
|
use Engelsystem\Database\Migration\Migrate;
|
2023-01-24 19:23:57 +01:00
|
|
|
use Engelsystem\Database\Migration\Direction;
|
2020-06-01 22:00:33 +02:00
|
|
|
use Engelsystem\Test\Unit\TestCase;
|
|
|
|
use Exception;
|
2018-01-16 21:26:59 +01:00
|
|
|
use Illuminate\Database\Capsule\Manager as CapsuleManager;
|
|
|
|
use Illuminate\Database\Schema\Builder as SchemaBuilder;
|
|
|
|
use Illuminate\Support\Collection;
|
|
|
|
use Illuminate\Support\Str;
|
|
|
|
use PHPUnit\Framework\MockObject\MockObject;
|
|
|
|
|
|
|
|
class MigrateTest extends TestCase
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* @covers \Engelsystem\Database\Migration\Migrate::__construct
|
|
|
|
* @covers \Engelsystem\Database\Migration\Migrate::getMigrations
|
2019-04-24 11:01:37 +02:00
|
|
|
* @covers \Engelsystem\Database\Migration\Migrate::run
|
2018-01-16 21:26:59 +01:00
|
|
|
* @covers \Engelsystem\Database\Migration\Migrate::setOutput
|
2019-07-21 20:38:07 +02:00
|
|
|
* @covers \Engelsystem\Database\Migration\Migrate::mergeMigrations
|
2018-01-16 21:26:59 +01:00
|
|
|
*/
|
2022-12-14 19:15:20 +01:00
|
|
|
public function testRun(): void
|
2018-01-16 21:26:59 +01:00
|
|
|
{
|
2019-04-24 10:45:00 +02:00
|
|
|
/** @var Application|MockObject $app */
|
2018-01-16 21:26:59 +01:00
|
|
|
$app = $this->getMockBuilder(Application::class)
|
2019-11-06 12:29:58 +01:00
|
|
|
->onlyMethods(['instance'])
|
2018-01-16 21:26:59 +01:00
|
|
|
->getMock();
|
2019-04-24 10:45:00 +02:00
|
|
|
/** @var SchemaBuilder|MockObject $builder */
|
2018-01-16 21:26:59 +01:00
|
|
|
$builder = $this->getMockBuilder(SchemaBuilder::class)
|
|
|
|
->disableOriginalConstructor()
|
|
|
|
->getMock();
|
2019-04-24 10:45:00 +02:00
|
|
|
/** @var Migrate|MockObject $migration */
|
2018-01-16 21:26:59 +01:00
|
|
|
$migration = $this->getMockBuilder(Migrate::class)
|
|
|
|
->setConstructorArgs([$builder, $app])
|
2020-06-01 22:00:33 +02:00
|
|
|
->onlyMethods([
|
|
|
|
'initMigration',
|
|
|
|
'getMigrationFiles',
|
|
|
|
'getMigrated',
|
|
|
|
'migrate',
|
|
|
|
'setMigrated',
|
|
|
|
'lockTable',
|
|
|
|
'unlockTable',
|
|
|
|
])
|
2018-01-16 21:26:59 +01:00
|
|
|
->getMock();
|
|
|
|
|
2020-06-01 22:00:33 +02:00
|
|
|
$this->setExpects($migration, 'initMigration', null, null, $this->atLeastOnce());
|
2018-01-16 21:26:59 +01:00
|
|
|
$migration->expects($this->atLeastOnce())
|
|
|
|
->method('getMigrationFiles')
|
|
|
|
->willReturn([
|
|
|
|
'foo/1234_01_23_123456_init_foo.php',
|
|
|
|
'foo/9876_03_22_210000_random_hack.php',
|
|
|
|
'foo/4567_11_01_000000_do_stuff.php',
|
|
|
|
'foo/9999_99_99_999999_another_foo.php',
|
|
|
|
]);
|
2020-06-01 22:00:33 +02:00
|
|
|
$this->setExpects($migration, 'getMigrated', null, new Collection([
|
|
|
|
['id' => 1, 'migration' => '1234_01_23_123456_init_foo'],
|
|
|
|
['id' => 2, 'migration' => '4567_11_01_000000_do_stuff'],
|
|
|
|
]), $this->atLeastOnce());
|
2018-01-16 21:26:59 +01:00
|
|
|
$migration->expects($this->atLeastOnce())
|
|
|
|
->method('migrate')
|
|
|
|
->withConsecutive(
|
2023-01-24 19:23:57 +01:00
|
|
|
['foo/9876_03_22_210000_random_hack.php', '9876_03_22_210000_random_hack', Direction::UP],
|
|
|
|
['foo/9999_99_99_999999_another_foo.php', '9999_99_99_999999_another_foo', Direction::UP],
|
|
|
|
['foo/9876_03_22_210000_random_hack.php', '9876_03_22_210000_random_hack', Direction::UP],
|
|
|
|
['foo/9999_99_99_999999_another_foo.php', '9999_99_99_999999_another_foo', Direction::UP],
|
|
|
|
['foo/9876_03_22_210000_random_hack.php', '9876_03_22_210000_random_hack', Direction::UP],
|
|
|
|
['foo/4567_11_01_000000_do_stuff.php', '4567_11_01_000000_do_stuff', Direction::DOWN]
|
2018-01-16 21:26:59 +01:00
|
|
|
);
|
|
|
|
$migration->expects($this->atLeastOnce())
|
|
|
|
->method('setMigrated')
|
|
|
|
->withConsecutive(
|
2023-01-24 19:23:57 +01:00
|
|
|
['9876_03_22_210000_random_hack', Direction::UP],
|
|
|
|
['9999_99_99_999999_another_foo', Direction::UP],
|
|
|
|
['9876_03_22_210000_random_hack', Direction::UP],
|
|
|
|
['9999_99_99_999999_another_foo', Direction::UP],
|
|
|
|
['9876_03_22_210000_random_hack', Direction::UP],
|
|
|
|
['4567_11_01_000000_do_stuff', Direction::DOWN]
|
2018-01-16 21:26:59 +01:00
|
|
|
);
|
2020-06-01 22:00:33 +02:00
|
|
|
$this->setExpects($migration, 'lockTable', null, null, $this->atLeastOnce());
|
|
|
|
$this->setExpects($migration, 'unlockTable', null, null, $this->atLeastOnce());
|
2018-01-16 21:26:59 +01:00
|
|
|
|
2023-01-24 19:23:57 +01:00
|
|
|
$migration->run('foo', Direction::UP);
|
2019-04-24 12:58:13 +02:00
|
|
|
|
2018-01-16 21:26:59 +01:00
|
|
|
$messages = [];
|
2022-12-14 19:15:20 +01:00
|
|
|
$migration->setOutput(function ($text) use (&$messages): void {
|
2018-01-16 21:26:59 +01:00
|
|
|
$messages[] = $text;
|
|
|
|
});
|
|
|
|
|
2023-01-24 19:23:57 +01:00
|
|
|
$migration->run('foo', Direction::UP);
|
2018-01-16 21:26:59 +01:00
|
|
|
|
|
|
|
$this->assertCount(4, $messages);
|
|
|
|
foreach (
|
|
|
|
[
|
|
|
|
'init_foo' => 'skipping',
|
|
|
|
'do_stuff' => 'skipping',
|
|
|
|
'random_hack' => 'migrating',
|
|
|
|
'another_foo' => 'migrating',
|
|
|
|
] as $value => $type
|
|
|
|
) {
|
|
|
|
$contains = false;
|
|
|
|
foreach ($messages as $message) {
|
2019-04-24 13:48:49 +02:00
|
|
|
if (!Str::contains(mb_strtolower($message), $type) || !Str::contains(mb_strtolower($message), $value)) {
|
2018-01-16 21:26:59 +01:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
$contains = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->assertTrue($contains, sprintf('Missing message "%s: %s"', $type, $value));
|
|
|
|
}
|
|
|
|
|
|
|
|
$messages = [];
|
2023-01-24 19:23:57 +01:00
|
|
|
$migration->run('foo', Direction::UP, true);
|
2018-01-16 21:26:59 +01:00
|
|
|
$this->assertCount(3, $messages);
|
|
|
|
|
2023-01-24 19:23:57 +01:00
|
|
|
$migration->run('foo', Direction::DOWN, true);
|
2018-01-16 21:26:59 +01:00
|
|
|
}
|
|
|
|
|
2020-06-01 22:00:33 +02:00
|
|
|
/**
|
|
|
|
* @covers \Engelsystem\Database\Migration\Migrate::run
|
|
|
|
*/
|
2022-12-14 19:15:20 +01:00
|
|
|
public function testRunExceptionUnlockTable(): void
|
2020-06-01 22:00:33 +02:00
|
|
|
{
|
|
|
|
/** @var Application|MockObject $app */
|
|
|
|
$app = $this->getMockBuilder(Application::class)
|
|
|
|
->onlyMethods(['instance'])
|
|
|
|
->getMock();
|
|
|
|
/** @var SchemaBuilder|MockObject $builder */
|
|
|
|
$builder = $this->getMockBuilder(SchemaBuilder::class)
|
|
|
|
->disableOriginalConstructor()
|
|
|
|
->getMock();
|
|
|
|
/** @var Migrate|MockObject $migration */
|
|
|
|
$migration = $this->getMockBuilder(Migrate::class)
|
|
|
|
->setConstructorArgs([$builder, $app])
|
|
|
|
->onlyMethods([
|
|
|
|
'initMigration',
|
|
|
|
'lockTable',
|
|
|
|
'getMigrations',
|
|
|
|
'getMigrated',
|
|
|
|
'migrate',
|
|
|
|
'unlockTable',
|
|
|
|
])
|
|
|
|
->getMock();
|
|
|
|
|
|
|
|
$this->setExpects($migration, 'initMigration');
|
|
|
|
$this->setExpects($migration, 'lockTable');
|
|
|
|
$this->setExpects($migration, 'unlockTable');
|
|
|
|
$this->setExpects($migration, 'getMigrations', null, collect([
|
2023-02-05 18:03:00 +01:00
|
|
|
['migration' => '1234_01_23_123456_init_foo', 'path' => '/foo'],
|
2020-06-01 22:00:33 +02:00
|
|
|
]));
|
2024-03-25 00:03:39 +01:00
|
|
|
$this->setExpects($migration, 'getMigrated', null, collect());
|
2020-06-01 22:00:33 +02:00
|
|
|
$migration->expects($this->once())
|
|
|
|
->method('migrate')
|
2022-12-14 19:15:20 +01:00
|
|
|
->willReturnCallback(function (): void {
|
2020-06-01 22:00:33 +02:00
|
|
|
throw new Exception();
|
|
|
|
});
|
|
|
|
|
|
|
|
$this->expectException(Exception::class);
|
|
|
|
$migration->run('');
|
|
|
|
}
|
|
|
|
|
2018-01-16 21:26:59 +01:00
|
|
|
/**
|
|
|
|
* @covers \Engelsystem\Database\Migration\Migrate::getMigrated
|
|
|
|
* @covers \Engelsystem\Database\Migration\Migrate::getMigrationFiles
|
|
|
|
* @covers \Engelsystem\Database\Migration\Migrate::getTableQuery
|
2019-04-24 11:01:37 +02:00
|
|
|
* @covers \Engelsystem\Database\Migration\Migrate::initMigration
|
|
|
|
* @covers \Engelsystem\Database\Migration\Migrate::migrate
|
|
|
|
* @covers \Engelsystem\Database\Migration\Migrate::setMigrated
|
2020-06-01 22:00:33 +02:00
|
|
|
* @covers \Engelsystem\Database\Migration\Migrate::lockTable
|
|
|
|
* @covers \Engelsystem\Database\Migration\Migrate::unlockTable
|
2018-01-16 21:26:59 +01:00
|
|
|
*/
|
2022-12-14 19:15:20 +01:00
|
|
|
public function testRunIntegration(): void
|
2018-01-16 21:26:59 +01:00
|
|
|
{
|
|
|
|
$app = new Application();
|
|
|
|
$dbManager = new CapsuleManager($app);
|
|
|
|
$dbManager->addConnection(['driver' => 'sqlite', 'database' => ':memory:']);
|
|
|
|
$dbManager->bootEloquent();
|
|
|
|
$db = $dbManager->getConnection();
|
|
|
|
$db->useDefaultSchemaGrammar();
|
2018-09-16 00:58:25 +02:00
|
|
|
$schema = $db->getSchemaBuilder();
|
2018-01-16 21:26:59 +01:00
|
|
|
|
2018-09-16 00:58:25 +02:00
|
|
|
$app->instance('schema', $schema);
|
|
|
|
$app->bind(SchemaBuilder::class, 'schema');
|
2018-01-16 21:26:59 +01:00
|
|
|
|
2018-09-16 00:58:25 +02:00
|
|
|
$migration = new Migrate($schema, $app);
|
2018-01-16 21:26:59 +01:00
|
|
|
|
|
|
|
$messages = [];
|
2022-12-14 19:15:20 +01:00
|
|
|
$migration->setOutput(function ($msg) use (&$messages): void {
|
2018-01-16 21:26:59 +01:00
|
|
|
$messages[] = $msg;
|
|
|
|
});
|
|
|
|
|
2023-01-24 19:23:57 +01:00
|
|
|
$migration->run(__DIR__ . '/Stub', Direction::UP);
|
2018-01-16 21:26:59 +01:00
|
|
|
|
2018-09-16 00:58:25 +02:00
|
|
|
$this->assertTrue($schema->hasTable('migrations'));
|
2018-01-16 21:26:59 +01:00
|
|
|
|
|
|
|
$migrations = $db->table('migrations')->get();
|
|
|
|
$this->assertCount(3, $migrations);
|
2020-06-01 22:00:33 +02:00
|
|
|
$this->assertFalse($migrations->contains('migration', 'lock'));
|
2018-01-16 21:26:59 +01:00
|
|
|
|
|
|
|
$this->assertTrue($migrations->contains('migration', '2001_04_11_123456_create_lorem_ipsum_table'));
|
|
|
|
$this->assertTrue($migrations->contains('migration', '2017_12_24_053300_another_stuff'));
|
|
|
|
$this->assertTrue($migrations->contains('migration', '2022_12_22_221222_add_some_feature'));
|
|
|
|
|
2018-09-16 00:58:25 +02:00
|
|
|
$this->assertTrue($schema->hasTable('lorem_ipsum'));
|
2018-01-16 21:26:59 +01:00
|
|
|
|
2023-01-24 19:23:57 +01:00
|
|
|
$migration->run(__DIR__ . '/Stub', Direction::DOWN, true);
|
2018-01-16 21:26:59 +01:00
|
|
|
|
|
|
|
$migrations = $db->table('migrations')->get();
|
|
|
|
$this->assertCount(2, $migrations);
|
|
|
|
|
2023-01-24 19:23:57 +01:00
|
|
|
$migration->run(__DIR__ . '/Stub', Direction::DOWN);
|
2018-01-16 21:26:59 +01:00
|
|
|
|
|
|
|
$migrations = $db->table('migrations')->get();
|
|
|
|
$this->assertCount(0, $migrations);
|
|
|
|
|
2018-09-16 00:58:25 +02:00
|
|
|
$this->assertFalse($schema->hasTable('lorem_ipsum'));
|
2020-06-01 22:00:33 +02:00
|
|
|
|
|
|
|
$db->table('migrations')->insert(['migration' => 'lock']);
|
|
|
|
$this->expectException(Exception::class);
|
2023-01-24 19:23:57 +01:00
|
|
|
$migration->run(__DIR__ . '/Stub', Direction::UP);
|
2018-01-16 21:26:59 +01:00
|
|
|
}
|
|
|
|
}
|