1<?php 2 3/* 4 * This file is part of Twig. 5 * 6 * (c) Fabien Potencier 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12use Twig\Environment; 13use Twig\Node\Expression\ConstantExpression; 14use Twig\Node\Expression\FilterExpression; 15use Twig\Node\Node; 16use Twig\Test\NodeTestCase; 17use Twig\TwigFilter; 18 19class Twig_Tests_Node_Expression_FilterTest extends NodeTestCase 20{ 21 public function testConstructor() 22 { 23 $expr = new ConstantExpression('foo', 1); 24 $name = new ConstantExpression('upper', 1); 25 $args = new Node(); 26 $node = new FilterExpression($expr, $name, $args, 1); 27 28 $this->assertEquals($expr, $node->getNode('node')); 29 $this->assertEquals($name, $node->getNode('filter')); 30 $this->assertEquals($args, $node->getNode('arguments')); 31 } 32 33 public function getTests() 34 { 35 $environment = new Environment($this->getMockBuilder('\Twig\Loader\LoaderInterface')->getMock()); 36 $environment->addFilter(new TwigFilter('bar', 'bar', ['needs_environment' => true])); 37 $environment->addFilter(new TwigFilter('barbar', 'twig_tests_filter_barbar', ['needs_context' => true, 'is_variadic' => true])); 38 39 $tests = []; 40 41 $expr = new ConstantExpression('foo', 1); 42 $node = $this->createFilter($expr, 'upper'); 43 $node = $this->createFilter($node, 'number_format', [new ConstantExpression(2, 1), new ConstantExpression('.', 1), new ConstantExpression(',', 1)]); 44 45 if (\function_exists('mb_get_info')) { 46 $tests[] = [$node, 'twig_number_format_filter($this->env, twig_upper_filter($this->env, "foo"), 2, ".", ",")']; 47 } else { 48 $tests[] = [$node, 'twig_number_format_filter($this->env, strtoupper("foo"), 2, ".", ",")']; 49 } 50 51 // named arguments 52 $date = new ConstantExpression(0, 1); 53 $node = $this->createFilter($date, 'date', [ 54 'timezone' => new ConstantExpression('America/Chicago', 1), 55 'format' => new ConstantExpression('d/m/Y H:i:s P', 1), 56 ]); 57 $tests[] = [$node, 'twig_date_format_filter($this->env, 0, "d/m/Y H:i:s P", "America/Chicago")']; 58 59 // skip an optional argument 60 $date = new ConstantExpression(0, 1); 61 $node = $this->createFilter($date, 'date', [ 62 'timezone' => new ConstantExpression('America/Chicago', 1), 63 ]); 64 $tests[] = [$node, 'twig_date_format_filter($this->env, 0, null, "America/Chicago")']; 65 66 // underscores vs camelCase for named arguments 67 $string = new ConstantExpression('abc', 1); 68 $node = $this->createFilter($string, 'reverse', [ 69 'preserve_keys' => new ConstantExpression(true, 1), 70 ]); 71 $tests[] = [$node, 'twig_reverse_filter($this->env, "abc", true)']; 72 $node = $this->createFilter($string, 'reverse', [ 73 'preserveKeys' => new ConstantExpression(true, 1), 74 ]); 75 $tests[] = [$node, 'twig_reverse_filter($this->env, "abc", true)']; 76 77 // filter as an anonymous function 78 if (PHP_VERSION_ID >= 50300) { 79 $node = $this->createFilter(new ConstantExpression('foo', 1), 'anonymous'); 80 $tests[] = [$node, 'call_user_func_array($this->env->getFilter(\'anonymous\')->getCallable(), ["foo"])']; 81 } 82 83 // needs environment 84 $node = $this->createFilter($string, 'bar'); 85 $tests[] = [$node, 'bar($this->env, "abc")', $environment]; 86 87 $node = $this->createFilter($string, 'bar', [new ConstantExpression('bar', 1)]); 88 $tests[] = [$node, 'bar($this->env, "abc", "bar")', $environment]; 89 90 // arbitrary named arguments 91 $node = $this->createFilter($string, 'barbar'); 92 $tests[] = [$node, 'twig_tests_filter_barbar($context, "abc")', $environment]; 93 94 $node = $this->createFilter($string, 'barbar', ['foo' => new ConstantExpression('bar', 1)]); 95 $tests[] = [$node, 'twig_tests_filter_barbar($context, "abc", null, null, ["foo" => "bar"])', $environment]; 96 97 $node = $this->createFilter($string, 'barbar', ['arg2' => new ConstantExpression('bar', 1)]); 98 $tests[] = [$node, 'twig_tests_filter_barbar($context, "abc", null, "bar")', $environment]; 99 100 $node = $this->createFilter($string, 'barbar', [ 101 new ConstantExpression('1', 1), 102 new ConstantExpression('2', 1), 103 new ConstantExpression('3', 1), 104 'foo' => new ConstantExpression('bar', 1), 105 ]); 106 $tests[] = [$node, 'twig_tests_filter_barbar($context, "abc", "1", "2", [0 => "3", "foo" => "bar"])', $environment]; 107 108 return $tests; 109 } 110 111 /** 112 * @expectedException \Twig\Error\SyntaxError 113 * @expectedExceptionMessage Unknown argument "foobar" for filter "date(format, timezone)" at line 1. 114 */ 115 public function testCompileWithWrongNamedArgumentName() 116 { 117 $date = new ConstantExpression(0, 1); 118 $node = $this->createFilter($date, 'date', [ 119 'foobar' => new ConstantExpression('America/Chicago', 1), 120 ]); 121 122 $compiler = $this->getCompiler(); 123 $compiler->compile($node); 124 } 125 126 /** 127 * @expectedException \Twig\Error\SyntaxError 128 * @expectedExceptionMessage Value for argument "from" is required for filter "replace" at line 1. 129 */ 130 public function testCompileWithMissingNamedArgument() 131 { 132 $value = new ConstantExpression(0, 1); 133 $node = $this->createFilter($value, 'replace', [ 134 'to' => new ConstantExpression('foo', 1), 135 ]); 136 137 $compiler = $this->getCompiler(); 138 $compiler->compile($node); 139 } 140 141 protected function createFilter($node, $name, array $arguments = []) 142 { 143 $name = new ConstantExpression($name, 1); 144 $arguments = new Node($arguments); 145 146 return new FilterExpression($node, $name, $arguments, 1); 147 } 148 149 protected function getEnvironment() 150 { 151 if (PHP_VERSION_ID >= 50300) { 152 return include 'PHP53/FilterInclude.php'; 153 } 154 155 return parent::getEnvironment(); 156 } 157} 158 159function twig_tests_filter_barbar($context, $string, $arg1 = null, $arg2 = null, array $args = []) 160{ 161} 162