3e7c22a5ae10dbcf23e061191e788c7222d24a7e
[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 * Copyright notice
6 *
7 * (c) 2013 Stefan Neufeind <info (at) speedpartner.de>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26
27 /**
28 * Test case for \TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser
29 */
30 class TypoScriptParserTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
31
32 /**
33 * @var \TYPO3\CMS\Core\TypoScript\Parser\TypoScriptParser|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
34 */
35 protected $typoScriptParser;
36
37 /**
38 * Set up
39 *
40 * @return void
41 */
42 protected function setUp() {
43 $accessibleClassName = $this->buildAccessibleProxy('TYPO3\\CMS\\Core\\TypoScript\\Parser\\TypoScriptParser');
44 $this->typoScriptParser = new $accessibleClassName();
45 }
46
47 /**
48 * Tear down
49 *
50 * @return void
51 */
52 protected function tearDown() {
53 unset($this->typoScriptParser);
54 }
55
56 /**
57 * Data provider for executeValueModifierReturnsModifiedResult
58 *
59 * @return array modifier name, modifier arguments, current value, expected result
60 */
61 public function executeValueModifierDataProvider() {
62 return array(
63 'prependString with string' => array(
64 'prependString',
65 'abc',
66 '!',
67 '!abc'
68 ),
69 'prependString with empty string' => array(
70 'prependString',
71 'foo',
72 '',
73 'foo',
74 ),
75 'appendString with string' => array(
76 'appendString',
77 'abc',
78 '!',
79 'abc!',
80 ),
81 'appendString with empty string' => array(
82 'appendString',
83 'abc',
84 '',
85 'abc',
86 ),
87 'removeString removes simple string' => array(
88 'removeString',
89 'abcdef',
90 'bc',
91 'adef',
92 ),
93 'removeString removes nothing if no match' => array(
94 'removeString',
95 'abcdef',
96 'foo',
97 'abcdef',
98 ),
99 'removeString removes multiple matches' => array(
100 'removeString',
101 'FooBarFoo',
102 'Foo',
103 'Bar',
104 ),
105 'replaceString replaces simple match' => array(
106 'replaceString',
107 'abcdef',
108 'bc|123',
109 'a123def',
110 ),
111 'replaceString replaces simple match with nothing' => array(
112 'replaceString',
113 'abcdef',
114 'bc',
115 'adef',
116 ),
117 'replaceString replaces multiple matches' => array(
118 'replaceString',
119 'FooBarFoo',
120 'Foo|Bar',
121 'BarBarBar',
122 ),
123 'addToList adds at end of existing list' => array(
124 'addToList',
125 '123,456',
126 '789',
127 '123,456,789',
128 ),
129 'addToList adds nothing' => array(
130 'addToList',
131 '123,456',
132 '',
133 '123,456,', // This result is probably not what we want (appended comma) ... fix it?
134 ),
135 'addToList adds to empty list' => array(
136 'addToList',
137 '',
138 'foo',
139 'foo',
140 ),
141 'removeFromList removes value from list' => array(
142 'removeFromList',
143 '123,456,789,abc',
144 '456',
145 '123,789,abc',
146 ),
147 'removeFromList removes value at beginning of list' => array(
148 'removeFromList',
149 '123,456,abc',
150 '123',
151 '456,abc',
152 ),
153 'removeFromList removes value at end of list' => array(
154 'removeFromList',
155 '123,456,abc',
156 'abc',
157 '123,456',
158 ),
159 'removeFromList removes multiple values from list' => array(
160 'removeFromList',
161 'foo,123,bar,123',
162 '123',
163 'foo,bar',
164 ),
165 'removeFromList removes empty values' => array(
166 'removeFromList',
167 'foo,,bar',
168 '',
169 'foo,bar',
170 ),
171 'uniqueList removes duplicates' => array(
172 'uniqueList',
173 '123,456,abc,456,456',
174 '',
175 '123,456,abc',
176 ),
177 'uniqueList removes duplicate empty list values' => array(
178 'uniqueList',
179 '123,,456,,abc',
180 '',
181 '123,,456,abc',
182 ),
183 'reverseList returns list reversed' => array(
184 'reverseList',
185 '123,456,abc,456',
186 '',
187 '456,abc,456,123',
188 ),
189 'reverseList keeps empty values' => array(
190 'reverseList',
191 ',123,,456,abc,,456',
192 '',
193 '456,,abc,456,,123,',
194 ),
195 'reverseList does not change single element' => array(
196 'reverseList',
197 '123',
198 '',
199 '123',
200 ),
201 'sortList sorts a list' => array(
202 'sortList',
203 '10,100,0,20,abc',
204 '',
205 '0,10,20,100,abc',
206 ),
207 'sortList sorts a list numeric' => array(
208 'sortList',
209 '10,0,100,-20,abc',
210 'numeric',
211 '-20,0,abc,10,100',
212 ),
213 'sortList sorts a list descending' => array(
214 'sortList',
215 '10,100,0,20,abc,-20',
216 'descending',
217 'abc,100,20,10,0,-20',
218 ),
219 'sortList sorts a list numeric descending' => array(
220 'sortList',
221 '10,100,0,20,abc,-20',
222 'descending,numeric',
223 '100,20,10,0,abc,-20',
224 ),
225 'sortList ignores invalid modifier arguments' => array(
226 'sortList',
227 '10,100,20',
228 'foo,descending,bar',
229 '100,20,10',
230 ),
231 );
232 }
233
234 /**
235 * @test
236 * @dataProvider executeValueModifierDataProvider
237 */
238 public function executeValueModifierReturnsModifiedResult($modifierName, $currentValue, $modifierArgument, $expected) {
239 $actualValue = $this->typoScriptParser->_call('executeValueModifier', $modifierName, $modifierArgument, $currentValue);
240 $this->assertEquals($expected, $actualValue);
241 }
242
243 /**
244 * @param string $typoScript
245 * @param array $expected
246 * @dataProvider typoScriptIsParsedToArrayDataProvider
247 * @test
248 */
249 public function typoScriptIsParsedToArray($typoScript, array $expected) {
250 $this->typoScriptParser->parse($typoScript);
251 $this->assertEquals($expected, $this->typoScriptParser->setup);
252 }
253
254 /**
255 * @return array
256 */
257 public function typoScriptIsParsedToArrayDataProvider() {
258 return array(
259 'simple assignment' => array(
260 'key = value',
261 array(
262 'key' => 'value',
263 )
264 ),
265 'nested assignment' => array(
266 'lib.key = value',
267 array(
268 'lib.' => array(
269 'key' => 'value',
270 ),
271 ),
272 ),
273 'nested structured assignment' => array(
274 'lib {' . LF .
275 'key = value' . LF .
276 '}',
277 array(
278 'lib.' => array(
279 'key' => 'value',
280 ),
281 ),
282 ),
283 'multiline assignment' => array(
284 'key (' . LF .
285 'first' . LF .
286 'second' . LF .
287 ')',
288 array(
289 'key' => 'first' . LF . 'second',
290 ),
291 ),
292 'copying values' => array(
293 'lib.default = value' . LF .
294 'lib.copy < lib.default',
295 array(
296 'lib.' => array(
297 'default' => 'value',
298 'copy' => 'value',
299 ),
300 ),
301 ),
302 'one-line hash comment' => array(
303 'first = 1' . LF .
304 '# ignore = me' . LF .
305 'second = 2',
306 array(
307 'first' => '1',
308 'second' => '2',
309 ),
310 ),
311 'one-line slash comment' => array(
312 'first = 1' . LF .
313 '// ignore = me' . LF .
314 'second = 2',
315 array(
316 'first' => '1',
317 'second' => '2',
318 ),
319 ),
320 'multi-line slash comment' => array(
321 'first = 1' . LF .
322 '/*' . LF .
323 'ignore = me' . LF .
324 '*/' . LF .
325 'second = 2',
326 array(
327 'first' => '1',
328 'second' => '2',
329 ),
330 ),
331 'nested assignment repeated segment names' => array(
332 'test.test.test = 1',
333 array(
334 'test.' => array(
335 'test.' => array(
336 'test' => '1',
337 ),
338 )
339 ),
340 ),
341 'simple assignment operator character as value "="' => array(
342 'test ==TEST=',
343 array(
344 'test' => '=TEST=',
345 ),
346 ),
347 'nested assignment operator character as value "="' => array(
348 'test.test ==TEST=',
349 array(
350 'test.' => array(
351 'test' => '=TEST=',
352 ),
353 ),
354 ),
355 'simple assignment character as value "<"' => array(
356 'test =<TEST>',
357 array(
358 'test' => '<TEST>',
359 ),
360 ),
361 'nested assignment character as value "<"' => array(
362 'test.test =<TEST>',
363 array(
364 'test.' => array(
365 'test' => '<TEST>',
366 ),
367 ),
368 ),
369 'simple assignment character as value ">"' => array(
370 'test =>TEST<',
371 array(
372 'test' => '>TEST<',
373 ),
374 ),
375 'nested assignment character as value ">"' => array(
376 'test.test =>TEST<',
377 array(
378 'test.' => array(
379 'test' => '>TEST<',
380 ),
381 ),
382 ),
383 'nested assignment repeated segment names with whitespaces' => array(
384 'test.test.test = 1' . " \t",
385 array(
386 'test.' => array(
387 'test.' => array(
388 'test' => '1',
389 ),
390 )
391 ),
392 ),
393 'simple assignment operator character as value "=" with whitespaces' => array(
394 'test = =TEST=' . " \t",
395 array(
396 'test' => '=TEST=',
397 ),
398 ),
399 'nested assignment operator character as value "=" with whitespaces' => array(
400 'test.test = =TEST=' . " \t",
401 array(
402 'test.' => array(
403 'test' => '=TEST=',
404 ),
405 ),
406 ),
407 'simple assignment character as value "<" with whitespaces' => array(
408 'test = <TEST>' . " \t",
409 array(
410 'test' => '<TEST>',
411 ),
412 ),
413 'nested assignment character as value "<" with whitespaces' => array(
414 'test.test = <TEST>' . " \t",
415 array(
416 'test.' => array(
417 'test' => '<TEST>',
418 ),
419 ),
420 ),
421 'simple assignment character as value ">" with whitespaces' => array(
422 'test = >TEST<' . " \t",
423 array(
424 'test' => '>TEST<',
425 ),
426 ),
427 'nested assignment character as value ">" with whitespaces' => array(
428 'test.test = >TEST<',
429 array(
430 'test.' => array(
431 'test' => '>TEST<',
432 ),
433 ),
434 ),
435 'CSC example #1' => array(
436 'linkParams.ATagParams.dataWrap = class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"',
437 array(
438 'linkParams.' => array(
439 'ATagParams.' => array(
440 'dataWrap' => 'class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"',
441 ),
442 ),
443 ),
444 ),
445 'CSC example #2' => array(
446 'linkParams.ATagParams {' . LF .
447 'dataWrap = class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"' . LF .
448 '}',
449 array(
450 'linkParams.' => array(
451 'ATagParams.' => array(
452 'dataWrap' => 'class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"',
453 ),
454 ),
455 ),
456 ),
457 'CSC example #3' => array(
458 'linkParams.ATagParams.dataWrap (' . LF .
459 'class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"' . LF .
460 ')',
461 array(
462 'linkParams.' => array(
463 'ATagParams.' => array(
464 'dataWrap' => 'class="{$styles.content.imgtext.linkWrap.lightboxCssClass}" rel="{$styles.content.imgtext.linkWrap.lightboxRelAttribute}"',
465 ),
466 ),
467 ),
468 ),
469 );
470 }
471
472 }