145 lines
4.6 KiB
PHP
145 lines
4.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Scape\Tests;
|
|
|
|
use PHPUnit\Framework\TestCase;
|
|
use Scape\Config;
|
|
use Scape\Interpreter\Interpreter;
|
|
use Scape\Parser\Node\ForeachNode;
|
|
use Scape\Parser\Node\TextNode;
|
|
use Scape\Parser\Node\VariableNode;
|
|
use Scape\Exceptions\PropertyNotFoundException;
|
|
|
|
class InterpreterTest extends TestCase
|
|
{
|
|
private Interpreter $interpreter;
|
|
private Config $config;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
$this->config = new Config(['mode' => 'production']);
|
|
$this->interpreter = new Interpreter($this->config);
|
|
}
|
|
|
|
public function testRendersText(): void
|
|
{
|
|
$nodes = [new TextNode("Hello World", 1)];
|
|
$this->assertEquals("Hello World", $this->interpreter->interpret($nodes, []));
|
|
}
|
|
|
|
public function testRendersVariable(): void
|
|
{
|
|
$nodes = [new VariableNode("{{ name }}", "name", [], false, 1)];
|
|
$this->assertEquals("Phred", $this->interpreter->interpret($nodes, ['name' => 'Phred']));
|
|
}
|
|
|
|
public function testEscapesVariable(): void
|
|
{
|
|
$nodes = [new VariableNode("{{ name }}", "name", [], false, 1)];
|
|
$this->assertEquals("<script>", $this->interpreter->interpret($nodes, ['name' => '<script>']));
|
|
}
|
|
|
|
public function testRendersRawVariable(): void
|
|
{
|
|
$nodes = [new VariableNode("{{{ name }}}", "name", [], true, 1)];
|
|
$this->assertEquals("<script>", $this->interpreter->interpret($nodes, ['name' => '<script>']));
|
|
}
|
|
|
|
public function testRendersNestedVariable(): void
|
|
{
|
|
$nodes = [new VariableNode("{{ user.name }}", "user.name", [], false, 1)];
|
|
$this->assertEquals("Phred", $this->interpreter->interpret($nodes, ['user' => ['name' => 'Phred']]));
|
|
}
|
|
|
|
public function testRendersBracketVariable(): void
|
|
{
|
|
$nodes = [new VariableNode("{{ items[0] }}", "items[0]", [], false, 1)];
|
|
$this->assertEquals("First", $this->interpreter->interpret($nodes, ['items' => ['First', 'Second']]));
|
|
}
|
|
|
|
public function testMissingVariableInProductionReturnsEmpty(): void
|
|
{
|
|
$nodes = [new VariableNode("{{ missing }}", "missing", [], false, 1)];
|
|
$this->assertEquals("", $this->interpreter->interpret($nodes, []));
|
|
}
|
|
|
|
public function testMissingVariableInDebugThrowsException(): void
|
|
{
|
|
$config = new Config(['mode' => 'debug']);
|
|
$interpreter = new Interpreter($config);
|
|
$nodes = [new VariableNode("{{ missing }}", "missing", [], false, 1)];
|
|
|
|
$this->expectException(PropertyNotFoundException::class);
|
|
$interpreter->interpret($nodes, []);
|
|
}
|
|
|
|
public function testRendersForeach(): void
|
|
{
|
|
$nodes = [
|
|
new ForeachNode(
|
|
"items",
|
|
"item",
|
|
null,
|
|
[
|
|
new VariableNode("{{ item }}", "item", [], false, 1),
|
|
new TextNode(" ", 1)
|
|
],
|
|
1
|
|
)
|
|
];
|
|
$this->assertEquals("A B C ", $this->interpreter->interpret($nodes, ['items' => ['A', 'B', 'C']]));
|
|
}
|
|
|
|
public function testRendersForeachWithKey(): void
|
|
{
|
|
$nodes = [
|
|
new ForeachNode(
|
|
"items",
|
|
"item",
|
|
"key",
|
|
[
|
|
new VariableNode("{{ key }}", "key", [], false, 1),
|
|
new TextNode(":", 1),
|
|
new VariableNode("{{ item }}", "item", [], false, 1),
|
|
new TextNode(" ", 1)
|
|
],
|
|
1
|
|
)
|
|
];
|
|
$this->assertEquals("a:1 b:2 ", $this->interpreter->interpret($nodes, ['items' => ['a' => 1, 'b' => 2]]));
|
|
}
|
|
|
|
public function testForeachPositionalRendering(): void
|
|
{
|
|
$nodes = [
|
|
new ForeachNode(
|
|
"items",
|
|
"item",
|
|
null,
|
|
[new VariableNode("{{ item }}", "item", [], false, 1)],
|
|
1,
|
|
[new TextNode("[FIRST]", 1)],
|
|
[new TextNode("[INNER]", 1)],
|
|
[new TextNode("[LAST]", 1)]
|
|
)
|
|
];
|
|
|
|
// 3 items:
|
|
// 1: [FIRST]A
|
|
// 2: [INNER]B
|
|
// 3: [LAST]C
|
|
$this->assertEquals("[FIRST]A[INNER]B[LAST]C", $this->interpreter->interpret($nodes, ['items' => ['A', 'B', 'C']]));
|
|
|
|
// 2 items:
|
|
// 1: [FIRST]A
|
|
// 2: [LAST]B
|
|
$this->assertEquals("[FIRST]A[LAST]B", $this->interpreter->interpret($nodes, ['items' => ['A', 'B']]));
|
|
|
|
// 1 item:
|
|
// 1: [FIRST][LAST]A
|
|
$this->assertEquals("[FIRST][LAST]A", $this->interpreter->interpret($nodes, ['items' => ['A']]));
|
|
}
|
|
}
|