- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
165 lines
5.7 KiB
PHP
165 lines
5.7 KiB
PHP
<?php
|
|
|
|
require_once __DIR__ . '/../../vendor/autoload.php';
|
|
|
|
use App\Framework\View\TemplateProcessor;
|
|
use App\Framework\View\RenderContext;
|
|
use App\Framework\View\ProcessingMode;
|
|
use App\Framework\Meta\MetaData;
|
|
use App\Framework\View\Dom\Transformer\XComponentTransformer;
|
|
use App\Framework\View\Processors\PlaceholderReplacer;
|
|
use App\Framework\View\Processors\ForStringProcessor;
|
|
use App\Framework\DI\DefaultContainer;
|
|
use App\Framework\LiveComponents\Contracts\ComponentRegistryInterface;
|
|
use App\Framework\LiveComponents\Contracts\LiveComponentContract;
|
|
use App\Framework\LiveComponents\Performance\ComponentMetadataCacheInterface;
|
|
use App\Framework\LiveComponents\Performance\CompiledComponentMetadata;
|
|
use App\Framework\LiveComponents\Performance\ComponentPropertyMetadata;
|
|
use App\Framework\LiveComponents\ValueObjects\ComponentData;
|
|
use App\Framework\LiveComponents\ValueObjects\ComponentId;
|
|
use App\Framework\LiveComponents\ValueObjects\ComponentRenderData;
|
|
use App\Framework\View\Contracts\HtmlComponentRegistryInterface;
|
|
|
|
echo "=== TemplateProcessor AST Migration Test ===\n\n";
|
|
|
|
// Mock LiveComponent
|
|
$mockComponent = Mockery::mock(LiveComponentContract::class);
|
|
$mockComponent->shouldReceive('getId')
|
|
->andReturn(ComponentId::create('counter', 'test'));
|
|
$mockComponent->shouldReceive('getData')
|
|
->andReturn(ComponentData::fromArray(['value' => 10]));
|
|
$mockComponent->shouldReceive('getRenderData')
|
|
->andReturn(new ComponentRenderData('counter-template', ['value' => 10]));
|
|
|
|
// Mock LiveComponent Registry
|
|
$liveComponentRegistry = Mockery::mock(ComponentRegistryInterface::class);
|
|
$liveComponentRegistry->shouldReceive('isRegistered')
|
|
->with('counter')
|
|
->andReturn(true);
|
|
$liveComponentRegistry->shouldReceive('getClassName')
|
|
->with('counter')
|
|
->andReturn('TestCounterComponent');
|
|
$liveComponentRegistry->shouldReceive('resolve')
|
|
->andReturn($mockComponent);
|
|
$liveComponentRegistry->shouldReceive('renderWithWrapper')
|
|
->with($mockComponent)
|
|
->andReturn('<div data-component-id="counter:test" class="counter">Counter: 10</div>');
|
|
$liveComponentRegistry->shouldReceive('getAllComponentNames')
|
|
->andReturn(['counter']);
|
|
|
|
// Mock HTML Component Registry
|
|
$htmlComponentRegistry = Mockery::mock(HtmlComponentRegistryInterface::class);
|
|
$htmlComponentRegistry->shouldReceive('has')
|
|
->andReturn(false);
|
|
$htmlComponentRegistry->shouldReceive('getAllComponentNames')
|
|
->andReturn([]);
|
|
|
|
// Mock Metadata Cache
|
|
$mockMetadata = new CompiledComponentMetadata(
|
|
className: 'TestCounterComponent',
|
|
componentName: 'counter',
|
|
properties: [
|
|
'value' => new ComponentPropertyMetadata(
|
|
name: 'value',
|
|
type: 'int',
|
|
isPublic: true,
|
|
isReadonly: false
|
|
)
|
|
],
|
|
actions: [],
|
|
constructorParams: []
|
|
);
|
|
|
|
$metadataCache = Mockery::mock(ComponentMetadataCacheInterface::class);
|
|
$metadataCache->shouldReceive('get')
|
|
->with('TestCounterComponent')
|
|
->andReturn($mockMetadata);
|
|
|
|
// Create Container and register dependencies
|
|
$container = new DefaultContainer();
|
|
$container->singleton(ComponentRegistryInterface::class, $liveComponentRegistry);
|
|
$container->singleton(HtmlComponentRegistryInterface::class, $htmlComponentRegistry);
|
|
$container->singleton(ComponentMetadataCacheInterface::class, $metadataCache);
|
|
|
|
// Register processors (with dependencies)
|
|
$componentRegistry = Mockery::mock(\App\Framework\LiveComponents\ComponentRegistry::class);
|
|
$placeholderReplacer = new PlaceholderReplacer($container, $componentRegistry);
|
|
$forStringProcessor = new ForStringProcessor();
|
|
$container->singleton(PlaceholderReplacer::class, $placeholderReplacer);
|
|
$container->singleton(ForStringProcessor::class, $forStringProcessor);
|
|
|
|
// XComponentTransformer wird automatisch vom Container resolved
|
|
// (benötigt HtmlParser, der wird automatisch erstellt)
|
|
|
|
// Create TemplateProcessor with AST transformers
|
|
$templateProcessor = new TemplateProcessor(
|
|
astTransformers: [XComponentTransformer::class],
|
|
stringProcessors: [
|
|
ForStringProcessor::class,
|
|
PlaceholderReplacer::class,
|
|
],
|
|
container: $container
|
|
);
|
|
|
|
// Test HTML with placeholders and x-component
|
|
$html = <<<HTML
|
|
<html>
|
|
<head>
|
|
<title>{title}</title>
|
|
</head>
|
|
<body>
|
|
<h1>{greeting}</h1>
|
|
<p>Welcome {username}!</p>
|
|
|
|
<x-counter id="test" value="10" />
|
|
|
|
<footer>© 2024</footer>
|
|
</body>
|
|
</html>
|
|
HTML;
|
|
|
|
echo "Input HTML:\n$html\n\n";
|
|
|
|
// Create RenderContext with data
|
|
$context = new RenderContext(
|
|
template: 'test-page',
|
|
metaData: new MetaData('Test Page'),
|
|
data: [
|
|
'title' => 'Test Page Title',
|
|
'greeting' => 'Hello World',
|
|
'username' => 'John Doe'
|
|
],
|
|
processingMode: ProcessingMode::FULL
|
|
);
|
|
|
|
// Render through TemplateProcessor
|
|
try {
|
|
$output = $templateProcessor->render($context, $html);
|
|
|
|
echo "Output HTML:\n$output\n\n";
|
|
|
|
// Verify results
|
|
$checks = [
|
|
'title replacement' => str_contains($output, '<title>Test Page Title</title>'),
|
|
'greeting replacement' => str_contains($output, '<h1>Hello World</h1>'),
|
|
'username replacement' => str_contains($output, 'Welcome John Doe!'),
|
|
'component rendering' => str_contains($output, 'data-component-id="counter:test"'),
|
|
'component content' => str_contains($output, 'Counter: 10'),
|
|
'footer preserved' => str_contains($output, '© 2024')
|
|
];
|
|
|
|
echo "Verification:\n";
|
|
foreach ($checks as $check => $passed) {
|
|
echo ($passed ? '✓' : '✗') . " $check\n";
|
|
}
|
|
|
|
$allPassed = array_reduce($checks, fn($carry, $item) => $carry && $item, true);
|
|
|
|
echo "\n" . ($allPassed ? '✅ ALL TESTS PASSED!' : '❌ SOME TESTS FAILED') . "\n";
|
|
|
|
} catch (\Throwable $e) {
|
|
echo "❌ ERROR: {$e->getMessage()}\n";
|
|
echo "Stack trace:\n{$e->getTraceAsString()}\n";
|
|
exit(1);
|
|
}
|