COMPLETADO: Fase 1 de la migración a Clean Architecture + POO ## Estructura de Carpetas - ✓ Estructura completa de 4 capas (Domain, Application, Infrastructure, Presentation) - ✓ Carpetas de Use Cases (SaveComponent, GetComponent, DeleteComponent, SyncSchema) - ✓ Estructura de tests (Unit, Integration, E2E) - ✓ Carpetas de schemas y templates ## Composer y Autoloading - ✓ PSR-4 autoloading configurado para ROITheme namespace - ✓ Autoloader optimizado regenerado ## DI Container - ✓ DIContainer implementado con patrón Singleton - ✓ Métodos set(), get(), has() para gestión de servicios - ✓ Getters específicos para ComponentRepository, ValidationService, CacheService - ✓ Placeholders que serán implementados en Fase 5 - ✓ Prevención de clonación y deserialización ## Interfaces - ✓ ComponentRepositoryInterface (Domain) - ✓ ValidationServiceInterface (Application) - ✓ CacheServiceInterface (Application) - ✓ Component entity placeholder (Domain) ## Bootstrap - ✓ functions.php actualizado con carga de Composer autoloader - ✓ Inicialización del DIContainer - ✓ Helper function roi_container() disponible globalmente ## Tests - ✓ 10 tests unitarios para DIContainer (100% cobertura) - ✓ Total: 13 tests unitarios, 28 assertions - ✓ Suite de tests pasando correctamente ## Validación - ✓ Script de validación automatizado (48/48 checks pasados) - ✓ 100% de validaciones exitosas La arquitectura base está lista para la Fase 2. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
176 lines
4.8 KiB
PHP
176 lines
4.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace ROITheme\Tests\Unit\Infrastructure\DI;
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
use ROITheme\Infrastructure\DI\DIContainer;
|
|
use RuntimeException;
|
|
use Exception;
|
|
|
|
/**
|
|
* DI Container Test
|
|
*
|
|
* Tests for the Dependency Injection Container.
|
|
*
|
|
* @package ROITheme\Tests\Unit\Infrastructure\DI
|
|
*/
|
|
class DIContainerTest extends TestCase
|
|
{
|
|
protected function setUp(): void
|
|
{
|
|
// Reset container before each test
|
|
DIContainer::reset();
|
|
}
|
|
|
|
protected function tearDown(): void
|
|
{
|
|
// Reset container after each test
|
|
DIContainer::reset();
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function it_should_return_singleton_instance(): void
|
|
{
|
|
$instance1 = DIContainer::getInstance();
|
|
$instance2 = DIContainer::getInstance();
|
|
|
|
$this->assertSame($instance1, $instance2, 'getInstance() should return the same instance');
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function it_should_prevent_cloning(): void
|
|
{
|
|
$this->expectError();
|
|
$this->expectErrorMessage('Call to private');
|
|
|
|
$container = DIContainer::getInstance();
|
|
$clone = clone $container; // This should trigger an error
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function it_should_prevent_unserialization(): void
|
|
{
|
|
$this->expectException(Exception::class);
|
|
$this->expectExceptionMessage('Cannot unserialize singleton');
|
|
|
|
$container = DIContainer::getInstance();
|
|
$serialized = serialize($container);
|
|
unserialize($serialized);
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function it_should_register_and_retrieve_service(): void
|
|
{
|
|
$container = DIContainer::getInstance();
|
|
$service = new \stdClass();
|
|
$service->name = 'Test Service';
|
|
|
|
$container->set('test_service', $service);
|
|
|
|
$this->assertTrue($container->has('test_service'), 'Container should have the registered service');
|
|
$this->assertSame($service, $container->get('test_service'), 'Should retrieve the same service instance');
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function it_should_return_null_for_non_existent_service(): void
|
|
{
|
|
$container = DIContainer::getInstance();
|
|
|
|
$this->assertFalse($container->has('non_existent'), 'Container should not have non-existent service');
|
|
$this->assertNull($container->get('non_existent'), 'Should return null for non-existent service');
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function it_should_throw_exception_for_unimplemented_component_repository(): void
|
|
{
|
|
$this->expectException(RuntimeException::class);
|
|
$this->expectExceptionMessage('ComponentRepository not implemented yet');
|
|
|
|
$container = DIContainer::getInstance();
|
|
$container->getComponentRepository();
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function it_should_throw_exception_for_unimplemented_validation_service(): void
|
|
{
|
|
$this->expectException(RuntimeException::class);
|
|
$this->expectExceptionMessage('ValidationService not implemented yet');
|
|
|
|
$container = DIContainer::getInstance();
|
|
$container->getValidationService();
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function it_should_throw_exception_for_unimplemented_cache_service(): void
|
|
{
|
|
$this->expectException(RuntimeException::class);
|
|
$this->expectExceptionMessage('CacheService not implemented yet');
|
|
|
|
$container = DIContainer::getInstance();
|
|
$container->getCacheService();
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function it_should_reset_singleton_instance(): void
|
|
{
|
|
$instance1 = DIContainer::getInstance();
|
|
$instance1->set('test', new \stdClass());
|
|
|
|
DIContainer::reset();
|
|
|
|
$instance2 = DIContainer::getInstance();
|
|
|
|
$this->assertNotSame($instance1, $instance2, 'Reset should create a new instance');
|
|
$this->assertFalse($instance2->has('test'), 'New instance should not have old services');
|
|
}
|
|
|
|
/**
|
|
* @test
|
|
*/
|
|
public function it_should_manage_multiple_services(): void
|
|
{
|
|
$container = DIContainer::getInstance();
|
|
|
|
$service1 = new \stdClass();
|
|
$service1->name = 'Service 1';
|
|
|
|
$service2 = new \stdClass();
|
|
$service2->name = 'Service 2';
|
|
|
|
$service3 = new \stdClass();
|
|
$service3->name = 'Service 3';
|
|
|
|
$container->set('service1', $service1);
|
|
$container->set('service2', $service2);
|
|
$container->set('service3', $service3);
|
|
|
|
$this->assertTrue($container->has('service1'));
|
|
$this->assertTrue($container->has('service2'));
|
|
$this->assertTrue($container->has('service3'));
|
|
|
|
$this->assertSame($service1, $container->get('service1'));
|
|
$this->assertSame($service2, $container->get('service2'));
|
|
$this->assertSame($service3, $container->get('service3'));
|
|
}
|
|
}
|