container = new DefaultContainer();
// Setup dependencies
$this->container->singleton(
PlaceholderReplacer::class,
new PlaceholderReplacer($this->container)
);
$this->componentService = new DomComponentService();
$this->componentRenderer = new ComponentRenderer(
__DIR__ . '/../../../src/Framework/View/templates/components'
);
$this->processor = new ComponentProcessor(
$this->componentService,
$this->componentRenderer,
$this->container
);
$this->parser = new DomTemplateParser();
});
describe('ComponentProcessor', function () {
it('processes simple component without attributes', function () {
$html = <<
HTML;
$dom = $this->parser->parseToWrapper($html);
$context = new RenderContext(
template: 'test',
data: [
'type' => 'info',
'message' => 'Test message',
]
);
$result = $this->processor->process($dom, $context);
$output = $result->document->saveHTML();
expect($output)->toContain('alert alert-info');
expect($output)->toContain('Test message');
});
it('processes component with attributes', function () {
$html = <<
HTML;
$dom = $this->parser->parseToWrapper($html);
$context = new RenderContext(template: 'test', data: []);
$result = $this->processor->process($dom, $context);
$output = $result->document->saveHTML();
expect($output)->toContain('alert alert-warning');
expect($output)->toContain('Custom message');
});
it('processes nested components', function () {
$html = <<
HTML;
$dom = $this->parser->parseToWrapper($html);
$context = new RenderContext(template: 'test', data: []);
$result = $this->processor->process($dom, $context);
$output = $result->document->saveHTML();
expect($output)->toContain('card');
expect($output)->toContain('Test Card');
expect($output)->toContain('Card content');
});
it('handles components with placeholder variables', function () {
$html = <<
HTML;
$dom = $this->parser->parseToWrapper($html);
$context = new RenderContext(
template: 'test',
data: [
'alertType' => 'success',
'alertMessage' => 'Operation successful',
]
);
$result = $this->processor->process($dom, $context);
$output = $result->document->saveHTML();
expect($output)->toContain('alert alert-success');
expect($output)->toContain('Operation successful');
});
it('gracefully handles missing component files', function () {
$html = <<
HTML;
$dom = $this->parser->parseToWrapper($html);
$context = new RenderContext(template: 'test', data: []);
// Should not throw exception
$result = $this->processor->process($dom, $context);
expect($result)->toBeInstanceOf(App\Framework\View\DomWrapper::class);
});
it('processes multiple components in sequence', function () {
$html = <<
HTML;
$dom = $this->parser->parseToWrapper($html);
$context = new RenderContext(template: 'test', data: []);
$result = $this->processor->process($dom, $context);
$output = $result->document->saveHTML();
expect($output)->toContain('First alert');
expect($output)->toContain('Second alert');
expect($output)->toContain('Third alert');
expect($output)->toContain('alert-info');
expect($output)->toContain('alert-warning');
expect($output)->toContain('alert-danger');
});
it('skips components without name attribute', function () {
$html = <<
HTML;
$dom = $this->parser->parseToWrapper($html);
$context = new RenderContext(template: 'test', data: []);
$result = $this->processor->process($dom, $context);
$output = $result->document->saveHTML();
// Should only process the valid component
expect($output)->toContain('Valid component');
});
});