56a9a270685d53d6f88a206d5dd4ddbbc123d3d8
[Packages/TYPO3.CMS.git] / typo3 / sysext / frontend / Tests / Unit / ContentObject / ContentObjectRendererTest.php
1 <?php
2 namespace TYPO3\CMS\Frontend\Tests\Unit\ContentObject;
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 use Psr\Log\LoggerInterface;
18 use TYPO3\CMS\Core\Charset\CharsetConverter;
19 use TYPO3\CMS\Core\Core\ApplicationContext;
20 use TYPO3\CMS\Core\Log\LogManager;
21 use TYPO3\CMS\Core\TypoScript\TemplateService;
22 use TYPO3\CMS\Core\Utility\DebugUtility;
23 use TYPO3\CMS\Core\Utility\GeneralUtility;
24 use TYPO3\CMS\Frontend\ContentObject\AbstractContentObject;
25 use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
26 use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
27 use TYPO3\CMS\Frontend\Tests\Unit\ContentObject\Fixtures\PageRepositoryFixture;
28 use TYPO3\CMS\Core\Cache\CacheManager;
29 use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface as CacheFrontendInterface;
30
31 /**
32 * Testcase for TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
33 */
34 class ContentObjectRendererTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
35 {
36 /**
37 * @var string
38 */
39 protected $currentLocale;
40
41 /**
42 * @var array A backup of registered singleton instances
43 */
44 protected $singletonInstances = array();
45
46 /**
47 * @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface|\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer
48 */
49 protected $subject = null;
50
51 /**
52 * @var \PHPUnit_Framework_MockObject_MockObject|TypoScriptFrontendController|\TYPO3\CMS\Core\Tests\AccessibleObjectInterface
53 */
54 protected $typoScriptFrontendControllerMock = null;
55
56 /**
57 * @var \PHPUnit_Framework_MockObject_MockObject|TemplateService
58 */
59 protected $templateServiceMock = null;
60
61 /**
62 * Default content object name -> class name map, shipped with TYPO3 CMS
63 *
64 * @var array
65 */
66 protected $contentObjectMap = array(
67 'TEXT' => \TYPO3\CMS\Frontend\ContentObject\TextContentObject::class,
68 'CASE' => \TYPO3\CMS\Frontend\ContentObject\CaseContentObject::class,
69 'COBJ_ARRAY' => \TYPO3\CMS\Frontend\ContentObject\ContentObjectArrayContentObject::class,
70 'COA' => \TYPO3\CMS\Frontend\ContentObject\ContentObjectArrayContentObject::class,
71 'COA_INT' => \TYPO3\CMS\Frontend\ContentObject\ContentObjectArrayInternalContentObject::class,
72 'USER' => \TYPO3\CMS\Frontend\ContentObject\UserContentObject::class,
73 'USER_INT' => \TYPO3\CMS\Frontend\ContentObject\UserInternalContentObject::class,
74 'FILE' => \TYPO3\CMS\Frontend\ContentObject\FileContentObject::class,
75 'FILES' => \TYPO3\CMS\Frontend\ContentObject\FilesContentObject::class,
76 'IMAGE' => \TYPO3\CMS\Frontend\ContentObject\ImageContentObject::class,
77 'IMG_RESOURCE' => \TYPO3\CMS\Frontend\ContentObject\ImageResourceContentObject::class,
78 'CONTENT' => \TYPO3\CMS\Frontend\ContentObject\ContentContentObject::class,
79 'RECORDS' => \TYPO3\CMS\Frontend\ContentObject\RecordsContentObject::class,
80 'HMENU' => \TYPO3\CMS\Frontend\ContentObject\HierarchicalMenuContentObject::class,
81 'CASEFUNC' => \TYPO3\CMS\Frontend\ContentObject\CaseContentObject::class,
82 'LOAD_REGISTER' => \TYPO3\CMS\Frontend\ContentObject\LoadRegisterContentObject::class,
83 'RESTORE_REGISTER' => \TYPO3\CMS\Frontend\ContentObject\RestoreRegisterContentObject::class,
84 'TEMPLATE' => \TYPO3\CMS\Frontend\ContentObject\TemplateContentObject::class,
85 'FLUIDTEMPLATE' => \TYPO3\CMS\Frontend\ContentObject\FluidTemplateContentObject::class,
86 'SVG' => \TYPO3\CMS\Frontend\ContentObject\ScalableVectorGraphicsContentObject::class,
87 'EDITPANEL' => \TYPO3\CMS\Frontend\ContentObject\EditPanelContentObject::class
88 );
89
90 /**
91 * Set up
92 */
93 protected function setUp()
94 {
95 $this->currentLocale = setlocale(LC_NUMERIC, 0);
96
97 $this->singletonInstances = \TYPO3\CMS\Core\Utility\GeneralUtility::getSingletonInstances();
98 $this->createMockedLoggerAndLogManager();
99
100 $this->templateServiceMock = $this->getMockBuilder(TemplateService::class)
101 ->setMethods(array('getFileName', 'linkData'))
102 ->getMock();
103 $pageRepositoryMock = $this->getMockBuilder(PageRepositoryFixture::class)
104 ->setMethods(array('getRawRecord', 'getMountPointInfo'))
105 ->getMock();
106
107 $this->typoScriptFrontendControllerMock = $this->getAccessibleMock(TypoScriptFrontendController::class, array('dummy'), array(), '', false);
108 $this->typoScriptFrontendControllerMock->tmpl = $this->templateServiceMock;
109 $this->typoScriptFrontendControllerMock->config = array();
110 $this->typoScriptFrontendControllerMock->page = array();
111 $this->typoScriptFrontendControllerMock->sys_page = $pageRepositoryMock;
112 $GLOBALS['TSFE'] = $this->typoScriptFrontendControllerMock;
113 $GLOBALS['TYPO3_DB'] = $this->getMockBuilder(\TYPO3\CMS\Core\Database\DatabaseConnection::class)->getMock();
114
115 $this->subject = $this->getAccessibleMock(
116 \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class,
117 array('getResourceFactory', 'getEnvironmentVariable'),
118 array($this->typoScriptFrontendControllerMock)
119 );
120 $this->subject->setContentObjectClassMap($this->contentObjectMap);
121 $this->subject->start(array(), 'tt_content');
122 }
123
124 protected function tearDown()
125 {
126 setlocale(LC_NUMERIC, $this->currentLocale);
127 GeneralUtility::resetSingletonInstances($this->singletonInstances);
128 parent::tearDown();
129 }
130
131 //////////////////////
132 // Utility functions
133 //////////////////////
134
135 /**
136 * Avoid logging to the file system (file writer is currently the only configured writer)
137 */
138 protected function createMockedLoggerAndLogManager()
139 {
140 $logManagerMock = $this->getMockBuilder(LogManager::class)->getMock();
141 $loggerMock = $this->getMockBuilder(LoggerInterface::class)->getMock();
142 $logManagerMock->expects($this->any())
143 ->method('getLogger')
144 ->willReturn($loggerMock);
145 GeneralUtility::setSingletonInstance(LogManager::class, $logManagerMock);
146 }
147
148 /**
149 * Converts the subject and the expected result into utf-8.
150 *
151 * @param string $subject the subject, will be modified
152 * @param string $expected the expected result, will be modified
153 */
154 protected function handleCharset(&$subject, &$expected)
155 {
156 $charsetConverter = new CharsetConverter();
157 $subject = $charsetConverter->conv($subject, 'iso-8859-1', 'utf-8');
158 $expected = $charsetConverter->conv($expected, 'iso-8859-1', 'utf-8');
159 }
160
161 /////////////////////////////////////////////
162 // Tests concerning the getImgResource hook
163 /////////////////////////////////////////////
164 /**
165 * @test
166 */
167 public function getImgResourceCallsGetImgResourcePostProcessHook()
168 {
169 $this->templateServiceMock
170 ->expects($this->atLeastOnce())
171 ->method('getFileName')
172 ->with('typo3/clear.gif')
173 ->will($this->returnValue('typo3/clear.gif'));
174
175 $resourceFactory = $this->createMock(\TYPO3\CMS\Core\Resource\ResourceFactory::class);
176 $this->subject->expects($this->any())->method('getResourceFactory')->will($this->returnValue($resourceFactory));
177
178 $className = $this->getUniqueId('tx_coretest');
179 $getImgResourceHookMock = $this->getMockBuilder(\TYPO3\CMS\Frontend\ContentObject\ContentObjectGetImageResourceHookInterface::class)
180 ->setMethods(array('getImgResourcePostProcess'))
181 ->setMockClassName($className)
182 ->getMock();
183 $getImgResourceHookMock
184 ->expects($this->once())
185 ->method('getImgResourcePostProcess')
186 ->will($this->returnCallback(array($this, 'isGetImgResourceHookCalledCallback')));
187 $getImgResourceHookObjects = array($getImgResourceHookMock);
188 $this->subject->_setRef('getImgResourceHookObjects', $getImgResourceHookObjects);
189 $this->subject->getImgResource('typo3/clear.gif', array());
190 }
191
192 /**
193 * Handles the arguments that have been sent to the getImgResource hook.
194 *
195 * @param string $file
196 * @param array $fileArray
197 * @param $imageResource
198 * @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $parent
199 * @return array
200 * @see getImgResourceHookGetsCalled
201 */
202 public function isGetImgResourceHookCalledCallback($file, $fileArray, $imageResource, $parent)
203 {
204 $this->assertEquals('typo3/clear.gif', $file);
205 $this->assertEquals('typo3/clear.gif', $imageResource['origFile']);
206 $this->assertTrue(is_array($fileArray));
207 $this->assertTrue($parent instanceof \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer);
208 return $imageResource;
209 }
210
211 //////////////////////////////////////
212 // Tests concerning getContentObject
213 //////////////////////////////////////
214
215 public function getContentObjectValidContentObjectsDataProvider()
216 {
217 $dataProvider = array();
218 foreach ($this->contentObjectMap as $name => $className) {
219 $dataProvider[] = array($name, $className);
220 }
221 return $dataProvider;
222 }
223
224 /**
225 * @test
226 * @dataProvider getContentObjectValidContentObjectsDataProvider
227 * @param string $name TypoScript name of content object
228 * @param string $fullClassName Expected class name
229 */
230 public function getContentObjectCallsMakeInstanceForNewContentObjectInstance($name, $fullClassName)
231 {
232 $contentObjectInstance = $this->createMock($fullClassName);
233 \TYPO3\CMS\Core\Utility\GeneralUtility::addInstance($fullClassName, $contentObjectInstance);
234 $this->assertSame($contentObjectInstance, $this->subject->getContentObject($name));
235 }
236
237 /////////////////////////////////////////
238 // Tests concerning getQueryArguments()
239 /////////////////////////////////////////
240 /**
241 * @test
242 */
243 public function getQueryArgumentsExcludesParameters()
244 {
245 $this->subject->expects($this->any())->method('getEnvironmentVariable')->with($this->equalTo('QUERY_STRING'))->will(
246 $this->returnValue('key1=value1&key2=value2&key3[key31]=value31&key3[key32][key321]=value321&key3[key32][key322]=value322')
247 );
248 $getQueryArgumentsConfiguration = array();
249 $getQueryArgumentsConfiguration['exclude'] = array();
250 $getQueryArgumentsConfiguration['exclude'][] = 'key1';
251 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
252 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
253 $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
254 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2&key3[key32][key322]=value322');
255 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
256 $this->assertEquals($expectedResult, $actualResult);
257 }
258
259 /**
260 * @test
261 */
262 public function getQueryArgumentsExcludesGetParameters()
263 {
264 $_GET = array(
265 'key1' => 'value1',
266 'key2' => 'value2',
267 'key3' => array(
268 'key31' => 'value31',
269 'key32' => array(
270 'key321' => 'value321',
271 'key322' => 'value322'
272 )
273 )
274 );
275 $getQueryArgumentsConfiguration = array();
276 $getQueryArgumentsConfiguration['method'] = 'GET';
277 $getQueryArgumentsConfiguration['exclude'] = array();
278 $getQueryArgumentsConfiguration['exclude'][] = 'key1';
279 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
280 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
281 $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
282 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2&key3[key32][key322]=value322');
283 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
284 $this->assertEquals($expectedResult, $actualResult);
285 }
286
287 /**
288 * @test
289 */
290 public function getQueryArgumentsOverrulesSingleParameter()
291 {
292 $this->subject->expects($this->any())->method('getEnvironmentVariable')->with($this->equalTo('QUERY_STRING'))->will(
293 $this->returnValue('key1=value1')
294 );
295 $getQueryArgumentsConfiguration = array();
296 $overruleArguments = array(
297 // Should be overridden
298 'key1' => 'value1Overruled',
299 // Shouldn't be set: Parameter doesn't exist in source array and is not forced
300 'key2' => 'value2Overruled'
301 );
302 $expectedResult = '&key1=value1Overruled';
303 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments);
304 $this->assertEquals($expectedResult, $actualResult);
305 }
306
307 /**
308 * @test
309 */
310 public function getQueryArgumentsOverrulesMultiDimensionalParameters()
311 {
312 $_POST = array(
313 'key1' => 'value1',
314 'key2' => 'value2',
315 'key3' => array(
316 'key31' => 'value31',
317 'key32' => array(
318 'key321' => 'value321',
319 'key322' => 'value322'
320 )
321 )
322 );
323 $getQueryArgumentsConfiguration = array();
324 $getQueryArgumentsConfiguration['method'] = 'POST';
325 $getQueryArgumentsConfiguration['exclude'] = array();
326 $getQueryArgumentsConfiguration['exclude'][] = 'key1';
327 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
328 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
329 $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
330 $overruleArguments = array(
331 // Should be overriden
332 'key2' => 'value2Overruled',
333 'key3' => array(
334 'key32' => array(
335 // Shouldn't be set: Parameter is excluded and not forced
336 'key321' => 'value321Overruled',
337 // Should be overriden: Parameter is not excluded
338 'key322' => 'value322Overruled',
339 // Shouldn't be set: Parameter doesn't exist in source array and is not forced
340 'key323' => 'value323Overruled'
341 )
342 )
343 );
344 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2Overruled&key3[key32][key322]=value322Overruled');
345 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments);
346 $this->assertEquals($expectedResult, $actualResult);
347 }
348
349 /**
350 * @test
351 */
352 public function getQueryArgumentsOverrulesMultiDimensionalForcedParameters()
353 {
354 $this->subject->expects($this->any())->method('getEnvironmentVariable')->with($this->equalTo('QUERY_STRING'))->will(
355 $this->returnValue('key1=value1&key2=value2&key3[key31]=value31&key3[key32][key321]=value321&key3[key32][key322]=value322')
356 );
357 $_POST = array(
358 'key1' => 'value1',
359 'key2' => 'value2',
360 'key3' => array(
361 'key31' => 'value31',
362 'key32' => array(
363 'key321' => 'value321',
364 'key322' => 'value322'
365 )
366 )
367 );
368 $getQueryArgumentsConfiguration = array();
369 $getQueryArgumentsConfiguration['exclude'] = array();
370 $getQueryArgumentsConfiguration['exclude'][] = 'key1';
371 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key31]';
372 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key321]';
373 $getQueryArgumentsConfiguration['exclude'][] = 'key3[key32][key322]';
374 $getQueryArgumentsConfiguration['exclude'] = implode(',', $getQueryArgumentsConfiguration['exclude']);
375 $overruleArguments = array(
376 // Should be overriden
377 'key2' => 'value2Overruled',
378 'key3' => array(
379 'key32' => array(
380 // Should be set: Parameter is excluded but forced
381 'key321' => 'value321Overruled',
382 // Should be set: Parameter doesn't exist in source array but is forced
383 'key323' => 'value323Overruled'
384 )
385 )
386 );
387 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key2=value2Overruled&key3[key32][key321]=value321Overruled&key3[key32][key323]=value323Overruled');
388 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments, true);
389 $this->assertEquals($expectedResult, $actualResult);
390 $getQueryArgumentsConfiguration['method'] = 'POST';
391 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration, $overruleArguments, true);
392 $this->assertEquals($expectedResult, $actualResult);
393 }
394
395 /**
396 * @test
397 */
398 public function getQueryArgumentsWithMethodPostGetMergesParameters()
399 {
400 $_POST = array(
401 'key1' => 'POST1',
402 'key2' => 'POST2',
403 'key3' => array(
404 'key31' => 'POST31',
405 'key32' => 'POST32',
406 'key33' => array(
407 'key331' => 'POST331',
408 'key332' => 'POST332',
409 )
410 )
411 );
412 $_GET = array(
413 'key2' => 'GET2',
414 'key3' => array(
415 'key32' => 'GET32',
416 'key33' => array(
417 'key331' => 'GET331',
418 )
419 )
420 );
421 $getQueryArgumentsConfiguration = array();
422 $getQueryArgumentsConfiguration['method'] = 'POST,GET';
423 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key1=POST1&key2=GET2&key3[key31]=POST31&key3[key32]=GET32&key3[key33][key331]=GET331&key3[key33][key332]=POST332');
424 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
425 $this->assertEquals($expectedResult, $actualResult);
426 }
427
428 /**
429 * @test
430 */
431 public function getQueryArgumentsWithMethodGetPostMergesParameters()
432 {
433 $_GET = array(
434 'key1' => 'GET1',
435 'key2' => 'GET2',
436 'key3' => array(
437 'key31' => 'GET31',
438 'key32' => 'GET32',
439 'key33' => array(
440 'key331' => 'GET331',
441 'key332' => 'GET332',
442 )
443 )
444 );
445 $_POST = array(
446 'key2' => 'POST2',
447 'key3' => array(
448 'key32' => 'POST32',
449 'key33' => array(
450 'key331' => 'POST331',
451 )
452 )
453 );
454 $getQueryArgumentsConfiguration = array();
455 $getQueryArgumentsConfiguration['method'] = 'GET,POST';
456 $expectedResult = $this->rawUrlEncodeSquareBracketsInUrl('&key1=GET1&key2=POST2&key3[key31]=GET31&key3[key32]=POST32&key3[key33][key331]=POST331&key3[key33][key332]=GET332');
457 $actualResult = $this->subject->getQueryArguments($getQueryArgumentsConfiguration);
458 $this->assertEquals($expectedResult, $actualResult);
459 }
460
461 /**
462 * Encodes square brackets in URL.
463 *
464 * @param string $string
465 * @return string
466 */
467 private function rawUrlEncodeSquareBracketsInUrl($string)
468 {
469 return str_replace(array('[', ']'), array('%5B', '%5D'), $string);
470 }
471
472 //////////////////////////
473 // Tests concerning crop
474 //////////////////////////
475 /**
476 * @test
477 */
478 public function cropIsMultibyteSafe()
479 {
480 $this->assertEquals('бла', $this->subject->crop('бла', '3|...'));
481 }
482
483 //////////////////////////////
484 // Tests concerning cropHTML
485 //////////////////////////////
486 /**
487 * This is the data provider for the tests of crop and cropHTML below. It provides all combinations
488 * of charset, text type, and configuration options to be tested.
489 *
490 * @return array two-dimensional array with the second level like this:
491 * @see cropHtmlWithDataProvider
492 */
493 public function cropHtmlDataProvider()
494 {
495 $plainText = 'Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j implemented the original version of the crop function.';
496 $textWithMarkup = '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a>' . ' implemented</strong> the original version of the crop function.';
497 $textWithEntities = 'Kasper Sk&aring;rh&oslash;j implemented the; original ' . 'version of the crop function.';
498 $data = array(
499 'plain text; 11|...' => array(
500 '11|...',
501 $plainText,
502 'Kasper Sk' . chr(229) . 'r...'
503 ),
504 'plain text; -58|...' => array(
505 '-58|...',
506 $plainText,
507 '...h' . chr(248) . 'j implemented the original version of the crop function.'
508 ),
509 'plain text; 4|...|1' => array(
510 '4|...|1',
511 $plainText,
512 'Kasp...'
513 ),
514 'plain text; 20|...|1' => array(
515 '20|...|1',
516 $plainText,
517 'Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j...'
518 ),
519 'plain text; -5|...|1' => array(
520 '-5|...|1',
521 $plainText,
522 '...tion.'
523 ),
524 'plain text; -49|...|1' => array(
525 '-49|...|1',
526 $plainText,
527 '...the original version of the crop function.'
528 ),
529 'text with markup; 11|...' => array(
530 '11|...',
531 $textWithMarkup,
532 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'r...</a></strong>'
533 ),
534 'text with markup; 13|...' => array(
535 '13|...',
536 $textWithMarkup,
537 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . '...</a></strong>'
538 ),
539 'text with markup; 14|...' => array(
540 '14|...',
541 $textWithMarkup,
542 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a>...</strong>'
543 ),
544 'text with markup; 15|...' => array(
545 '15|...',
546 $textWithMarkup,
547 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a> ...</strong>'
548 ),
549 'text with markup; 29|...' => array(
550 '29|...',
551 $textWithMarkup,
552 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a> implemented</strong> th...'
553 ),
554 'text with markup; -58|...' => array(
555 '-58|...',
556 $textWithMarkup,
557 '<strong><a href="mailto:kasper@typo3.org">...h' . chr(248) . 'j</a> implemented</strong> the original version of the crop function.'
558 ),
559 'text with markup 4|...|1' => array(
560 '4|...|1',
561 $textWithMarkup,
562 '<strong><a href="mailto:kasper@typo3.org">Kasp...</a></strong>'
563 ),
564 'text with markup; 11|...|1' => array(
565 '11|...|1',
566 $textWithMarkup,
567 '<strong><a href="mailto:kasper@typo3.org">Kasper...</a></strong>'
568 ),
569 'text with markup; 13|...|1' => array(
570 '13|...|1',
571 $textWithMarkup,
572 '<strong><a href="mailto:kasper@typo3.org">Kasper...</a></strong>'
573 ),
574 'text with markup; 14|...|1' => array(
575 '14|...|1',
576 $textWithMarkup,
577 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a>...</strong>'
578 ),
579 'text with markup; 15|...|1' => array(
580 '15|...|1',
581 $textWithMarkup,
582 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a>...</strong>'
583 ),
584 'text with markup; 29|...|1' => array(
585 '29|...|1',
586 $textWithMarkup,
587 '<strong><a href="mailto:kasper@typo3.org">Kasper Sk' . chr(229) . 'rh' . chr(248) . 'j</a> implemented</strong>...'
588 ),
589 'text with markup; -66|...|1' => array(
590 '-66|...|1',
591 $textWithMarkup,
592 '<strong><a href="mailto:kasper@typo3.org">...Sk' . chr(229) . 'rh' . chr(248) . 'j</a> implemented</strong> the original version of the crop function.'
593 ),
594 'text with entities 9|...' => array(
595 '9|...',
596 $textWithEntities,
597 'Kasper Sk...'
598 ),
599 'text with entities 10|...' => array(
600 '10|...',
601 $textWithEntities,
602 'Kasper Sk&aring;...'
603 ),
604 'text with entities 11|...' => array(
605 '11|...',
606 $textWithEntities,
607 'Kasper Sk&aring;r...'
608 ),
609 'text with entities 13|...' => array(
610 '13|...',
611 $textWithEntities,
612 'Kasper Sk&aring;rh&oslash;...'
613 ),
614 'text with entities 14|...' => array(
615 '14|...',
616 $textWithEntities,
617 'Kasper Sk&aring;rh&oslash;j...'
618 ),
619 'text with entities 15|...' => array(
620 '15|...',
621 $textWithEntities,
622 'Kasper Sk&aring;rh&oslash;j ...'
623 ),
624 'text with entities 16|...' => array(
625 '16|...',
626 $textWithEntities,
627 'Kasper Sk&aring;rh&oslash;j i...'
628 ),
629 'text with entities -57|...' => array(
630 '-57|...',
631 $textWithEntities,
632 '...j implemented the; original version of the crop function.'
633 ),
634 'text with entities -58|...' => array(
635 '-58|...',
636 $textWithEntities,
637 '...&oslash;j implemented the; original version of the crop function.'
638 ),
639 'text with entities -59|...' => array(
640 '-59|...',
641 $textWithEntities,
642 '...h&oslash;j implemented the; original version of the crop function.'
643 ),
644 'text with entities 4|...|1' => array(
645 '4|...|1',
646 $textWithEntities,
647 'Kasp...'
648 ),
649 'text with entities 9|...|1' => array(
650 '9|...|1',
651 $textWithEntities,
652 'Kasper...'
653 ),
654 'text with entities 10|...|1' => array(
655 '10|...|1',
656 $textWithEntities,
657 'Kasper...'
658 ),
659 'text with entities 11|...|1' => array(
660 '11|...|1',
661 $textWithEntities,
662 'Kasper...'
663 ),
664 'text with entities 13|...|1' => array(
665 '13|...|1',
666 $textWithEntities,
667 'Kasper...'
668 ),
669 'text with entities 14|...|1' => array(
670 '14|...|1',
671 $textWithEntities,
672 'Kasper Sk&aring;rh&oslash;j...'
673 ),
674 'text with entities 15|...|1' => array(
675 '15|...|1',
676 $textWithEntities,
677 'Kasper Sk&aring;rh&oslash;j...'
678 ),
679 'text with entities 16|...|1' => array(
680 '16|...|1',
681 $textWithEntities,
682 'Kasper Sk&aring;rh&oslash;j...'
683 ),
684 'text with entities -57|...|1' => array(
685 '-57|...|1',
686 $textWithEntities,
687 '...implemented the; original version of the crop function.'
688 ),
689 'text with entities -58|...|1' => array(
690 '-58|...|1',
691 $textWithEntities,
692 '...implemented the; original version of the crop function.'
693 ),
694 'text with entities -59|...|1' => array(
695 '-59|...|1',
696 $textWithEntities,
697 '...implemented the; original version of the crop function.'
698 ),
699 'text with dash in html-element 28|...|1' => array(
700 '28|...|1',
701 'Some text with a link to <link email.address@example.org - mail "Open email window">my email.address@example.org</link> and text after it',
702 'Some text with a link to <link email.address@example.org - mail "Open email window">my...</link>'
703 ),
704 'html elements with dashes in attributes' => array(
705 '9',
706 '<em data-foo="x">foobar</em>foobaz',
707 '<em data-foo="x">foobar</em>foo'
708 ),
709 'html elements with iframe embedded 24|...|1' => array(
710 '24|...|1',
711 'Text with iframe <iframe src="//what.ever/"></iframe> and text after it',
712 'Text with iframe <iframe src="//what.ever/"></iframe> and...'
713 ),
714 'html elements with script tag embedded 24|...|1' => array(
715 '24|...|1',
716 'Text with script <script>alert(\'foo\');</script> and text after it',
717 'Text with script <script>alert(\'foo\');</script> and...'
718 )
719 );
720 return $data;
721 }
722
723 /**
724 * Checks if stdWrap.cropHTML works with plain text cropping from left
725 *
726 * @test
727 * @dataProvider cropHtmlDataProvider
728 * @param string $settings
729 * @param string $subject the string to crop
730 * @param string $expected the expected cropped result
731 */
732 public function cropHtmlWithDataProvider($settings, $subject, $expected)
733 {
734 $this->handleCharset($subject, $expected);
735 $this->assertEquals($expected, $this->subject->cropHTML($subject, $settings), 'cropHTML failed with settings: "' . $settings . '"');
736 }
737
738 /**
739 * Checks if stdWrap.cropHTML works with a complex content with many tags. Currently cropHTML
740 * counts multiple invisible characters not as one (as the browser will output the content).
741 *
742 * @test
743 */
744 public function cropHtmlWorksWithComplexContent()
745 {
746 $input =
747 '<h1>Blog Example</h1>' . LF .
748 '<hr>' . LF .
749 '<div class="csc-header csc-header-n1">' . LF .
750 ' <h2 class="csc-firstHeader">Welcome to Blog #1</h2>' . LF .
751 '</div>' . LF .
752 '<p class="bodytext">' . LF .
753 ' A blog about TYPO3 extension development. In order to start blogging, read the <a href="#">Help section</a>. If you have any further questions, feel free to contact the administrator John Doe (<a href="mailto:john.doe@example.com">john.doe@example.com)</a>.' . LF .
754 '</p>' . LF .
755 '<div class="tx-blogexample-list-container">' . LF .
756 ' <p class="bodytext">' . LF .
757 ' Below are the most recent posts:' . LF .
758 ' </p>' . LF .
759 ' <ul>' . LF .
760 ' <li data-element="someId">' . LF .
761 ' <h3>' . LF .
762 ' <a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog]=&amp;tx_blogexample_pi1[action]=show&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=003b0131ed">The Post #1</a>' . LF .
763 ' </h3>' . LF .
764 ' <p class="bodytext">' . LF .
765 ' Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut...' . LF .
766 ' </p>' . LF .
767 ' <p class="metadata">' . LF .
768 ' Published on 26.08.2009 by Jochen Rau' . LF .
769 ' </p>' . LF .
770 ' <p>' . LF .
771 ' Tags: [MVC]&nbsp;[Domain Driven Design]&nbsp;<br>' . LF .
772 ' <a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[action]=show&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=f982643bc3">read more &gt;&gt;</a><br>' . LF .
773 ' <a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=edit&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=5b481bc8f0">Edit</a>&nbsp;<a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=delete&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=4e52879656">Delete</a>' . LF .
774 ' </p>' . LF .
775 ' </li>' . LF .
776 ' </ul>' . LF .
777 ' <p>' . LF .
778 ' <a href="index.php?id=99&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=new&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=2718a4b1a0">Create a new Post</a>' . LF .
779 ' </p>' . LF .
780 '</div>' . LF .
781 '<hr>' . LF .
782 '<p>' . LF .
783 ' ? TYPO3 Association' . LF .
784 '</p>';
785
786 $result = $this->subject->cropHTML($input, '300');
787
788 $expected =
789 '<h1>Blog Example</h1>' . LF .
790 '<hr>' . LF .
791 '<div class="csc-header csc-header-n1">' . LF .
792 ' <h2 class="csc-firstHeader">Welcome to Blog #1</h2>' . LF .
793 '</div>' . LF .
794 '<p class="bodytext">' . LF .
795 ' A blog about TYPO3 extension development. In order to start blogging, read the <a href="#">Help section</a>. If you have any further questions, feel free to contact the administrator John Doe (<a href="mailto:john.doe@example.com">john.doe@example.com)</a>.' . LF .
796 '</p>' . LF .
797 '<div class="tx-blogexample-list-container">' . LF .
798 ' <p class="bodytext">' . LF .
799 ' Below are the most recent posts:' . LF .
800 ' </p>' . LF .
801 ' <ul>' . LF .
802 ' <li data-element="someId">' . LF .
803 ' <h3>' . LF .
804 ' <a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog]=&amp;tx_blogexample_pi1[action]=show&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=003b0131ed">The Post</a></h3></li></ul></div>';
805
806 $this->assertEquals($expected, $result);
807
808 $result = $this->subject->cropHTML($input, '-100');
809
810 $expected =
811 '<div class="tx-blogexample-list-container"><ul><li data-element="someId"><p> Design]&nbsp;<br>' . LF .
812 ' <a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[action]=show&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=f982643bc3">read more &gt;&gt;</a><br>' . LF .
813 ' <a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=edit&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=5b481bc8f0">Edit</a>&nbsp;<a href="index.php?id=99&amp;tx_blogexample_pi1[post][uid]=211&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=delete&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=4e52879656">Delete</a>' . LF .
814 ' </p>' . LF .
815 ' </li>' . LF .
816 ' </ul>' . LF .
817 ' <p>' . LF .
818 ' <a href="index.php?id=99&amp;tx_blogexample_pi1[blog][uid]=70&amp;tx_blogexample_pi1[action]=new&amp;tx_blogexample_pi1[controller]=Post&amp;cHash=2718a4b1a0">Create a new Post</a>' . LF .
819 ' </p>' . LF .
820 '</div>' . LF .
821 '<hr>' . LF .
822 '<p>' . LF .
823 ' ? TYPO3 Association' . LF .
824 '</p>';
825
826 $this->assertEquals($expected, $result);
827 }
828
829 /**
830 * Checks if stdWrap.cropHTML handles linebreaks correctly (by ignoring them)
831 *
832 * @test
833 */
834 public function cropHtmlWorksWithLinebreaks()
835 {
836 $subject = "Lorem ipsum dolor sit amet,\nconsetetur sadipscing elitr,\nsed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam";
837 $expected = "Lorem ipsum dolor sit amet,\nconsetetur sadipscing elitr,\nsed diam nonumy eirmod tempor invidunt ut labore et dolore magna";
838 $result = $this->subject->cropHTML($subject, '121');
839 $this->assertEquals($expected, $result);
840 }
841
842 /**
843 * Data provider for stdWrap_cacheRead
844 *
845 * @return array Order: expect, input, conf, times, with, will
846 */
847 public function stdWrap_cacheReadDataProvider()
848 {
849 $cacheConf = [$this->getUniqueId('cache.')];
850 $conf = ['cache.' => $cacheConf];
851 return [
852 'no conf' => [
853 'content', 'content', [],
854 0, null, null,
855 ],
856 'no cache. conf' => [
857 'content', 'content', ['otherConf' => 1],
858 0, null, null,
859 ],
860 'non-cached simulation' => [
861 'content', 'content', $conf,
862 1, $cacheConf, false,
863 ],
864 'cached simulation' => [
865 'cachedContent', 'content', $conf,
866 1, $cacheConf, 'cachedContent',
867 ],
868 ];
869 }
870
871 /**
872 * Check if stdWrap_cacheRead works properly.
873 *
874 * - the method branches correctly
875 * - getFromCache is called to fetch from cache
876 * - $conf['cache.'] is passed on as parameter
877 *
878 * @test
879 * @dataProvider stdWrap_cacheReadDataProvider
880 * @param string $expect Expected result.
881 * @param string $input Given input string.
882 * @param array $conf Property 'cache.'
883 * @param integer $times Times called mocked method.
884 * @param array $with Parameter passed to mocked method.
885 * @param string|false $will Return value of mocked method.
886 * @return void
887 */
888 public function stdWrap_cacheRead(
889 $expect, $input, $conf, $times, $with, $will)
890 {
891 $subject = $this->getAccessibleMock(
892 ContentObjectRenderer::class, ['getFromCache']);
893 $subject
894 ->expects($this->exactly($times))
895 ->method('getFromCache')
896 ->with($with)
897 ->willReturn($will);
898 $this->assertSame($expect,
899 $subject->stdWrap_cacheRead($input, $conf));
900 }
901
902 /**
903 * Check if stdWrap_setContentToCurrent works properly.
904 *
905 * @test
906 * @return void
907 */
908 public function stdWrap_setContentToCurrent()
909 {
910 $content = $this->getUniqueId('content');
911 $this->assertNotSame($content, $this->subject->getData('current'));
912 $this->assertSame($content,
913 $this->subject->stdWrap_setContentToCurrent($content));
914 $this->assertSame($content, $this->subject->getData('current'));
915 }
916
917 /**
918 * Data provider for stdWrap_setCurrent
919 *
920 * @return array Order input, conf
921 */
922 public function stdWrap_setCurrentDataProvider()
923 {
924 return [
925 'no conf' => [
926 'content',
927 [],
928 ],
929 'empty string' => [
930 'content',
931 ['setCurrent' => ''],
932 ],
933 'non-empty string' => [
934 'content',
935 ['setCurrent' => 'xxx'],
936 ],
937 'integer null' => [
938 'content',
939 ['setCurrent' => 0],
940 ],
941 'integer not null' => [
942 'content',
943 ['setCurrent' => 1],
944 ],
945 'boolean true' => [
946 'content',
947 ['setCurrent' => true],
948 ],
949 'boolean false' => [
950 'content',
951 ['setCurrent' => false],
952 ],
953 ];
954 }
955
956 /**
957 * Check if stdWrap_setCurrent works properly.
958 *
959 * @test
960 * @dataProvider stdWrap_setCurrentDataProvider
961 * @param string $input The input value.
962 * @param array $conf Property: setCurrent
963 * @return void
964 */
965 public function stdWrap_setCurrent($input, $conf)
966 {
967 if (isset($conf['setCurrent'])) {
968 $this->assertNotSame($conf['setCurrent'], $this->subject->getData('current'));
969 }
970 $this->assertSame($input, $this->subject->stdWrap_setCurrent($input, $conf));
971 if (isset($conf['setCurrent'])) {
972 $this->assertSame($conf['setCurrent'], $this->subject->getData('current'));
973 }
974 }
975
976 /**
977 * Data provider for stdWrap_data.
978 *
979 * @return array [$expect, $data, $alt]
980 */
981 public function stdWrap_dataDataProvider()
982 {
983 $data = [$this->getUniqueId('data')];
984 $alt = [$this->getUniqueId('alternativeData')];
985 return [
986 'default' => [$data, $data, ''],
987 'alt is array' => [$alt, $data, $alt],
988 'alt is empty array' => [[], $data, []],
989 'alt null' => [$data, $data, null],
990 'alt string' => [$data, $data, 'xxx'],
991 'alt int' => [$data, $data, 1],
992 'alt bool' => [$data, $data, true],
993 ];
994 }
995
996 /**
997 * Checks that stdWrap_data works properly.
998 *
999 * Show:
1000 *
1001 * - Delegates to method getData.
1002 * - Parameter 1 is $conf['data'].
1003 * - Parameter 2 is property data by default.
1004 * - Parameter 2 is property alternativeData, if set as array.
1005 * - Property alternativeData is always unset to ''.
1006 * - Returns the return value.
1007 *
1008 * @test
1009 * @dataProvider stdWrap_dataDataProvider
1010 * @param mixed $expect Expect either $data or $alternativeData.
1011 * @param array $data The data.
1012 * @param mixed $alt The alternativeData.
1013 * @return void
1014 */
1015 public function stdWrap_data($expect, $data, $alt)
1016 {
1017 $conf = ['data' => $this->getUniqueId('conf.data')];
1018 $return = $this->getUniqueId('return');
1019 $subject = $this->getAccessibleMock(
1020 ContentObjectRenderer::class, ['getData']);
1021 $subject->_set('data', $data);
1022 $subject->_set('alternativeData', $alt);
1023 $subject
1024 ->expects($this->once())
1025 ->method('getData')
1026 ->with($conf['data'], $expect)
1027 ->willReturn($return);
1028 $this->assertSame($return, $subject->stdWrap_data('discard', $conf));
1029 $this->assertSame('', $subject->_get('alternativeData'));
1030 }
1031
1032 /**
1033 * Check if stdWrap_preIfEmptyListNum works properly.
1034 *
1035 * Show:
1036 *
1037 * - Delegates to method listNum.
1038 * - Parameter 1 is $content.
1039 * - Parameter 2 is $conf['preIfEmptyListNum'].
1040 * - Parameter 3 is $conf['preIfEmptyListNum.']['splitChar'].
1041 * - Returns the return value.
1042 *
1043 * @test
1044 * @return void
1045 */
1046 public function stdWrap_preIfEmptyListNum()
1047 {
1048 $content = $this->getUniqueId('content');
1049 $conf = [
1050 'preIfEmptyListNum' => $this->getUniqueId('preIfEmptyListNum'),
1051 'preIfEmptyListNum.' => [
1052 'splitChar' => $this->getUniqueId('splitChar')
1053 ],
1054 ];
1055 $return = $this->getUniqueId('return');
1056 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1057 ->setMethods(['listNum'])->getMock();
1058 $subject
1059 ->expects($this->once())
1060 ->method('listNum')
1061 ->with(
1062 $content,
1063 $conf['preIfEmptyListNum'],
1064 $conf['preIfEmptyListNum.']['splitChar']
1065 )
1066 ->willReturn($return);
1067 $this->assertSame($return,
1068 $subject->stdWrap_preIfEmptyListNum($content, $conf));
1069 }
1070
1071 /**
1072 * Check if stdWrap_current works properly.
1073 *
1074 * Show:
1075 *
1076 * - current is returned from $this->data
1077 * - the key is stored in $this->currentValKey
1078 * - the key defaults to 'currentValue_kidjls9dksoje'
1079 *
1080 * @test
1081 * @return void
1082 */
1083 public function stdWrap_current()
1084 {
1085 $data = [
1086 'currentValue_kidjls9dksoje' => 'default',
1087 'currentValue_new' => 'new',
1088 ];
1089 $this->subject->_set('data', $data);
1090 $this->assertSame('currentValue_kidjls9dksoje',
1091 $this->subject->_get('currentValKey'));
1092 $this->assertSame('default',
1093 $this->subject->stdWrap_current('discarded', ['discarded']));
1094 $this->subject->_set('currentValKey', 'currentValue_new');
1095 $this->assertSame('new',
1096 $this->subject->stdWrap_current('discarded', ['discarded']));
1097 }
1098
1099 /**
1100 * Check if stdWrap_preUserFunc works properly.
1101 *
1102 * Show:
1103 *
1104 * - Delegates to method callUserFunction.
1105 * - Parameter 1 is $conf['preUserFunc'].
1106 * - Parameter 2 is $conf['preUserFunc.'].
1107 * - Parameter 3 is $content.
1108 * - Returns the return value.
1109 *
1110 * @test
1111 * @return void
1112 */
1113 public function stdWrap_preUserFunc()
1114 {
1115 $content = $this->getUniqueId('content');
1116 $conf = [
1117 'preUserFunc' => $this->getUniqueId('preUserFunc'),
1118 'preUserFunc.' => [$this->getUniqueId('preUserFunc.')],
1119 ];
1120 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1121 ->setMethods(['callUserFunction'])->getMock();
1122 $subject->expects($this->once())->method('callUserFunction')
1123 ->with($conf['preUserFunc'], $conf['preUserFunc.'], $content)
1124 ->willReturn('return');
1125 $this->assertSame('return',
1126 $subject->stdWrap_preUserFunc($content, $conf));
1127 }
1128
1129 /**
1130 * Data provider for stdWrap_csConv
1131 *
1132 * @return array Order expected, input, conf
1133 */
1134 public function stdWrap_overrideDataProvider()
1135 {
1136 return [
1137 'standard case' => [
1138 'override', 'content', ['override' => 'override']
1139 ],
1140 'empty conf does not override' => [
1141 'content', 'content', []
1142 ],
1143 'empty string does not override' => [
1144 'content', 'content', ['override' => '']
1145 ],
1146 'whitespace does not override' => [
1147 'content', 'content', ['override' => ' ' . TAB]
1148 ],
1149 'zero does not override' => [
1150 'content', 'content', ['override' => 0]
1151 ],
1152 'false does not override' => [
1153 'content', 'content', ['override' => false]
1154 ],
1155 'null does not override' => [
1156 'content', 'content', ['override' => null]
1157 ],
1158 'one does override' => [
1159 1, 'content', ['override' => 1]
1160 ],
1161 'minus one does override' => [
1162 -1, 'content', ['override' => -1]
1163 ],
1164 'float does override' => [
1165 -0.1, 'content', ['override' => -0.1]
1166 ],
1167 'true does override' => [
1168 true, 'content', ['override' => true]
1169 ],
1170 'the value is not trimmed' => [
1171 TAB . 'override', 'content', ['override' => TAB . 'override']
1172 ],
1173 ];
1174 }
1175
1176 /**
1177 * Check if stdWrap_override works properly.
1178 *
1179 * @test
1180 * @dataProvider stdWrap_overrideDataProvider
1181 * @param string $input The input value.
1182 * @param array $conf Property: setCurrent
1183 * @return void
1184 */
1185 public function stdWrap_override($expect, $content, $conf)
1186 {
1187 $this->assertSame($expect,
1188 $this->subject->stdWrap_override($content, $conf));
1189 }
1190
1191 /**
1192 * Check if stdWrap_listNum works properly.
1193 *
1194 * Show:
1195 *
1196 * - Delegates to method listNum.
1197 * - Parameter 1 is $content.
1198 * - Parameter 2 is $conf['listNum'].
1199 * - Parameter 3 is $conf['listNum.']['splitChar'].
1200 * - Returns the return value.
1201 *
1202 * @test
1203 * @return void
1204 */
1205 public function stdWrap_listNum()
1206 {
1207 $content = $this->getUniqueId('content');
1208 $conf = [
1209 'listNum' => $this->getUniqueId('listNum'),
1210 'listNum.' => [
1211 'splitChar' => $this->getUniqueId('splitChar')
1212 ],
1213 ];
1214 $return = $this->getUniqueId('return');
1215 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1216 ->setMethods(['listNum'])->getMock();
1217 $subject
1218 ->expects($this->once())
1219 ->method('listNum')
1220 ->with(
1221 $content,
1222 $conf['listNum'],
1223 $conf['listNum.']['splitChar']
1224 )
1225 ->willReturn($return);
1226 $this->assertSame($return,
1227 $subject->stdWrap_listNum($content, $conf));
1228 }
1229
1230 /**
1231 * Check if stdWrap_field works properly.
1232 *
1233 * Show:
1234 *
1235 * - calls getFieldVal
1236 * - passes conf['field'] as parameter
1237 *
1238 * @test
1239 * @return void
1240 */
1241 public function stdWrap_field()
1242 {
1243 $expect = $this->getUniqueId('expect');
1244 $conf = ['field' => $this->getUniqueId('field')];
1245 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1246 ->setMethods(['getFieldVal'])->getMock();
1247 $subject
1248 ->expects($this->once())
1249 ->method('getFieldVal')
1250 ->with($conf['field'])
1251 ->willReturn($expect);
1252 $this->assertSame($expect,
1253 $subject->stdWrap_field('discarded', $conf));
1254 }
1255
1256 /**
1257 * Data provider for stdWrap_csConv
1258 *
1259 * @return array Order expected, input, conf
1260 */
1261 public function stdWrap_csConvDataProvider()
1262 {
1263 return [
1264 'empty string from ISO-8859-15' => [
1265 '',
1266 iconv('UTF-8', 'ISO-8859-15', ''),
1267 ['csConv' => 'ISO-8859-15']
1268 ],
1269 'empty string from BIG-5' => [
1270 '',
1271 mb_convert_encoding('', 'BIG-5'),
1272 ['csConv' => 'BIG-5']
1273 ],
1274 '"0" from ISO-8859-15' => [
1275 '0',
1276 iconv('UTF-8', 'ISO-8859-15', '0'),
1277 ['csConv' => 'ISO-8859-15']
1278 ],
1279 '"0" from BIG-5' => [
1280 '0',
1281 mb_convert_encoding('0', 'BIG-5'),
1282 ['csConv' => 'BIG-5']
1283 ],
1284 'euro symbol from ISO-88859-15' => [
1285 '€',
1286 iconv('UTF-8', 'ISO-8859-15', '€'),
1287 ['csConv' => 'ISO-8859-15']
1288 ],
1289 'good morning from BIG-5' => [
1290 '早安',
1291 mb_convert_encoding('早安', 'BIG-5'),
1292 ['csConv' => 'BIG-5']
1293 ],
1294 ];
1295 }
1296
1297 /**
1298 * Check if stdWrap_csConv works properly.
1299 *
1300 * @test
1301 * @dataProvider stdWrap_csConvDataProvider
1302 * @param string $expected The expected value.
1303 * @param string $value The input value.
1304 * @param array $conf Property: csConv
1305 * @return void
1306 */
1307 public function stdWrap_csConv($expected, $input, $conf)
1308 {
1309 $this->assertSame($expected,
1310 $this->subject->stdWrap_csConv($input, $conf));
1311 }
1312
1313 /**
1314 * Check if stdWrap_split works properly.
1315 *
1316 * Show:
1317 *
1318 * - Delegates to method splitObj.
1319 * - Parameter 1 is $content.
1320 * - Prameter 2 is $conf['split.'].
1321 * - Returns the return value.
1322 *
1323 * @test
1324 * @return void
1325 */
1326 public function stdWrap_split()
1327 {
1328 $content = $this->getUniqueId('content');
1329 $conf = [
1330 'split' => $this->getUniqueId('not used'),
1331 'split.' => [$this->getUniqueId('split.')],
1332 ];
1333 $return = $this->getUniqueId('return');
1334 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1335 ->setMethods(['splitObj'])->getMock();
1336 $subject
1337 ->expects($this->once())
1338 ->method('splitObj')
1339 ->with($content, $conf['split.'])
1340 ->willReturn($return);
1341 $this->assertSame($return,
1342 $subject->stdWrap_split($content, $conf));
1343 }
1344
1345 /**
1346 * Data provider for stdWrap_prioriCalc
1347 *
1348 * @return array [$expect, $content, $conf]
1349 */
1350 public function stdWrap_prioriCalcDataProvider()
1351 {
1352 return [
1353 'priority of *' => ['7', '1 + 2 * 3', []],
1354 'priority of parentheses' => ['9', '(1 + 2) * 3', []],
1355 'float' => ['1.5', '3/2', []],
1356 'intval casts to int' => [1, '3/2', ['prioriCalc' => 'intval']],
1357 'intval does not round' => [2, '2.7', ['prioriCalc' => 'intval']],
1358 ];
1359 }
1360
1361 /**
1362 * Check if stdWrap_prioriCalc works properly.
1363 *
1364 * Show:
1365 *
1366 * - If $conf['prioriCalc'] is 'intval' the return is casted to int.
1367 * - Delegates to MathUtility::calculateWithParentheses.
1368 *
1369 * Note: As PHPUnit can't mock static methods, the call to
1370 * MathUtility::calculateWithParentheses can't be easily intercepted.
1371 * The test is done by testing input/output pairs instead. To not
1372 * duplicate the testing of calculateWithParentheses just a few
1373 * smoke tests are done here.
1374 *
1375 * @test
1376 * @dataProvider stdWrap_prioriCalcDataProvider
1377 * @param mixed $expect The expected output.
1378 * @param string $content The given content.
1379 * @param array $conf The given configuration.
1380 * @return void
1381 */
1382 public function stdWrap_prioriCalc($expect, $content, $conf)
1383 {
1384 $result = $this->subject->stdWrap_prioriCalc($content, $conf);
1385 $this->assertSame($expect, $result);
1386 }
1387
1388 /**
1389 * Test for the stdWrap_stripHtml
1390 *
1391 * @test
1392 */
1393 public function stdWrap_stripHtml()
1394 {
1395 $content = '<html><p>Hello <span class="inline">inline tag<span>!</p><p>Hello!</p></html>';
1396 $expected = 'Hello inline tag!Hello!';
1397 $this->assertSame($expected, $this->subject->stdWrap_stripHtml($content));
1398 }
1399
1400 /**
1401 * Data provider for round
1402 *
1403 * @return array [$expect, $contet, $conf]
1404 */
1405 public function roundDataProvider()
1406 {
1407 return [
1408 // floats
1409 'down' => [1.0, 1.11, []],
1410 'up' => [2.0, 1.51, []],
1411 'rounds up from x.50' => [2.0, 1.50, []],
1412 'down with decimals' => [0.12, 0.1231, ['decimals' => 2]],
1413 'up with decimals' => [0.13, 0.1251, ['decimals' => 2]],
1414 'ceil' => [1.0, 0.11, ['roundType' => 'ceil']],
1415 'ceil does not accept decimals' => [
1416 1.0, 0.111, [
1417 'roundType' => 'ceil',
1418 'decimals' => 2,
1419 ],
1420 ],
1421 'floor' => [2.0, 2.99, ['roundType' => 'floor']],
1422 'floor does not accept decimals' => [
1423 2.0, 2.999, [
1424 'roundType' => 'floor',
1425 'decimals' => 2,
1426 ],
1427 ],
1428 'round, down' => [1.0, 1.11, ['roundType' => 'round']],
1429 'round, up' => [2.0, 1.55, ['roundType' => 'round']],
1430 'round does accept decimals' => [
1431 5.56, 5.5555, [
1432 'roundType' => 'round',
1433 'decimals' => 2,
1434 ],
1435 ],
1436 // strings
1437 'emtpy string' => [0.0, '', []],
1438 'word string' => [0.0, 'word', []],
1439 'float string' => [1.0, '1.123456789', []],
1440 // other types
1441 'null' => [0.0, null, []],
1442 'false' => [0.0, false, []],
1443 'true' => [1.0, true, []]
1444 ];
1445 }
1446
1447 /**
1448 * Check if round works properly
1449 *
1450 * Show:
1451 *
1452 * - Different types of input are casted to float.
1453 * - Configuration ceil rounds like ceil().
1454 * - Configuration floor rounds like floor().
1455 * - Otherwise rounds like round() and decimals can be applied.
1456 * - Always returns float.
1457 *
1458 * @param float $expected The expected output.
1459 * @param mixed $content The given content.
1460 * @param array $conf The given configuration of 'round.'.
1461 * @return void
1462 * @dataProvider roundDataProvider
1463 * @test
1464 */
1465 public function round($expect, $content, $conf)
1466 {
1467 $this->assertSame($expect,
1468 $this->subject->_call('round', $content, $conf));
1469 }
1470
1471 /**
1472 * Check if stdWrap_round works properly
1473 *
1474 * Show:
1475 *
1476 * - Delegates to method round.
1477 * - Parameter 1 is $content.
1478 * - Parameter 2 is $conf['round.'].
1479 * - Returns the return value.
1480 *
1481 * @test
1482 * @return void
1483 */
1484 public function stdWrap_round()
1485 {
1486 $content = $this->getUniqueId('content');
1487 $conf = [
1488 'round' => $this->getUniqueId('not used'),
1489 'round.' => [$this->getUniqueId('round.')],
1490 ];
1491 $return = $this->getUniqueId('return');
1492 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1493 ->setMethods(['round'])->getMock();
1494 $subject
1495 ->expects($this->once())
1496 ->method('round')
1497 ->with($content, $conf['round.'])
1498 ->willReturn($return);
1499 $this->assertSame($return, $subject->stdWrap_round($content, $conf));
1500 }
1501
1502 /**
1503 * @return array
1504 */
1505 public function stdWrap_numberFormatDataProvider()
1506 {
1507 return array(
1508 'testing decimals' => array(
1509 0.8,
1510 array(
1511 'numberFormat.' => array(
1512 'decimals' => 2
1513 ),
1514 ),
1515 '0.80'
1516 ),
1517 'testing decimals with input as string' => array(
1518 '0.8',
1519 array(
1520 'numberFormat.' => array(
1521 'decimals' => 2
1522 ),
1523 ),
1524 '0.80'
1525 ),
1526 'testing dec_point' => array(
1527 0.8,
1528 array(
1529 'numberFormat.' => array(
1530 'decimals' => 1,
1531 'dec_point' => ','
1532 ),
1533 ),
1534 '0,8'
1535 ),
1536 'testing thousands_sep' => array(
1537 999.99,
1538 array(
1539 'numberFormat.' => array(
1540 'decimals' => 0,
1541 'thousands_sep.' => array(
1542 'char' => 46
1543 ),
1544 ),
1545 ),
1546 '1.000'
1547 ),
1548 'testing mixture' => array(
1549 1281731.45,
1550 array(
1551 'numberFormat.' => array(
1552 'decimals' => 1,
1553 'dec_point.' => array(
1554 'char' => 44
1555 ),
1556 'thousands_sep.' => array(
1557 'char' => 46
1558 ),
1559 ),
1560 ),
1561 '1.281.731,5'
1562 )
1563 );
1564 }
1565
1566 /**
1567 * Test for the stdWrap function "stdWrap_numberFormat"
1568 *
1569 * @param float $float
1570 * @param array $conf
1571 * @param string $expected
1572 * @return void
1573 * @dataProvider stdWrap_numberFormatDataProvider
1574 * @test
1575 */
1576 public function stdWrap_numberFormat($float, $conf, $expected)
1577 {
1578 $result = $this->subject->stdWrap_numberFormat($float, $conf);
1579 $this->assertEquals($expected, $result);
1580 }
1581
1582 /**
1583 * Data provider for expandList
1584 *
1585 * @return array [$expect, $content]
1586 */
1587 public function stdWrap_expandListDataProvider()
1588 {
1589 return [
1590 'numbers' => ['1,2,3', '1,2,3'],
1591 'range' => ['3,4,5', '3-5'],
1592 'numbers and range' => ['1,3,4,5,7', '1,3-5,7']
1593 ];
1594 }
1595
1596 /**
1597 * Test for the stdWrap function "expandList"
1598 *
1599 * The method simply delegates to GeneralUtility::expandList. There is no
1600 * need to repeat the full set of tests of this method here. As PHPUnit
1601 * can't mock static methods, to prove they are called, all we do here
1602 * is to provide a few smoke tests.
1603 *
1604 * @test
1605 * @dataProvider stdWrap_expandListDataProvider
1606 * @param string $expected The expeced output.
1607 * @param string $content The given content.
1608 * @return void
1609 */
1610 public function stdWrap_expandList($expected, $content)
1611 {
1612 $this->assertEquals($expected,
1613 $this->subject->stdWrap_expandList($content));
1614 }
1615
1616 /**
1617 * Data provider for stdWrap_trim.
1618 *
1619 * @return array [$expect, $content]
1620 */
1621 public function stdWrap_trimDataProvider()
1622 {
1623 return [
1624 // string not trimmed
1625 'empty string' => ['', ''],
1626 'string without whitespace' => ['xxx', 'xxx'],
1627 'string with whitespace inside' => [
1628 'xx ' . TAB . ' xx',
1629 'xx ' . TAB . ' xx',
1630 ],
1631 'string with newlines inside' => [
1632 'xx ' . PHP_EOL . ' xx',
1633 'xx ' . PHP_EOL . ' xx',
1634 ],
1635 // string trimmed
1636 'blanks around' => ['xxx', ' xxx '],
1637 'tabs around' => ['xxx', TAB . 'xxx' . TAB],
1638 'newlines around' => ['xxx', PHP_EOL . 'xxx' . PHP_EOL],
1639 'mixed case' => ['xxx', TAB . ' xxx ' . PHP_EOL],
1640 // non strings
1641 'null' => ['', null],
1642 'false' => ['', false],
1643 'true' => ['1', true],
1644 'zero' => ['0', 0],
1645 'one' => ['1', 1],
1646 '-1' => ['-1', -1],
1647 '0.0' => ['0', 0.0],
1648 '1.0' => ['1', 1.0],
1649 '-1.0' => ['-1', -1.0],
1650 '1.1' => ['1.1', 1.1],
1651 ];
1652 }
1653
1654 /**
1655 * Check that stdWrap_trim works properly.
1656 *
1657 * Show:
1658 *
1659 * - the given string is trimmed like PHP trim
1660 * - non-strings are casted to strings:
1661 * - null => 'null'
1662 * - false => ''
1663 * - true => '1'
1664 * - 0 => '0'
1665 * - -1 => '-1'
1666 * - 1.0 => '1'
1667 * - 1.1 => '1.1'
1668 *
1669 * @test
1670 * @dataProvider stdWrap_trimDataProvider
1671 * @param string $expected The expected output.
1672 * @param mixed $content The given content.
1673 * @return void
1674 */
1675 public function stdWrap_trim($expect, $content)
1676 {
1677 $result = $this->subject->stdWrap_trim($content);
1678 $this->assertSame($expect, $result);
1679 }
1680
1681 /**
1682 * Data provider for stdWrap_if.
1683 *
1684 * @return array [$expect, $stop, $content, $conf, $times, $will]
1685 */
1686 public function stdWrap_ifDataProvider()
1687 {
1688 $content = $this->getUniqueId('content');
1689 $conf = ['if.' => [$this->getUniqueId('if.')]];
1690 return [
1691 // evals to true
1692 'empty config' => [
1693 $content, false, $content, [], 0, null
1694 ],
1695 'if. is empty array' => [
1696 $content, false, $content, ['if.' => []], 0, null
1697 ],
1698 'if. is null' => [
1699 $content, false, $content, ['if.' => null], 0, null
1700 ],
1701 'if. is false' => [
1702 $content, false, $content, ['if.' => false], 0, null
1703 ],
1704 'if. is 0' => [
1705 $content, false, $content, ['if.' => false], 0, null
1706 ],
1707 'if. is "0"' => [
1708 $content, false, $content, ['if.' => '0'], 0, null
1709 ],
1710 'checkIf returning true' => [
1711 $content, false, $content, $conf, 1, true
1712 ],
1713 // evals to false
1714 'checkIf returning false' => [
1715 '', true, $content, $conf, 1, false
1716 ],
1717 ];
1718 }
1719
1720 /**
1721 * Check if stdWrap_if works properly.
1722 *
1723 * Show:
1724 *
1725 * - Delegates to the method checkIf to check for 'true'.
1726 * - The parameter to checkIf is $conf['if.'].
1727 * - Is also 'true' if $conf['if.'] is empty (PHP method empty).
1728 * - 'False' triggers a stop of further rendering.
1729 * - Returns the content as is or '' if false.
1730 *
1731 * @test
1732 * @dataProvider stdWrap_ifDataProvider
1733 * @param mixed $expect The expected output.
1734 * @param bool $stop Expect stop further rendering.
1735 * @param mixed $content The given content.
1736 * @param mixed $config The given configuration.
1737 * @param int $times Times checkIf is called (0 or 1).
1738 * @param bool|null $will Return of checkIf (null if not called).
1739 * @return void
1740 */
1741 public function stdWrap_if($expect, $stop, $content, $conf, $times, $will)
1742 {
1743 $subject = $this->getAccessibleMock(
1744 ContentObjectRenderer::class, ['checkIf']);
1745 $subject->_set('stdWrapRecursionLevel', 1);
1746 $subject->_set('stopRendering', [1 => false]);
1747 $subject
1748 ->expects($this->exactly($times))
1749 ->method('checkIf')
1750 ->with($conf['if.'])
1751 ->willReturn($will);
1752 $this->assertSame($expect, $subject->stdWrap_if($content, $conf));
1753 $this->assertSame($stop, $subject->_get('stopRendering')[1]);
1754 }
1755
1756 /**
1757 * Data provider for stdWrap_intval
1758 *
1759 * @return array [$expect, $content]
1760 */
1761 public function stdWrap_intvalDataProvider()
1762 {
1763 return [
1764 // numbers
1765 'int' => [123, 123],
1766 'float' => [123, 123.45],
1767 'float does not round up' => [123, 123.55],
1768 // negative numbers
1769 'negative int' => [-123, -123],
1770 'negative float' => [-123, -123.45],
1771 'negative float does not round down' => [ -123, -123.55],
1772 // strings
1773 'word string' => [0, 'string'],
1774 'empty string' => [0, ''],
1775 'zero string' => [0, '0'],
1776 'int string' => [123, '123'],
1777 'float string' => [123, '123.55'],
1778 'negative float string' => [-123, '-123.55'],
1779 // other types
1780 'null' => [0, null],
1781 'true' => [1, true],
1782 'false' => [0, false]
1783 ];
1784 }
1785
1786 /**
1787 * Check that stdWrap_intval works properly.
1788 *
1789 * Show:
1790 *
1791 * - It does not round up.
1792 * - All types of input is casted to int:
1793 * - null: 0
1794 * - false: 0
1795 * - true: 1
1796 * -
1797 *
1798 *
1799 *
1800 * @test
1801 * @dataProvider stdWrap_intvalDataProvider
1802 * @param int $expect The expected output.
1803 * @param string $content The given input.
1804 * @return void
1805 */
1806 public function stdWrap_intval($expect, $content)
1807 {
1808 $this->assertSame($expect, $this->subject->stdWrap_intval($content));
1809 }
1810
1811 /**
1812 * Data provider for stdWrap_strPad.
1813 *
1814 * @return array [$expect, $content, $conf]
1815 */
1816 public function stdWrap_strPadDataProvider()
1817 {
1818 return [
1819 'pad string with default settings and length 10' => [
1820 'Alien ',
1821 'Alien',
1822 [
1823 'length' => '10',
1824 ],
1825 ],
1826 'pad string with padWith -= and type left and length 10' => [
1827 '-=-=-Alien',
1828 'Alien',
1829 [
1830 'length' => '10',
1831 'padWith' => '-=',
1832 'type' => 'left',
1833 ],
1834 ],
1835 'pad string with padWith _ and type both and length 10' => [
1836 '__Alien___',
1837 'Alien',
1838 [
1839 'length' => '10',
1840 'padWith' => '_',
1841 'type' => 'both',
1842 ],
1843 ],
1844 'pad string with padWith 0 and type both and length 10' => [
1845 '00Alien000',
1846 'Alien',
1847 [
1848 'length' => '10',
1849 'padWith' => '0',
1850 'type' => 'both',
1851 ],
1852 ],
1853 'pad string with padWith ___ and type both and length 6' => [
1854 'Alien_',
1855 'Alien',
1856 [
1857 'length' => '6',
1858 'padWith' => '___',
1859 'type' => 'both',
1860 ],
1861 ],
1862 'pad string with padWith _ and type both and length 12, using stdWrap for length' => [
1863 '___Alien____',
1864 'Alien',
1865 [
1866 'length' => '1',
1867 'length.' => [
1868 'wrap' => '|2',
1869 ],
1870 'padWith' => '_',
1871 'type' => 'both',
1872 ],
1873 ],
1874 'pad string with padWith _ and type both and length 12, using stdWrap for padWidth' => [
1875 '-_=Alien-_=-',
1876 'Alien',
1877 [
1878 'length' => '12',
1879 'padWith' => '_',
1880 'padWith.' => [
1881 'wrap' => '-|=',
1882 ],
1883 'type' => 'both',
1884 ],
1885 ],
1886 'pad string with padWith _ and type both and length 12, using stdWrap for type' => [
1887 '_______Alien',
1888 'Alien',
1889 [
1890 'length' => '12',
1891 'padWith' => '_',
1892 'type' => 'both',
1893 // make type become "left"
1894 'type.' => [
1895 'substring' => '2,1',
1896 'wrap' => 'lef|',
1897 ],
1898 ],
1899 ],
1900 ];
1901 }
1902
1903 /**
1904 * Check if stdWrap_strPad works properly.
1905 *
1906 * @test
1907 * @dataProvider stdWrap_strPadDataProvider
1908 * @param string $expect The expected output.
1909 * @param string $content The given input.
1910 * @param array $conf The configuration of 'strPad.'.
1911 * @return void
1912 */
1913 public function stdWrap_strPad($expect, $content, $conf)
1914 {
1915 $conf = ['strPad.' => $conf];
1916 $result = $this->subject->stdWrap_strPad($content, $conf);
1917 $this->assertSame($expect, $result);
1918 }
1919
1920 /**
1921 * Check that stdWrap_stdWrap works properly.
1922 *
1923 * Show:
1924 * - Delegates to method stdWrap.
1925 * - Parameter 1 is $content.
1926 * - Parameter 2 is $conf['stdWrap.'].
1927 * - Returns the return value.
1928 *
1929 * @test
1930 * @return void.
1931 */
1932 public function stdWrap_stdWrap()
1933 {
1934 $content = $this->getUniqueId('content');
1935 $conf = [
1936 'stdWrap' => $this->getUniqueId('not used'),
1937 'stdWrap.' => [$this->getUniqueId('stdWrap.')],
1938 ];
1939 $return = $this->getUniqueId('return');
1940 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1941 ->setMethods(['stdWrap'])->getMock();
1942 $subject
1943 ->expects($this->once())
1944 ->method('stdWrap')
1945 ->with($content, $conf['stdWrap.'])
1946 ->willReturn($return);
1947 $this->assertSame($return, $subject->stdWrap_stdWrap($content, $conf));
1948 }
1949
1950 /**
1951 * Data provider for the hash test
1952 *
1953 * @return array [$expect, $content, $conf]
1954 */
1955 public function hashDataProvider()
1956 {
1957 return [
1958 'md5' => [
1959 'bacb98acf97e0b6112b1d1b650b84971',
1960 'joh316',
1961 ['hash' => 'md5']
1962 ],
1963 'sha1' => [
1964 '063b3d108bed9f88fa618c6046de0dccadcf3158',
1965 'joh316',
1966 ['hash' => 'sha1']
1967 ],
1968 'stdWrap capability' => [
1969 'bacb98acf97e0b6112b1d1b650b84971',
1970 'joh316',
1971 [
1972 'hash' => '5',
1973 'hash.' => ['wrap' => 'md|']
1974 ]
1975 ],
1976 'non-existing hashing algorithm' => [
1977 '',
1978 'joh316',
1979 ['hash' => 'non-existing']
1980 ]
1981 ];
1982 }
1983
1984 /**
1985 * Check if stdWrap_hash works properly.
1986 *
1987 * Show:
1988 *
1989 * - Algorithms: sha1, md5
1990 * - Returns '' for invalid algorithm.
1991 * - Value can be processed by stdWrap.
1992 *
1993 * @test
1994 * @dataProvider hashDataProvider
1995 * @param string $expect The expected output.
1996 * @param string $content The given content.
1997 * @param array $conf The given configuration.
1998 * @return void
1999 */
2000 public function stdWrap_hash($expect, $content, $conf)
2001 {
2002 $this->assertSame($expect,
2003 $this->subject->stdWrap_hash($content, $conf));
2004 }
2005
2006 /**
2007 * @test
2008 */
2009 public function recursiveStdWrapProperlyRendersBasicString()
2010 {
2011 $stdWrapConfiguration = array(
2012 'noTrimWrap' => '|| 123|',
2013 'stdWrap.' => array(
2014 'wrap' => '<b>|</b>'
2015 )
2016 );
2017 $this->assertSame(
2018 '<b>Test</b> 123',
2019 $this->subject->stdWrap('Test', $stdWrapConfiguration)
2020 );
2021 }
2022
2023 /**
2024 * @test
2025 */
2026 public function recursiveStdWrapIsOnlyCalledOnce()
2027 {
2028 $stdWrapConfiguration = array(
2029 'append' => 'TEXT',
2030 'append.' => array(
2031 'data' => 'register:Counter'
2032 ),
2033 'stdWrap.' => array(
2034 'append' => 'LOAD_REGISTER',
2035 'append.' => array(
2036 'Counter.' => array(
2037 'prioriCalc' => 'intval',
2038 'cObject' => 'TEXT',
2039 'cObject.' => array(
2040 'data' => 'register:Counter',
2041 'wrap' => '|+1',
2042 )
2043 )
2044 )
2045 )
2046 );
2047 $this->assertSame(
2048 'Counter:1',
2049 $this->subject->stdWrap('Counter:', $stdWrapConfiguration)
2050 );
2051 }
2052
2053 /**
2054 * Data provider for the numberFormat test
2055 *
2056 * @return array multi-dimensional array with the second level like this:
2057 * @see numberFormat
2058 */
2059 public function numberFormatDataProvider()
2060 {
2061 $data = array(
2062 'testing decimals' => array(
2063 0.8,
2064 array(
2065 'decimals' => 2
2066 ),
2067 '0.80'
2068 ),
2069 'testing decimals with input as string' => array(
2070 '0.8',
2071 array(
2072 'decimals' => 2
2073 ),
2074 '0.80'
2075 ),
2076 'testing dec_point' => array(
2077 0.8,
2078 array(
2079 'decimals' => 1,
2080 'dec_point' => ','
2081 ),
2082 '0,8'
2083 ),
2084 'testing thousands_sep' => array(
2085 999.99,
2086 array(
2087 'decimals' => 0,
2088 'thousands_sep.' => array(
2089 'char' => 46
2090 )
2091 ),
2092 '1.000'
2093 ),
2094 'testing mixture' => array(
2095 1281731.45,
2096 array(
2097 'decimals' => 1,
2098 'dec_point.' => array(
2099 'char' => 44
2100 ),
2101 'thousands_sep.' => array(
2102 'char' => 46
2103 )
2104 ),
2105 '1.281.731,5'
2106 )
2107 );
2108 return $data;
2109 }
2110
2111 /**
2112 * Check if stdWrap.numberFormat and all of its properties work properly
2113 *
2114 * @dataProvider numberFormatDataProvider
2115 * @test
2116 */
2117 public function numberFormat($float, $formatConf, $expected)
2118 {
2119 $result = $this->subject->numberFormat($float, $formatConf);
2120 $this->assertEquals($expected, $result);
2121 }
2122
2123 /**
2124 * Check if stdWrap_replacement works properly.
2125 *
2126 * Show:
2127 *
2128 * - Delegates to method replacement.
2129 * - Parameter 1 is $content.
2130 * - Parameter 2 is $conf['replacement.'].
2131 * - Returns the return value.
2132 *
2133 * @test
2134 * @return void
2135 */
2136 public function stdWrap_replacement()
2137 {
2138 $content = $this->getUniqueId('content');
2139 $conf = [
2140 'replacement' => $this->getUniqueId('not used'),
2141 'replacement.' => [$this->getUniqueId('replacement.')],
2142 ];
2143 $return = $this->getUniqueId('return');
2144 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
2145 ->setMethods(['replacement'])->getMock();
2146 $subject
2147 ->expects($this->once())
2148 ->method('replacement')
2149 ->with( $content, $conf['replacement.'])
2150 ->willReturn($return);
2151 $this->assertSame($return,
2152 $subject->stdWrap_replacement($content, $conf));
2153 }
2154
2155 /**
2156 * Data provider replacement
2157 *
2158 * @return array [$expect, $content, $conf]
2159 */
2160 public function replacementDataProvider()
2161 {
2162 return [
2163 'multiple replacements, including regex' => [
2164 'There is an animal, an animal and an animal around the block! Yeah!',
2165 'There_is_a_cat,_a_dog_and_a_tiger_in_da_hood!_Yeah!',
2166 [
2167 '20.' => [
2168 'search' => '_',
2169 'replace.' => ['char' => '32']
2170 ],
2171 '120.' => [
2172 'search' => 'in da hood',
2173 'replace' => 'around the block'
2174 ],
2175 '130.' => [
2176 'search' => '#a (Cat|Dog|Tiger)#i',
2177 'replace' => 'an animal',
2178 'useRegExp' => '1'
2179 ]
2180 ]
2181 ],
2182 'replacement with optionSplit, normal pattern' => [
2183 'There1is2a3cat,3a3dog3and3a3tiger3in3da3hood!3Yeah!',
2184 'There_is_a_cat,_a_dog_and_a_tiger_in_da_hood!_Yeah!',
2185 [
2186 '10.' => [
2187 'search' => '_',
2188 'replace' => '1 || 2 || 3',
2189 'useOptionSplitReplace' => '1'
2190 ]
2191 ]
2192 ],
2193 'replacement with optionSplit, using regex' => [
2194 'There is a tiny cat, a midsized dog and a big tiger in da hood! Yeah!',
2195 'There is a cat, a dog and a tiger in da hood! Yeah!',
2196 [
2197 '10.' => [
2198 'search' => '#(a) (Cat|Dog|Tiger)#i',
2199 'replace' => '${1} tiny ${2} || ${1} midsized ${2} || ${1} big ${2}',
2200 'useOptionSplitReplace' => '1',
2201 'useRegExp' => '1'
2202 ]
2203 ]
2204 ]
2205 ];
2206 }
2207
2208 /**
2209 * Check if stdWrap.replacement and all of its properties work properly
2210 *
2211 * @test
2212 * @dataProvider replacementDataProvider
2213 * @param string $content The given input.
2214 * @param string $expects The expected result.
2215 * @param array $conf The given configuration.
2216 * @return void
2217 */
2218 public function replacement($expects, $content, $conf)
2219 {
2220 $this->assertSame($expects,
2221 $this->subject->_call('replacement', $content, $conf));
2222 }
2223
2224 /**
2225 * @return array
2226 */
2227 public function stdWrapRawUrlEncodeDataProvider()
2228 {
2229 return [
2230 'https://typo3.org?id=10' => ['https://typo3.org?id=10', 'https%3A%2F%2Ftypo3.org%3Fid%3D10'],
2231 'https://typo3.org?id=10&foo=bar' => ['https://typo3.org?id=10&foo=bar', 'https%3A%2F%2Ftypo3.org%3Fid%3D10%26foo%3Dbar'],
2232 ];
2233 }
2234
2235 /**
2236 * Check if rawUrlEncode works properly
2237 *
2238 * @test
2239 * @dataProvider stdWrapRawUrlEncodeDataProvider
2240 */
2241 public function stdWrap_rawUrlEncode($input, $expected)
2242 {
2243 $this->assertEquals($expected, $this->subject->stdWrap_rawUrlEncode($input));
2244 }
2245
2246 /**
2247 * Data provider for the getQuery test
2248 *
2249 * @return array multi-dimensional array with the second level like this:
2250 * @see getQuery
2251 */
2252 public function getQueryDataProvider()
2253 {
2254 $data = array(
2255 'testing empty conf' => array(
2256 'tt_content',
2257 array(),
2258 array(
2259 'SELECT' => '*'
2260 )
2261 ),
2262 'testing #17284: adding uid/pid for workspaces' => array(
2263 'tt_content',
2264 array(
2265 'selectFields' => 'header,bodytext'
2266 ),
2267 array(
2268 'SELECT' => 'header,bodytext, tt_content.uid as uid, tt_content.pid as pid, tt_content.t3ver_state as t3ver_state'
2269 )
2270 ),
2271 'testing #17284: no need to add' => array(
2272 'tt_content',
2273 array(
2274 'selectFields' => 'tt_content.*'
2275 ),
2276 array(
2277 'SELECT' => 'tt_content.*'
2278 )
2279 ),
2280 'testing #17284: no need to add #2' => array(
2281 'tt_content',
2282 array(
2283 'selectFields' => '*'
2284 ),
2285 array(
2286 'SELECT' => '*'
2287 )
2288 ),
2289 'testing #29783: joined tables, prefix tablename' => array(
2290 'tt_content',
2291 array(
2292 'selectFields' => 'tt_content.header,be_users.username',
2293 'join' => 'be_users ON tt_content.cruser_id = be_users.uid'
2294 ),
2295 array(
2296 'SELECT' => 'tt_content.header,be_users.username, tt_content.uid as uid, tt_content.pid as pid, tt_content.t3ver_state as t3ver_state'
2297 )
2298 ),
2299 'testing #34152: single count(*), add nothing' => array(
2300 'tt_content',
2301 array(
2302 'selectFields' => 'count(*)'
2303 ),
2304 array(
2305 'SELECT' => 'count(*)'
2306 )
2307 ),
2308 'testing #34152: single max(crdate), add nothing' => array(
2309 'tt_content',
2310 array(
2311 'selectFields' => 'max(crdate)'
2312 ),
2313 array(
2314 'SELECT' => 'max(crdate)'
2315 )
2316 ),
2317 'testing #34152: single min(crdate), add nothing' => array(
2318 'tt_content',
2319 array(
2320 'selectFields' => 'min(crdate)'
2321 ),
2322 array(
2323 'SELECT' => 'min(crdate)'
2324 )
2325 ),
2326 'testing #34152: single sum(is_siteroot), add nothing' => array(
2327 'tt_content',
2328 array(
2329 'selectFields' => 'sum(is_siteroot)'
2330 ),
2331 array(
2332 'SELECT' => 'sum(is_siteroot)'
2333 )
2334 ),
2335 'testing #34152: single avg(crdate), add nothing' => array(
2336 'tt_content',
2337 array(
2338 'selectFields' => 'avg(crdate)'
2339 ),
2340 array(
2341 'SELECT' => 'avg(crdate)'
2342 )
2343 )
2344 );
2345 return $data;
2346 }
2347
2348 /**
2349 * Check if sanitizeSelectPart works as expected
2350 *
2351 * @dataProvider getQueryDataProvider
2352 * @test
2353 */
2354 public function getQuery($table, $conf, $expected)
2355 {
2356 $GLOBALS['TCA'] = array(
2357 'pages' => array(
2358 'ctrl' => array(
2359 'enablecolumns' => array(
2360 'disabled' => 'hidden'
2361 )
2362 )
2363 ),
2364 'tt_content' => array(
2365 'ctrl' => array(
2366 'enablecolumns' => array(
2367 'disabled' => 'hidden'
2368 ),
2369 'versioningWS' => true
2370 )
2371 ),
2372 );
2373 $result = $this->subject->getQuery($table, $conf, true);
2374 foreach ($expected as $field => $value) {
2375 $this->assertEquals($value, $result[$field]);
2376 }
2377 }
2378
2379 /**
2380 * @test
2381 */
2382 public function getQueryCallsGetTreeListWithNegativeValuesIfRecursiveIsSet()
2383 {
2384 $GLOBALS['TCA'] = array(
2385 'pages' => array(
2386 'ctrl' => array(
2387 'enablecolumns' => array(
2388 'disabled' => 'hidden'
2389 )
2390 )
2391 ),
2392 'tt_content' => array(
2393 'ctrl' => array(
2394 'enablecolumns' => array(
2395 'disabled' => 'hidden'
2396 )
2397 )
2398 ),
2399 );
2400 $this->subject = $this->getAccessibleMock(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class, array('getTreeList'));
2401 $this->subject->start(array(), 'tt_content');
2402 $conf = array(
2403 'recursive' => '15',
2404 'pidInList' => '16, -35'
2405 );
2406 $this->subject->expects($this->at(0))
2407 ->method('getTreeList')
2408 ->with(-16, 15)
2409 ->will($this->returnValue('15,16'));
2410 $this->subject->expects($this->at(1))
2411 ->method('getTreeList')
2412 ->with(-35, 15)
2413 ->will($this->returnValue('15,35'));
2414 $this->subject->getQuery('tt_content', $conf, true);
2415 }
2416
2417 /**
2418 * @test
2419 */
2420 public function getQueryCallsGetTreeListWithCurrentPageIfThisIsSet()
2421 {
2422 $GLOBALS['TCA'] = array(
2423 'pages' => array(
2424 'ctrl' => array(
2425 'enablecolumns' => array(
2426 'disabled' => 'hidden'
2427 )
2428 )
2429 ),
2430 'tt_content' => array(
2431 'ctrl' => array(
2432 'enablecolumns' => array(
2433 'disabled' => 'hidden'
2434 )
2435 )
2436 ),
2437 );
2438 $this->subject = $this->getAccessibleMock(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class, array('getTreeList'));
2439 $GLOBALS['TSFE']->id = 27;
2440 $this->subject->start(array(), 'tt_content');
2441 $conf = array(
2442 'pidInList' => 'this',
2443 'recursive' => '4'
2444 );
2445 $this->subject->expects($this->once())
2446 ->method('getTreeList')
2447 ->with(-27)
2448 ->will($this->returnValue('27'));
2449 $this->subject->getQuery('tt_content', $conf, true);
2450 }
2451
2452 /**
2453 * Data provider for the stdWrap_date test
2454 *
2455 * @return array [$expect, $content, $conf, $now]
2456 */
2457 public function stdWrap_dateDataProvider()
2458 {
2459 // Fictive execution time: 2015-10-02 12:00
2460 $now = 1443780000;
2461 return [
2462 'given timestamp' => [
2463 '02.10.2015',
2464 $now,
2465 ['date' => 'd.m.Y'],
2466 $now
2467 ],
2468 'empty string' => [
2469 '02.10.2015',
2470 '',
2471 ['date' => 'd.m.Y'],
2472 $now
2473 ],
2474 'testing null' => [
2475 '02.10.2015',
2476 null,
2477 ['date' => 'd.m.Y'],
2478 $now
2479 ],
2480 'given timestamp return GMT' => [
2481 '02.10.2015 10:00:00',
2482 $now,
2483 [
2484 'date' => 'd.m.Y H:i:s',
2485 'date.' => ['GMT' => true],
2486 ],
2487 $now
2488 ]
2489 ];
2490 }
2491
2492 /**
2493 * Check if stdWrap_date works properly.
2494 *
2495 * @test
2496 * @dataProvider stdWrap_dateDataProvider
2497 * @param string $expected The expected output.
2498 * @param mixed $content The given input.
2499 * @param array $conf The given configuration.
2500 * @param int $now Fictive execution time.
2501 * @return void
2502 */
2503 public function stdWrap_date($expected, $content, $conf, $now)
2504 {
2505 $GLOBALS['EXEC_TIME'] = $now;
2506 $this->assertEquals($expected,
2507 $this->subject->stdWrap_date($content, $conf));
2508 }
2509
2510 /**
2511 * Data provider for stdWrap_strftime
2512 *
2513 * @return array [$expect, $content, $conf, $now]
2514 */
2515 public function stdWrap_strftimeDataProvider()
2516 {
2517 // Fictive execution time is 2012-09-01 12:00 in UTC/GMT.
2518 $now = 1346500800;
2519 return [
2520 'given timestamp' => [
2521 '01-09-2012',
2522 $now,
2523 ['strftime' => '%d-%m-%Y'],
2524 $now
2525 ],
2526 'empty string' => [
2527 '01-09-2012',
2528 '',
2529 ['strftime' => '%d-%m-%Y'],
2530 $now
2531 ],
2532 'testing null' => [
2533 '01-09-2012',
2534 null,
2535 ['strftime' => '%d-%m-%Y'],
2536 $now
2537 ]
2538 ];
2539 }
2540
2541 /**
2542 * Check if stdWrap_strftime works properly.
2543 *
2544 * @test
2545 * @dataProvider stdWrap_strftimeDataProvider
2546 * @param string $expect The expected output.
2547 * @param mixed $content The given input.
2548 * @param array $conf The given configuration.
2549 * @param int $now Fictive execution time.
2550 * @return void
2551 */
2552 public function stdWrap_strftime($expect, $content, $conf, $now)
2553 {
2554 // Save current timezone and set to UTC to make the system under test
2555 // behave the same in all server timezone settings
2556 $timezoneBackup = date_default_timezone_get();
2557 date_default_timezone_set('UTC');
2558
2559 $GLOBALS['EXEC_TIME'] = $now;
2560 $result = $this->subject->stdWrap_strftime($content, $conf);
2561
2562 // Reset timezone
2563 date_default_timezone_set($timezoneBackup);
2564
2565 $this->assertSame($expect, $result);
2566 }
2567
2568 /**
2569 * Data provider for the stdWrap_strtotime test
2570 *
2571 * @return array [$expect, $content, $conf]
2572 */
2573 public function stdWrap_strtotimeDataProvider()
2574 {
2575 return [
2576 'date from content' => [
2577 1417651200, '2014-12-04',
2578 ['strtotime' => '1']
2579 ],
2580 'manipulation of date from content' => [
2581 1417996800, '2014-12-04',
2582 ['strtotime' => '+ 2 weekdays']
2583 ],
2584 'date from configuration' => [
2585 1417651200, '',
2586 ['strtotime' => '2014-12-04']
2587 ],
2588 'manipulation of date from configuration' => [
2589 1417996800, '',
2590 ['strtotime' => '2014-12-04 + 2 weekdays']
2591 ],
2592 'empty input' => [
2593 false, '',
2594 ['strtotime' => '1']
2595 ],
2596 'date from content and configuration' => [
2597 false, '2014-12-04',
2598 ['strtotime' => '2014-12-05']
2599 ]
2600 ];
2601 }
2602
2603 /**
2604 * Check if stdWrap_strtotime works properly.
2605 *
2606 * @test
2607 * @dataProvider stdWrap_strtotimeDataProvider
2608 * @param int $expect The expected output.
2609 * @param mixed $content The given input.
2610 * @param array $conf The given configuration.
2611 * @return void
2612 */
2613 public function stdWrap_strtotime($expect, $content, $conf)
2614 {
2615 // Set exec_time to a hard timestamp
2616 $GLOBALS['EXEC_TIME'] = 1417392000;
2617 // Save current timezone and set to UTC to make the system under test
2618 // behave the same in all server timezone settings
2619 $timezoneBackup = date_default_timezone_get();
2620 date_default_timezone_set('UTC');
2621
2622 $result = $this->subject->stdWrap_strtotime($content, $conf);
2623
2624 // Reset timezone
2625 date_default_timezone_set($timezoneBackup);
2626
2627 $this->assertEquals($expect, $result);
2628 }
2629
2630 /**
2631 * @test
2632 */
2633 public function stdWrap_ageCallsCalcAgeWithSubtractedTimestampAndSubPartOfArray()
2634 {
2635 $subject = $this->getMockBuilder(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class)
2636 ->setMethods(array('calcAge'))
2637 ->getMock();
2638 // Set exec_time to a hard timestamp
2639 $GLOBALS['EXEC_TIME'] = 10;
2640 $subject->expects($this->once())->method('calcAge')->with(1, 'Min| Hrs| Days| Yrs');
2641 $subject->stdWrap_age(9, array('age' => 'Min| Hrs| Days| Yrs'));
2642 }
2643
2644 /**
2645 * Data provider for calcAgeCalculatesAgeOfTimestamp
2646 *
2647 * @return array
2648 * @see calcAge
2649 */
2650 public function calcAgeCalculatesAgeOfTimestampDataProvider()
2651 {
2652 return array(
2653 'minutes' => array(
2654 120,
2655 ' min| hrs| days| yrs',
2656 '2 min',
2657 ),
2658 'hours' => array(
2659 7200,
2660 ' min| hrs| days| yrs',
2661 '2 hrs',
2662 ),
2663 'days' => array(
2664 604800,
2665 ' min| hrs| days| yrs',
2666 '7 days',
2667 ),
2668 'day with provided singular labels' => array(
2669 86400,
2670 ' min| hrs| days| yrs| min| hour| day| year',
2671 '1 day',
2672 ),
2673 'years' => array(
2674 1417997800,
2675 ' min| hrs| days| yrs',
2676 '45 yrs',
2677 ),
2678 'different labels' => array(
2679 120,
2680 ' Minutes| Hrs| Days| Yrs',
2681 '2 Minutes',
2682 ),
2683 'negative values' => array(
2684 -604800,
2685 ' min| hrs| days| yrs',
2686 '-7 days',
2687 ),
2688 'default label values for wrong label input' => array(
2689 121,
2690 10,
2691 '2 min',
2692 ),
2693 'default singular label values for wrong label input' => array(
2694 31536000,
2695 10,
2696 '1 year',
2697 )
2698 );
2699 }
2700
2701 /**
2702 * @param int $timestamp
2703 * @param string $labels
2704 * @param int $expectation
2705 * @dataProvider calcAgeCalculatesAgeOfTimestampDataProvider
2706 * @test
2707 */
2708 public function calcAgeCalculatesAgeOfTimestamp($timestamp, $labels, $expectation)
2709 {
2710 $result = $this->subject->calcAge($timestamp, $labels);
2711 $this->assertEquals($result, $expectation);
2712 }
2713
2714 /**
2715 * @return array
2716 */
2717 public function stdWrapReturnsExpectationDataProvider()
2718 {
2719 return [
2720 'Prevent silent bool conversion' => [
2721 '1+1',
2722 [
2723 'prioriCalc.' => [
2724 'wrap' => '|',
2725 ],
2726 ],
2727 '1+1',
2728 ],
2729 ];
2730 }
2731
2732 /**
2733 * @param string $content
2734 * @param array $configuration
2735 * @param string $expectation
2736 * @dataProvider stdWrapReturnsExpectationDataProvider
2737 * @test
2738 */
2739 public function stdWrapReturnsExpectation($content, array $configuration, $expectation)
2740 {
2741 $this->assertSame($expectation, $this->subject->stdWrap($content, $configuration));
2742 }
2743
2744 /**
2745 * Data provider for stdWrap_case test
2746 *
2747 * @return array
2748 */
2749 public function stdWrap_caseDataProvider()
2750 {
2751 return array(
2752 'lower case text to upper' => array(
2753 '<span>text</span>',
2754 array(
2755 'case' => 'upper',
2756 ),
2757 '<span>TEXT</span>',
2758 ),
2759 'upper case text to lower' => array(
2760 '<span>TEXT</span>',
2761 array(
2762 'case' => 'lower',
2763 ),
2764 '<span>text</span>',
2765 ),
2766 'capitalize text' => array(
2767 '<span>this is a text</span>',
2768 array(
2769 'case' => 'capitalize',
2770 ),
2771 '<span>This Is A Text</span>',
2772 ),
2773 'ucfirst text' => array(
2774 '<span>this is a text</span>',
2775 array(
2776 'case' => 'ucfirst',
2777 ),
2778 '<span>This is a text</span>',
2779 ),
2780 'lcfirst text' => array(
2781 '<span>This is a Text</span>',
2782 array(
2783 'case' => 'lcfirst',
2784 ),
2785 '<span>this is a Text</span>',
2786 ),
2787 'uppercamelcase text' => array(
2788 '<span>this_is_a_text</span>',
2789 array(
2790 'case' => 'uppercamelcase',
2791 ),
2792 '<span>ThisIsAText</span>',
2793 ),
2794 'lowercamelcase text' => array(
2795 '<span>this_is_a_text</span>',
2796 array(
2797 'case' => 'lowercamelcase',
2798 ),
2799 '<span>thisIsAText</span>',
2800 ),
2801 );
2802 }
2803
2804 /**
2805 * @param string|NULL $content
2806 * @param array $configuration
2807 * @param string $expected
2808 * @dataProvider stdWrap_caseDataProvider
2809 * @test
2810 */
2811 public function stdWrap_case($content, array $configuration, $expected)
2812 {
2813 $result = $this->subject->stdWrap_case($content, $configuration);
2814 $this->assertEquals($expected, $result);
2815 }
2816
2817 /**
2818 * Data provider for stdWrap_bytes test
2819 *
2820 * @return array
2821 */
2822 public function stdWrap_bytesDataProvider()
2823 {
2824 return array(
2825 'value 1234 default' => array(
2826 '1234',
2827 array(
2828 'bytes.' => array(
2829 'labels' => '',
2830 'base' => 0,
2831 ),
2832 ),
2833 '1.21 Ki',
2834 'en_US.UTF-8'
2835 ),
2836 'value 1234 si' => array(
2837 '1234',
2838 array(
2839 'bytes.' => array(
2840 'labels' => 'si',
2841 'base' => 0,
2842 ),
2843 ),
2844 '1.23 k',
2845 'en_US.UTF-8'
2846 ),
2847 'value 1234 iec' => array(
2848 '1234',
2849 array(
2850 'bytes.' => array(
2851 'labels' => 'iec',
2852 'base' => 0,
2853 ),
2854 ),
2855 '1.21 Ki',
2856 'en_US.UTF-8'
2857 ),
2858 'value 1234 a-i' => array(
2859 '1234',
2860 array(
2861 'bytes.' => array(
2862 'labels' => 'a|b|c|d|e|f|g|h|i',
2863 'base' => 1000,
2864 ),
2865 ),
2866 '1.23b',
2867 'en_US.UTF-8'
2868 ),
2869 'value 1234 a-i invalid base' => array(
2870 '1234',
2871 array(
2872 'bytes.' => array(
2873 'labels' => 'a|b|c|d|e|f|g|h|i',
2874 'base' => 54,
2875 ),
2876 ),
2877 '1.21b',
2878 'en_US.UTF-8'
2879 ),
2880 'value 1234567890 default' => array(
2881 '1234567890',
2882 array(
2883 'bytes.' => array(
2884 'labels' => '',
2885 'base' => 0,
2886 ),
2887 ),
2888 '1.15 Gi',
2889 'en_US.UTF-8'
2890 ),
2891 );
2892 }
2893
2894 /**
2895 * @param string|NULL $content
2896 * @param array $configuration
2897 * @param string $expected
2898 * @dataProvider stdWrap_bytesDataProvider
2899 * @test
2900 */
2901 public function stdWrap_bytes($content, array $configuration, $expected, $locale)
2902 {
2903 if (!setlocale(LC_NUMERIC, $locale)) {
2904 $this->markTestSkipped('Locale ' . $locale . ' is not available.');
2905 }
2906 $result = $this->subject->stdWrap_bytes($content, $configuration);
2907 $this->assertSame($expected, $result);
2908 }
2909
2910 /**
2911 * Data provider for stdWrap_substring test
2912 *
2913 * @return array
2914 */
2915 public function stdWrap_substringDataProvider()
2916 {
2917 return array(
2918 'sub -1' => array(
2919 'substring',
2920 array(
2921 'substring' => '-1',
2922 ),
2923 'g',
2924 ),
2925 'sub -1,0' => array(
2926 'substring',
2927 array(
2928 'substring' => '-1,0',
2929 ),
2930 'g',
2931 ),
2932 'sub -1,-1' => array(
2933 'substring',
2934 array(
2935 'substring' => '-1,-1',
2936 ),
2937 '',
2938 ),
2939 'sub -1,1' => array(
2940 'substring',
2941 array(
2942 'substring' => '-1,1',
2943 ),
2944 'g',
2945 ),
2946 'sub 0' => array(
2947 'substring',
2948 array(
2949 'substring' => '0',
2950 ),
2951 'substring',
2952 ),
2953 'sub 0,0' => array(
2954 'substring',
2955 array(
2956 'substring' => '0,0',
2957 ),
2958 'substring',
2959 ),
2960 'sub 0,-1' => array(
2961 'substring',
2962 array(
2963 'substring' => '0,-1',
2964 ),
2965 'substrin',
2966 ),
2967 'sub 0,1' => array(
2968 'substring',
2969 array(
2970 'substring' => '0,1',
2971 ),
2972 's',
2973 ),
2974 'sub 1' => array(
2975 'substring',
2976 array(
2977 'substring' => '1',
2978 ),
2979 'ubstring',
2980 ),
2981 'sub 1,0' => array(
2982 'substring',
2983 array(
2984 'substring' => '1,0',
2985 ),
2986 'ubstring',
2987 ),
2988 'sub 1,-1' => array(
2989 'substring',
2990 array(
2991 'substring' => '1,-1',
2992 ),
2993 'ubstrin',
2994 ),
2995 'sub 1,1' => array(
2996 'substring',
2997 array(
2998 'substring' => '1,1',
2999 ),
3000 'u',
3001 ),
3002 'sub' => array(
3003 'substring',
3004 array(
3005 'substring' => '',
3006 ),
3007 'substring',
3008 ),
3009 );
3010 }
3011
3012 /**
3013 * @param string $content
3014 * @param array $configuration
3015 * @param string $expected
3016 * @dataProvider stdWrap_substringDataProvider
3017 * @test
3018 */
3019 public function stdWrap_substring($content, array $configuration, $expected)
3020 {
3021 $result = $this->subject->stdWrap_substring($content, $configuration);
3022 $this->assertSame($expected, $result);
3023 }
3024
3025 /**
3026 * Data provider for stdWrap_stdWrapValue test
3027 *
3028 * @return array
3029 */
3030 public function stdWrap_stdWrapValueDataProvider()
3031 {
3032 return array(
3033 'only key returns value' => array(
3034 'ifNull',
3035 array(
3036 'ifNull' => '1',
3037 ),
3038