From 567b1e2a0639a1d6b414c6b40a074de38b7c992e Mon Sep 17 00:00:00 2001 From: Thijs van Dijk Date: Thu, 28 May 2020 17:37:56 +0200 Subject: [PATCH] In |filter(), |map(), and |reduce(), throw a RuntimeError instead of a TypeError --- src/Extension/CoreExtension.php | 4 ++ tests/ErrorTest.php | 79 +++++++++++++++++++++++++++++++++ 2 files changed, 83 insertions(+) diff --git a/src/Extension/CoreExtension.php b/src/Extension/CoreExtension.php index 2f24848a4..dc6114d3a 100644 --- a/src/Extension/CoreExtension.php +++ b/src/Extension/CoreExtension.php @@ -1724,6 +1724,10 @@ function twig_array_map($array, $arrow) function twig_array_reduce($array, $arrow, $initial = null) { if (!\is_array($array)) { + if (!$array instanceof \Traversable) { + throw new RuntimeError(sprintf('The "reduce" filter only works with arrays or "Traversable", got "%s" as first argument.', \gettype($array))); + } + $array = iterator_to_array($array); } diff --git a/tests/ErrorTest.php b/tests/ErrorTest.php index a84da2eea..b0f1ce529 100644 --- a/tests/ErrorTest.php +++ b/tests/ErrorTest.php @@ -161,6 +161,85 @@ EOHTML } } + public function testTwigArrayFilterThrowsRuntimeExceptions() + { + $loader = new ArrayLoader([ + 'filter-null.html' => << x > 3) %} + This list contains {{n}}. +{% endfor %} +EOHTML + ]); + + $twig = new Environment($loader, ['debug' => true, 'cache' => false]); + + $template = $twig->load('filter-null.html'); + $out = $template->render(['variable' => [1, 2, 3, 4]]); + $this->assertEquals('This list contains 4.', trim($out)); + + try { + $template->render(['variable' => null]); + + $this->fail(); + } catch (RuntimeError $e) { + $this->assertEquals(2, $e->getTemplateLine()); + $this->assertEquals('filter-null.html', $e->getSourceContext()->getName()); + } + } + + public function testTwigArrayMapThrowsRuntimeExceptions() + { + $loader = new ArrayLoader([ + 'map-null.html' => << x * 3) %} + {{- n -}} +{% endfor %} +EOHTML + ]); + + $twig = new Environment($loader, ['debug' => true, 'cache' => false]); + + $template = $twig->load('map-null.html'); + $out = $template->render(['variable' => [1, 2, 3, 4]]); + $this->assertEquals('36912', trim($out)); + + try { + $template->render(['variable' => null]); + + $this->fail(); + } catch (RuntimeError $e) { + $this->assertEquals(2, $e->getTemplateLine()); + $this->assertEquals('map-null.html', $e->getSourceContext()->getName()); + } + } + + public function testTwigArrayReduceThrowsRuntimeExceptions() + { + $loader = new ArrayLoader([ + 'reduce-null.html' => << carry + x) }} +EOHTML + ]); + + $twig = new Environment($loader, ['debug' => true, 'cache' => false]); + + $template = $twig->load('reduce-null.html'); + $out = $template->render(['variable' => [1, 2, 3, 4]]); + $this->assertEquals('10', trim($out)); + + try { + $template->render(['variable' => null]); + + $this->fail(); + } catch (RuntimeError $e) { + $this->assertEquals(2, $e->getTemplateLine()); + $this->assertEquals('reduce-null.html', $e->getSourceContext()->getName()); + } + } + public function getErroredTemplates() { return [