tests/ErrorTest.php
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
     }
 }