[CLEANUP] Rework/simplify copyright header and remove @package
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid / Tests / Unit / ViewHelpers / ForViewHelperTest.php
1 <?php
2 namespace TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers;
3
4 /* *
5 * This script is backported from the TYPO3 Flow package "TYPO3.Fluid". *
6 * *
7 * It is free software; you can redistribute it and/or modify it under *
8 * the terms of the GNU Lesser General Public License, either version 3 *
9 * of the License, or (at your option) any later version. *
10 * *
11 * The TYPO3 project - inspiring people to share! *
12 * */
13
14 /**
15 * Testcase for ForViewHelper
16 */
17 class ForViewHelperTest extends \TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\ViewHelperBaseTestcase {
18
19 public function setUp() {
20 parent::setUp();
21 $this->templateVariableContainer = new \TYPO3\CMS\Fluid\Core\ViewHelper\TemplateVariableContainer(array());
22 $this->renderingContext->injectTemplateVariableContainer($this->templateVariableContainer);
23
24 $this->arguments['reverse'] = NULL;
25 $this->arguments['key'] = '';
26 $this->arguments['iteration'] = NULL;
27 }
28
29 /**
30 * @test
31 */
32 public function renderExecutesTheLoopCorrectly() {
33 $viewHelper = new \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper();
34
35 $viewHelperNode = new \TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Fixtures\ConstraintSyntaxTreeNode($this->templateVariableContainer);
36 $this->arguments['each'] = array(0, 1, 2, 3);
37 $this->arguments['as'] = 'innerVariable';
38
39 $this->injectDependenciesIntoViewHelper($viewHelper);
40 $viewHelper->setViewHelperNode($viewHelperNode);
41 $viewHelper->render($this->arguments['each'], $this->arguments['as']);
42
43 $expectedCallProtocol = array(
44 array('innerVariable' => 0),
45 array('innerVariable' => 1),
46 array('innerVariable' => 2),
47 array('innerVariable' => 3)
48 );
49 $this->assertEquals($expectedCallProtocol, $viewHelperNode->callProtocol, 'The call protocol differs -> The for loop does not work as it should!');
50 }
51
52 /**
53 * @test
54 */
55 public function renderPreservesKeys() {
56 $viewHelper = new \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper();
57
58 $viewHelperNode = new \TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Fixtures\ConstraintSyntaxTreeNode($this->templateVariableContainer);
59
60 $this->arguments['each'] = array('key1' => 'value1', 'key2' => 'value2');
61 $this->arguments['as'] = 'innerVariable';
62 $this->arguments['key'] = 'someKey';
63
64 $this->injectDependenciesIntoViewHelper($viewHelper);
65 $viewHelper->setViewHelperNode($viewHelperNode);
66 $viewHelper->render($this->arguments['each'], $this->arguments['as'], $this->arguments['key']);
67
68 $expectedCallProtocol = array(
69 array(
70 'innerVariable' => 'value1',
71 'someKey' => 'key1'
72 ),
73 array(
74 'innerVariable' => 'value2',
75 'someKey' => 'key2'
76 )
77 );
78 $this->assertEquals($expectedCallProtocol, $viewHelperNode->callProtocol, 'The call protocol differs -> The for loop does not work as it should!');
79 }
80
81 /**
82 * @test
83 */
84 public function renderReturnsEmptyStringIfObjectIsNull() {
85 $viewHelper = new \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper();
86
87 $this->arguments['each'] = NULL;
88 $this->arguments['as'] = 'foo';
89
90 $this->injectDependenciesIntoViewHelper($viewHelper);
91
92 $this->assertEquals('', $viewHelper->render($this->arguments['each'], $this->arguments['as']));
93 }
94
95 /**
96 * @test
97 */
98 public function renderReturnsEmptyStringIfObjectIsEmptyArray() {
99 $viewHelper = new \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper();
100
101 $this->arguments['each'] = array();
102 $this->arguments['as'] = 'foo';
103
104 $this->injectDependenciesIntoViewHelper($viewHelper);
105
106 $this->assertEquals('', $viewHelper->render($this->arguments['each'], $this->arguments['as']));
107 }
108
109 /**
110 * @test
111 */
112 public function renderIteratesElementsInReverseOrderIfReverseIsTrue() {
113 $viewHelper = new \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper();
114
115 $viewHelperNode = new \TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Fixtures\ConstraintSyntaxTreeNode($this->templateVariableContainer);
116
117 $this->arguments['each'] = array(0, 1, 2, 3);
118 $this->arguments['as'] = 'innerVariable';
119 $this->arguments['reverse'] = TRUE;
120
121 $this->injectDependenciesIntoViewHelper($viewHelper);
122 $viewHelper->setViewHelperNode($viewHelperNode);
123 $viewHelper->render($this->arguments['each'], $this->arguments['as'], $this->arguments['key'], $this->arguments['reverse']);
124
125 $expectedCallProtocol = array(
126 array('innerVariable' => 3),
127 array('innerVariable' => 2),
128 array('innerVariable' => 1),
129 array('innerVariable' => 0)
130 );
131 $this->assertEquals($expectedCallProtocol, $viewHelperNode->callProtocol, 'The call protocol differs -> The for loop does not work as it should!');
132 }
133
134 /**
135 * @test
136 */
137 public function renderPreservesKeysIfReverseIsTrue() {
138 $viewHelper = new \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper();
139
140 $viewHelperNode = new \TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Fixtures\ConstraintSyntaxTreeNode($this->templateVariableContainer);
141
142 $this->arguments['each'] = array('key1' => 'value1', 'key2' => 'value2');
143 $this->arguments['as'] = 'innerVariable';
144 $this->arguments['key'] = 'someKey';
145 $this->arguments['reverse'] = TRUE;
146
147 $this->injectDependenciesIntoViewHelper($viewHelper);
148 $viewHelper->setViewHelperNode($viewHelperNode);
149 $viewHelper->render($this->arguments['each'], $this->arguments['as'], $this->arguments['key'], $this->arguments['reverse']);
150
151 $expectedCallProtocol = array(
152 array(
153 'innerVariable' => 'value2',
154 'someKey' => 'key2'
155 ),
156 array(
157 'innerVariable' => 'value1',
158 'someKey' => 'key1'
159 )
160 );
161 $this->assertEquals($expectedCallProtocol, $viewHelperNode->callProtocol, 'The call protocol differs -> The for loop does not work as it should!');
162 }
163
164 /**
165 * @test
166 */
167 public function keyContainsNumericalIndexIfTheGivenArrayDoesNotHaveAKey() {
168 $viewHelper = new \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper();
169
170 $viewHelperNode = new \TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Fixtures\ConstraintSyntaxTreeNode($this->templateVariableContainer);
171
172 $this->arguments['each'] = array('foo', 'bar', 'baz');
173 $this->arguments['as'] = 'innerVariable';
174 $this->arguments['key'] = 'someKey';
175
176 $this->injectDependenciesIntoViewHelper($viewHelper);
177 $viewHelper->setViewHelperNode($viewHelperNode);
178 $viewHelper->render($this->arguments['each'], $this->arguments['as'], $this->arguments['key']);
179
180 $expectedCallProtocol = array(
181 array(
182 'innerVariable' => 'foo',
183 'someKey' => 0
184 ),
185 array(
186 'innerVariable' => 'bar',
187 'someKey' => 1
188 ),
189 array(
190 'innerVariable' => 'baz',
191 'someKey' => 2
192 )
193 );
194 $this->assertSame($expectedCallProtocol, $viewHelperNode->callProtocol, 'The call protocol differs -> The for loop does not work as it should!');
195 }
196
197 /**
198 * @test
199 */
200 public function keyContainsNumericalIndexInAscendingOrderEvenIfReverseIsTrueIfTheGivenArrayDoesNotHaveAKey() {
201 $viewHelper = new \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper();
202
203 $viewHelperNode = new \TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Fixtures\ConstraintSyntaxTreeNode($this->templateVariableContainer);
204
205 $this->arguments['each'] = array('foo', 'bar', 'baz');
206 $this->arguments['as'] = 'innerVariable';
207 $this->arguments['key'] = 'someKey';
208 $this->arguments['reverse'] = TRUE;
209
210 $this->injectDependenciesIntoViewHelper($viewHelper);
211 $viewHelper->setViewHelperNode($viewHelperNode);
212 $viewHelper->render($this->arguments['each'], $this->arguments['as'], $this->arguments['key'], $this->arguments['reverse']);
213
214 $expectedCallProtocol = array(
215 array(
216 'innerVariable' => 'baz',
217 'someKey' => 0
218 ),
219 array(
220 'innerVariable' => 'bar',
221 'someKey' => 1
222 ),
223 array(
224 'innerVariable' => 'foo',
225 'someKey' => 2
226 )
227 );
228 $this->assertSame($expectedCallProtocol, $viewHelperNode->callProtocol, 'The call protocol differs -> The for loop does not work as it should!');
229 }
230
231 /**
232 * @test
233 * @expectedException \TYPO3\CMS\Fluid\Core\ViewHelper\Exception
234 */
235 public function renderThrowsExceptionWhenPassingObjectsToEachThatAreNotTraversable() {
236 $viewHelper = new \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper();
237 $object = new \stdClass();
238
239 $this->arguments['each'] = $object;
240 $this->arguments['as'] = 'innerVariable';
241 $this->arguments['key'] = 'someKey';
242 $this->arguments['reverse'] = TRUE;
243
244 $this->injectDependenciesIntoViewHelper($viewHelper);
245 $viewHelper->render($this->arguments['each'], $this->arguments['as'], $this->arguments['key']);
246 }
247
248
249 /**
250 * @test
251 */
252 public function renderIteratesThroughElementsOfTraversableObjects() {
253 $viewHelper = new \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper();
254
255 $viewHelperNode = new \TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Fixtures\ConstraintSyntaxTreeNode($this->templateVariableContainer);
256
257 $this->arguments['each'] = new \ArrayObject(array('key1' => 'value1', 'key2' => 'value2'));
258 $this->arguments['as'] = 'innerVariable';
259
260 $this->injectDependenciesIntoViewHelper($viewHelper);
261 $viewHelper->setViewHelperNode($viewHelperNode);
262 $viewHelper->render($this->arguments['each'], $this->arguments['as']);
263
264 $expectedCallProtocol = array(
265 array('innerVariable' => 'value1'),
266 array('innerVariable' => 'value2')
267 );
268 $this->assertEquals($expectedCallProtocol, $viewHelperNode->callProtocol, 'The call protocol differs -> The for loop does not work as it should!');
269 }
270
271 /**
272 * @test
273 */
274 public function renderPreservesKeyWhenIteratingThroughElementsOfObjectsThatImplementIteratorInterface() {
275 $viewHelper = new \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper();
276
277 $viewHelperNode = new \TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Fixtures\ConstraintSyntaxTreeNode($this->templateVariableContainer);
278
279 $this->arguments['each'] = new \ArrayIterator(array('key1' => 'value1', 'key2' => 'value2'));
280 $this->arguments['as'] = 'innerVariable';
281 $this->arguments['key'] = 'someKey';
282
283 $this->injectDependenciesIntoViewHelper($viewHelper);
284 $viewHelper->setViewHelperNode($viewHelperNode);
285 $viewHelper->render($this->arguments['each'], $this->arguments['as'], $this->arguments['key']);
286
287 $expectedCallProtocol = array(
288 array(
289 'innerVariable' => 'value1',
290 'someKey' => 'key1'
291 ),
292 array(
293 'innerVariable' => 'value2',
294 'someKey' => 'key2'
295 )
296 );
297 $this->assertEquals($expectedCallProtocol, $viewHelperNode->callProtocol, 'The call protocol differs -> The for loop does not work as it should!');
298 }
299
300 /**
301 * @test
302 */
303 public function keyContainsTheNumericalIndexWhenIteratingThroughElementsOfObjectsOfTyeSplObjectStorage() {
304 $viewHelper = new \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper();
305
306 $viewHelperNode = new \TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Fixtures\ConstraintSyntaxTreeNode($this->templateVariableContainer);
307
308 $splObjectStorageObject = new \SplObjectStorage();
309 $object1 = new \stdClass();
310 $splObjectStorageObject->attach($object1);
311 $object2 = new \stdClass();
312 $splObjectStorageObject->attach($object2, 'foo');
313 $object3 = new \stdClass();
314 $splObjectStorageObject->attach($object3, 'bar');
315
316 $this->arguments['each'] = $splObjectStorageObject;
317 $this->arguments['as'] = 'innerVariable';
318 $this->arguments['key'] = 'someKey';
319
320 $this->injectDependenciesIntoViewHelper($viewHelper);
321 $viewHelper->setViewHelperNode($viewHelperNode);
322 $viewHelper->render($this->arguments['each'], $this->arguments['as'], $this->arguments['key']);
323
324 $expectedCallProtocol = array(
325 array(
326 'innerVariable' => $object1,
327 'someKey' => 0
328 ),
329 array(
330 'innerVariable' => $object2,
331 'someKey' => 1
332 ),
333 array(
334 'innerVariable' => $object3,
335 'someKey' => 2
336 )
337 );
338 $this->assertSame($expectedCallProtocol, $viewHelperNode->callProtocol, 'The call protocol differs -> The for loop does not work as it should!');
339 }
340
341 /**
342 * @test
343 */
344 public function iterationDataIsAddedToTemplateVariableContainerIfIterationArgumentIsSet() {
345 $viewHelper = new \TYPO3\CMS\Fluid\ViewHelpers\ForViewHelper();
346
347 $viewHelperNode = new \TYPO3\CMS\Fluid\Tests\Unit\ViewHelpers\Fixtures\ConstraintSyntaxTreeNode($this->templateVariableContainer);
348
349 $this->arguments['each'] = array('foo' => 'bar', 'FLOW3' => 'Fluid', 'TYPO3' => 'rocks');
350 $this->arguments['as'] = 'innerVariable';
351 $this->arguments['iteration'] = 'iteration';
352
353 $this->injectDependenciesIntoViewHelper($viewHelper);
354 $viewHelper->setViewHelperNode($viewHelperNode);
355 $viewHelper->render($this->arguments['each'], $this->arguments['as'], $this->arguments['key'], $this->arguments['reverse'], $this->arguments['iteration']);
356
357 $expectedCallProtocol = array(
358 array(
359 'innerVariable' => 'bar',
360 'iteration' => array(
361 'index' => 0,
362 'cycle' => 1,
363 'total' => 3,
364 'isFirst' => TRUE,
365 'isLast' => FALSE,
366 'isEven' => FALSE,
367 'isOdd' => TRUE
368 )
369 ),
370 array(
371 'innerVariable' => 'Fluid',
372 'iteration' => array(
373 'index' => 1,
374 'cycle' => 2,
375 'total' => 3,
376 'isFirst' => FALSE,
377 'isLast' => FALSE,
378 'isEven' => TRUE,
379 'isOdd' => FALSE
380 )
381 ),
382 array(
383 'innerVariable' => 'rocks',
384 'iteration' => array(
385 'index' => 2,
386 'cycle' => 3,
387 'total' => 3,
388 'isFirst' => FALSE,
389 'isLast' => TRUE,
390 'isEven' => FALSE,
391 'isOdd' => TRUE
392 )
393 )
394 );
395 $this->assertSame($expectedCallProtocol, $viewHelperNode->callProtocol, 'The call protocol differs -> The for loop does not work as it should!');
396 }
397 }