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 RouteRegistry(), 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 RouteRegistry(), 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 RouteRegistry(), 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 RouteRegistry(), 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; } }