34ff3b4a |
<?php
|
2119e60c |
namespace Twig\Tests;
|
34ff3b4a |
/*
* This file is part of Twig.
*
* (c) Fabien Potencier
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
|
34bdab4d |
use PHPUnit\Framework\TestCase;
|
90d579e4 |
use Twig\Environment;
use Twig\Error\Error;
use Twig\Error\RuntimeError;
use Twig\Loader\ArrayLoader;
use Twig\Loader\FilesystemLoader;
use Twig\Source;
|
34bdab4d |
class ErrorTest extends TestCase
|
34ff3b4a |
{
|
1b47b401 |
public function testErrorWithObjectFilename()
{
|
90d579e4 |
$error = new Error('foo');
$error->setSourceContext(new Source('', new \SplFileInfo(__FILE__)));
|
1b47b401 |
|
b776e41f |
$this->assertStringContainsString('tests'.\DIRECTORY_SEPARATOR.'ErrorTest.php', $error->getMessage());
|
1b47b401 |
}
|
44f0f9ce |
public function testTwigExceptionGuessWithMissingVarAndArrayLoader()
|
49ee8d6e |
{
|
90d579e4 |
$loader = new ArrayLoader([
|
44f0f9ce |
'base.html' => '{% block content %}{% endblock %}',
'index.html' => <<<EOHTML
{% extends 'base.html' %}
{% block content %}
{{ foo.bar }}
{% endblock %}
{% block foo %}
{{ foo.bar }}
{% endblock %}
EOHTML
|
5c55243d |
]);
|
c795267a |
|
90d579e4 |
$twig = new Environment($loader, ['strict_variables' => true, 'debug' => true, 'cache' => false]);
|
49ee8d6e |
|
e2103c87 |
$template = $twig->load('index.html');
|
49ee8d6e |
try {
|
5c55243d |
$template->render([]);
|
49ee8d6e |
$this->fail();
|
90d579e4 |
} catch (RuntimeError $e) {
|
9ee6fe33 |
$this->assertEquals('Variable "foo" does not exist in "index.html" at line 3.', $e->getMessage());
|
49ee8d6e |
$this->assertEquals(3, $e->getTemplateLine());
|
44f0f9ce |
$this->assertEquals('index.html', $e->getSourceContext()->getName());
|
49ee8d6e |
}
|
44f0f9ce |
}
public function testTwigExceptionGuessWithExceptionAndArrayLoader()
{
|
90d579e4 |
$loader = new ArrayLoader([
|
44f0f9ce |
'base.html' => '{% block content %}{% endblock %}',
'index.html' => <<<EOHTML
{% extends 'base.html' %}
{% block content %}
{{ foo.bar }}
{% endblock %}
{% block foo %}
{{ foo.bar }}
{% endblock %}
EOHTML
|
5c55243d |
]);
|
90d579e4 |
$twig = new Environment($loader, ['strict_variables' => true, 'debug' => true, 'cache' => false]);
|
7051d2e5 |
|
e2103c87 |
$template = $twig->load('index.html');
|
7051d2e5 |
try {
|
2119e60c |
$template->render(['foo' => new ErrorTest_Foo()]);
|
7051d2e5 |
$this->fail();
|
90d579e4 |
} catch (RuntimeError $e) {
|
ba0bf636 |
$this->assertEquals('An exception has been thrown during the rendering of a template ("Runtime error...") in "index.html" at line 3.', $e->getMessage());
|
7051d2e5 |
$this->assertEquals(3, $e->getTemplateLine());
|
44f0f9ce |
$this->assertEquals('index.html', $e->getSourceContext()->getName());
}
}
public function testTwigExceptionGuessWithMissingVarAndFilesystemLoader()
{
|
90d579e4 |
$loader = new FilesystemLoader(__DIR__.'/Fixtures/errors');
$twig = new Environment($loader, ['strict_variables' => true, 'debug' => true, 'cache' => false]);
|
44f0f9ce |
|
e2103c87 |
$template = $twig->load('index.html');
|
44f0f9ce |
try {
|
5c55243d |
$template->render([]);
|
44f0f9ce |
$this->fail();
|
90d579e4 |
} catch (RuntimeError $e) {
|
44f0f9ce |
$this->assertEquals('Variable "foo" does not exist.', $e->getMessage());
$this->assertEquals(3, $e->getTemplateLine());
$this->assertEquals('index.html', $e->getSourceContext()->getName());
$this->assertEquals(3, $e->getLine());
|
920a4f5f |
$this->assertEquals(strtr(__DIR__.'/Fixtures/errors/index.html', '/', \DIRECTORY_SEPARATOR), $e->getFile());
|
44f0f9ce |
}
}
public function testTwigExceptionGuessWithExceptionAndFilesystemLoader()
{
|
90d579e4 |
$loader = new FilesystemLoader(__DIR__.'/Fixtures/errors');
$twig = new Environment($loader, ['strict_variables' => true, 'debug' => true, 'cache' => false]);
|
44f0f9ce |
|
e2103c87 |
$template = $twig->load('index.html');
|
44f0f9ce |
try {
|
2119e60c |
$template->render(['foo' => new ErrorTest_Foo()]);
|
44f0f9ce |
$this->fail();
|
90d579e4 |
} catch (RuntimeError $e) {
|
44f0f9ce |
$this->assertEquals('An exception has been thrown during the rendering of a template ("Runtime error...").', $e->getMessage());
$this->assertEquals(3, $e->getTemplateLine());
$this->assertEquals('index.html', $e->getSourceContext()->getName());
$this->assertEquals(3, $e->getLine());
|
920a4f5f |
$this->assertEquals(strtr(__DIR__.'/Fixtures/errors/index.html', '/', \DIRECTORY_SEPARATOR), $e->getFile());
|
7051d2e5 |
}
}
|
ba0bf636 |
/**
* @dataProvider getErroredTemplates
*/
public function testTwigExceptionAddsFileAndLine($templates, $name, $line)
|
650295f5 |
{
|
90d579e4 |
$loader = new ArrayLoader($templates);
$twig = new Environment($loader, ['strict_variables' => true, 'debug' => true, 'cache' => false]);
|
650295f5 |
|
e2103c87 |
$template = $twig->load('index');
|
ba0bf636 |
|
650295f5 |
try {
|
5c55243d |
$template->render([]);
|
650295f5 |
$this->fail();
|
90d579e4 |
} catch (RuntimeError $e) {
|
9ee6fe33 |
$this->assertEquals(sprintf('Variable "foo" does not exist in "%s" at line %d.', $name, $line), $e->getMessage());
|
ba0bf636 |
$this->assertEquals($line, $e->getTemplateLine());
|
44f0f9ce |
$this->assertEquals($name, $e->getSourceContext()->getName());
|
650295f5 |
}
|
de985a87 |
try {
|
2119e60c |
$template->render(['foo' => new ErrorTest_Foo()]);
|
de985a87 |
$this->fail();
|
90d579e4 |
} catch (RuntimeError $e) {
|
ba0bf636 |
$this->assertEquals(sprintf('An exception has been thrown during the rendering of a template ("Runtime error...") in "%s" at line %d.', $name, $line), $e->getMessage());
$this->assertEquals($line, $e->getTemplateLine());
|
44f0f9ce |
$this->assertEquals($name, $e->getSourceContext()->getName());
|
de985a87 |
}
}
|
ba0bf636 |
public function getErroredTemplates()
|
7051d2e5 |
{
|
5c55243d |
return [
|
ba0bf636 |
// error occurs in a template
|
5c55243d |
[
[
|
ba0bf636 |
'index' => "\n\n{{ foo.bar }}\n\n\n{{ 'foo' }}",
|
5c55243d |
],
|
ba0bf636 |
'index', 3,
|
5c55243d |
],
|
ba0bf636 |
// error occurs in an included template
|
5c55243d |
[
[
|
b0c41d42 |
'index' => "{% include 'partial' %}",
|
ba0bf636 |
'partial' => '{{ foo.bar }}',
|
5c55243d |
],
|
ba0bf636 |
'partial', 1,
|
5c55243d |
],
|
ba0bf636 |
// error occurs in a parent block when called via parent()
|
5c55243d |
[
[
|
ba0bf636 |
'index' => "{% extends 'base' %}
{% block content %}
{{ parent() }}
{% endblock %}",
|
89df3c20 |
'base' => '{% block content %}{{ foo.bar }}{% endblock %}',
|
5c55243d |
],
|
ba0bf636 |
'base', 1,
|
5c55243d |
],
|
ba0bf636 |
// error occurs in a block from the child
|
5c55243d |
[
[
|
ba0bf636 |
'index' => "{% extends 'base' %}
{% block content %}
{{ foo.bar }}
{% endblock %}
{% block foo %}
{{ foo.bar }}
{% endblock %}",
|
89df3c20 |
'base' => '{% block content %}{% endblock %}',
|
5c55243d |
],
|
ba0bf636 |
'index', 3,
|
5c55243d |
],
];
|
49ee8d6e |
}
|
c910e71f |
public function testTwigLeakOutputInDebugMode()
{
|
fa0213a9 |
$output = exec(sprintf('%s %s debug', \PHP_BINARY, escapeshellarg(__DIR__.'/Fixtures/errors/leak-output.php')));
|
c910e71f |
$this->assertSame('Hello OOPS', $output);
}
public function testDoesNotTwigLeakOutput()
{
|
fa0213a9 |
$output = exec(sprintf('%s %s', \PHP_BINARY, escapeshellarg(__DIR__.'/Fixtures/errors/leak-output.php')));
|
c910e71f |
$this->assertSame('', $output);
}
|
34ff3b4a |
}
|
2119e60c |
class ErrorTest_Foo
|
34ff3b4a |
{
public function bar()
{
|
b8daa6c4 |
throw new \Exception('Runtime error...');
|
34ff3b4a |
}
}
|