Scape/tests/EngineTest.php

124 lines
3.8 KiB
PHP
Raw Normal View History

<?php
declare(strict_types=1);
namespace Scape\Tests;
use PHPUnit\Framework\TestCase;
use Scape\Engine;
use Scape\Exceptions\TemplateNotFoundException;
use Scape\Exceptions\RecursionLimitException;
class EngineTest extends TestCase
{
private string $templatesDir;
protected function setUp(): void
{
$this->templatesDir = __DIR__ . '/fixtures';
}
public function testRenderSignature(): void
{
$engine = new Engine();
$this->assertTrue(method_exists($engine, 'render'));
}
public function testThrowsTemplateNotFoundExceptionInDebug(): void
{
$this->expectException(TemplateNotFoundException::class);
$engine = new Engine(['mode' => 'debug']);
$engine->render('missing.template');
}
public function testRendersPlaceholderInProduction(): void
{
$engine = new Engine(['mode' => 'production']);
$output = $engine->render('missing.template');
$this->assertEquals("<!-- Scape: Template 'missing.template' not found -->", $output);
}
public function testRenders404Fallback(): void
{
file_put_contents($this->templatesDir . '/404.scape.php', 'Custom 404: {{ missing_template }}');
$engine = new Engine(['templates_dir' => $this->templatesDir, 'mode' => 'production']);
$output = $engine->render('missing.template');
$this->assertEquals('Custom 404: missing.template', $output);
unlink($this->templatesDir . '/404.scape.php');
}
public function testRendersSimpleTemplate(): void
{
$engine = new Engine([
'templates_dir' => $this->templatesDir,
'mode' => 'production'
]);
$output = $engine->render('tests.simple', [
'name' => 'Funky',
'items' => ['Apple', 'Banana']
]);
$expected = "Hello Funky!\n - Apple\n - Banana\n";
$this->assertEquals($expected, $output);
}
public function testRendersTemplateWithInheritance(): void
{
$engine = new Engine([
'templates_dir' => $this->templatesDir,
'layouts_dir' => $this->templatesDir . '/layouts',
'mode' => 'production'
]);
$output = $engine->render('tests.child', [
'name' => 'Funky'
]);
$this->assertStringContainsString('<title>Child Page - Funky</title>', $output);
$this->assertStringContainsString('<h1>Site Header</h1>', $output);
$this->assertStringContainsString('<h2>Welcome</h2>', $output);
$this->assertStringContainsString('Nested default', $output);
$this->assertStringContainsString('&copy; 2026 - Custom Footer', $output);
}
public function testRendersIncludeWithContext(): void
{
$engine = new Engine([
'templates_dir' => $this->templatesDir,
'partials_dir' => $this->templatesDir . '/partials',
'mode' => 'production'
]);
$output = $engine->render('tests.include', [
'name' => 'Funky',
'id' => 123,
'person' => ['name' => 'John', 'id' => 456]
]);
$this->assertStringContainsString('Hello Funky!', $output);
$this->assertStringContainsString('Name: Funky', $output);
$this->assertStringContainsString('ID: 123', $output);
$this->assertStringContainsString('Name: John', $output);
$this->assertStringContainsString('ID: 456', $output);
}
public function testRecursionLimit(): void
{
$this->expectException(RecursionLimitException::class);
$engine = new Engine([
'templates_dir' => $this->templatesDir,
'partials_dir' => $this->templatesDir . '/partials',
'mode' => 'production'
]);
$engine->render('partials.recursive');
}
}