[TASK] Re-work/simplify copyright header in PHP files - Part 4
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / TypoScript / Parser / TypoScriptParserTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\TypoScript\Parser;
3
4 /**
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 /**
18 * Test case for \TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser
19 */
20 class TypoScriptParserTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
21
22 /**
23 * @var \TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
24 */
25 protected $typoScriptParser = NULL;
26
27 /**
28 * Set up
29 *
30 * @return void
31 */
32 protected function setUp() {
33 $accessibleClassName = $this->buildAccessibleProxy('TYPO3\\CMS\\Core\\TypoScript\\Parser\\TypoScriptParser');
34 $this->typoScriptParser = new $accessibleClassName();
35 }
36
37 /**
38 * Data provider for executeValueModifierReturnsModifiedResult
39 *
40 * @return array modifier name, modifier arguments, current value, expected result
41 */
42 public function executeValueModifierDataProvider() {
43 return array(
44 'prependString with string' => array(
45 'prependString',
46 'abc',
47 '!',
48 '!abc'
49 ),
50 'prependString with empty string' => array(
51 'prependString',
52 'foo',
53 '',
54 'foo',
55 ),
56 'appendString with string' => array(
57 'appendString',
58 'abc',
59 '!',
60 'abc!',
61 ),
62 'appendString with empty string' => array(
63 'appendString',
64 'abc',
65 '',
66 'abc',
67 ),
68 'removeString removes simple string' => array(
69 'removeString',
70 'abcdef',
71 'bc',
72 'adef',
73 ),
74 'removeString removes nothing if no match' => array(
75 'removeString',
76 'abcdef',
77 'foo',
78 'abcdef',
79 ),
80 'removeString removes multiple matches' => array(
81 'removeString',
82 'FooBarFoo',
83 'Foo',
84 'Bar',
85 ),
86 'replaceString replaces simple match' => array(
87 'replaceString',
88 'abcdef',
89 'bc|123',
90 'a123def',
91 ),
92 'replaceString replaces simple match with nothing' => array(
93 'replaceString',
94 'abcdef',
95 'bc',
96 'adef',
97 ),
98 'replaceString replaces multiple matches' => array(
99 'replaceString',
100 'FooBarFoo',
101 'Foo|Bar',
102 'BarBarBar',
103 ),
104 'addToList adds at end of existing list' => array(
105 'addToList',
106 '123,456',
107 '789',
108 '123,456,789',
109 ),
110 'addToList adds nothing' => array(
111 'addToList',
112 '123,456',
113 '',
114 '123,456,', // This result is probably not what we want (appended comma) ... fix it?
115 ),
116 'addToList adds to empty list' => array(
117 'addToList',
118 '',
119 'foo',
120 'foo',
121 ),
122 'removeFromList removes value from list' => array(
123 'removeFromList',
124 '123,456,789,abc',
125 '456',
126 '123,789,abc',
127 ),
128 'removeFromList removes value at beginning of list' => array(
129 'removeFromList',
130 '123,456,abc',
131 '123',
132 '456,abc',
133 ),
134 'removeFromList removes value at end of list' => array(
135 'removeFromList',
136 '123,456,abc',
137 'abc',
138 '123,456',
139 ),
140 'removeFromList removes multiple values from list' => array(
141 'removeFromList',
142 'foo,123,bar,123',
143 '123',
144 'foo,bar',
145 ),
146 'removeFromList removes empty values' => array(
147 'removeFromList',
148 'foo,,bar',
149 '',
150 'foo,bar',
151 ),
152 'uniqueList removes duplicates' => array(
153 'uniqueList',
154 '123,456,abc,456,456',
155 '',
156 '123,456,abc',
157 ),
158 'uniqueList removes duplicate empty list values' => array(
159 'uniqueList',
160 '123,,456,,abc',
161 '',
162 '123,,456,abc',
163 ),
164 'reverseList returns list reversed' => array(
165 'reverseList',
166 '123,456,abc,456',
167 '',
168 '456,abc,456,123',
169 ),
170 'reverseList keeps empty values' => array(
171 'reverseList',
172 ',123,,456,abc,,456',
173 '',
174 '456,,abc,456,,123,',
175 ),
176 'reverseList does not change single element' => array(
177 'reverseList',
178 '123',
179 '',
180 '123',
181 ),
182 'sortList sorts a list' => array(
183 'sortList',
184 '10,100,0,20,abc',
185 '',
186 '0,10,20,100,abc',
187 ),
188 'sortList sorts a list numeric' => array(
189 'sortList',
190 '10,0,100,-20,abc',
191 'numeric',
192 '-20,0,abc,10,100',
193 ),
194 'sortList sorts a list descending' => array(
195 'sortList',
196 '10,100,0,20,abc,-20',
197 'descending',
198 'abc,100,20,10,0,-20',
199 ),
200 'sortList sorts a list numeric descending' => array(
201 'sortList',
202 '10,100,0,20,abc,-20',
203 'descending,numeric',
204 '100,20,10,0,abc,-20',
205 ),
206 'sortList ignores invalid modifier arguments' => array(
207 'sortList',
208 '10,100,20',
209 'foo,descending,bar',
210 '100,20,10',
211 ),
212 );
213 }
214
215 /**
216 * @test
217 * @dataProvider executeValueModifierDataProvider
218 */
219 public function executeValueModifierReturnsModifiedResult($modifierName, $currentValue, $modifierArgument, $expected) {
220 $actualValue = $this->typoScriptParser->_call('executeValueModifier', $modifierName, $modifierArgument, $currentValue);
221 $this->assertEquals($expected, $actualValue);
222 }
223
224 /**
225 * @param string $typoScript
226 * @param array $expected
227 * @dataProvider typoScriptIsParsedToArrayDataProvider
228 * @test
229 */
230 public function typoScriptIsParsedToArray($typoScript, array $expected) {
231 $this->typoScriptParser->parse($typoScript);
232 $this->assertEquals($expected, $this->typoScriptParser->setup);
233 }
234
235 /**
236 * @return array
237 */
238 public function typoScriptIsParsedToArrayDataProvider() {
239 return array(
240 'simple assignment' => array(
241 'key = value',
242 array(
243 'key' => 'value',
244 )
245 ),
246 'simple assignment with escaped dot at the beginning' => array(
247 '\\.key = value',
248 array(
249 '.key' => 'value',
250 )
251 ),
252 'simple assignment with protected escaped dot at the beginning' => array(
253 '\\\\.key = value',
254 array(
255 '\\.' => array(
256 'key' => 'value',
257 ),
258 )
259 ),
260 'nested assignment' => array(
261 'lib.key = value',
262 array(
263 'lib.' => array(
264 'key' => 'value',
265 ),
266 ),
267 ),
268 'nested assignment with escaped key' => array(
269 'lib\\.key = value',
270 array(
271 'lib.key' => 'value',
272 ),
273 ),
274 'nested assignment with escaped key and escaped dot at the beginning' => array(
275 '\\.lib\\.key = value',
276 array(
277 '.lib.key' => 'value',
278 ),
279 ),
280 'nested assignment with protected escaped key' => array(
281 'lib\\\\.key = value',
282 array(
283 'lib\\.' => array('key' => 'value'),
284 ),
285 ),
286 'nested assignment with protected escaped key and protected escaped dot at the beginning' => array(
287 '\\\\.lib\\\\.key = value',
288 array(
289 '\\.' => array(
290 'lib\\.' => array('key' => 'value'),
291 ),
292 ),
293 ),
294 'assignment with escaped an non escaped keys' => array(
295 'firstkey.secondkey\\.thirdkey.setting = value',
296 array(
297 'firstkey.' => array(
298 'secondkey.thirdkey.' => array(
299 'setting' => 'value'
300 )
301 )
302 )
303 ),
304 'nested structured assignment' => array(
305 'lib {' . LF .
306 'key = value' . LF .
307 '}',
308 array(
309 'lib.' => array(
310 'key' => 'value',
311 ),
312 ),
313 ),
314 'nested structured assignment with escaped key inside' => array(
315 'lib {' . LF .
316 'key\\.nextkey = value' . LF .
317 '}',
318 array(
319 'lib.' => array(
320 'key.nextkey' => 'value',
321 ),
322 ),
323 ),
324 'nested structured assignment with escaped key inside and escaped dots at the beginning' => array(
325 '\\.lib {' . LF .
326 '\\.key\\.nextkey = value' . LF .
327 '}',
328 array(
329 '.lib.' => array(
330 '.key.nextkey' => 'value',
331 ),
332 ),
333 ),
334 'nested structured assignment with protected escaped key inside' => array(
335 'lib {' . LF .
336 'key\\\\.nextkey = value' . LF .
337 '}',
338 array(
339 'lib.' => array(
340 'key\\.' => array('nextkey' => 'value'),
341 ),
342 ),
343 ),
344 'nested structured assignment with protected escaped key inside and protected escaped dots at the beginning' => array(
345 '\\\\.lib {' . LF .
346 '\\\\.key\\\\.nextkey = value' . LF .
347 '}',
348 array(
349 '\\.' => array(
350 'lib.' => array(
351 '\\.' => array(
352 'key\\.' => array('nextkey' => 'value'),
353 ),
354 ),
355 ),
356 ),
357 ),
358 'nested structured assignment with escaped key' => array(
359 'lib\\.anotherkey {' . LF .
360 'key = value' . LF .
361 '}',
362 array(
363 'lib.anotherkey.' => array(
364 'key' => 'value',
365 ),
366 ),
367 ),
368 'nested structured assignment with protected escaped key' => array(
369 'lib\\\\.anotherkey {' . LF .
370 'key = value' . LF .
371 '}',
372 array(
373 'lib\\.' => array(
374 'anotherkey.' => array(
375 'key' => 'value',
376 ),
377 ),
378 ),
379 ),
380 'multiline assignment' => array(
381 'key (' . LF .
382 'first' . LF .
383 'second' . LF .
384 ')',
385 array(
386 'key' => 'first' . LF . 'second',
387 ),
388 ),
389 'multiline assignment with escaped key' => array(
390 'key\\.nextkey (' . LF .
391 'first' . LF .
392 'second' . LF .
393 ')',
394 array(
395 'key.nextkey' => 'first' . LF . 'second',
396 ),
397 ),
398 'multiline assignment with protected escaped key' => array(
399 'key\\\\.nextkey (' . LF .
400 'first' . LF .
401 'second' . LF .
402 ')',
403 array(
404 'key\\.' => array('nextkey' => 'first' . LF . 'second'),
405 ),
406 ),
407 'copying values' => array(
408 'lib.default = value' . LF .
409 'lib.copy < lib.default',
410 array(
411 'lib.' => array(
412 'default' => 'value',
413 'copy' => 'value',
414 ),
415 ),
416 ),
417 'copying values with escaped key' => array(
418 'lib\\.default = value' . LF .
419 'lib.copy < lib\\.default',
420 array(
421 'lib.default' => 'value',
422 'lib.' => array(
423 'copy' => 'value',
424 ),
425 ),
426 ),
427 'copying values with protected escaped key' => array(
428 'lib\\\\.default = value' . LF .
429 'lib.copy < lib\\\\.default',
430 array(
431 'lib\\.' => array('default' => 'value'),
432 'lib.' => array(
433 'copy' => 'value',
434 ),
435 ),
436 ),
437 'one-line hash comment' => array(
438 'first = 1' . LF .
439 '# ignore = me' . LF .
440 'second = 2',
441 array(
442 'first' => '1',
443 'second' => '2',
444 ),
445 ),
446 'one-line slash comment' => array(
447 'first = 1' . LF .
448 '// ignore = me' . LF .
449 'second = 2',
450 array(
451 'first' => '1',
452 'second' => '2',
453 ),
454 ),
455 'multi-line slash comment' => array(
456 'first = 1' . LF .
457 '/*' . LF .
458 'ignore = me' . LF .
459 '*/' . LF .
460 'second = 2',
461 array(
462 'first' => '1',
463 'second' => '2',
464 ),
465 ),
466 'nested assignment repeated segment names' => array(
467 'test.test.test = 1',
468 array(
469 'test.' => array(
470 'test.' => array(
471 'test' => '1',
472 ),
473 )
474 ),
475 ),
476 'simple assignment operator with tab character before "="' => array(
477 'test = someValue',
478 array(
479 'test' => 'someValue',
480 ),
481 ),
482 'simple assignment operator character as value "="' => array(
483 'test ==TEST=',
484 array(
485 'test' => '=TEST=',
486 ),
487 ),
488 'nested assignment operator character as value "="' => array(
489 'test.test ==TEST=',
490 array(
491 'test.' => array(
492 'test' => '=TEST=',
493 ),
494 ),
495 ),
496 'simple assignment character as value "<"' => array(
497 'test =<TEST>',
498 array(
499 'test' => '<TEST>',
500 ),
501 ),
502 'nested assignment character as value "<"' => array(
503 'test.test =<TEST>',
504 array(
505 'test.' => array(
506 'test' => '<TEST>',
507 ),
508 ),
509 ),
510 'simple assignment character as value ">"' => array(
511 'test =>TEST<',
512 array(
513 'test' => '>TEST<',
514 ),
515 ),
516 'nested assignment character as value ">"' => array(
517 'test.test =>TEST<',
518 array(
519 'test.' => array(
520 'test' => '>TEST<',
521 ),
522 ),
523 ),
524 'nested assignment repeated segment names with whitespaces' => array(
525 'test.test.test = 1' . " \t",
526 array(
527 'test.' => array(
528 'test.' => array(
529 'test' => '1',
530 ),
531 )
532 ),
533 ),
534 'simple assignment operator character as value "=" with whitespaces' => array(
535 'test = =TEST=' . " \t",
536 array(
537 'test' => '=TEST=',
538 ),
539 ),
540 'nested assignment operator character as value "=" with whitespaces' => array(
541 'test.test = =TEST=' . " \t",
542 array(
543 'test.' => array(
544 'test' => '=TEST=',
545 ),
546 ),
547 ),
548 'simple assignment character as value "<" with whitespaces' => array(
549 'test = <TEST>' . " \t",
550 array(
551 'test' => '<TEST>',
552 ),
553 ),
554 'nested assignment character as value "<" with whitespaces' => array(
555 'test.test = <TEST>' . " \t",
556 array(
557 'test.' => array(
558 'test' => '<TEST>',
559 ),
560 ),
561 ),
562 'simple assignment character as value ">" with whitespaces' => array(
563 'test = >TEST<' . " \t",
564 array(
565 'test' => '>TEST<',
566 ),
567 ),
568 'nested assignment character as value ">" with whitespaces' => array(
569 'test.test = >TEST<',
570 array(
571 'test.' => array(
572 'test' => '>TEST<',
573 ),
574 ),
575 ),
576 'CSC example #1' => array(
577 'linkParams.ATagParams.dataWrap = class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"',
578 array(
579 'linkParams.' => array(
580 'ATagParams.' => array(
581 'dataWrap' => 'class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"',
582 ),
583 ),
584 ),
585 ),
586 'CSC example #2' => array(
587 'linkParams.ATagParams {' . LF .
588 'dataWrap = class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"' . LF .
589 '}',
590 array(
591 'linkParams.' => array(
592 'ATagParams.' => array(
593 'dataWrap' => 'class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"',
594 ),
595 ),
596 ),
597 ),
598 'CSC example #3' => array(
599 'linkParams.ATagParams.dataWrap (' . LF .
600 'class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"' . LF .
601 ')',
602 array(
603 'linkParams.' => array(
604 'ATagParams.' => array(
605 'dataWrap' => 'class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"',
606 ),
607 ),
608 ),
609 ),
610 );
611 }
612
613 /**
614 * @test
615 */
616 public function setValCanBeCalledWithArrayValueParameter() {
617 $string = '';
618 $setup = array();
619 $value = array();
620 $this->typoScriptParser->setVal($string, $setup, $value);
621 }
622
623 /**
624 * @test
625 */
626 public function setValCanBeCalledWithStringValueParameter() {
627 $string = '';
628 $setup = array();
629 $value = '';
630 $this->typoScriptParser->setVal($string, $setup, $value);
631 }
632
633 /**
634 * @test
635 * @dataProvider parseNextKeySegmentReturnsCorrectNextKeySegmentDataProvider
636 */
637 public function parseNextKeySegmentReturnsCorrectNextKeySegment($key, $expectedKeySegment, $expectedRemainingKey) {
638 list($keySegment, $remainingKey) = $this->typoScriptParser->_call('parseNextKeySegment', $key);
639 $this->assertSame($expectedKeySegment, $keySegment);
640 $this->assertSame($expectedRemainingKey, $remainingKey);
641 }
642
643 /**
644 * @return array
645 */
646 public function parseNextKeySegmentReturnsCorrectNextKeySegmentDataProvider() {
647 return array(
648 'key without separator' => array(
649 'testkey',
650 'testkey',
651 ''
652 ),
653 'key with normal separator' => array(
654 'test.key',
655 'test',
656 'key'
657 ),
658 'key with multiple normal separators' => array(
659 'test.key.subkey',
660 'test',
661 'key.subkey'
662 ),
663 'key with separator and escape character' => array(
664 'te\\st.test',
665 'te\\st',
666 'test'
667 ),
668 'key with escaped separators' => array(
669 'test\\.key\\.subkey',
670 'test.key.subkey',
671 ''
672 ),
673 'key with escaped and unescaped separator 1' => array(
674 'test.test\\.key',
675 'test',
676 'test\\.key'
677 ),
678 'key with escaped and unescaped separator 2' => array(
679 'test\\.test.key\\.key2',
680 'test.test',
681 'key\\.key2'
682 ),
683 'key with escaped escape character' => array(
684 'test\\\\.key',
685 'test\\',
686 'key'
687 ),
688 'key with escaped separator and additional escape character' => array(
689 'test\\\\\\.key',
690 'test\\\\',
691 'key'
692 ),
693
694 'multiple escape characters within the key are preserved' => array(
695 'te\\\\st\\\\.key',
696 'te\\\\st\\',
697 'key'
698 )
699 );
700 }
701 }