TYPO3 CMS  TYPO3_6-2
TypoScriptParserTest.php
Go to the documentation of this file.
1 <?php
3 
21 
25  protected $typoScriptParser = NULL;
26 
32  protected function setUp() {
33  $accessibleClassName = $this->buildAccessibleProxy('TYPO3\\CMS\\Core\\TypoScript\\Parser\\TypoScriptParser');
34  $this->typoScriptParser = new $accessibleClassName();
35  }
36 
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 at end of existing list including white-spaces' => array(
111  'addToList',
112  '123,456',
113  ' 789 , 32 , 12 ',
114  '123,456, 789 , 32 , 12 ',
115  ),
116  'addToList adds nothing' => array(
117  'addToList',
118  '123,456',
119  '',
120  '123,456,', // This result is probably not what we want (appended comma) ... fix it?
121  ),
122  'addToList adds to empty list' => array(
123  'addToList',
124  '',
125  'foo',
126  'foo',
127  ),
128  'removeFromList removes value from list' => array(
129  'removeFromList',
130  '123,456,789,abc',
131  '456',
132  '123,789,abc',
133  ),
134  'removeFromList removes value at beginning of list' => array(
135  'removeFromList',
136  '123,456,abc',
137  '123',
138  '456,abc',
139  ),
140  'removeFromList removes value at end of list' => array(
141  'removeFromList',
142  '123,456,abc',
143  'abc',
144  '123,456',
145  ),
146  'removeFromList removes multiple values from list' => array(
147  'removeFromList',
148  'foo,123,bar,123',
149  '123',
150  'foo,bar',
151  ),
152  'removeFromList removes empty values' => array(
153  'removeFromList',
154  'foo,,bar',
155  '',
156  'foo,bar',
157  ),
158  'uniqueList removes duplicates' => array(
159  'uniqueList',
160  '123,456,abc,456,456',
161  '',
162  '123,456,abc',
163  ),
164  'uniqueList removes duplicate empty list values' => array(
165  'uniqueList',
166  '123,,456,,abc',
167  '',
168  '123,,456,abc',
169  ),
170  'reverseList returns list reversed' => array(
171  'reverseList',
172  '123,456,abc,456',
173  '',
174  '456,abc,456,123',
175  ),
176  'reverseList keeps empty values' => array(
177  'reverseList',
178  ',123,,456,abc,,456',
179  '',
180  '456,,abc,456,,123,',
181  ),
182  'reverseList does not change single element' => array(
183  'reverseList',
184  '123',
185  '',
186  '123',
187  ),
188  'sortList sorts a list' => array(
189  'sortList',
190  '10,100,0,20,abc',
191  '',
192  '0,10,20,100,abc',
193  ),
194  'sortList sorts a list numeric' => array(
195  'sortList',
196  '10,0,100,-20,abc',
197  'numeric',
198  '-20,0,abc,10,100',
199  ),
200  'sortList sorts a list descending' => array(
201  'sortList',
202  '10,100,0,20,abc,-20',
203  'descending',
204  'abc,100,20,10,0,-20',
205  ),
206  'sortList sorts a list numeric descending' => array(
207  'sortList',
208  '10,100,0,20,abc,-20',
209  'descending,numeric',
210  '100,20,10,0,abc,-20',
211  ),
212  'sortList ignores invalid modifier arguments' => array(
213  'sortList',
214  '10,100,20',
215  'foo,descending,bar',
216  '100,20,10',
217  ),
218  );
219  }
220 
225  public function executeValueModifierReturnsModifiedResult($modifierName, $currentValue, $modifierArgument, $expected) {
226  $actualValue = $this->typoScriptParser->_call('executeValueModifier', $modifierName, $modifierArgument, $currentValue);
227  $this->assertEquals($expected, $actualValue);
228  }
229 
236  public function typoScriptIsParsedToArray($typoScript, array $expected) {
237  $this->typoScriptParser->parse($typoScript);
238  $this->assertEquals($expected, $this->typoScriptParser->setup);
239  }
240 
245  return array(
246  'simple assignment' => array(
247  'key = value',
248  array(
249  'key' => 'value',
250  )
251  ),
252  'simple assignment with escaped dot at the beginning' => array(
253  '\\.key = value',
254  array(
255  '.key' => 'value',
256  )
257  ),
258  'simple assignment with protected escaped dot at the beginning' => array(
259  '\\\\.key = value',
260  array(
261  '\\.' => array(
262  'key' => 'value',
263  ),
264  )
265  ),
266  'nested assignment' => array(
267  'lib.key = value',
268  array(
269  'lib.' => array(
270  'key' => 'value',
271  ),
272  ),
273  ),
274  'nested assignment with escaped key' => array(
275  'lib\\.key = value',
276  array(
277  'lib.key' => 'value',
278  ),
279  ),
280  'nested assignment with escaped key and escaped dot at the beginning' => array(
281  '\\.lib\\.key = value',
282  array(
283  '.lib.key' => 'value',
284  ),
285  ),
286  'nested assignment with protected escaped key' => array(
287  'lib\\\\.key = value',
288  array(
289  'lib\\.' => array('key' => 'value'),
290  ),
291  ),
292  'nested assignment with protected escaped key and protected escaped dot at the beginning' => array(
293  '\\\\.lib\\\\.key = value',
294  array(
295  '\\.' => array(
296  'lib\\.' => array('key' => 'value'),
297  ),
298  ),
299  ),
300  'assignment with escaped an non escaped keys' => array(
301  'firstkey.secondkey\\.thirdkey.setting = value',
302  array(
303  'firstkey.' => array(
304  'secondkey.thirdkey.' => array(
305  'setting' => 'value'
306  )
307  )
308  )
309  ),
310  'nested structured assignment' => array(
311  'lib {' . LF .
312  'key = value' . LF .
313  '}',
314  array(
315  'lib.' => array(
316  'key' => 'value',
317  ),
318  ),
319  ),
320  'nested structured assignment with escaped key inside' => array(
321  'lib {' . LF .
322  'key\\.nextkey = value' . LF .
323  '}',
324  array(
325  'lib.' => array(
326  'key.nextkey' => 'value',
327  ),
328  ),
329  ),
330  'nested structured assignment with escaped key inside and escaped dots at the beginning' => array(
331  '\\.lib {' . LF .
332  '\\.key\\.nextkey = value' . LF .
333  '}',
334  array(
335  '.lib.' => array(
336  '.key.nextkey' => 'value',
337  ),
338  ),
339  ),
340  'nested structured assignment with protected escaped key inside' => array(
341  'lib {' . LF .
342  'key\\\\.nextkey = value' . LF .
343  '}',
344  array(
345  'lib.' => array(
346  'key\\.' => array('nextkey' => 'value'),
347  ),
348  ),
349  ),
350  'nested structured assignment with protected escaped key inside and protected escaped dots at the beginning' => array(
351  '\\\\.lib {' . LF .
352  '\\\\.key\\\\.nextkey = value' . LF .
353  '}',
354  array(
355  '\\.' => array(
356  'lib.' => array(
357  '\\.' => array(
358  'key\\.' => array('nextkey' => 'value'),
359  ),
360  ),
361  ),
362  ),
363  ),
364  'nested structured assignment with escaped key' => array(
365  'lib\\.anotherkey {' . LF .
366  'key = value' . LF .
367  '}',
368  array(
369  'lib.anotherkey.' => array(
370  'key' => 'value',
371  ),
372  ),
373  ),
374  'nested structured assignment with protected escaped key' => array(
375  'lib\\\\.anotherkey {' . LF .
376  'key = value' . LF .
377  '}',
378  array(
379  'lib\\.' => array(
380  'anotherkey.' => array(
381  'key' => 'value',
382  ),
383  ),
384  ),
385  ),
386  'multiline assignment' => array(
387  'key (' . LF .
388  'first' . LF .
389  'second' . LF .
390  ')',
391  array(
392  'key' => 'first' . LF . 'second',
393  ),
394  ),
395  'multiline assignment with escaped key' => array(
396  'key\\.nextkey (' . LF .
397  'first' . LF .
398  'second' . LF .
399  ')',
400  array(
401  'key.nextkey' => 'first' . LF . 'second',
402  ),
403  ),
404  'multiline assignment with protected escaped key' => array(
405  'key\\\\.nextkey (' . LF .
406  'first' . LF .
407  'second' . LF .
408  ')',
409  array(
410  'key\\.' => array('nextkey' => 'first' . LF . 'second'),
411  ),
412  ),
413  'copying values' => array(
414  'lib.default = value' . LF .
415  'lib.copy < lib.default',
416  array(
417  'lib.' => array(
418  'default' => 'value',
419  'copy' => 'value',
420  ),
421  ),
422  ),
423  'copying values with escaped key' => array(
424  'lib\\.default = value' . LF .
425  'lib.copy < lib\\.default',
426  array(
427  'lib.default' => 'value',
428  'lib.' => array(
429  'copy' => 'value',
430  ),
431  ),
432  ),
433  'copying values with protected escaped key' => array(
434  'lib\\\\.default = value' . LF .
435  'lib.copy < lib\\\\.default',
436  array(
437  'lib\\.' => array('default' => 'value'),
438  'lib.' => array(
439  'copy' => 'value',
440  ),
441  ),
442  ),
443  'one-line hash comment' => array(
444  'first = 1' . LF .
445  '# ignore = me' . LF .
446  'second = 2',
447  array(
448  'first' => '1',
449  'second' => '2',
450  ),
451  ),
452  'one-line slash comment' => array(
453  'first = 1' . LF .
454  '// ignore = me' . LF .
455  'second = 2',
456  array(
457  'first' => '1',
458  'second' => '2',
459  ),
460  ),
461  'multi-line slash comment' => array(
462  'first = 1' . LF .
463  '/*' . LF .
464  'ignore = me' . LF .
465  '*/' . LF .
466  'second = 2',
467  array(
468  'first' => '1',
469  'second' => '2',
470  ),
471  ),
472  'nested assignment repeated segment names' => array(
473  'test.test.test = 1',
474  array(
475  'test.' => array(
476  'test.' => array(
477  'test' => '1',
478  ),
479  )
480  ),
481  ),
482  'simple assignment operator with tab character before "="' => array(
483  'test = someValue',
484  array(
485  'test' => 'someValue',
486  ),
487  ),
488  'simple assignment operator character as value "="' => array(
489  'test ==TEST=',
490  array(
491  'test' => '=TEST=',
492  ),
493  ),
494  'nested assignment operator character as value "="' => array(
495  'test.test ==TEST=',
496  array(
497  'test.' => array(
498  'test' => '=TEST=',
499  ),
500  ),
501  ),
502  'simple assignment character as value "<"' => array(
503  'test =<TEST>',
504  array(
505  'test' => '<TEST>',
506  ),
507  ),
508  'nested assignment character as value "<"' => array(
509  'test.test =<TEST>',
510  array(
511  'test.' => array(
512  'test' => '<TEST>',
513  ),
514  ),
515  ),
516  'simple assignment character as value ">"' => array(
517  'test =>TEST<',
518  array(
519  'test' => '>TEST<',
520  ),
521  ),
522  'nested assignment character as value ">"' => array(
523  'test.test =>TEST<',
524  array(
525  'test.' => array(
526  'test' => '>TEST<',
527  ),
528  ),
529  ),
530  'nested assignment repeated segment names with whitespaces' => array(
531  'test.test.test = 1' . " \t",
532  array(
533  'test.' => array(
534  'test.' => array(
535  'test' => '1',
536  ),
537  )
538  ),
539  ),
540  'simple assignment operator character as value "=" with whitespaces' => array(
541  'test = =TEST=' . " \t",
542  array(
543  'test' => '=TEST=',
544  ),
545  ),
546  'nested assignment operator character as value "=" with whitespaces' => array(
547  'test.test = =TEST=' . " \t",
548  array(
549  'test.' => array(
550  'test' => '=TEST=',
551  ),
552  ),
553  ),
554  'simple assignment character as value "<" with whitespaces' => array(
555  'test = <TEST>' . " \t",
556  array(
557  'test' => '<TEST>',
558  ),
559  ),
560  'nested assignment character as value "<" with whitespaces' => array(
561  'test.test = <TEST>' . " \t",
562  array(
563  'test.' => array(
564  'test' => '<TEST>',
565  ),
566  ),
567  ),
568  'simple assignment character as value ">" with whitespaces' => array(
569  'test = >TEST<' . " \t",
570  array(
571  'test' => '>TEST<',
572  ),
573  ),
574  'nested assignment character as value ">" with whitespaces' => array(
575  'test.test = >TEST<',
576  array(
577  'test.' => array(
578  'test' => '>TEST<',
579  ),
580  ),
581  ),
582  'CSC example #1' => array(
583  'linkParams.ATagParams.dataWrap = class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"',
584  array(
585  'linkParams.' => array(
586  'ATagParams.' => array(
587  'dataWrap' => 'class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"',
588  ),
589  ),
590  ),
591  ),
592  'CSC example #2' => array(
593  'linkParams.ATagParams {' . LF .
594  'dataWrap = class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"' . LF .
595  '}',
596  array(
597  'linkParams.' => array(
598  'ATagParams.' => array(
599  'dataWrap' => 'class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"',
600  ),
601  ),
602  ),
603  ),
604  'CSC example #3' => array(
605  'linkParams.ATagParams.dataWrap (' . LF .
606  'class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"' . LF .
607  ')',
608  array(
609  'linkParams.' => array(
610  'ATagParams.' => array(
611  'dataWrap' => 'class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"',
612  ),
613  ),
614  ),
615  ),
616  'key with colon' => array(
617  'some:key = is valid',
618  array(
619  'some:key' => 'is valid'
620  )
621  ),
622  'special operator' => array(
623  'some := addToList(a)',
624  array(
625  'some' => 'a'
626  )
627  ),
628  'special operator with white-spaces' => array(
629  'some := addToList (a)',
630  array(
631  'some' => 'a'
632  )
633  ),
634  'special operator with tabs' => array(
635  'some := addToList (a)',
636  array(
637  'some' => 'a'
638  )
639  ),
640  'special operator with white-spaces and tabs in value' => array(
641  'some := addToList( a, b, c )',
642  array(
643  'some' => 'a, b, c'
644  )
645  ),
646  'special operator and colon, no spaces' => array(
647  'some:key:=addToList(a)',
648  array(
649  'some:key' => 'a'
650  )
651  ),
652  'key with all special symbols' => array(
653  'someSpecial\\_:-\\.Chars = is valid',
654  array(
655  'someSpecial\\_:-.Chars' => 'is valid'
656  )
657  ),
658  );
659  }
660 
665  $string = '';
666  $setup = array();
667  $value = array();
668  $this->typoScriptParser->setVal($string, $setup, $value);
669  }
670 
675  $string = '';
676  $setup = array();
677  $value = '';
678  $this->typoScriptParser->setVal($string, $setup, $value);
679  }
680 
685  public function parseNextKeySegmentReturnsCorrectNextKeySegment($key, $expectedKeySegment, $expectedRemainingKey) {
686  list($keySegment, $remainingKey) = $this->typoScriptParser->_call('parseNextKeySegment', $key);
687  $this->assertSame($expectedKeySegment, $keySegment);
688  $this->assertSame($expectedRemainingKey, $remainingKey);
689  }
690 
695  return array(
696  'key without separator' => array(
697  'testkey',
698  'testkey',
699  ''
700  ),
701  'key with normal separator' => array(
702  'test.key',
703  'test',
704  'key'
705  ),
706  'key with multiple normal separators' => array(
707  'test.key.subkey',
708  'test',
709  'key.subkey'
710  ),
711  'key with separator and escape character' => array(
712  'te\\st.test',
713  'te\\st',
714  'test'
715  ),
716  'key with escaped separators' => array(
717  'test\\.key\\.subkey',
718  'test.key.subkey',
719  ''
720  ),
721  'key with escaped and unescaped separator 1' => array(
722  'test.test\\.key',
723  'test',
724  'test\\.key'
725  ),
726  'key with escaped and unescaped separator 2' => array(
727  'test\\.test.key\\.key2',
728  'test.test',
729  'key\\.key2'
730  ),
731  'key with escaped escape character' => array(
732  'test\\\\.key',
733  'test\\',
734  'key'
735  ),
736  'key with escaped separator and additional escape character' => array(
737  'test\\\\\\.key',
738  'test\\\\',
739  'key'
740  ),
741 
742  'multiple escape characters within the key are preserved' => array(
743  'te\\\\st\\\\.key',
744  'te\\\\st\\',
745  'key'
746  )
747  );
748  }
749 }
executeValueModifierReturnsModifiedResult($modifierName, $currentValue, $modifierArgument, $expected)
parseNextKeySegmentReturnsCorrectNextKeySegment($key, $expectedKeySegment, $expectedRemainingKey)