|
12 | 12 | */
|
13 | 13 |
|
14 | 14 | use PHPUnit\Framework\TestCase;
|
| 15 | +use Twig\Attribute\YieldReady; |
| 16 | +use Twig\Compiler; |
15 | 17 | use Twig\Environment;
|
16 | 18 | use Twig\Error\Error;
|
17 | 19 | use Twig\Error\RuntimeError;
|
18 | 20 | use Twig\Error\SyntaxError;
|
19 | 21 | use Twig\Loader\ArrayLoader;
|
20 | 22 | use Twig\Loader\FilesystemLoader;
|
| 23 | +use Twig\Loader\LoaderInterface; |
| 24 | +use Twig\Node\Node; |
21 | 25 | use Twig\Source;
|
| 26 | +use Twig\Token; |
| 27 | +use Twig\TokenParser\AbstractTokenParser; |
22 | 28 |
|
23 | 29 | class ErrorTest extends TestCase
|
24 | 30 | {
|
@@ -253,6 +259,91 @@ public function testTwigExceptionUpdateFileAndLineTogether()
|
253 | 259 | }
|
254 | 260 | }
|
255 | 261 |
|
| 262 | + /** |
| 263 | + * @dataProvider getErrorWithoutLineAndContextData |
| 264 | + */ |
| 265 | + public function testErrorWithoutLineAndContext(LoaderInterface $loader, bool $debug, bool $addDebugInfo) |
| 266 | + { |
| 267 | + $twig = new Environment($loader, ['debug' => $debug, 'cache' => false]); |
| 268 | + $twig->removeCache('no_line_and_context_exception.twig'); |
| 269 | + $twig->removeCache('no_line_and_context_exception_include.twig'); |
| 270 | + $twig->addTokenParser(new class($addDebugInfo) extends AbstractTokenParser { |
| 271 | + public function __construct(private bool $addDebugInfo) |
| 272 | + { |
| 273 | + } |
| 274 | + |
| 275 | + public function parse(Token $token) |
| 276 | + { |
| 277 | + $this->parser->getStream()->expect(Token::BLOCK_END_TYPE); |
| 278 | + |
| 279 | + return new #[YieldReady]class($this->addDebugInfo) extends Node |
| 280 | + { |
| 281 | + public function __construct(private bool $addDebugInfo) |
| 282 | + { |
| 283 | + parent::__construct([], [], 2); |
| 284 | + } |
| 285 | + |
| 286 | + public function compile(Compiler $compiler): void |
| 287 | + { |
| 288 | + if ($this->addDebugInfo) { |
| 289 | + $compiler->addDebugInfo($this); |
| 290 | + } |
| 291 | + $compiler->write('throw new \Twig\Error\RuntimeError("Runtime error.");'); |
| 292 | + } |
| 293 | + }; |
| 294 | + } |
| 295 | + |
| 296 | + public function getTag() |
| 297 | + { |
| 298 | + return 'foo'; |
| 299 | + } |
| 300 | + }); |
| 301 | + |
| 302 | + try { |
| 303 | + $twig->render('no_line_and_context_exception.twig'); |
| 304 | + $this->fail(); |
| 305 | + } catch (RuntimeError $e) { |
| 306 | + if ($addDebugInfo) { |
| 307 | + $this->assertSame('Runtime error in "no_line_and_context_exception_include.twig" at line 2.', $e->getMessage()); |
| 308 | + $this->assertSame(2, $e->getTemplateLine()); |
| 309 | + } else { |
| 310 | + $this->assertSame('Runtime error in "no_line_and_context_exception_include.twig".', $e->getMessage()); |
| 311 | + $this->assertSame(0, $e->getTemplateLine()); |
| 312 | + } |
| 313 | + |
| 314 | + if ($loader instanceof FilesystemLoader) { |
| 315 | + $this->assertStringContainsString('errors/no_line_and_context_exception_include.twig', $e->getFile()); |
| 316 | + if ($addDebugInfo) { |
| 317 | + $this->assertSame(2, $e->getLine()); |
| 318 | + } else { |
| 319 | + $this->assertSame(-1, $e->getLine()); |
| 320 | + } |
| 321 | + } else { |
| 322 | + $this->assertStringContainsString('Environment.php', $e->getFile()); |
| 323 | + $this->assertNotSame(2, $e->getLine()); |
| 324 | + } |
| 325 | + } |
| 326 | + } |
| 327 | + |
| 328 | + public static function getErrorWithoutLineAndContextData(): iterable |
| 329 | + { |
| 330 | + $arrayLoader = new ArrayLoader([ |
| 331 | + 'no_line_and_context_exception.twig' => '{{ include("no_line_and_context_exception_include.twig") }}', |
| 332 | + 'no_line_and_context_exception_include.twig' => '{% foo %}', |
| 333 | + ]); |
| 334 | + |
| 335 | + yield [$arrayLoader, false, false]; |
| 336 | + yield [$arrayLoader, false, true]; |
| 337 | + yield [$arrayLoader, true, false]; |
| 338 | + yield [$arrayLoader, true, true]; |
| 339 | + |
| 340 | + $filesystemLoader = new FilesystemLoader(__DIR__.'/Fixtures/errors'); |
| 341 | + yield [$filesystemLoader, false, false]; |
| 342 | + yield [$filesystemLoader, false, true]; |
| 343 | + yield [$filesystemLoader, true, false]; |
| 344 | + yield [$filesystemLoader, true, true]; |
| 345 | + } |
| 346 | + |
256 | 347 | public static function getErroredTemplates()
|
257 | 348 | {
|
258 | 349 | return [
|
|
0 commit comments