Files
michaelschiemer/tests/Framework/Database/Migration/MigrationLoaderTest.php
Michael Schiemer c8b47e647d feat(Docker): Upgrade to PHP 8.5.0RC3 with native ext-uri support
BREAKING CHANGE: Requires PHP 8.5.0RC3

Changes:
- Update Docker base image from php:8.4-fpm to php:8.5.0RC3-fpm
- Enable ext-uri for native WHATWG URL parsing support
- Update composer.json PHP requirement from ^8.4 to ^8.5
- Add ext-uri as required extension in composer.json
- Move URL classes from Url.php85/ to Url/ directory (now compatible)
- Remove temporary PHP 8.4 compatibility workarounds

Benefits:
- Native URL parsing with Uri\WhatWg\Url class
- Better performance for URL operations
- Future-proof with latest PHP features
- Eliminates PHP version compatibility issues
2025-10-27 09:31:28 +01:00

175 lines
6.0 KiB
PHP

<?php
declare(strict_types=1);
namespace Tests\Framework\Database\Migration;
use App\Framework\Core\ValueObjects\ClassName;
use App\Framework\Database\Migration\Migration;
use App\Framework\Database\Migration\MigrationCollection;
use App\Framework\Database\Migration\MigrationLoader;
use App\Framework\Database\Migration\MigrationVersion;
use App\Framework\DI\Container;
use App\Framework\Discovery\Results\AttributeRegistry;
use App\Framework\Discovery\Results\DiscoveryRegistry;
use App\Framework\Discovery\Results\InterfaceRegistry;
use App\Framework\Discovery\Results\TemplateRegistry;
use App\Framework\Discovery\ValueObjects\InterfaceMapping;
use App\Framework\Filesystem\ValueObjects\FilePath;
use PHPUnit\Framework\Attributes\Test;
use PHPUnit\Framework\TestCase;
final class MigrationLoaderTest extends TestCase
{
private Container $container;
protected function setUp(): void
{
$this->container = $this->createMock(Container::class);
}
#[Test]
public function loadMigrations_returns_empty_collection_when_no_migrations_found(): void
{
// Setup interface registry with no migrations
$interfaceRegistry = new InterfaceRegistry();
$discoveryRegistry = new DiscoveryRegistry(
new AttributeRegistry(),
$interfaceRegistry,
new TemplateRegistry()
);
$loader = new MigrationLoader($discoveryRegistry, $this->container);
$result = $loader->loadMigrations();
$this->assertInstanceOf(MigrationCollection::class, $result);
$this->assertTrue($result->isEmpty());
$this->assertSame(0, $result->count());
}
#[Test]
public function loadMigrations_returns_sorted_collection_of_migrations(): void
{
// Create mock migration instances (in unsorted order)
$migration1 = $this->createMockMigration('2024_01_03_120000', 'Third migration');
$migration2 = $this->createMockMigration('2024_01_01_120000', 'First migration');
$migration3 = $this->createMockMigration('2024_01_02_120000', 'Second migration');
// Create interface mappings
$mapping1 = new InterfaceMapping(
ClassName::create(Migration::class),
ClassName::create('App\\Migration1'),
FilePath::create('/path/to/migration1.php')
);
$mapping2 = new InterfaceMapping(
ClassName::create(Migration::class),
ClassName::create('App\\Migration2'),
FilePath::create('/path/to/migration2.php')
);
$mapping3 = new InterfaceMapping(
ClassName::create(Migration::class),
ClassName::create('App\\Migration3'),
FilePath::create('/path/to/migration3.php')
);
// Setup interface registry
$interfaceRegistry = new InterfaceRegistry();
$interfaceRegistry->add($mapping1);
$interfaceRegistry->add($mapping2);
$interfaceRegistry->add($mapping3);
$discoveryRegistry = new DiscoveryRegistry(
new AttributeRegistry(),
$interfaceRegistry,
new TemplateRegistry()
);
$loader = new MigrationLoader($discoveryRegistry, $this->container);
// Setup container to return migration instances
$this->container->method('get')
->willReturnMap([
['App\\Migration1', $migration1],
['App\\Migration2', $migration2],
['App\\Migration3', $migration3],
]);
$result = $loader->loadMigrations();
$this->assertInstanceOf(MigrationCollection::class, $result);
$this->assertSame(3, $result->count());
// Verify migrations are sorted by version
$migrations = $result->toArray();
$this->assertSame($migration2, $migrations[0]); // 2024_01_01_120000
$this->assertSame($migration3, $migrations[1]); // 2024_01_02_120000
$this->assertSame($migration1, $migrations[2]); // 2024_01_03_120000
}
#[Test]
public function loadMigrations_uses_discovery_registry_to_find_migration_implementations(): void
{
$interfaceRegistry = new InterfaceRegistry();
$discoveryRegistry = new DiscoveryRegistry(
new AttributeRegistry(),
$interfaceRegistry,
new TemplateRegistry()
);
$loader = new MigrationLoader($discoveryRegistry, $this->container);
$result = $loader->loadMigrations();
// Verify that the discovery registry was used by checking we get an empty collection
$this->assertInstanceOf(MigrationCollection::class, $result);
$this->assertTrue($result->isEmpty());
}
#[Test]
public function loadMigrations_uses_container_to_instantiate_migrations(): void
{
$migration = $this->createMockMigration('2024_01_01_120000', 'Test migration');
$mapping = new InterfaceMapping(
ClassName::create(Migration::class),
ClassName::create('App\\TestMigration'),
FilePath::create('/path/to/test_migration.php')
);
$interfaceRegistry = new InterfaceRegistry();
$interfaceRegistry->add($mapping);
$discoveryRegistry = new DiscoveryRegistry(
new AttributeRegistry(),
$interfaceRegistry,
new TemplateRegistry()
);
$loader = new MigrationLoader($discoveryRegistry, $this->container);
$this->container->expects($this->once())
->method('get')
->with('App\\TestMigration')
->willReturn($migration);
$result = $loader->loadMigrations();
$this->assertSame(1, $result->count());
$this->assertSame($migration, $result->toArray()[0]);
}
private function createMockMigration(string $version, string $description): Migration
{
$migration = $this->createMock(Migration::class);
$migration->method('getVersion')
->willReturn(MigrationVersion::fromTimestamp($version));
$migration->method('getDescription')
->willReturn($description);
return $migration;
}
}