1<?php
2
3/*
4 * This file is part of the Symfony package.
5 *
6 * (c) Fabien Potencier <fabien@symfony.com>
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Symfony\Bridge\Twig\Tests\Node;
13
14use PHPUnit\Framework\TestCase;
15use Symfony\Bridge\Twig\Node\SearchAndRenderBlockNode;
16use Twig\Compiler;
17use Twig\Environment;
18use Twig\Node\Expression\ArrayExpression;
19use Twig\Node\Expression\ConditionalExpression;
20use Twig\Node\Expression\ConstantExpression;
21use Twig\Node\Expression\NameExpression;
22use Twig\Node\Node;
23
24class SearchAndRenderBlockNodeTest extends TestCase
25{
26    public function testCompileWidget()
27    {
28        $arguments = new Node(array(
29            new NameExpression('form', 0),
30        ));
31
32        $node = new SearchAndRenderBlockNode('form_widget', $arguments, 0);
33
34        $compiler = new Compiler(new Environment($this->getMockBuilder('Twig\Loader\LoaderInterface')->getMock()));
35
36        $this->assertEquals(
37            sprintf(
38                '$this->env->getExtension(\'Symfony\Bridge\Twig\Extension\FormExtension\')->renderer->searchAndRenderBlock(%s, \'widget\')',
39                $this->getVariableGetter('form')
40             ),
41            trim($compiler->compile($node)->getSource())
42        );
43    }
44
45    public function testCompileWidgetWithVariables()
46    {
47        $arguments = new Node(array(
48            new NameExpression('form', 0),
49            new ArrayExpression(array(
50                new ConstantExpression('foo', 0),
51                new ConstantExpression('bar', 0),
52            ), 0),
53        ));
54
55        $node = new SearchAndRenderBlockNode('form_widget', $arguments, 0);
56
57        $compiler = new Compiler(new Environment($this->getMockBuilder('Twig\Loader\LoaderInterface')->getMock()));
58
59        $this->assertEquals(
60            sprintf(
61                '$this->env->getExtension(\'Symfony\Bridge\Twig\Extension\FormExtension\')->renderer->searchAndRenderBlock(%s, \'widget\', array("foo" => "bar"))',
62                $this->getVariableGetter('form')
63            ),
64            trim($compiler->compile($node)->getSource())
65        );
66    }
67
68    public function testCompileLabelWithLabel()
69    {
70        $arguments = new Node(array(
71            new NameExpression('form', 0),
72            new ConstantExpression('my label', 0),
73        ));
74
75        $node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
76
77        $compiler = new Compiler(new Environment($this->getMockBuilder('Twig\Loader\LoaderInterface')->getMock()));
78
79        $this->assertEquals(
80            sprintf(
81                '$this->env->getExtension(\'Symfony\Bridge\Twig\Extension\FormExtension\')->renderer->searchAndRenderBlock(%s, \'label\', array("label" => "my label"))',
82                $this->getVariableGetter('form')
83            ),
84            trim($compiler->compile($node)->getSource())
85        );
86    }
87
88    public function testCompileLabelWithNullLabel()
89    {
90        $arguments = new Node(array(
91            new NameExpression('form', 0),
92            new ConstantExpression(null, 0),
93        ));
94
95        $node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
96
97        $compiler = new Compiler(new Environment($this->getMockBuilder('Twig\Loader\LoaderInterface')->getMock()));
98
99        // "label" => null must not be included in the output!
100        // Otherwise the default label is overwritten with null.
101        $this->assertEquals(
102            sprintf(
103                '$this->env->getExtension(\'Symfony\Bridge\Twig\Extension\FormExtension\')->renderer->searchAndRenderBlock(%s, \'label\')',
104                $this->getVariableGetter('form')
105            ),
106            trim($compiler->compile($node)->getSource())
107        );
108    }
109
110    public function testCompileLabelWithEmptyStringLabel()
111    {
112        $arguments = new Node(array(
113            new NameExpression('form', 0),
114            new ConstantExpression('', 0),
115        ));
116
117        $node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
118
119        $compiler = new Compiler(new Environment($this->getMockBuilder('Twig\Loader\LoaderInterface')->getMock()));
120
121        // "label" => null must not be included in the output!
122        // Otherwise the default label is overwritten with null.
123        $this->assertEquals(
124            sprintf(
125                '$this->env->getExtension(\'Symfony\Bridge\Twig\Extension\FormExtension\')->renderer->searchAndRenderBlock(%s, \'label\')',
126                $this->getVariableGetter('form')
127            ),
128            trim($compiler->compile($node)->getSource())
129        );
130    }
131
132    public function testCompileLabelWithDefaultLabel()
133    {
134        $arguments = new Node(array(
135            new NameExpression('form', 0),
136        ));
137
138        $node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
139
140        $compiler = new Compiler(new Environment($this->getMockBuilder('Twig\Loader\LoaderInterface')->getMock()));
141
142        $this->assertEquals(
143            sprintf(
144                '$this->env->getExtension(\'Symfony\Bridge\Twig\Extension\FormExtension\')->renderer->searchAndRenderBlock(%s, \'label\')',
145                $this->getVariableGetter('form')
146            ),
147            trim($compiler->compile($node)->getSource())
148        );
149    }
150
151    public function testCompileLabelWithAttributes()
152    {
153        $arguments = new Node(array(
154            new NameExpression('form', 0),
155            new ConstantExpression(null, 0),
156            new ArrayExpression(array(
157                new ConstantExpression('foo', 0),
158                new ConstantExpression('bar', 0),
159            ), 0),
160        ));
161
162        $node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
163
164        $compiler = new Compiler(new Environment($this->getMockBuilder('Twig\Loader\LoaderInterface')->getMock()));
165
166        // "label" => null must not be included in the output!
167        // Otherwise the default label is overwritten with null.
168        // https://github.com/symfony/symfony/issues/5029
169        $this->assertEquals(
170            sprintf(
171                '$this->env->getExtension(\'Symfony\Bridge\Twig\Extension\FormExtension\')->renderer->searchAndRenderBlock(%s, \'label\', array("foo" => "bar"))',
172                $this->getVariableGetter('form')
173            ),
174            trim($compiler->compile($node)->getSource())
175        );
176    }
177
178    public function testCompileLabelWithLabelAndAttributes()
179    {
180        $arguments = new Node(array(
181            new NameExpression('form', 0),
182            new ConstantExpression('value in argument', 0),
183            new ArrayExpression(array(
184                new ConstantExpression('foo', 0),
185                new ConstantExpression('bar', 0),
186                new ConstantExpression('label', 0),
187                new ConstantExpression('value in attributes', 0),
188            ), 0),
189        ));
190
191        $node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
192
193        $compiler = new Compiler(new Environment($this->getMockBuilder('Twig\Loader\LoaderInterface')->getMock()));
194
195        $this->assertEquals(
196            sprintf(
197                '$this->env->getExtension(\'Symfony\Bridge\Twig\Extension\FormExtension\')->renderer->searchAndRenderBlock(%s, \'label\', array("foo" => "bar", "label" => "value in argument"))',
198                $this->getVariableGetter('form')
199            ),
200            trim($compiler->compile($node)->getSource())
201        );
202    }
203
204    public function testCompileLabelWithLabelThatEvaluatesToNull()
205    {
206        $arguments = new Node(array(
207            new NameExpression('form', 0),
208            new ConditionalExpression(
209                // if
210                new ConstantExpression(true, 0),
211                // then
212                new ConstantExpression(null, 0),
213                // else
214                new ConstantExpression(null, 0),
215                0
216            ),
217        ));
218
219        $node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
220
221        $compiler = new Compiler(new Environment($this->getMockBuilder('Twig\Loader\LoaderInterface')->getMock()));
222
223        // "label" => null must not be included in the output!
224        // Otherwise the default label is overwritten with null.
225        // https://github.com/symfony/symfony/issues/5029
226        $this->assertEquals(
227            sprintf(
228                '$this->env->getExtension(\'Symfony\Bridge\Twig\Extension\FormExtension\')->renderer->searchAndRenderBlock(%s, \'label\', (twig_test_empty($_label_ = ((true) ? (null) : (null))) ? array() : array("label" => $_label_)))',
229                $this->getVariableGetter('form')
230            ),
231            trim($compiler->compile($node)->getSource())
232        );
233    }
234
235    public function testCompileLabelWithLabelThatEvaluatesToNullAndAttributes()
236    {
237        $arguments = new Node(array(
238            new NameExpression('form', 0),
239            new ConditionalExpression(
240                // if
241                new ConstantExpression(true, 0),
242                // then
243                new ConstantExpression(null, 0),
244                // else
245                new ConstantExpression(null, 0),
246                0
247            ),
248            new ArrayExpression(array(
249                new ConstantExpression('foo', 0),
250                new ConstantExpression('bar', 0),
251                new ConstantExpression('label', 0),
252                new ConstantExpression('value in attributes', 0),
253            ), 0),
254        ));
255
256        $node = new SearchAndRenderBlockNode('form_label', $arguments, 0);
257
258        $compiler = new Compiler(new Environment($this->getMockBuilder('Twig\Loader\LoaderInterface')->getMock()));
259
260        // "label" => null must not be included in the output!
261        // Otherwise the default label is overwritten with null.
262        // https://github.com/symfony/symfony/issues/5029
263        $this->assertEquals(
264            sprintf(
265                '$this->env->getExtension(\'Symfony\Bridge\Twig\Extension\FormExtension\')->renderer->searchAndRenderBlock(%s, \'label\', array("foo" => "bar", "label" => "value in attributes") + (twig_test_empty($_label_ = ((true) ? (null) : (null))) ? array() : array("label" => $_label_)))',
266                $this->getVariableGetter('form')
267            ),
268            trim($compiler->compile($node)->getSource())
269        );
270    }
271
272    protected function getVariableGetter($name)
273    {
274        if (\PHP_VERSION_ID >= 70000) {
275            return sprintf('($context["%s"] ?? null)', $name);
276        }
277
278        if (\PHP_VERSION_ID >= 50400) {
279            return sprintf('(isset($context["%s"]) ? $context["%1$s"] : null)', $name);
280        }
281
282        return sprintf('$this->getContext($context, "%s")', $name);
283    }
284}
285