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\Node\Expression\AssignNameExpression;
13use Twig\Node\Expression\ConstantExpression;
14use Twig\Node\Expression\NameExpression;
15use Twig\Node\ForNode;
16use Twig\Node\Node;
17use Twig\Node\PrintNode;
18use Twig\Test\NodeTestCase;
19
20class Twig_Tests_Node_ForTest extends NodeTestCase
21{
22    public function testConstructor()
23    {
24        $keyTarget = new AssignNameExpression('key', 1);
25        $valueTarget = new AssignNameExpression('item', 1);
26        $seq = new NameExpression('items', 1);
27        $ifexpr = new ConstantExpression(true, 1);
28        $body = new Node([new PrintNode(new NameExpression('foo', 1), 1)], [], 1);
29        $else = null;
30        $node = new ForNode($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 1);
31        $node->setAttribute('with_loop', false);
32
33        $this->assertEquals($keyTarget, $node->getNode('key_target'));
34        $this->assertEquals($valueTarget, $node->getNode('value_target'));
35        $this->assertEquals($seq, $node->getNode('seq'));
36        $this->assertTrue($node->getAttribute('ifexpr'));
37        $this->assertInstanceOf('\Twig\Node\IfNode', $node->getNode('body'));
38        $this->assertEquals($body, $node->getNode('body')->getNode('tests')->getNode(1)->getNode(0));
39        $this->assertFalse($node->hasNode('else'));
40
41        $else = new PrintNode(new NameExpression('foo', 1), 1);
42        $node = new ForNode($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 1);
43        $node->setAttribute('with_loop', false);
44        $this->assertEquals($else, $node->getNode('else'));
45    }
46
47    public function getTests()
48    {
49        $tests = [];
50
51        $keyTarget = new AssignNameExpression('key', 1);
52        $valueTarget = new AssignNameExpression('item', 1);
53        $seq = new NameExpression('items', 1);
54        $ifexpr = null;
55        $body = new Node([new PrintNode(new NameExpression('foo', 1), 1)], [], 1);
56        $else = null;
57        $node = new ForNode($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 1);
58        $node->setAttribute('with_loop', false);
59
60        $tests[] = [$node, <<<EOF
61// line 1
62\$context['_parent'] = \$context;
63\$context['_seq'] = twig_ensure_traversable({$this->getVariableGetter('items')});
64foreach (\$context['_seq'] as \$context["key"] => \$context["item"]) {
65    echo {$this->getVariableGetter('foo')};
66}
67\$_parent = \$context['_parent'];
68unset(\$context['_seq'], \$context['_iterated'], \$context['key'], \$context['item'], \$context['_parent'], \$context['loop']);
69\$context = array_intersect_key(\$context, \$_parent) + \$_parent;
70EOF
71        ];
72
73        $keyTarget = new AssignNameExpression('k', 1);
74        $valueTarget = new AssignNameExpression('v', 1);
75        $seq = new NameExpression('values', 1);
76        $ifexpr = null;
77        $body = new Node([new PrintNode(new NameExpression('foo', 1), 1)], [], 1);
78        $else = null;
79        $node = new ForNode($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 1);
80        $node->setAttribute('with_loop', true);
81
82        $tests[] = [$node, <<<EOF
83// line 1
84\$context['_parent'] = \$context;
85\$context['_seq'] = twig_ensure_traversable({$this->getVariableGetter('values')});
86\$context['loop'] = [
87  'parent' => \$context['_parent'],
88  'index0' => 0,
89  'index'  => 1,
90  'first'  => true,
91];
92if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof \Countable)) {
93    \$length = count(\$context['_seq']);
94    \$context['loop']['revindex0'] = \$length - 1;
95    \$context['loop']['revindex'] = \$length;
96    \$context['loop']['length'] = \$length;
97    \$context['loop']['last'] = 1 === \$length;
98}
99foreach (\$context['_seq'] as \$context["k"] => \$context["v"]) {
100    echo {$this->getVariableGetter('foo')};
101    ++\$context['loop']['index0'];
102    ++\$context['loop']['index'];
103    \$context['loop']['first'] = false;
104    if (isset(\$context['loop']['length'])) {
105        --\$context['loop']['revindex0'];
106        --\$context['loop']['revindex'];
107        \$context['loop']['last'] = 0 === \$context['loop']['revindex0'];
108    }
109}
110\$_parent = \$context['_parent'];
111unset(\$context['_seq'], \$context['_iterated'], \$context['k'], \$context['v'], \$context['_parent'], \$context['loop']);
112\$context = array_intersect_key(\$context, \$_parent) + \$_parent;
113EOF
114        ];
115
116        $keyTarget = new AssignNameExpression('k', 1);
117        $valueTarget = new AssignNameExpression('v', 1);
118        $seq = new NameExpression('values', 1);
119        $ifexpr = new ConstantExpression(true, 1);
120        $body = new Node([new PrintNode(new NameExpression('foo', 1), 1)], [], 1);
121        $else = null;
122        $node = new ForNode($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 1);
123        $node->setAttribute('with_loop', true);
124
125        $tests[] = [$node, <<<EOF
126// line 1
127\$context['_parent'] = \$context;
128\$context['_seq'] = twig_ensure_traversable({$this->getVariableGetter('values')});
129\$context['loop'] = [
130  'parent' => \$context['_parent'],
131  'index0' => 0,
132  'index'  => 1,
133  'first'  => true,
134];
135foreach (\$context['_seq'] as \$context["k"] => \$context["v"]) {
136    if (true) {
137        echo {$this->getVariableGetter('foo')};
138        ++\$context['loop']['index0'];
139        ++\$context['loop']['index'];
140        \$context['loop']['first'] = false;
141    }
142}
143\$_parent = \$context['_parent'];
144unset(\$context['_seq'], \$context['_iterated'], \$context['k'], \$context['v'], \$context['_parent'], \$context['loop']);
145\$context = array_intersect_key(\$context, \$_parent) + \$_parent;
146EOF
147        ];
148
149        $keyTarget = new AssignNameExpression('k', 1);
150        $valueTarget = new AssignNameExpression('v', 1);
151        $seq = new NameExpression('values', 1);
152        $ifexpr = null;
153        $body = new Node([new PrintNode(new NameExpression('foo', 1), 1)], [], 1);
154        $else = new PrintNode(new NameExpression('foo', 1), 1);
155        $node = new ForNode($keyTarget, $valueTarget, $seq, $ifexpr, $body, $else, 1);
156        $node->setAttribute('with_loop', true);
157
158        $tests[] = [$node, <<<EOF
159// line 1
160\$context['_parent'] = \$context;
161\$context['_seq'] = twig_ensure_traversable({$this->getVariableGetter('values')});
162\$context['_iterated'] = false;
163\$context['loop'] = [
164  'parent' => \$context['_parent'],
165  'index0' => 0,
166  'index'  => 1,
167  'first'  => true,
168];
169if (is_array(\$context['_seq']) || (is_object(\$context['_seq']) && \$context['_seq'] instanceof \Countable)) {
170    \$length = count(\$context['_seq']);
171    \$context['loop']['revindex0'] = \$length - 1;
172    \$context['loop']['revindex'] = \$length;
173    \$context['loop']['length'] = \$length;
174    \$context['loop']['last'] = 1 === \$length;
175}
176foreach (\$context['_seq'] as \$context["k"] => \$context["v"]) {
177    echo {$this->getVariableGetter('foo')};
178    \$context['_iterated'] = true;
179    ++\$context['loop']['index0'];
180    ++\$context['loop']['index'];
181    \$context['loop']['first'] = false;
182    if (isset(\$context['loop']['length'])) {
183        --\$context['loop']['revindex0'];
184        --\$context['loop']['revindex'];
185        \$context['loop']['last'] = 0 === \$context['loop']['revindex0'];
186    }
187}
188if (!\$context['_iterated']) {
189    echo {$this->getVariableGetter('foo')};
190}
191\$_parent = \$context['_parent'];
192unset(\$context['_seq'], \$context['_iterated'], \$context['k'], \$context['v'], \$context['_parent'], \$context['loop']);
193\$context = array_intersect_key(\$context, \$_parent) + \$_parent;
194EOF
195        ];
196
197        return $tests;
198    }
199}
200