forked from larastan/larastan
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: improve database migration scanning (larastan#670)
- Loading branch information
Showing
10 changed files
with
318 additions
and
58 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace NunoMaduro\Larastan\Properties; | ||
|
||
use Iterator; | ||
use PHPStan\Parser\CachedParser; | ||
use RecursiveDirectoryIterator; | ||
use RecursiveIteratorIterator; | ||
use RegexIterator; | ||
use SplFileInfo; | ||
|
||
class MigrationHelper | ||
{ | ||
/** @var CachedParser */ | ||
private $parser; | ||
|
||
/** @var ?string */ | ||
private $databaseMigrationPath; | ||
|
||
public function __construct(CachedParser $parser, ?string $databaseMigrationPath) | ||
{ | ||
$this->parser = $parser; | ||
$this->databaseMigrationPath = $databaseMigrationPath; | ||
} | ||
|
||
/** | ||
* @return array<string, SchemaTable> | ||
*/ | ||
public function initializeTables(): array | ||
{ | ||
if ($this->databaseMigrationPath === null) { | ||
$this->databaseMigrationPath = database_path().'/migrations'; | ||
} | ||
|
||
if (! is_dir($this->databaseMigrationPath)) { | ||
return []; | ||
} | ||
|
||
$schemaAggregator = new SchemaAggregator(); | ||
$files = $this->getMigrationFiles($this->databaseMigrationPath); | ||
$filesArray = iterator_to_array($files); | ||
ksort($filesArray); | ||
|
||
$this->requireFiles($filesArray); | ||
|
||
foreach ($filesArray as $file) { | ||
$schemaAggregator->addStatements($this->parser->parseFile($file->getPathname())); | ||
} | ||
|
||
return $schemaAggregator->tables; | ||
} | ||
|
||
/** | ||
* @param string $path | ||
* | ||
* @return Iterator<SplFileInfo> | ||
*/ | ||
private function getMigrationFiles(string $path): Iterator | ||
{ | ||
return new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path)), '/\.php$/i'); | ||
} | ||
|
||
/** | ||
* @param SplFileInfo[] $files | ||
*/ | ||
private function requireFiles(array $files): void | ||
{ | ||
foreach ($files as $file) { | ||
require_once $file; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Tests\Unit; | ||
|
||
use NunoMaduro\Larastan\Properties\MigrationHelper; | ||
use NunoMaduro\Larastan\Properties\SchemaTable; | ||
use PHPStan\Parser\CachedParser; | ||
use PHPStan\Testing\TestCase; | ||
|
||
class MigrationHelperTest extends TestCase | ||
{ | ||
/** @var CachedParser */ | ||
private $cachedParser; | ||
|
||
public function setUp(): void | ||
{ | ||
$this->cachedParser = self::getContainer()->getByType(CachedParser::class); | ||
} | ||
|
||
/** @test */ | ||
public function it_will_return_empty_array_if_migrations_path_is_not_a_directory() | ||
{ | ||
$migrationHelper = new MigrationHelper($this->cachedParser, 'foobar'); | ||
|
||
self::assertSame([], $migrationHelper->initializeTables()); | ||
} | ||
|
||
/** @test */ | ||
public function it_can_read_basic_migrations_and_create_table_structure() | ||
{ | ||
$migrationHelper = new MigrationHelper($this->cachedParser, __DIR__.'/data/basic_migration'); | ||
|
||
$tables = $migrationHelper->initializeTables(); | ||
|
||
$this->assertUsersTableSchema($tables); | ||
} | ||
|
||
/** @test */ | ||
public function it_can_read_schema_definitions_from_any_method_in_class() | ||
{ | ||
$migrationHelper = new MigrationHelper($this->cachedParser, __DIR__.'/data/migrations_with_different_methods'); | ||
|
||
$tables = $migrationHelper->initializeTables(); | ||
|
||
$this->assertUsersTableSchema($tables); | ||
} | ||
|
||
/** @test */ | ||
public function it_can_read_schema_definitions_with_multiple_create_and_drop_methods_for_one_table() | ||
{ | ||
$migrationHelper = new MigrationHelper($this->cachedParser, __DIR__.'/data/complex_migrations'); | ||
|
||
$tables = $migrationHelper->initializeTables(); | ||
|
||
self::assertCount(1, $tables); | ||
self::assertArrayHasKey('users', $tables); | ||
self::assertCount(6, $tables['users']->columns); | ||
self::assertSame(['id', 'email', 'birthday', 'created_at', 'updated_at', 'active'], array_keys($tables['users']->columns)); | ||
self::assertSame('int', $tables['users']->columns['id']->readableType); | ||
self::assertSame('string', $tables['users']->columns['email']->readableType); | ||
self::assertSame('string', $tables['users']->columns['birthday']->readableType); | ||
self::assertSame('string', $tables['users']->columns['created_at']->readableType); | ||
self::assertSame('string', $tables['users']->columns['updated_at']->readableType); | ||
self::assertSame('int', $tables['users']->columns['active']->readableType); | ||
} | ||
|
||
/** | ||
* @param array<string, SchemaTable> $tables | ||
*/ | ||
private function assertUsersTableSchema(array $tables): void | ||
{ | ||
self::assertCount(1, $tables); | ||
self::assertArrayHasKey('users', $tables); | ||
self::assertCount(5, $tables['users']->columns); | ||
self::assertSame(['id', 'name', 'email', 'created_at', 'updated_at'], array_keys($tables['users']->columns)); | ||
self::assertSame('int', $tables['users']->columns['id']->readableType); | ||
self::assertSame('string', $tables['users']->columns['name']->readableType); | ||
self::assertSame('string', $tables['users']->columns['email']->readableType); | ||
self::assertSame('string', $tables['users']->columns['created_at']->readableType); | ||
self::assertSame('string', $tables['users']->columns['updated_at']->readableType); | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
tests/Unit/data/basic_migration/2020_01_30_000000_create_users_table.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Tests\Unit\BasicMigrations; | ||
|
||
use Illuminate\Database\Migrations\Migration; | ||
use Illuminate\Database\Schema\Blueprint; | ||
use Illuminate\Support\Facades\Schema; | ||
|
||
class CreateUsersTable extends Migration | ||
{ | ||
/** | ||
* Run the migrations. | ||
*/ | ||
public function up(): void | ||
{ | ||
Schema::create('users', static function (Blueprint $table) { | ||
$table->bigIncrements('id'); | ||
$table->string('name')->nullable(); | ||
$table->string('email')->unique(); | ||
$table->timestamps(); | ||
}); | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
tests/Unit/data/complex_migrations/2020_01_30_000000_create_users_table.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Tests\Unit\ComplexMigrations; | ||
|
||
use Illuminate\Database\Migrations\Migration; | ||
use Illuminate\Database\Schema\Blueprint; | ||
use Illuminate\Support\Facades\Schema; | ||
|
||
class CreateUsersTable extends Migration | ||
{ | ||
/** | ||
* Run the migrations. | ||
*/ | ||
public function up(): void | ||
{ | ||
Schema::create('users', static function (Blueprint $table) { | ||
$table->bigIncrements('id'); | ||
$table->string('name')->nullable(); | ||
$table->string('email')->unique(); | ||
$table->timestamps(); | ||
}); | ||
} | ||
} |
Oops, something went wrong.