Files
roi-theme/scripts/validate-phase-1.php
FrankZamora de5fff4f5c Fase 1: Estructura Base y DI Container - Clean Architecture
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>
2025-11-17 13:48:24 -06:00

294 lines
8.8 KiB
PHP

<?php
/**
* Validation Script for Phase 1
*
* Validates that all Phase 1 tasks have been completed successfully.
*
* @package ROITheme
*/
declare(strict_types=1);
class Phase1Validator
{
private int $totalChecks = 0;
private int $passedChecks = 0;
private array $errors = [];
public function run(): void
{
echo "\n";
echo "========================================\n";
echo " VALIDACIÓN DE FASE 1 - ROI THEME \n";
echo "========================================\n\n";
$this->checkFolderStructure();
$this->checkComposerAutoloader();
$this->checkDIContainer();
$this->checkInterfaces();
$this->checkBootstrap();
$this->checkTests();
$this->printResults();
}
private function check(string $description, callable $test): void
{
$this->totalChecks++;
try {
$result = $test();
if ($result) {
echo "{$description}\n";
$this->passedChecks++;
} else {
echo "{$description}\n";
$this->errors[] = $description;
}
} catch (Exception $e) {
echo "{$description} (Error: {$e->getMessage()})\n";
$this->errors[] = $description . ': ' . $e->getMessage();
}
}
private function checkFolderStructure(): void
{
echo "Validando estructura de carpetas...\n";
$requiredDirs = [
'src/Domain/Component',
'src/Domain/Component/ValueObjects',
'src/Domain/Component/Exceptions',
'src/Domain/Shared/ValueObjects',
'src/Application/UseCases/SaveComponent',
'src/Application/UseCases/GetComponent',
'src/Application/UseCases/DeleteComponent',
'src/Application/UseCases/SyncSchema',
'src/Application/DTO',
'src/Application/Contracts',
'src/Infrastructure/Persistence/WordPress/Repositories',
'src/Infrastructure/API/WordPress',
'src/Infrastructure/Services',
'src/Infrastructure/DI',
'src/Infrastructure/Facades',
'src/Infrastructure/Presentation/Public/Renderers',
'src/Infrastructure/Presentation/Admin/FormBuilders',
'src/Infrastructure/UI/Assets',
'src/Infrastructure/UI/Views',
'tests/Unit/Domain/Component',
'tests/Unit/Application/UseCases',
'tests/Unit/Infrastructure/Persistence',
'tests/Unit/Infrastructure/Services',
'tests/Integration',
'tests/E2E',
'schemas',
'templates/admin',
'templates/public',
];
foreach ($requiredDirs as $dir) {
$this->check(
"Carpeta {$dir} existe",
fn() => is_dir(__DIR__ . '/../' . $dir)
);
}
echo "\n";
}
private function checkComposerAutoloader(): void
{
echo "Validando Composer y autoloader...\n";
$this->check(
'composer.json existe',
fn() => file_exists(__DIR__ . '/../composer.json')
);
$this->check(
'vendor/autoload.php existe',
fn() => file_exists(__DIR__ . '/../vendor/autoload.php')
);
$this->check(
'PSR-4 autoloading configurado',
function () {
$composer = json_decode(file_get_contents(__DIR__ . '/../composer.json'), true);
return isset($composer['autoload']['psr-4']['ROITheme\\']);
}
);
echo "\n";
}
private function checkDIContainer(): void
{
echo "Validando DI Container...\n";
require_once __DIR__ . '/../vendor/autoload.php';
$this->check(
'DIContainer class existe',
fn() => class_exists('ROITheme\Infrastructure\DI\DIContainer')
);
$this->check(
'DIContainer es singleton',
function () {
$instance1 = \ROITheme\Infrastructure\DI\DIContainer::getInstance();
$instance2 = \ROITheme\Infrastructure\DI\DIContainer::getInstance();
return $instance1 === $instance2;
}
);
$this->check(
'DIContainer tiene método set()',
fn() => method_exists('ROITheme\Infrastructure\DI\DIContainer', 'set')
);
$this->check(
'DIContainer tiene método get()',
fn() => method_exists('ROITheme\Infrastructure\DI\DIContainer', 'get')
);
$this->check(
'DIContainer tiene método has()',
fn() => method_exists('ROITheme\Infrastructure\DI\DIContainer', 'has')
);
$this->check(
'DIContainer tiene métodos de servicio',
function () {
return method_exists('ROITheme\Infrastructure\DI\DIContainer', 'getComponentRepository')
&& method_exists('ROITheme\Infrastructure\DI\DIContainer', 'getValidationService')
&& method_exists('ROITheme\Infrastructure\DI\DIContainer', 'getCacheService');
}
);
echo "\n";
}
private function checkInterfaces(): void
{
echo "Validando interfaces...\n";
$this->check(
'ComponentRepositoryInterface existe',
fn() => interface_exists('ROITheme\Domain\Component\ComponentRepositoryInterface')
);
$this->check(
'ValidationServiceInterface existe',
fn() => interface_exists('ROITheme\Application\Contracts\ValidationServiceInterface')
);
$this->check(
'CacheServiceInterface existe',
fn() => interface_exists('ROITheme\Application\Contracts\CacheServiceInterface')
);
$this->check(
'Component entity existe',
fn() => class_exists('ROITheme\Domain\Component\Component')
);
echo "\n";
}
private function checkBootstrap(): void
{
echo "Validando bootstrap en functions.php...\n";
$functionsContent = file_get_contents(__DIR__ . '/../functions.php');
$this->check(
'functions.php existe',
fn() => file_exists(__DIR__ . '/../functions.php')
);
$this->check(
'functions.php carga Composer autoloader',
fn() => strpos($functionsContent, "require_once __DIR__ . '/vendor/autoload.php'") !== false
);
$this->check(
'functions.php importa DIContainer',
fn() => strpos($functionsContent, 'use ROITheme\Infrastructure\DI\DIContainer') !== false
);
$this->check(
'functions.php define roi_container()',
fn() => strpos($functionsContent, 'function roi_container()') !== false
);
echo "\n";
}
private function checkTests(): void
{
echo "Validando tests unitarios...\n";
$this->check(
'phpunit.xml configurado',
fn() => file_exists(__DIR__ . '/../phpunit.xml')
);
$this->check(
'DIContainerTest existe',
fn() => file_exists(__DIR__ . '/../tests/Unit/Infrastructure/DI/DIContainerTest.php')
);
// Run PHPUnit tests
$baseDir = dirname(__DIR__);
$phpunitPath = $baseDir . DIRECTORY_SEPARATOR . 'vendor' . DIRECTORY_SEPARATOR . 'bin' . DIRECTORY_SEPARATOR . 'phpunit';
// For Windows compatibility
if (PHP_OS_FAMILY === 'Windows') {
$command = "cd /d \"$baseDir\" && \"$phpunitPath\" --testsuite Unit 2>&1";
} else {
$command = "cd \"$baseDir\" && \"$phpunitPath\" --testsuite Unit 2>&1";
}
exec($command, $output, $returnCode);
$this->check(
'Tests unitarios pasan',
fn() => $returnCode === 0
);
echo "\n";
}
private function printResults(): void
{
echo "========================================\n";
echo " RESULTADOS DE VALIDACIÓN\n";
echo "========================================\n\n";
$percentage = $this->totalChecks > 0
? round(($this->passedChecks / $this->totalChecks) * 100, 2)
: 0;
echo "Checks pasados: {$this->passedChecks}/{$this->totalChecks} ({$percentage}%)\n\n";
if (count($this->errors) > 0) {
echo "ERRORES ENCONTRADOS:\n";
foreach ($this->errors as $error) {
echo " - {$error}\n";
}
echo "\n";
exit(1);
} else {
echo " ¡FASE 1 COMPLETADA EXITOSAMENTE!\n\n";
echo "Todas las validaciones pasaron correctamente.\n";
echo "La arquitectura base está lista para la Fase 2.\n\n";
exit(0);
}
}
}
// Run validation
$validator = new Phase1Validator();
$validator->run();