[TASK] Add unit test to cover stdWrap_numRows
[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 * Check if stdWrap_cObject works properly.
1258 *
1259 * Show:
1260 *
1261 * - Delegates to the method cObjGetSingle().
1262 * - First parameter is $conf['cObject'].
1263 * - Second parameter is $conf['cObject.'].
1264 * - Third parameter is '/stdWrap/.cObject'.
1265 * - Returns the return.
1266 *
1267 * @test
1268 * @return void
1269 */
1270 public function stdWrap_cObject()
1271 {
1272 $debugKey = '/stdWrap/.cObject';
1273 $conf = [
1274 'cObject' => $this->getUniqueId('cObject'),
1275 'cObject.' => [$this->getUniqueId('cObject.')],
1276 ];
1277 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1278 ->setMethods(['cObjGetSingle'])->getMock();
1279 $subject
1280 ->expects($this->once())
1281 ->method('cObjGetSingle')
1282 ->with($conf['cObject'], $conf['cObject.'], $debugKey)
1283 ->willReturn('return');
1284 $this->assertSame('return',
1285 $subject->stdWrap_cObject('discard', $conf));
1286 }
1287
1288 /**
1289 * Check if stdWrap_numRows works properly.
1290 *
1291 * Show:
1292 *
1293 * - Delegates to method numRows.
1294 * - Parameter is $conf['numRows.'].
1295 * - Returns the return value.
1296 *
1297 * @test
1298 * @return void
1299 */
1300 public function stdWrap_numRows()
1301 {
1302 $conf = [
1303 'numRows' => $this->getUniqueId('numRows'),
1304 'numRows.' => [$this->getUniqueId('numRows')],
1305 ];
1306 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1307 ->setMethods(['numRows'])->getMock();
1308 $subject->expects($this->once())->method('numRows')
1309 ->with($conf['numRows.'])->willReturn('return');
1310 $this->assertSame('return',
1311 $subject->stdWrap_numRows('discard', $conf));
1312 }
1313
1314 /**
1315 * Data provider for stdWrap_csConv
1316 *
1317 * @return array Order expected, input, conf
1318 */
1319 public function stdWrap_csConvDataProvider()
1320 {
1321 return [
1322 'empty string from ISO-8859-15' => [
1323 '',
1324 iconv('UTF-8', 'ISO-8859-15', ''),
1325 ['csConv' => 'ISO-8859-15']
1326 ],
1327 'empty string from BIG-5' => [
1328 '',
1329 mb_convert_encoding('', 'BIG-5'),
1330 ['csConv' => 'BIG-5']
1331 ],
1332 '"0" from ISO-8859-15' => [
1333 '0',
1334 iconv('UTF-8', 'ISO-8859-15', '0'),
1335 ['csConv' => 'ISO-8859-15']
1336 ],
1337 '"0" from BIG-5' => [
1338 '0',
1339 mb_convert_encoding('0', 'BIG-5'),
1340 ['csConv' => 'BIG-5']
1341 ],
1342 'euro symbol from ISO-88859-15' => [
1343 '€',
1344 iconv('UTF-8', 'ISO-8859-15', '€'),
1345 ['csConv' => 'ISO-8859-15']
1346 ],
1347 'good morning from BIG-5' => [
1348 '早安',
1349 mb_convert_encoding('早安', 'BIG-5'),
1350 ['csConv' => 'BIG-5']
1351 ],
1352 ];
1353 }
1354
1355 /**
1356 * Check if stdWrap_csConv works properly.
1357 *
1358 * @test
1359 * @dataProvider stdWrap_csConvDataProvider
1360 * @param string $expected The expected value.
1361 * @param string $value The input value.
1362 * @param array $conf Property: csConv
1363 * @return void
1364 */
1365 public function stdWrap_csConv($expected, $input, $conf)
1366 {
1367 $this->assertSame($expected,
1368 $this->subject->stdWrap_csConv($input, $conf));
1369 }
1370
1371 /**
1372 * Check if stdWrap_split works properly.
1373 *
1374 * Show:
1375 *
1376 * - Delegates to method splitObj.
1377 * - Parameter 1 is $content.
1378 * - Prameter 2 is $conf['split.'].
1379 * - Returns the return value.
1380 *
1381 * @test
1382 * @return void
1383 */
1384 public function stdWrap_split()
1385 {
1386 $content = $this->getUniqueId('content');
1387 $conf = [
1388 'split' => $this->getUniqueId('not used'),
1389 'split.' => [$this->getUniqueId('split.')],
1390 ];
1391 $return = $this->getUniqueId('return');
1392 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1393 ->setMethods(['splitObj'])->getMock();
1394 $subject
1395 ->expects($this->once())
1396 ->method('splitObj')
1397 ->with($content, $conf['split.'])
1398 ->willReturn($return);
1399 $this->assertSame($return,
1400 $subject->stdWrap_split($content, $conf));
1401 }
1402
1403 /**
1404 * Data provider for stdWrap_prioriCalc
1405 *
1406 * @return array [$expect, $content, $conf]
1407 */
1408 public function stdWrap_prioriCalcDataProvider()
1409 {
1410 return [
1411 'priority of *' => ['7', '1 + 2 * 3', []],
1412 'priority of parentheses' => ['9', '(1 + 2) * 3', []],
1413 'float' => ['1.5', '3/2', []],
1414 'intval casts to int' => [1, '3/2', ['prioriCalc' => 'intval']],
1415 'intval does not round' => [2, '2.7', ['prioriCalc' => 'intval']],
1416 ];
1417 }
1418
1419 /**
1420 * Check if stdWrap_prioriCalc works properly.
1421 *
1422 * Show:
1423 *
1424 * - If $conf['prioriCalc'] is 'intval' the return is casted to int.
1425 * - Delegates to MathUtility::calculateWithParentheses.
1426 *
1427 * Note: As PHPUnit can't mock static methods, the call to
1428 * MathUtility::calculateWithParentheses can't be easily intercepted.
1429 * The test is done by testing input/output pairs instead. To not
1430 * duplicate the testing of calculateWithParentheses just a few
1431 * smoke tests are done here.
1432 *
1433 * @test
1434 * @dataProvider stdWrap_prioriCalcDataProvider
1435 * @param mixed $expect The expected output.
1436 * @param string $content The given content.
1437 * @param array $conf The given configuration.
1438 * @return void
1439 */
1440 public function stdWrap_prioriCalc($expect, $content, $conf)
1441 {
1442 $result = $this->subject->stdWrap_prioriCalc($content, $conf);
1443 $this->assertSame($expect, $result);
1444 }
1445
1446 /**
1447 * Test for the stdWrap_stripHtml
1448 *
1449 * @test
1450 */
1451 public function stdWrap_stripHtml()
1452 {
1453 $content = '<html><p>Hello <span class="inline">inline tag<span>!</p><p>Hello!</p></html>';
1454 $expected = 'Hello inline tag!Hello!';
1455 $this->assertSame($expected, $this->subject->stdWrap_stripHtml($content));
1456 }
1457
1458 /**
1459 * Data provider for round
1460 *
1461 * @return array [$expect, $contet, $conf]
1462 */
1463 public function roundDataProvider()
1464 {
1465 return [
1466 // floats
1467 'down' => [1.0, 1.11, []],
1468 'up' => [2.0, 1.51, []],
1469 'rounds up from x.50' => [2.0, 1.50, []],
1470 'down with decimals' => [0.12, 0.1231, ['decimals' => 2]],
1471 'up with decimals' => [0.13, 0.1251, ['decimals' => 2]],
1472 'ceil' => [1.0, 0.11, ['roundType' => 'ceil']],
1473 'ceil does not accept decimals' => [
1474 1.0, 0.111, [
1475 'roundType' => 'ceil',
1476 'decimals' => 2,
1477 ],
1478 ],
1479 'floor' => [2.0, 2.99, ['roundType' => 'floor']],
1480 'floor does not accept decimals' => [
1481 2.0, 2.999, [
1482 'roundType' => 'floor',
1483 'decimals' => 2,
1484 ],
1485 ],
1486 'round, down' => [1.0, 1.11, ['roundType' => 'round']],
1487 'round, up' => [2.0, 1.55, ['roundType' => 'round']],
1488 'round does accept decimals' => [
1489 5.56, 5.5555, [
1490 'roundType' => 'round',
1491 'decimals' => 2,
1492 ],
1493 ],
1494 // strings
1495 'emtpy string' => [0.0, '', []],
1496 'word string' => [0.0, 'word', []],
1497 'float string' => [1.0, '1.123456789', []],
1498 // other types
1499 'null' => [0.0, null, []],
1500 'false' => [0.0, false, []],
1501 'true' => [1.0, true, []]
1502 ];
1503 }
1504
1505 /**
1506 * Check if round works properly
1507 *
1508 * Show:
1509 *
1510 * - Different types of input are casted to float.
1511 * - Configuration ceil rounds like ceil().
1512 * - Configuration floor rounds like floor().
1513 * - Otherwise rounds like round() and decimals can be applied.
1514 * - Always returns float.
1515 *
1516 * @param float $expected The expected output.
1517 * @param mixed $content The given content.
1518 * @param array $conf The given configuration of 'round.'.
1519 * @return void
1520 * @dataProvider roundDataProvider
1521 * @test
1522 */
1523 public function round($expect, $content, $conf)
1524 {
1525 $this->assertSame($expect,
1526 $this->subject->_call('round', $content, $conf));
1527 }
1528
1529 /**
1530 * Check if stdWrap_round works properly
1531 *
1532 * Show:
1533 *
1534 * - Delegates to method round.
1535 * - Parameter 1 is $content.
1536 * - Parameter 2 is $conf['round.'].
1537 * - Returns the return value.
1538 *
1539 * @test
1540 * @return void
1541 */
1542 public function stdWrap_round()
1543 {
1544 $content = $this->getUniqueId('content');
1545 $conf = [
1546 'round' => $this->getUniqueId('not used'),
1547 'round.' => [$this->getUniqueId('round.')],
1548 ];
1549 $return = $this->getUniqueId('return');
1550 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1551 ->setMethods(['round'])->getMock();
1552 $subject
1553 ->expects($this->once())
1554 ->method('round')
1555 ->with($content, $conf['round.'])
1556 ->willReturn($return);
1557 $this->assertSame($return, $subject->stdWrap_round($content, $conf));
1558 }
1559
1560 /**
1561 * @return array
1562 */
1563 public function stdWrap_numberFormatDataProvider()
1564 {
1565 return array(
1566 'testing decimals' => array(
1567 0.8,
1568 array(
1569 'numberFormat.' => array(
1570 'decimals' => 2
1571 ),
1572 ),
1573 '0.80'
1574 ),
1575 'testing decimals with input as string' => array(
1576 '0.8',
1577 array(
1578 'numberFormat.' => array(
1579 'decimals' => 2
1580 ),
1581 ),
1582 '0.80'
1583 ),
1584 'testing dec_point' => array(
1585 0.8,
1586 array(
1587 'numberFormat.' => array(
1588 'decimals' => 1,
1589 'dec_point' => ','
1590 ),
1591 ),
1592 '0,8'
1593 ),
1594 'testing thousands_sep' => array(
1595 999.99,
1596 array(
1597 'numberFormat.' => array(
1598 'decimals' => 0,
1599 'thousands_sep.' => array(
1600 'char' => 46
1601 ),
1602 ),
1603 ),
1604 '1.000'
1605 ),
1606 'testing mixture' => array(
1607 1281731.45,
1608 array(
1609 'numberFormat.' => array(
1610 'decimals' => 1,
1611 'dec_point.' => array(
1612 'char' => 44
1613 ),
1614 'thousands_sep.' => array(
1615 'char' => 46
1616 ),
1617 ),
1618 ),
1619 '1.281.731,5'
1620 )
1621 );
1622 }
1623
1624 /**
1625 * Test for the stdWrap function "stdWrap_numberFormat"
1626 *
1627 * @param float $float
1628 * @param array $conf
1629 * @param string $expected
1630 * @return void
1631 * @dataProvider stdWrap_numberFormatDataProvider
1632 * @test
1633 */
1634 public function stdWrap_numberFormat($float, $conf, $expected)
1635 {
1636 $result = $this->subject->stdWrap_numberFormat($float, $conf);
1637 $this->assertEquals($expected, $result);
1638 }
1639
1640 /**
1641 * Data provider for expandList
1642 *
1643 * @return array [$expect, $content]
1644 */
1645 public function stdWrap_expandListDataProvider()
1646 {
1647 return [
1648 'numbers' => ['1,2,3', '1,2,3'],
1649 'range' => ['3,4,5', '3-5'],
1650 'numbers and range' => ['1,3,4,5,7', '1,3-5,7']
1651 ];
1652 }
1653
1654 /**
1655 * Test for the stdWrap function "expandList"
1656 *
1657 * The method simply delegates to GeneralUtility::expandList. There is no
1658 * need to repeat the full set of tests of this method here. As PHPUnit
1659 * can't mock static methods, to prove they are called, all we do here
1660 * is to provide a few smoke tests.
1661 *
1662 * @test
1663 * @dataProvider stdWrap_expandListDataProvider
1664 * @param string $expected The expeced output.
1665 * @param string $content The given content.
1666 * @return void
1667 */
1668 public function stdWrap_expandList($expected, $content)
1669 {
1670 $this->assertEquals($expected,
1671 $this->subject->stdWrap_expandList($content));
1672 }
1673
1674 /**
1675 * Data provider for stdWrap_trim.
1676 *
1677 * @return array [$expect, $content]
1678 */
1679 public function stdWrap_trimDataProvider()
1680 {
1681 return [
1682 // string not trimmed
1683 'empty string' => ['', ''],
1684 'string without whitespace' => ['xxx', 'xxx'],
1685 'string with whitespace inside' => [
1686 'xx ' . TAB . ' xx',
1687 'xx ' . TAB . ' xx',
1688 ],
1689 'string with newlines inside' => [
1690 'xx ' . PHP_EOL . ' xx',
1691 'xx ' . PHP_EOL . ' xx',
1692 ],
1693 // string trimmed
1694 'blanks around' => ['xxx', ' xxx '],
1695 'tabs around' => ['xxx', TAB . 'xxx' . TAB],
1696 'newlines around' => ['xxx', PHP_EOL . 'xxx' . PHP_EOL],
1697 'mixed case' => ['xxx', TAB . ' xxx ' . PHP_EOL],
1698 // non strings
1699 'null' => ['', null],
1700 'false' => ['', false],
1701 'true' => ['1', true],
1702 'zero' => ['0', 0],
1703 'one' => ['1', 1],
1704 '-1' => ['-1', -1],
1705 '0.0' => ['0', 0.0],
1706 '1.0' => ['1', 1.0],
1707 '-1.0' => ['-1', -1.0],
1708 '1.1' => ['1.1', 1.1],
1709 ];
1710 }
1711
1712 /**
1713 * Check that stdWrap_trim works properly.
1714 *
1715 * Show:
1716 *
1717 * - the given string is trimmed like PHP trim
1718 * - non-strings are casted to strings:
1719 * - null => 'null'
1720 * - false => ''
1721 * - true => '1'
1722 * - 0 => '0'
1723 * - -1 => '-1'
1724 * - 1.0 => '1'
1725 * - 1.1 => '1.1'
1726 *
1727 * @test
1728 * @dataProvider stdWrap_trimDataProvider
1729 * @param string $expected The expected output.
1730 * @param mixed $content The given content.
1731 * @return void
1732 */
1733 public function stdWrap_trim($expect, $content)
1734 {
1735 $result = $this->subject->stdWrap_trim($content);
1736 $this->assertSame($expect, $result);
1737 }
1738
1739 /**
1740 * Data provider for stdWrap_if.
1741 *
1742 * @return array [$expect, $stop, $content, $conf, $times, $will]
1743 */
1744 public function stdWrap_ifDataProvider()
1745 {
1746 $content = $this->getUniqueId('content');
1747 $conf = ['if.' => [$this->getUniqueId('if.')]];
1748 return [
1749 // evals to true
1750 'empty config' => [
1751 $content, false, $content, [], 0, null
1752 ],
1753 'if. is empty array' => [
1754 $content, false, $content, ['if.' => []], 0, null
1755 ],
1756 'if. is null' => [
1757 $content, false, $content, ['if.' => null], 0, null
1758 ],
1759 'if. is false' => [
1760 $content, false, $content, ['if.' => false], 0, null
1761 ],
1762 'if. is 0' => [
1763 $content, false, $content, ['if.' => false], 0, null
1764 ],
1765 'if. is "0"' => [
1766 $content, false, $content, ['if.' => '0'], 0, null
1767 ],
1768 'checkIf returning true' => [
1769 $content, false, $content, $conf, 1, true
1770 ],
1771 // evals to false
1772 'checkIf returning false' => [
1773 '', true, $content, $conf, 1, false
1774 ],
1775 ];
1776 }
1777
1778 /**
1779 * Check if stdWrap_if works properly.
1780 *
1781 * Show:
1782 *
1783 * - Delegates to the method checkIf to check for 'true'.
1784 * - The parameter to checkIf is $conf['if.'].
1785 * - Is also 'true' if $conf['if.'] is empty (PHP method empty).
1786 * - 'False' triggers a stop of further rendering.
1787 * - Returns the content as is or '' if false.
1788 *
1789 * @test
1790 * @dataProvider stdWrap_ifDataProvider
1791 * @param mixed $expect The expected output.
1792 * @param bool $stop Expect stop further rendering.
1793 * @param mixed $content The given content.
1794 * @param mixed $config The given configuration.
1795 * @param int $times Times checkIf is called (0 or 1).
1796 * @param bool|null $will Return of checkIf (null if not called).
1797 * @return void
1798 */
1799 public function stdWrap_if($expect, $stop, $content, $conf, $times, $will)
1800 {
1801 $subject = $this->getAccessibleMock(
1802 ContentObjectRenderer::class, ['checkIf']);
1803 $subject->_set('stdWrapRecursionLevel', 1);
1804 $subject->_set('stopRendering', [1 => false]);
1805 $subject
1806 ->expects($this->exactly($times))
1807 ->method('checkIf')
1808 ->with($conf['if.'])
1809 ->willReturn($will);
1810 $this->assertSame($expect, $subject->stdWrap_if($content, $conf));
1811 $this->assertSame($stop, $subject->_get('stopRendering')[1]);
1812 }
1813
1814 /**
1815 * Data provider for stdWrap_intval
1816 *
1817 * @return array [$expect, $content]
1818 */
1819 public function stdWrap_intvalDataProvider()
1820 {
1821 return [
1822 // numbers
1823 'int' => [123, 123],
1824 'float' => [123, 123.45],
1825 'float does not round up' => [123, 123.55],
1826 // negative numbers
1827 'negative int' => [-123, -123],
1828 'negative float' => [-123, -123.45],
1829 'negative float does not round down' => [ -123, -123.55],
1830 // strings
1831 'word string' => [0, 'string'],
1832 'empty string' => [0, ''],
1833 'zero string' => [0, '0'],
1834 'int string' => [123, '123'],
1835 'float string' => [123, '123.55'],
1836 'negative float string' => [-123, '-123.55'],
1837 // other types
1838 'null' => [0, null],
1839 'true' => [1, true],
1840 'false' => [0, false]
1841 ];
1842 }
1843
1844 /**
1845 * Check that stdWrap_intval works properly.
1846 *
1847 * Show:
1848 *
1849 * - It does not round up.
1850 * - All types of input is casted to int:
1851 * - null: 0
1852 * - false: 0
1853 * - true: 1
1854 * -
1855 *
1856 *
1857 *
1858 * @test
1859 * @dataProvider stdWrap_intvalDataProvider
1860 * @param int $expect The expected output.
1861 * @param string $content The given input.
1862 * @return void
1863 */
1864 public function stdWrap_intval($expect, $content)
1865 {
1866 $this->assertSame($expect, $this->subject->stdWrap_intval($content));
1867 }
1868
1869 /**
1870 * Data provider for stdWrap_strPad.
1871 *
1872 * @return array [$expect, $content, $conf]
1873 */
1874 public function stdWrap_strPadDataProvider()
1875 {
1876 return [
1877 'pad string with default settings and length 10' => [
1878 'Alien ',
1879 'Alien',
1880 [
1881 'length' => '10',
1882 ],
1883 ],
1884 'pad string with padWith -= and type left and length 10' => [
1885 '-=-=-Alien',
1886 'Alien',
1887 [
1888 'length' => '10',
1889 'padWith' => '-=',
1890 'type' => 'left',
1891 ],
1892 ],
1893 'pad string with padWith _ and type both and length 10' => [
1894 '__Alien___',
1895 'Alien',
1896 [
1897 'length' => '10',
1898 'padWith' => '_',
1899 'type' => 'both',
1900 ],
1901 ],
1902 'pad string with padWith 0 and type both and length 10' => [
1903 '00Alien000',
1904 'Alien',
1905 [
1906 'length' => '10',
1907 'padWith' => '0',
1908 'type' => 'both',
1909 ],
1910 ],
1911 'pad string with padWith ___ and type both and length 6' => [
1912 'Alien_',
1913 'Alien',
1914 [
1915 'length' => '6',
1916 'padWith' => '___',
1917 'type' => 'both',
1918 ],
1919 ],
1920 'pad string with padWith _ and type both and length 12, using stdWrap for length' => [
1921 '___Alien____',
1922 'Alien',
1923 [
1924 'length' => '1',
1925 'length.' => [
1926 'wrap' => '|2',
1927 ],
1928 'padWith' => '_',
1929 'type' => 'both',
1930 ],
1931 ],
1932 'pad string with padWith _ and type both and length 12, using stdWrap for padWidth' => [
1933 '-_=Alien-_=-',
1934 'Alien',
1935 [
1936 'length' => '12',
1937 'padWith' => '_',
1938 'padWith.' => [
1939 'wrap' => '-|=',
1940 ],
1941 'type' => 'both',
1942 ],
1943 ],
1944 'pad string with padWith _ and type both and length 12, using stdWrap for type' => [
1945 '_______Alien',
1946 'Alien',
1947 [
1948 'length' => '12',
1949 'padWith' => '_',
1950 'type' => 'both',
1951 // make type become "left"
1952 'type.' => [
1953 'substring' => '2,1',
1954 'wrap' => 'lef|',
1955 ],
1956 ],
1957 ],
1958 ];
1959 }
1960
1961 /**
1962 * Check if stdWrap_strPad works properly.
1963 *
1964 * @test
1965 * @dataProvider stdWrap_strPadDataProvider
1966 * @param string $expect The expected output.
1967 * @param string $content The given input.
1968 * @param array $conf The configuration of 'strPad.'.
1969 * @return void
1970 */
1971 public function stdWrap_strPad($expect, $content, $conf)
1972 {
1973 $conf = ['strPad.' => $conf];
1974 $result = $this->subject->stdWrap_strPad($content, $conf);
1975 $this->assertSame($expect, $result);
1976 }
1977
1978 /**
1979 * Check that stdWrap_stdWrap works properly.
1980 *
1981 * Show:
1982 * - Delegates to method stdWrap.
1983 * - Parameter 1 is $content.
1984 * - Parameter 2 is $conf['stdWrap.'].
1985 * - Returns the return value.
1986 *
1987 * @test
1988 * @return void.
1989 */
1990 public function stdWrap_stdWrap()
1991 {
1992 $content = $this->getUniqueId('content');
1993 $conf = [
1994 'stdWrap' => $this->getUniqueId('not used'),
1995 'stdWrap.' => [$this->getUniqueId('stdWrap.')],
1996 ];
1997 $return = $this->getUniqueId('return');
1998 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
1999 ->setMethods(['stdWrap'])->getMock();
2000 $subject
2001 ->expects($this->once())
2002 ->method('stdWrap')
2003 ->with($content, $conf['stdWrap.'])
2004 ->willReturn($return);
2005 $this->assertSame($return, $subject->stdWrap_stdWrap($content, $conf));
2006 }
2007
2008 /**
2009 * Data provider for the hash test
2010 *
2011 * @return array [$expect, $content, $conf]
2012 */
2013 public function hashDataProvider()
2014 {
2015 return [
2016 'md5' => [
2017 'bacb98acf97e0b6112b1d1b650b84971',
2018 'joh316',
2019 ['hash' => 'md5']
2020 ],
2021 'sha1' => [
2022 '063b3d108bed9f88fa618c6046de0dccadcf3158',
2023 'joh316',
2024 ['hash' => 'sha1']
2025 ],
2026 'stdWrap capability' => [
2027 'bacb98acf97e0b6112b1d1b650b84971',
2028 'joh316',
2029 [
2030 'hash' => '5',
2031 'hash.' => ['wrap' => 'md|']
2032 ]
2033 ],
2034 'non-existing hashing algorithm' => [
2035 '',
2036 'joh316',
2037 ['hash' => 'non-existing']
2038 ]
2039 ];
2040 }
2041
2042 /**
2043 * Check if stdWrap_hash works properly.
2044 *
2045 * Show:
2046 *
2047 * - Algorithms: sha1, md5
2048 * - Returns '' for invalid algorithm.
2049 * - Value can be processed by stdWrap.
2050 *
2051 * @test
2052 * @dataProvider hashDataProvider
2053 * @param string $expect The expected output.
2054 * @param string $content The given content.
2055 * @param array $conf The given configuration.
2056 * @return void
2057 */
2058 public function stdWrap_hash($expect, $content, $conf)
2059 {
2060 $this->assertSame($expect,
2061 $this->subject->stdWrap_hash($content, $conf));
2062 }
2063
2064 /**
2065 * @test
2066 */
2067 public function recursiveStdWrapProperlyRendersBasicString()
2068 {
2069 $stdWrapConfiguration = array(
2070 'noTrimWrap' => '|| 123|',
2071 'stdWrap.' => array(
2072 'wrap' => '<b>|</b>'
2073 )
2074 );
2075 $this->assertSame(
2076 '<b>Test</b> 123',
2077 $this->subject->stdWrap('Test', $stdWrapConfiguration)
2078 );
2079 }
2080
2081 /**
2082 * @test
2083 */
2084 public function recursiveStdWrapIsOnlyCalledOnce()
2085 {
2086 $stdWrapConfiguration = array(
2087 'append' => 'TEXT',
2088 'append.' => array(
2089 'data' => 'register:Counter'
2090 ),
2091 'stdWrap.' => array(
2092 'append' => 'LOAD_REGISTER',
2093 'append.' => array(
2094 'Counter.' => array(
2095 'prioriCalc' => 'intval',
2096 'cObject' => 'TEXT',
2097 'cObject.' => array(
2098 'data' => 'register:Counter',
2099 'wrap' => '|+1',
2100 )
2101 )
2102 )
2103 )
2104 );
2105 $this->assertSame(
2106 'Counter:1',
2107 $this->subject->stdWrap('Counter:', $stdWrapConfiguration)
2108 );
2109 }
2110
2111 /**
2112 * Data provider for the numberFormat test
2113 *
2114 * @return array multi-dimensional array with the second level like this:
2115 * @see numberFormat
2116 */
2117 public function numberFormatDataProvider()
2118 {
2119 $data = array(
2120 'testing decimals' => array(
2121 0.8,
2122 array(
2123 'decimals' => 2
2124 ),
2125 '0.80'
2126 ),
2127 'testing decimals with input as string' => array(
2128 '0.8',
2129 array(
2130 'decimals' => 2
2131 ),
2132 '0.80'
2133 ),
2134 'testing dec_point' => array(
2135 0.8,
2136 array(
2137 'decimals' => 1,
2138 'dec_point' => ','
2139 ),
2140 '0,8'
2141 ),
2142 'testing thousands_sep' => array(
2143 999.99,
2144 array(
2145 'decimals' => 0,
2146 'thousands_sep.' => array(
2147 'char' => 46
2148 )
2149 ),
2150 '1.000'
2151 ),
2152 'testing mixture' => array(
2153 1281731.45,
2154 array(
2155 'decimals' => 1,
2156 'dec_point.' => array(
2157 'char' => 44
2158 ),
2159 'thousands_sep.' => array(
2160 'char' => 46
2161 )
2162 ),
2163 '1.281.731,5'
2164 )
2165 );
2166 return $data;
2167 }
2168
2169 /**
2170 * Check if stdWrap.numberFormat and all of its properties work properly
2171 *
2172 * @dataProvider numberFormatDataProvider
2173 * @test
2174 */
2175 public function numberFormat($float, $formatConf, $expected)
2176 {
2177 $result = $this->subject->numberFormat($float, $formatConf);
2178 $this->assertEquals($expected, $result);
2179 }
2180
2181 /**
2182 * Check if stdWrap_replacement works properly.
2183 *
2184 * Show:
2185 *
2186 * - Delegates to method replacement.
2187 * - Parameter 1 is $content.
2188 * - Parameter 2 is $conf['replacement.'].
2189 * - Returns the return value.
2190 *
2191 * @test
2192 * @return void
2193 */
2194 public function stdWrap_replacement()
2195 {
2196 $content = $this->getUniqueId('content');
2197 $conf = [
2198 'replacement' => $this->getUniqueId('not used'),
2199 'replacement.' => [$this->getUniqueId('replacement.')],
2200 ];
2201 $return = $this->getUniqueId('return');
2202 $subject = $this->getMockBuilder(ContentObjectRenderer::class)
2203 ->setMethods(['replacement'])->getMock();
2204 $subject
2205 ->expects($this->once())
2206 ->method('replacement')
2207 ->with( $content, $conf['replacement.'])
2208 ->willReturn($return);
2209 $this->assertSame($return,
2210 $subject->stdWrap_replacement($content, $conf));
2211 }
2212
2213 /**
2214 * Data provider replacement
2215 *
2216 * @return array [$expect, $content, $conf]
2217 */
2218 public function replacementDataProvider()
2219 {
2220 return [
2221 'multiple replacements, including regex' => [
2222 'There is an animal, an animal and an animal around the block! Yeah!',
2223 'There_is_a_cat,_a_dog_and_a_tiger_in_da_hood!_Yeah!',
2224 [
2225 '20.' => [
2226 'search' => '_',
2227 'replace.' => ['char' => '32']
2228 ],
2229 '120.' => [
2230 'search' => 'in da hood',
2231 'replace' => 'around the block'
2232 ],
2233 '130.' => [
2234 'search' => '#a (Cat|Dog|Tiger)#i',
2235 'replace' => 'an animal',
2236 'useRegExp' => '1'
2237 ]
2238 ]
2239 ],
2240 'replacement with optionSplit, normal pattern' => [
2241 'There1is2a3cat,3a3dog3and3a3tiger3in3da3hood!3Yeah!',
2242 'There_is_a_cat,_a_dog_and_a_tiger_in_da_hood!_Yeah!',
2243 [
2244 '10.' => [
2245 'search' => '_',
2246 'replace' => '1 || 2 || 3',
2247 'useOptionSplitReplace' => '1'
2248 ]
2249 ]
2250 ],
2251 'replacement with optionSplit, using regex' => [
2252 'There is a tiny cat, a midsized dog and a big tiger in da hood! Yeah!',
2253 'There is a cat, a dog and a tiger in da hood! Yeah!',
2254 [
2255 '10.' => [
2256 'search' => '#(a) (Cat|Dog|Tiger)#i',
2257 'replace' => '${1} tiny ${2} || ${1} midsized ${2} || ${1} big ${2}',
2258 'useOptionSplitReplace' => '1',
2259 'useRegExp' => '1'
2260 ]
2261 ]
2262 ]
2263 ];
2264 }
2265
2266 /**
2267 * Check if stdWrap.replacement and all of its properties work properly
2268 *
2269 * @test
2270 * @dataProvider replacementDataProvider
2271 * @param string $content The given input.
2272 * @param string $expects The expected result.
2273 * @param array $conf The given configuration.
2274 * @return void
2275 */
2276 public function replacement($expects, $content, $conf)
2277 {
2278 $this->assertSame($expects,
2279 $this->subject->_call('replacement', $content, $conf));
2280 }
2281
2282 /**
2283 * @return array
2284 */
2285 public function stdWrapRawUrlEncodeDataProvider()
2286 {
2287 return [
2288 'https://typo3.org?id=10' => ['https://typo3.org?id=10', 'https%3A%2F%2Ftypo3.org%3Fid%3D10'],
2289 'https://typo3.org?id=10&foo=bar' => ['https://typo3.org?id=10&foo=bar', 'https%3A%2F%2Ftypo3.org%3Fid%3D10%26foo%3Dbar'],
2290 ];
2291 }
2292
2293 /**
2294 * Check if rawUrlEncode works properly
2295 *
2296 * @test
2297 * @dataProvider stdWrapRawUrlEncodeDataProvider
2298 */
2299 public function stdWrap_rawUrlEncode($input, $expected)
2300 {
2301 $this->assertEquals($expected, $this->subject->stdWrap_rawUrlEncode($input));
2302 }
2303
2304 /**
2305 * Data provider for the getQuery test
2306 *
2307 * @return array multi-dimensional array with the second level like this:
2308 * @see getQuery
2309 */
2310 public function getQueryDataProvider()
2311 {
2312 $data = array(
2313 'testing empty conf' => array(
2314 'tt_content',
2315 array(),
2316 array(
2317 'SELECT' => '*'
2318 )
2319 ),
2320 'testing #17284: adding uid/pid for workspaces' => array(
2321 'tt_content',
2322 array(
2323 'selectFields' => 'header,bodytext'
2324 ),
2325 array(
2326 'SELECT' => 'header,bodytext, tt_content.uid as uid, tt_content.pid as pid, tt_content.t3ver_state as t3ver_state'
2327 )
2328 ),
2329 'testing #17284: no need to add' => array(
2330 'tt_content',
2331 array(
2332 'selectFields' => 'tt_content.*'
2333 ),
2334 array(
2335 'SELECT' => 'tt_content.*'
2336 )
2337 ),
2338 'testing #17284: no need to add #2' => array(
2339 'tt_content',
2340 array(
2341 'selectFields' => '*'
2342 ),
2343 array(
2344 'SELECT' => '*'
2345 )
2346 ),
2347 'testing #29783: joined tables, prefix tablename' => array(
2348 'tt_content',
2349 array(
2350 'selectFields' => 'tt_content.header,be_users.username',
2351 'join' => 'be_users ON tt_content.cruser_id = be_users.uid'
2352 ),
2353 array(
2354 'SELECT' => 'tt_content.header,be_users.username, tt_content.uid as uid, tt_content.pid as pid, tt_content.t3ver_state as t3ver_state'
2355 )
2356 ),
2357 'testing #34152: single count(*), add nothing' => array(
2358 'tt_content',
2359 array(
2360 'selectFields' => 'count(*)'
2361 ),
2362 array(
2363 'SELECT' => 'count(*)'
2364 )
2365 ),
2366 'testing #34152: single max(crdate), add nothing' => array(
2367 'tt_content',
2368 array(
2369 'selectFields' => 'max(crdate)'
2370 ),
2371 array(
2372 'SELECT' => 'max(crdate)'
2373 )
2374 ),
2375 'testing #34152: single min(crdate), add nothing' => array(
2376 'tt_content',
2377 array(
2378 'selectFields' => 'min(crdate)'
2379 ),
2380 array(
2381 'SELECT' => 'min(crdate)'
2382 )
2383 ),
2384 'testing #34152: single sum(is_siteroot), add nothing' => array(
2385 'tt_content',
2386 array(
2387 'selectFields' => 'sum(is_siteroot)'
2388 ),
2389 array(
2390 'SELECT' => 'sum(is_siteroot)'
2391 )
2392 ),
2393 'testing #34152: single avg(crdate), add nothing' => array(
2394 'tt_content',
2395 array(
2396 'selectFields' => 'avg(crdate)'
2397 ),
2398 array(
2399 'SELECT' => 'avg(crdate)'
2400 )
2401 )
2402 );
2403 return $data;
2404 }
2405
2406 /**
2407 * Check if sanitizeSelectPart works as expected
2408 *
2409 * @dataProvider getQueryDataProvider
2410 * @test
2411 */
2412 public function getQuery($table, $conf, $expected)
2413 {
2414 $GLOBALS['TCA'] = array(
2415 'pages' => array(
2416 'ctrl' => array(
2417 'enablecolumns' => array(
2418 'disabled' => 'hidden'
2419 )
2420 )
2421 ),
2422 'tt_content' => array(
2423 'ctrl' => array(
2424 'enablecolumns' => array(
2425 'disabled' => 'hidden'
2426 ),
2427 'versioningWS' => true
2428 )
2429 ),
2430 );
2431 $result = $this->subject->getQuery($table, $conf, true);
2432 foreach ($expected as $field => $value) {
2433 $this->assertEquals($value, $result[$field]);
2434 }
2435 }
2436
2437 /**
2438 * @test
2439 */
2440 public function getQueryCallsGetTreeListWithNegativeValuesIfRecursiveIsSet()
2441 {
2442 $GLOBALS['TCA'] = array(
2443 'pages' => array(
2444 'ctrl' => array(
2445 'enablecolumns' => array(
2446 'disabled' => 'hidden'
2447 )
2448 )
2449 ),
2450 'tt_content' => array(
2451 'ctrl' => array(
2452 'enablecolumns' => array(
2453 'disabled' => 'hidden'
2454 )
2455 )
2456 ),
2457 );
2458 $this->subject = $this->getAccessibleMock(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class, array('getTreeList'));
2459 $this->subject->start(array(), 'tt_content');
2460 $conf = array(
2461 'recursive' => '15',
2462 'pidInList' => '16, -35'
2463 );
2464 $this->subject->expects($this->at(0))
2465 ->method('getTreeList')
2466 ->with(-16, 15)
2467 ->will($this->returnValue('15,16'));
2468 $this->subject->expects($this->at(1))
2469 ->method('getTreeList')
2470 ->with(-35, 15)
2471 ->will($this->returnValue('15,35'));
2472 $this->subject->getQuery('tt_content', $conf, true);
2473 }
2474
2475 /**
2476 * @test
2477 */
2478 public function getQueryCallsGetTreeListWithCurrentPageIfThisIsSet()
2479 {
2480 $GLOBALS['TCA'] = array(
2481 'pages' => array(
2482 'ctrl' => array(
2483 'enablecolumns' => array(
2484 'disabled' => 'hidden'
2485 )
2486 )
2487 ),
2488 'tt_content' => array(
2489 'ctrl' => array(
2490 'enablecolumns' => array(
2491 'disabled' => 'hidden'
2492 )
2493 )
2494 ),
2495 );
2496 $this->subject = $this->getAccessibleMock(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class, array('getTreeList'));
2497 $GLOBALS['TSFE']->id = 27;
2498 $this->subject->start(array(), 'tt_content');
2499 $conf = array(
2500 'pidInList' => 'this',
2501 'recursive' => '4'
2502 );
2503 $this->subject->expects($this->once())
2504 ->method('getTreeList')
2505 ->with(-27)
2506 ->will($this->returnValue('27'));
2507 $this->subject->getQuery('tt_content', $conf, true);
2508 }
2509
2510 /**
2511 * Data provider for the stdWrap_date test
2512 *
2513 * @return array [$expect, $content, $conf, $now]
2514 */
2515 public function stdWrap_dateDataProvider()
2516 {
2517 // Fictive execution time: 2015-10-02 12:00
2518 $now = 1443780000;
2519 return [
2520 'given timestamp' => [
2521 '02.10.2015',
2522 $now,
2523 ['date' => 'd.m.Y'],
2524 $now
2525 ],
2526 'empty string' => [
2527 '02.10.2015',
2528 '',
2529 ['date' => 'd.m.Y'],
2530 $now
2531 ],
2532 'testing null' => [
2533 '02.10.2015',
2534 null,
2535 ['date' => 'd.m.Y'],
2536 $now
2537 ],
2538 'given timestamp return GMT' => [
2539 '02.10.2015 10:00:00',
2540 $now,
2541 [
2542 'date' => 'd.m.Y H:i:s',
2543 'date.' => ['GMT' => true],
2544 ],
2545 $now
2546 ]
2547 ];
2548 }
2549
2550 /**
2551 * Check if stdWrap_date works properly.
2552 *
2553 * @test
2554 * @dataProvider stdWrap_dateDataProvider
2555 * @param string $expected The expected output.
2556 * @param mixed $content The given input.
2557 * @param array $conf The given configuration.
2558 * @param int $now Fictive execution time.
2559 * @return void
2560 */
2561 public function stdWrap_date($expected, $content, $conf, $now)
2562 {
2563 $GLOBALS['EXEC_TIME'] = $now;
2564 $this->assertEquals($expected,
2565 $this->subject->stdWrap_date($content, $conf));
2566 }
2567
2568 /**
2569 * Data provider for stdWrap_strftime
2570 *
2571 * @return array [$expect, $content, $conf, $now]
2572 */
2573 public function stdWrap_strftimeDataProvider()
2574 {
2575 // Fictive execution time is 2012-09-01 12:00 in UTC/GMT.
2576 $now = 1346500800;
2577 return [
2578 'given timestamp' => [
2579 '01-09-2012',
2580 $now,
2581 ['strftime' => '%d-%m-%Y'],
2582 $now
2583 ],
2584 'empty string' => [
2585 '01-09-2012',
2586 '',
2587 ['strftime' => '%d-%m-%Y'],
2588 $now
2589 ],
2590 'testing null' => [
2591 '01-09-2012',
2592 null,
2593 ['strftime' => '%d-%m-%Y'],
2594 $now
2595 ]
2596 ];
2597 }
2598
2599 /**
2600 * Check if stdWrap_strftime works properly.
2601 *
2602 * @test
2603 * @dataProvider stdWrap_strftimeDataProvider
2604 * @param string $expect The expected output.
2605 * @param mixed $content The given input.
2606 * @param array $conf The given configuration.
2607 * @param int $now Fictive execution time.
2608 * @return void
2609 */
2610 public function stdWrap_strftime($expect, $content, $conf, $now)
2611 {
2612 // Save current timezone and set to UTC to make the system under test
2613 // behave the same in all server timezone settings
2614 $timezoneBackup = date_default_timezone_get();
2615 date_default_timezone_set('UTC');
2616
2617 $GLOBALS['EXEC_TIME'] = $now;
2618 $result = $this->subject->stdWrap_strftime($content, $conf);
2619
2620 // Reset timezone
2621 date_default_timezone_set($timezoneBackup);
2622
2623 $this->assertSame($expect, $result);
2624 }
2625
2626 /**
2627 * Data provider for the stdWrap_strtotime test
2628 *
2629 * @return array [$expect, $content, $conf]
2630 */
2631 public function stdWrap_strtotimeDataProvider()
2632 {
2633 return [
2634 'date from content' => [
2635 1417651200, '2014-12-04',
2636 ['strtotime' => '1']
2637 ],
2638 'manipulation of date from content' => [
2639 1417996800, '2014-12-04',
2640 ['strtotime' => '+ 2 weekdays']
2641 ],
2642 'date from configuration' => [
2643 1417651200, '',
2644 ['strtotime' => '2014-12-04']
2645 ],
2646 'manipulation of date from configuration' => [
2647 1417996800, '',
2648 ['strtotime' => '2014-12-04 + 2 weekdays']
2649 ],
2650 'empty input' => [
2651 false, '',
2652 ['strtotime' => '1']
2653 ],
2654 'date from content and configuration' => [
2655 false, '2014-12-04',
2656 ['strtotime' => '2014-12-05']
2657 ]
2658 ];
2659 }
2660
2661 /**
2662 * Check if stdWrap_strtotime works properly.
2663 *
2664 * @test
2665 * @dataProvider stdWrap_strtotimeDataProvider
2666 * @param int $expect The expected output.
2667 * @param mixed $content The given input.
2668 * @param array $conf The given configuration.
2669 * @return void
2670 */
2671 public function stdWrap_strtotime($expect, $content, $conf)
2672 {
2673 // Set exec_time to a hard timestamp
2674 $GLOBALS['EXEC_TIME'] = 1417392000;
2675 // Save current timezone and set to UTC to make the system under test
2676 // behave the same in all server timezone settings
2677 $timezoneBackup = date_default_timezone_get();
2678 date_default_timezone_set('UTC');
2679
2680 $result = $this->subject->stdWrap_strtotime($content, $conf);
2681
2682 // Reset timezone
2683 date_default_timezone_set($timezoneBackup);
2684
2685 $this->assertEquals($expect, $result);
2686 }
2687
2688 /**
2689 * @test
2690 */
2691 public function stdWrap_ageCallsCalcAgeWithSubtractedTimestampAndSubPartOfArray()
2692 {
2693 $subject = $this->getMockBuilder(\TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer::class)
2694 ->setMethods(array('calcAge'))
2695 ->getMock();
2696 // Set exec_time to a hard timestamp
2697 $GLOBALS['EXEC_TIME'] = 10;
2698 $subject->expects($this->once())->method('calcAge')->with(1, 'Min| Hrs| Days| Yrs');
2699 $subject->stdWrap_age(9, array('age' => 'Min| Hrs| Days| Yrs'));
2700 }
2701
2702 /**
2703 * Data provider for calcAgeCalculatesAgeOfTimestamp
2704 *
2705 * @return array
2706 * @see calcAge
2707 */
2708 public function calcAgeCalculatesAgeOfTimestampDataProvider()
2709 {
2710 return array(
2711 'minutes' => array(
2712 120,
2713 ' min| hrs| days| yrs',
2714 '2 min',
2715 ),
2716 'hours' => array(
2717 7200,
2718 ' min| hrs| days| yrs',
2719 '2 hrs',
2720 ),
2721 'days' => array(
2722 604800,
2723 ' min| hrs| days| yrs',
2724 '7 days',
2725 ),
2726 'day with provided singular labels' => array(
2727 86400,
2728 ' min| hrs| days| yrs| min| hour| day| year',
2729 '1 day',
2730 ),
2731 'years' => array(
2732 1417997800,
2733 ' min| hrs| days| yrs',
2734 '45 yrs',
2735 ),
2736 'different labels' => array(
2737 120,
2738 ' Minutes| Hrs| Days| Yrs',
2739 '2 Minutes',
2740 ),
2741 'negative values' => array(
2742 -604800,
2743 ' min| hrs| days| yrs',
2744 '-7 days',
2745 ),
2746 'default label values for wrong label input' => array(
2747 121,
2748 10,
2749 '2 min',
2750 ),
2751 'default singular label values for wrong label input' => array(
2752 31536000,
2753 10,
2754 '1 year',
2755 )
2756 );
2757 }
2758
2759 /**
2760 * @param int $timestamp
2761 * @param string $labels
2762 * @param int $expectation
2763 * @dataProvider calcAgeCalculatesAgeOfTimestampDataProvider
2764 * @test
2765 */
2766 public function calcAgeCalculatesAgeOfTimestamp($timestamp, $labels, $expectation)
2767 {
2768 $result = $this->subject->calcAge($timestamp, $labels);
2769 $this->assertEquals($result, $expectation);
2770 }
2771
2772 /**
2773 * @return array
2774 */
2775 public function stdWrapReturnsExpectationDataProvider()
2776 {
2777 return [
2778 'Prevent silent bool conversion' => [
2779 '1+1',
2780 [
2781 'prioriCalc.' => [
2782 'wrap' => '|',
2783 ],
2784 ],
2785 '1+1',
2786 ],
2787 ];
2788 }
2789
2790 /**
2791 * @param string $content
2792 * @param array $configuration
2793 * @param string $expectation
2794 * @dataProvider stdWrapReturnsExpectationDataProvider
2795 * @test
2796 */
2797 public function stdWrapReturnsExpectation($content, array $configuration, $expectation)
2798 {
2799 $this->assertSame($expectation, $this->subject->stdWrap($content, $configuration));
2800 }
2801
2802 /**
2803 * Data provider for stdWrap_case test
2804 *
2805 * @return array
2806 */
2807 public function stdWrap_caseDataProvider()
2808 {
2809 return array(
2810 'lower case text to upper' => array(
2811 '<span>text</span>',
2812 array(
2813 'case' => 'upper',
2814 ),
2815 '<span>TEXT</span>',
2816 ),
2817 'upper case text to lower' => array(
2818 '<span>TEXT</span>',
2819 array(
2820 'case' => 'lower',
2821 ),
2822 '<span>text</span>',
2823 ),
2824 'capitalize text' => array(
2825 '<span>this is a text</span>',
2826 array(
2827 'case' => 'capitalize',
2828 ),
2829 '<span>This Is A Text</span>',
2830 ),
2831 'ucfirst text' => array(
2832 '<span>this is a text</span>',
2833 array(
2834 'case' => 'ucfirst',
2835 ),
2836 '<span>This is a text</span>',
2837 ),
2838 'lcfirst text' => array(
2839 '<span>This is a Text</span>',
2840 array(
2841 'case' => 'lcfirst',
2842 ),
2843 '<span>this is a Text</span>',
2844 ),
2845 'uppercamelcase text' => array(
2846 '<span>this_is_a_text</span>',
2847 array(
2848 'case' => 'uppercamelcase',
2849 ),
2850 '<span>ThisIsAText</span>',
2851 ),
2852 'lowercamelcase text' => array(
2853 '<span>this_is_a_text</span>',
2854 array(
2855 'case' => 'lowercamelcase',
2856 ),
2857 '<span>thisIsAText</span>',
2858 ),
2859 );
2860 }
2861
2862 /**
2863 * @param string|NULL $content
2864 * @param array $configuration
2865 * @param string $expected
2866 * @dataProvider stdWrap_caseDataProvider
2867 * @test
2868 */
2869 public function stdWrap_case($content, array $configuration, $expected)
2870 {
2871 $result = $this->subject->stdWrap_case($content, $configuration);
2872 $this->assertEquals($expected, $result);
2873 }
2874
2875 /**
2876 * Data provider for stdWrap_bytes test
2877 *
2878 * @return array
2879 */
2880 public function stdWrap_bytesDataProvider()
2881 {
2882 return array(
2883 'value 1234 default' => array(
2884 '1234',
2885 array(
2886 'bytes.' => array(
2887 'labels' => '',
2888 'base' => 0,
2889 ),
2890 ),
2891 '1.21 Ki',
2892 'en_US.UTF-8'
2893 ),
2894 'value 1234 si' => array(
2895 '1234',
2896 array(
2897 'bytes.' => array(
2898 'labels' => 'si',
2899 'base' => 0,
2900 ),
2901 ),
2902 '1.23 k',
2903 'en_US.UTF-8'
2904 ),
2905 'value 1234 iec' => array(
2906 '1234',
2907 array(
2908 'bytes.' => array(
2909 'labels' => 'iec',
2910 'base' => 0,
2911 ),
2912 ),
2913 '1.21 Ki',
2914 'en_US.UTF-8'
2915 ),
2916 'value 1234 a-i' => array(
2917 '1234',
2918 array(
2919 'bytes.' => array(
2920 'labels' => 'a|b|c|d|e|f|g|h|i',
2921 'base' => 1000,
2922 ),
2923 ),
2924 '1.23b',
2925 'en_US.UTF-8'
2926 ),
2927 'value 1234 a-i invalid base' => array(
2928 '1234',
2929 array(
2930 'bytes.' => array(
2931 'labels' => 'a|b|c|d|e|f|g|h|i',
2932 'base' => 54,
2933 ),
2934 ),
2935 '1.21b',
2936 'en_US.UTF-8'
2937 ),
2938 'value 1234567890 default' => array(
2939 '1234567890',
2940 array(
2941 'bytes.' => array(
2942 'labels' => '',
2943 'base' => 0,
2944 ),
2945 ),
2946 '1.15 Gi',
2947 'en_US.UTF-8'
2948 ),
2949 );
2950 }
2951
2952 /**
2953 * @param string|NULL $content
2954 * @param array $configuration
2955 * @param string $expected
2956 * @dataProvider stdWrap_bytesDataProvider
2957 * @test
2958 */
2959 public function stdWrap_bytes($content, array $configuration, $expected, $locale)
2960 {
2961 if (!setlocale(LC_NUMERIC, $locale)) {
2962 $this->markTestSkipped('Locale ' . $locale . ' is not available.');
2963 }
2964 $result = $this->subject->stdWrap_bytes($content, $configuration);
2965 $this->assertSame($expected, $result);
2966 }
2967
2968 /**
2969 * Data provider for stdWrap_substring test
2970 *
2971 * @return array
2972 */
2973 public function stdWrap_substringDataProvider()
2974 {
2975 return array(
2976 'sub -1' => array(
2977 'substring',
2978 array(
2979 'substring' => '-1',
2980 ),
2981 'g',
2982 ),
2983 'sub -1,0' => array(
2984 'substring',
2985 array(
2986 'substring' => '-1,0',
2987 ),
2988 'g',
2989 ),
2990 'sub -1,-1' => array(
2991 'substring',
2992 array(
2993 'substring' => '-1,-1',
2994 ),
2995 '',
2996 ),
2997 'sub -1,1' => array(
2998 'substring',
2999 array(
3000 'substring' => '-1,1',
3001 ),
3002 'g',
3003 ),
3004 'sub 0' => array(
3005 'substring',
3006 array(
3007 'substring' => '0',
3008 ),
3009 'substring',
3010 ),
3011 'sub 0,0' => array(
3012 'substring',
3013 array(
3014 'substring' => '0,0',
3015 ),
3016 'substring',
3017 ),
3018 'sub 0,-1' => array(
3019 'substring',
3020 array(
3021 'substring' => '0,-1',
3022 ),
3023 'substrin',
3024 ),
3025 'sub 0,1' => array(
3026 'substring',
3027 array(
3028 'substring' => '0,1',
3029 ),
3030 's',
3031 ),
3032 'sub 1' => array(
3033 'substring',
3034 array(
3035 'substring' => '1',
3036 ),