2 /***************************************************************
5 * (c) 2009-2011 Ingo Renner <ingo@typo3.org>
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
26 * Testcase for class t3lib_div
28 * @author Ingo Renner <ingo@typo3.org>
29 * @author Oliver Klee <typo3-coding@oliverklee.de>
34 class t3lib_divTest
extends tx_phpunit_testcase
{
36 * Enable backup of global and system variables
40 protected $backupGlobals = TRUE;
43 * Exclude TYPO3_DB from backup/ restore of $GLOBALS
44 * because resource types cannot be handled during serializing
48 protected $backupGlobalsBlacklist = array('TYPO3_DB');
50 public function tearDown() {
51 t3lib_div
::purgeInstances();
54 ///////////////////////////
55 // Tests concerning _GP
56 ///////////////////////////
60 * @dataProvider gpDataProvider
62 public function canRetrieveValueWithGP($key, $get, $post, $expected) {
65 $this->assertSame($expected, t3lib_div
::_GP($key));
69 * Data provider for canRetrieveValueWithGP.
70 * All test values also check whether slashes are stripped properly.
74 public function gpDataProvider() {
77 => array(NULL, array(), array(), NULL),
79 => array('cake', array(), array(), NULL),
81 => array('cake', array('cake' => 'li\\e'), array(), 'lie'),
83 => array('cake', array(), array('cake' => 'l\\ie'), 'lie'),
84 'Value from POST preferred over GET'
85 => array('cake', array('cake' => 'is a'), array('cake' => '\\lie'), 'lie'),
86 'Value can be an array'
89 array('cake' => array('is a' => 'l\\ie')),
91 array('is a' => 'lie')
96 ///////////////////////////
97 // Tests concerning _GPmerged
98 ///////////////////////////
102 * @dataProvider gpMergedDataProvider
104 public function gpMergedWillMergeArraysFromGetAndPost($get, $post, $expected) {
107 $this->assertEquals($expected, t3lib_div
::_GPmerged('cake'));
111 * Data provider for gpMergedWillMergeArraysFromGetAndPost
115 public function gpMergedDataProvider() {
116 $fullDataArray = array('cake' => array('a' => 'is a','b' => 'lie'));
117 $postPartData = array('cake' => array('b' => 'lie'));
118 $getPartData = array('cake' => array('a' => 'is a'));
119 $getPartDataModified = array('cake' => array('a' => 'is not a'));
122 => array(array('foo'), array('bar'), array()),
124 => array($fullDataArray, array(), $fullDataArray['cake']),
126 => array(array(), $fullDataArray, $fullDataArray['cake']),
127 'POST and GET are merged'
128 => array($getPartData, $postPartData, $fullDataArray['cake']),
129 'POST is preferred over GET'
130 => array($getPartDataModified, $fullDataArray, $fullDataArray['cake'])
134 ///////////////////////////////
135 // Tests concerning _GET / _POST
136 ///////////////////////////////
139 * Data provider for canRetrieveGlobalInputsThroughGet
140 * and canRetrieveGlobalInputsThroughPost
144 public function getAndPostDataProvider() {
146 'Requested input data doesn\'t exist'
147 => array('cake', array(), NULL),
148 'No key will return entire input data'
149 => array(NULL, array('cake' => 'l\\ie'), array('cake' => 'lie')),
150 'Can retrieve specific input'
151 => array('cake', array('cake' => 'li\\e', 'foo'), 'lie'),
152 'Can retrieve nested input data'
153 => array('cake', array('cake' => array('is a' => 'l\\ie')), array('is a' => 'lie'))
159 * @dataProvider getAndPostDataProvider
161 public function canRetrieveGlobalInputsThroughGet($key, $get, $expected) {
163 $this->assertSame($expected, t3lib_div
::_GET($key));
168 * @dataProvider getAndPostDataProvider
170 public function canRetrieveGlobalInputsThroughPost($key, $post, $expected) {
172 $this->assertSame($expected, t3lib_div
::_POST($key));
175 ///////////////////////////////
176 // Tests concerning _GETset
177 ///////////////////////////////
181 * @dataProvider getSetDataProvider
183 public function canSetNewGetInputValues($input, $key, $expected, $getPreset=array()) {
185 t3lib_div
::_GETset($input, $key);
186 $this->assertSame($expected, $_GET);
190 * Data provider for canSetNewGetInputValues
194 public function getSetDataProvider() {
196 'No input data used without target key'
197 => array(NULL, NULL, array()),
198 'No input data used with target key'
199 => array(NULL, 'cake', array('cake' => '')),
200 'No target key used with string input data'
201 => array('data', NULL, array()),
202 'No target key used with array input data'
203 => array(array('cake' => 'lie'), NULL, array('cake' => 'lie')),
204 'Target key and string input data'
205 => array('lie', 'cake', array('cake' => 'lie')),
206 'Replace existing GET data'
207 => array('lie', 'cake', array('cake' => 'lie'), array('cake' => 'is a lie')),
208 'Target key pointing to sublevels and string input data'
209 => array('lie', 'cake|is', array('cake' => array('is' => 'lie'))),
210 'Target key pointing to sublevels and array input data'
211 => array(array('a' => 'lie'), 'cake|is', array('cake' => array('is' => array('a' => 'lie'))))
215 ///////////////////////////////
216 // Tests concerning gif_compress
217 ///////////////////////////////
222 public function gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() {
223 if (TYPO3_OS
== 'WIN') {
224 $this->markTestSkipped('gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() test not available on Windows.');
227 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] ||
!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']) {
228 $this->markTestSkipped('gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() test not available without imagemagick setup.');
231 $testFinder = t3lib_div
::makeInstance('Tx_Phpunit_Service_TestFinder');
232 $fixtureGifFile = $testFinder->getAbsoluteCoreTestsPath() . 'Unit/t3lib/fixtures/clear.gif';
234 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gif_compress'] = TRUE;
236 // Copy file to unique filename in typo3temp, set target permissions and run method
237 $testFilename = PATH_site
. 'typo3temp/' . uniqid('test_') . '.gif';
238 @copy
($fixtureGifFile, $testFilename);
239 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
240 t3lib_div
::gif_compress($testFilename, 'IM');
242 // Get actual permissions and clean up
244 $resultFilePermissions = substr(decoct(fileperms($testFilename)), 2);
245 t3lib_div
::unlink_tempfile($testFilename);
247 $this->assertEquals($resultFilePermissions, '0777');
253 public function gifCompressFixesPermissionOfConvertedFileIfUsingGd() {
254 if (TYPO3_OS
== 'WIN') {
255 $this->markTestSkipped('gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() test not available on Windows.');
258 $testFinder = t3lib_div
::makeInstance('Tx_Phpunit_Service_TestFinder');
259 $fixtureGifFile = $testFinder->getAbsoluteCoreTestsPath() . 'Unit/t3lib/fixtures/clear.gif';
261 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'] = TRUE;
262 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'] = FALSE;
264 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gif_compress'] = TRUE;
266 // Copy file to unique filename in typo3temp, set target permissions and run method
267 $testFilename = PATH_site
. 'typo3temp/' . uniqid('test_') . '.gif';
268 @copy
($fixtureGifFile, $testFilename);
269 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
270 t3lib_div
::gif_compress($testFilename, 'GD');
272 // Get actual permissions and clean up
274 $resultFilePermissions = substr(decoct(fileperms($testFilename)), 2);
275 t3lib_div
::unlink_tempfile($testFilename);
277 $this->assertEquals($resultFilePermissions, '0777');
280 ///////////////////////////////
281 // Tests concerning png_to_gif_by_imagemagick
282 ///////////////////////////////
287 public function pngToGifByImagemagickFixesPermissionsOfConvertedFile() {
288 if (TYPO3_OS
== 'WIN') {
289 $this->markTestSkipped('pngToGifByImagemagickFixesPermissionsOfConvertedFile() test not available on Windows.');
292 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] ||
!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']) {
293 $this->markTestSkipped('pngToGifByImagemagickFixesPermissionsOfConvertedFile() test not available without imagemagick setup.');
296 $testFinder = t3lib_div
::makeInstance('Tx_Phpunit_Service_TestFinder');
297 $fixturePngFile = $testFinder->getAbsoluteCoreTestsPath() . 'Unit/t3lib/fixtures/clear.png';
299 $GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif'] = TRUE;
301 // Copy file to unique filename in typo3temp, set target permissions and run method
302 $testFilename = PATH_site
. 'typo3temp/' . uniqid('test_') . '.png';
303 @copy
($fixturePngFile, $testFilename);
304 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
305 $newGifFile = t3lib_div
::png_to_gif_by_imagemagick($testFilename);
307 // Get actual permissions and clean up
309 $resultFilePermissions = substr(decoct(fileperms($newGifFile)), 2);
310 t3lib_div
::unlink_tempfile($newGifFile);
312 $this->assertEquals($resultFilePermissions, '0777');
315 ///////////////////////////////
316 // Tests concerning read_png_gif
317 ///////////////////////////////
322 public function readPngGifFixesPermissionsOfConvertedFile() {
323 if (TYPO3_OS
== 'WIN') {
324 $this->markTestSkipped('readPngGifFixesPermissionsOfConvertedFile() test not available on Windows.');
327 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) {
328 $this->markTestSkipped('readPngGifFixesPermissionsOfConvertedFile() test not available without imagemagick setup.');
331 $testFinder = t3lib_div
::makeInstance('Tx_Phpunit_Service_TestFinder');
332 $testGifFile = $testFinder->getAbsoluteCoreTestsPath() . 'Unit/t3lib/fixtures/clear.gif';
334 // Set target permissions and run method
335 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
336 $newPngFile = t3lib_div
::read_png_gif($testGifFile, TRUE);
338 // Get actual permissions and clean up
340 $resultFilePermissions = substr(decoct(fileperms($newPngFile)), 2);
341 t3lib_div
::unlink_tempfile($newPngFile);
343 $this->assertEquals($resultFilePermissions, '0777');
346 ///////////////////////////
347 // Tests concerning cmpIPv4
348 ///////////////////////////
351 * Data provider for cmpIPv4ReturnsTrueForMatchingAddress
353 * @return array Data sets
355 public static function cmpIPv4DataProviderMatching() {
357 'host with full IP address' => array('127.0.0.1', '127.0.0.1'),
358 'host with two wildcards at the end' => array('127.0.0.1', '127.0.*.*'),
359 'host with wildcard at third octet' => array('127.0.0.1', '127.0.*.1'),
360 'host with wildcard at second octet' => array('127.0.0.1', '127.*.0.1'),
361 '/8 subnet' => array('127.0.0.1', '127.1.1.1/8'),
362 '/32 subnet (match only name)' => array('127.0.0.1', '127.0.0.1/32'),
363 '/30 subnet' => array('10.10.3.1', '10.10.3.3/30'),
364 'host with wildcard in list with IPv4/IPv6 addresses' => array('192.168.1.1', '127.0.0.1, 1234:5678::/126, 192.168.*'),
365 'host in list with IPv4/IPv6 addresses' => array('192.168.1.1', '::1, 1234:5678::/126, 192.168.1.1'),
371 * @dataProvider cmpIPv4DataProviderMatching
373 public function cmpIPv4ReturnsTrueForMatchingAddress($ip, $list) {
374 $this->assertTrue(t3lib_div
::cmpIPv4($ip, $list));
378 * Data provider for cmpIPv4ReturnsFalseForNotMatchingAddress
380 * @return array Data sets
382 public static function cmpIPv4DataProviderNotMatching() {
384 'single host' => array('127.0.0.1', '127.0.0.2'),
385 'single host with wildcard' => array('127.0.0.1', '127.*.1.1'),
386 'single host with /32 subnet mask' => array('127.0.0.1', '127.0.0.2/32'),
387 '/31 subnet' => array('127.0.0.1', '127.0.0.2/31'),
388 'list with IPv4/IPv6 addresses' => array('127.0.0.1', '10.0.2.3, 192.168.1.1, ::1'),
389 'list with only IPv6 addresses' => array('10.20.30.40', '::1, 1234:5678::/127'),
395 * @dataProvider cmpIPv4DataProviderNotMatching
397 public function cmpIPv4ReturnsFalseForNotMatchingAddress($ip, $list) {
398 $this->assertFalse(t3lib_div
::cmpIPv4($ip, $list));
400 ///////////////////////////
401 // Tests concerning cmpIPv6
402 ///////////////////////////
405 * Data provider for cmpIPv6ReturnsTrueForMatchingAddress
407 * @return array Data sets
409 public static function cmpIPv6DataProviderMatching() {
411 'empty address' => array('::', '::'),
412 'empty with netmask in list' => array('::', '::/0'),
413 'empty with netmask 0 and host-bits set in list' => array('::', '::123/0'),
414 'localhost' => array('::1', '::1'),
415 'localhost with leading zero blocks' => array('::1', '0:0::1'),
416 'host with submask /128' => array('::1', '0:0::1/128'),
417 '/16 subnet' => array('1234::1', '1234:5678::/16'),
418 '/126 subnet' => array('1234:5678::3', '1234:5678::/126'),
419 '/126 subnet with host-bits in list set' => array('1234:5678::3', '1234:5678::2/126'),
420 'list with IPv4/IPv6 addresses' => array('1234:5678::3', '::1, 127.0.0.1, 1234:5678::/126, 192.168.1.1'),
426 * @dataProvider cmpIPv6DataProviderMatching
428 public function cmpIPv6ReturnsTrueForMatchingAddress($ip, $list) {
429 $this->assertTrue(t3lib_div
::cmpIPv6($ip, $list));
433 * Data provider for cmpIPv6ReturnsFalseForNotMatchingAddress
435 * @return array Data sets
437 public static function cmpIPv6DataProviderNotMatching() {
439 'empty against localhost' => array('::', '::1'),
440 'empty against localhost with /128 netmask' => array('::', '::1/128'),
441 'localhost against different host' => array('::1', '::2'),
442 'localhost against host with prior bits set' => array('::1', '::1:1'),
443 'host against different /17 subnet' => array('1234::1', '1234:f678::/17'),
444 'host against different /127 subnet' => array('1234:5678::3', '1234:5678::/127'),
445 'host against IPv4 address list' => array('1234:5678::3', '127.0.0.1, 192.168.1.1'),
446 'host against mixed list with IPv6 host in different subnet' => array('1234:5678::3', '::1, 1234:5678::/127'),
452 * @dataProvider cmpIPv6DataProviderNotMatching
454 public function cmpIPv6ReturnsFalseForNotMatchingAddress($ip, $list) {
455 $this->assertFalse(t3lib_div
::cmpIPv6($ip, $list));
458 ///////////////////////////////
459 // Tests concerning IPv6Hex2Bin
460 ///////////////////////////////
463 * Data provider for IPv6Hex2BinCorrect
465 * @return array Data sets
467 public static function IPv6Hex2BinDataProviderCorrect() {
469 'empty 1' => array('::', str_pad('', 16, "\x00")),
470 'empty 2, already normalized' => array('0000:0000:0000:0000:0000:0000:0000:0000', str_pad('', 16, "\x00")),
471 'already normalized' => array('0102:0304:0000:0000:0000:0000:0506:0078', "\x01\x02\x03\x04" . str_pad('', 8, "\x00") . "\x05\x06\x00\x78"),
472 'expansion in middle 1' => array('1::2', "\x00\x01" . str_pad('', 12, "\x00") . "\x00\x02"),
473 'expansion in middle 2' => array('beef::fefa', "\xbe\xef" . str_pad('', 12, "\x00") . "\xfe\xfa"),
479 * @dataProvider IPv6Hex2BinDataProviderCorrect
481 public function IPv6Hex2BinCorrectlyConvertsAddresses($hex, $binary) {
482 $this->assertTrue(t3lib_div
::IPv6Hex2Bin($hex) === $binary);
485 ///////////////////////////////
486 // Tests concerning IPv6Bin2Hex
487 ///////////////////////////////
490 * Data provider for IPv6Bin2HexCorrect
492 * @return array Data sets
494 public static function IPv6Bin2HexDataProviderCorrect() {
496 'empty' => array(str_pad('', 16, "\x00"), '::'),
497 'non-empty front' => array("\x01" . str_pad('', 15, "\x00"), '100::'),
498 'non-empty back' => array(str_pad('', 15, "\x00") . "\x01", '::1'),
499 'normalized' => array("\x01\x02\x03\x04" . str_pad('', 8, "\x00") . "\x05\x06\x00\x78", '102:304::506:78'),
500 'expansion in middle 1' => array("\x00\x01" . str_pad('', 12, "\x00") . "\x00\x02", '1::2'),
501 'expansion in middle 2' => array("\xbe\xef" . str_pad('', 12, "\x00") . "\xfe\xfa", 'beef::fefa'),
507 * @dataProvider IPv6Bin2HexDataProviderCorrect
509 public function IPv6Bin2HexCorrectlyConvertsAddresses($binary, $hex) {
510 $this->assertEquals(t3lib_div
::IPv6Bin2Hex($binary), $hex);
513 ////////////////////////////////////////////////
514 // Tests concerning normalizeIPv6 / compressIPv6
515 ////////////////////////////////////////////////
518 * Data provider for normalizeIPv6ReturnsCorrectlyNormalizedFormat
520 * @return array Data sets
522 public static function normalizeCompressIPv6DataProviderCorrect() {
524 'empty' => array('::', '0000:0000:0000:0000:0000:0000:0000:0000'),
525 'localhost' => array('::1', '0000:0000:0000:0000:0000:0000:0000:0001'),
526 'some address on right side' => array('::f0f', '0000:0000:0000:0000:0000:0000:0000:0f0f'),
527 'expansion in middle 1' => array('1::2', '0001:0000:0000:0000:0000:0000:0000:0002'),
528 'expansion in middle 2' => array('1:2::3', '0001:0002:0000:0000:0000:0000:0000:0003'),
529 'expansion in middle 3' => array('1::2:3', '0001:0000:0000:0000:0000:0000:0002:0003'),
530 'expansion in middle 4' => array('1:2::3:4:5', '0001:0002:0000:0000:0000:0003:0004:0005'),
536 * @dataProvider normalizeCompressIPv6DataProviderCorrect
538 public function normalizeIPv6CorrectlyNormalizesAddresses($compressed, $normalized) {
539 $this->assertEquals(t3lib_div
::normalizeIPv6($compressed), $normalized);
544 * @dataProvider normalizeCompressIPv6DataProviderCorrect
546 public function compressIPv6CorrectlyCompressesAdresses($compressed, $normalized) {
547 $this->assertEquals(t3lib_div
::compressIPv6($normalized), $compressed);
550 ///////////////////////////////
551 // Tests concerning validIP
552 ///////////////////////////////
555 * Data provider for checkValidIpReturnsTrueForValidIp
557 * @return array Data sets
559 public static function validIpDataProvider() {
561 '0.0.0.0' => array('0.0.0.0'),
562 'private IPv4 class C' => array('192.168.0.1'),
563 'private IPv4 class A' => array('10.0.13.1'),
564 'private IPv6' => array('fe80::daa2:5eff:fe8b:7dfb'),
570 * @dataProvider validIpDataProvider
572 public function validIpReturnsTrueForValidIp($ip) {
573 $this->assertTrue(t3lib_div
::validIP($ip));
577 * Data provider for checkValidIpReturnsFalseForInvalidIp
579 * @return array Data sets
581 public static function invalidIpDataProvider() {
583 'null' => array(NULL),
585 'string' => array('test'),
586 'string empty' => array(''),
587 'string NULL' => array('NULL'),
588 'out of bounds IPv4' => array('300.300.300.300'),
589 'dotted decimal notation with only two dots' => array('127.0.1'),
595 * @dataProvider invalidIpDataProvider
597 public function validIpReturnsFalseForInvalidIp($ip) {
598 $this->assertFalse(t3lib_div
::validIP($ip));
601 ///////////////////////////////
602 // Tests concerning cmpFQDN
603 ///////////////////////////////
606 * Data provider for cmpFqdnReturnsTrue
608 * @return array Data sets
610 public static function cmpFqdnValidDataProvider() {
612 'localhost should usually resolve, IPv4' => array('127.0.0.1', '*'),
613 'localhost should usually resolve, IPv6' => array('::1', '*'),
614 // other testcases with resolving not possible since it would
615 // require a working IPv4/IPv6-connectivity
616 'aaa.bbb.ccc.ddd.eee, full' => array('aaa.bbb.ccc.ddd.eee', 'aaa.bbb.ccc.ddd.eee'),
617 'aaa.bbb.ccc.ddd.eee, wildcard first' => array('aaa.bbb.ccc.ddd.eee', '*.ccc.ddd.eee'),
618 'aaa.bbb.ccc.ddd.eee, wildcard last' => array('aaa.bbb.ccc.ddd.eee', 'aaa.bbb.ccc.*'),
619 'aaa.bbb.ccc.ddd.eee, wildcard middle' => array('aaa.bbb.ccc.ddd.eee', 'aaa.*.eee'),
620 'list-matches, 1' => array('aaa.bbb.ccc.ddd.eee', 'xxx, yyy, zzz, aaa.*.eee'),
621 'list-matches, 2' => array('aaa.bbb.ccc.ddd.eee', '127:0:0:1,,aaa.*.eee,::1'),
627 * @dataProvider cmpFqdnValidDataProvider
629 public function cmpFqdnReturnsTrue($baseHost, $list) {
630 $this->assertTrue(t3lib_div
::cmpFQDN($baseHost, $list));
634 * Data provider for cmpFqdnReturnsFalse
636 * @return array Data sets
638 public static function cmpFqdnInvalidDataProvider() {
640 'num-parts of hostname to check can only be less or equal than hostname, 1' => array('aaa.bbb.ccc.ddd.eee', 'aaa.bbb.ccc.ddd.eee.fff'),
641 'num-parts of hostname to check can only be less or equal than hostname, 2' => array('aaa.bbb.ccc.ddd.eee', 'aaa.*.bbb.ccc.ddd.eee'),
647 * @dataProvider cmpFqdnInvalidDataProvider
649 public function cmpFqdnReturnsFalse($baseHost, $list) {
650 $this->assertFalse(t3lib_div
::cmpFQDN($baseHost, $list));
653 ///////////////////////////////
654 // Tests concerning inList
655 ///////////////////////////////
660 * @param string $haystack
662 * @dataProvider inListForItemContainedReturnsTrueDataProvider
664 public function inListForItemContainedReturnsTrue($haystack) {
666 t3lib_div
::inList($haystack, 'findme')
671 * Data provider for inListForItemContainedReturnsTrue.
675 public function inListForItemContainedReturnsTrueDataProvider() {
677 'Element as second element of four items' => array('one,findme,three,four'),
678 'Element at beginning of list' => array('findme,one,two'),
679 'Element at end of list' => array('one,two,findme'),
680 'One item list' => array('findme'),
687 * @param string $haystack
689 * @dataProvider inListForItemNotContainedReturnsFalseDataProvider
691 public function inListForItemNotContainedReturnsFalse($haystack) {
693 t3lib_div
::inList($haystack, 'findme')
698 * Data provider for inListForItemNotContainedReturnsFalse.
702 public function inListForItemNotContainedReturnsFalseDataProvider() {
704 'Four item list' => array('one,two,three,four'),
705 'One item list' => array('one'),
706 'Empty list' => array(''),
710 ///////////////////////////////
711 // Tests concerning rmFromList
712 ///////////////////////////////
717 * @param string $initialList
718 * @param string $listWithElementRemoved
720 * @dataProvider rmFromListRemovesElementsFromCommaSeparatedListDataProvider
722 public function rmFromListRemovesElementsFromCommaSeparatedList($initialList, $listWithElementRemoved) {
724 $listWithElementRemoved,
725 t3lib_div
::rmFromList('removeme', $initialList)
730 * Data provider for rmFromListRemovesElementsFromCommaSeparatedList
734 public function rmFromListRemovesElementsFromCommaSeparatedListDataProvider() {
736 'Element as second element of three' => array('one,removeme,two', 'one,two'),
737 'Element at beginning of list' => array('removeme,one,two', 'one,two'),
738 'Element at end of list' => array('one,two,removeme', 'one,two'),
739 'One item list' => array('removeme', ''),
740 'Element not contained in list' => array('one,two,three', 'one,two,three'),
741 'Empty list' => array('', ''),
745 ///////////////////////////////
746 // Tests concerning expandList
747 ///////////////////////////////
752 * @param string $list
753 * @param string $expectation
755 * @dataProvider expandListExpandsIntegerRangesDataProvider
757 public function expandListExpandsIntegerRanges($list, $expectation) {
760 t3lib_div
::expandList($list)
765 * Data provider for expandListExpandsIntegerRangesDataProvider
769 public function expandListExpandsIntegerRangesDataProvider() {
771 'Expand for the same number' => array('1,2-2,7', '1,2,7'),
772 'Small range expand with parameters reversed ignores reversed items' => array('1,5-3,7', '1,7'),
773 'Small range expand' => array('1,3-5,7', '1,3,4,5,7'),
774 'Expand at beginning' => array('3-5,1,7', '3,4,5,1,7'),
775 'Expand at end' => array('1,7,3-5', '1,7,3,4,5'),
776 'Multiple small range expands' => array('1,3-5,7-10,12', '1,3,4,5,7,8,9,10,12'),
777 'One item list' => array('1-5', '1,2,3,4,5'),
778 'Nothing to expand' => array('1,2,3,4', '1,2,3,4'),
779 'Empty list' => array('', ''),
786 public function expandListExpandsForTwoThousandElementsExpandsOnlyToThousandElementsMaximum() {
787 $list = t3lib_div
::expandList('1-2000');
791 count(explode(',', $list))
795 ///////////////////////////////
796 // Tests concerning uniqueList
797 ///////////////////////////////
802 * @param string $initialList
803 * @param string $unifiedList
805 * @dataProvider uniqueListUnifiesCommaSeparatedListDataProvider
807 public function uniqueListUnifiesCommaSeparatedList($initialList, $unifiedList) {
810 t3lib_div
::uniqueList($initialList)
815 * Data provider for uniqueListUnifiesCommaSeparatedList
819 public function uniqueListUnifiesCommaSeparatedListDataProvider() {
821 'List without duplicates' => array('one,two,three', 'one,two,three'),
822 'List with two consecutive duplicates' => array('one,two,two,three,three', 'one,two,three'),
823 'List with non-consecutive duplicates' => array('one,two,three,two,three', 'one,two,three'),
824 'One item list' => array('one', 'one'),
825 'Empty list' => array('', ''),
830 ///////////////////////////////
831 // Tests concerning isFirstPartOfStr
832 ///////////////////////////////
835 * Data provider for isFirstPartOfStrReturnsTrueForMatchingFirstParts
839 public function isFirstPartOfStrReturnsTrueForMatchingFirstPartDataProvider() {
841 'match first part of string' => array('hello world', 'hello'),
842 'match whole string' => array('hello', 'hello'),
843 'integer is part of string with same number' => array('24', 24),
844 'string is part of integer with same number' => array(24, '24'),
845 'integer is part of string starting with same number' => array('24 beer please', 24),
851 * @dataProvider isFirstPartOfStrReturnsTrueForMatchingFirstPartDataProvider
853 public function isFirstPartOfStrReturnsTrueForMatchingFirstPart($string, $part) {
854 $this->assertTrue(t3lib_div
::isFirstPartOfStr($string, $part));
858 * Data provider for checkIsFirstPartOfStrReturnsFalseForNotMatchingFirstParts
862 public function isFirstPartOfStrReturnsFalseForNotMatchingFirstPartDataProvider() {
864 'no string match' => array('hello', 'bye'),
865 'no case sensitive string match' => array('hello world', 'Hello'),
866 'array is not part of string' => array('string', array()),
867 'string is not part of array' => array(array(), 'string'),
868 'NULL is not part of string' => array('string', NULL),
869 'string is not part of array' => array(NULL, 'string'),
870 'NULL is not part of array' => array(array(), NULL),
871 'array is not part of string' => array(NULL, array()),
872 'empty string is not part of empty string' => array('', ''),
873 'NULL is not part of empty string' => array('', NULL),
874 'false is not part of empty string' => array('', FALSE),
875 'empty string is not part of NULL' => array(NULL, ''),
876 'empty string is not part of false' => array(FALSE, ''),
877 'empty string is not part of zero integer' => array(0, ''),
878 'zero integer is not part of NULL' => array(NULL, 0),
879 'zero integer is not part of empty string' => array('', 0),
885 * @dataProvider isFirstPartOfStrReturnsFalseForNotMatchingFirstPartDataProvider
887 public function isFirstPartOfStrReturnsFalseForNotMatchingFirstPart($string, $part) {
888 $this->assertFalse(t3lib_div
::isFirstPartOfStr($string, $part));
891 ///////////////////////////////
892 // Tests concerning formatSize
893 ///////////////////////////////
897 * @dataProvider formatSizeDataProvider
899 public function formatSizeTranslatesBytesToHigherOrderRepresentation($size, $label, $expected) {
900 $this->assertEquals($expected, t3lib_div
::formatSize($size, $label));
904 * Data provider for formatSizeTranslatesBytesToHigherOrderRepresentation
908 public function formatSizeDataProvider() {
910 'Bytes keep beeing bytes (min)' => array(1, '', '1 '),
911 'Bytes keep beeing bytes (max)' => array(899, '', '899 '),
912 'Kilobytes are detected' => array(1024, '', '1.0 K'),
913 'Megabytes are detected' => array(1048576, '', '1.0 M'),
914 'Gigabytes are detected' => array(1073741824, '', '1.0 G'),
915 'Decimal is omitted for large kilobytes' => array(31080, '', '30 K'),
916 'Decimal is omitted for large megabytes' => array(31458000, '', '30 M'),
917 'Decimal is omitted for large gigabytes' => array(32212254720, '', '30 G'),
918 'Label for bytes can be exchanged' => array(1, ' Foo|||', '1 Foo'),
919 'Label for kilobytes can be exchanged' => array(1024, '| Foo||', '1.0 Foo'),
920 'Label for megabyes can be exchanged' => array(1048576, '|| Foo|', '1.0 Foo'),
921 'Label for gigabytes can be exchanged' => array(1073741824, '||| Foo', '1.0 Foo')
925 ///////////////////////////////
926 // Tests concerning splitCalc
927 ///////////////////////////////
930 * Data provider for splitCalc
932 * @return array expected values, arithmetic expression
934 public function splitCalcDataProvider() {
936 'empty string returns empty array' => array(
940 'number without operator returns array with plus and number' => array(
941 array(array('+', 42)),
944 'two numbers with asterisk return first number with plus and second number with asterisk' => array(
945 array(array('+', 42), array('*', 31)),
953 * @dataProvider splitCalcDataProvider
955 public function splitCalcCorrectlySplitsExpression($expected, $expression) {
956 $this->assertEquals($expected, t3lib_div
::splitCalc($expression, '+-*/'));
959 ///////////////////////////////
960 // Tests concerning htmlspecialchars_decode
961 ///////////////////////////////
966 public function htmlspecialcharsDecodeReturnsDecodedString() {
967 $string ='<typo3 version="6.0"> </typo3>';
968 $encoded = htmlspecialchars($string);
969 $decoded = t3lib_div
::htmlspecialchars_decode($encoded);
970 $this->assertEquals($string, $decoded);
973 ///////////////////////////////
974 // Tests concerning deHSCentities
975 ///////////////////////////////
979 * @dataProvider deHSCentitiesReturnsDecodedStringDataProvider
981 public function deHSCentitiesReturnsDecodedString($input, $expected) {
982 $this->assertEquals($expected, t3lib_div
::deHSCentities($input));
986 * Data provider for deHSCentitiesReturnsDecodedString
990 public function deHSCentitiesReturnsDecodedStringDataProvider() {
992 'Empty string' => array('', ''),
993 'Double encoded &' => array('&amp;', '&'),
994 'Double encoded numeric entity' => array('&#1234;', 'Ӓ'),
995 'Double encoded hexadecimal entity' => array('&#x1b;', ''),
996 'Single encoded entities are not touched' => array('& Ӓ ', '& Ӓ ')
1000 //////////////////////////////////
1001 // Tests concerning slashJS
1002 //////////////////////////////////
1006 * @dataProvider slashJsDataProvider
1008 public function slashJsEscapesSingleQuotesAndSlashes($input, $extended, $expected) {
1009 $this->assertEquals($expected, t3lib_div
::slashJS($input, $extended));
1013 * Data provider for slashJsEscapesSingleQuotesAndSlashes
1017 public function slashJsDataProvider() {
1019 'Empty string is not changed' => array('', FALSE, ''),
1020 'Normal string is not changed' => array('The cake is a lie √', FALSE, 'The cake is a lie √'),
1021 'String with single quotes' => array("The 'cake' is a lie", FALSE, "The \\'cake\\' is a lie"),
1022 'String with single quotes and backslashes - just escape single quotes'
1023 => array("The \\'cake\\' is a lie", FALSE, "The \\\\'cake\\\\' is a lie"),
1024 'String with single quotes and backslashes - escape both'
1025 => array("The \\'cake\\' is a lie", TRUE, "The \\\\\\'cake\\\\\\' is a lie")
1029 //////////////////////////////////
1030 // Tests concerning rawUrlEncodeJS
1031 //////////////////////////////////
1036 public function rawUrlEncodeJsPreservesWhitespaces() {
1037 $input = "Encode 'me', but leave my spaces √";
1038 $expected = "Encode %27me%27%2C but leave my spaces %E2%88%9A";
1039 $this->assertEquals($expected, t3lib_div
::rawUrlEncodeJS($input));
1042 //////////////////////////////////
1043 // Tests concerning rawUrlEncodeJS
1044 //////////////////////////////////
1049 public function rawUrlEncodeFpPreservesSlashes() {
1050 $input = "Encode 'me', but leave my / √";
1051 $expected = "Encode%20%27me%27%2C%20but%20leave%20my%20/%20%E2%88%9A";
1052 $this->assertEquals($expected, t3lib_div
::rawUrlEncodeFP($input));
1055 //////////////////////////////////
1056 // Tests concerning strtoupper / strtolower
1057 //////////////////////////////////
1060 * Data provider for strtoupper and strtolower
1064 public function strtouppperDataProvider() {
1066 'Empty string' => array('', ''),
1067 'String containing only latin characters' => array('the cake is a lie.', 'THE CAKE IS A LIE.'),
1068 'String with umlauts and accent characters' => array('the cà kê is ä lie.', 'THE Cà Kê IS ä LIE.')
1074 * @dataProvider strtouppperDataProvider
1076 public function strtoupperConvertsOnlyLatinCharacters($input, $expected) {
1077 $this->assertEquals($expected, t3lib_div
::strtoupper($input));
1082 * @dataProvider strtouppperDataProvider
1084 public function strtolowerConvertsOnlyLatinCharacters($expected, $input) {
1085 $this->assertEquals($expected, t3lib_div
::strtolower($input));
1089 //////////////////////////////////
1090 // Tests concerning validEmail
1091 //////////////////////////////////
1094 * Data provider for valid validEmail's
1096 * @return array Valid email addresses
1098 public function validEmailValidDataProvider() {
1100 'short mail address' => array('a@b.c'),
1101 'simple mail address' => array('test@example.com'),
1102 'uppercase characters' => array('QWERTYUIOPASDFGHJKLZXCVBNM@QWERTYUIOPASDFGHJKLZXCVBNM.NET'),
1103 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6 and 5.3.2 but fails with 5.3.0 on windows
1104 // 'equal sign in local part' => array('test=mail@example.com'),
1105 'dash in local part' => array('test-mail@example.com'),
1106 'plus in local part' => array('test+mail@example.com'),
1107 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6 and 5.3.2 but fails with 5.3.0 on windows
1108 // 'question mark in local part' => array('test?mail@example.com'),
1109 'slash in local part' => array('foo/bar@example.com'),
1110 'hash in local part' => array('foo#bar@example.com'),
1111 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6 and 5.3.2 but fails with 5.3.0 on windows
1112 // 'dot in local part' => array('firstname.lastname@employee.2something.com'),
1113 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
1114 // 'dash as local part' => array('-@foo.com'),
1115 'umlauts in local part' => array('äöüfoo@bar.com'),
1116 'umlauts in domain part' => array('foo@äöüfoo.com'),
1122 * @dataProvider validEmailValidDataProvider
1124 public function validEmailReturnsTrueForValidMailAddress($address) {
1125 $this->assertTrue(t3lib_div
::validEmail($address));
1129 * Data provider for invalid validEmail's
1131 * @return array Invalid email addresses
1133 public function validEmailInvalidDataProvider() {
1135 '@ sign only' => array('@'),
1136 'duplicate @' => array('test@@example.com'),
1137 'duplicate @ combined with further special characters in local part' => array('test!.!@#$%^&*@example.com'),
1138 'opening parenthesis in local part' => array('foo(bar@example.com'),
1139 'closing parenthesis in local part' => array('foo)bar@example.com'),
1140 'opening square bracket in local part' => array('foo[bar@example.com'),
1141 'closing square bracket as local part' => array(']@example.com'),
1142 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
1143 // 'top level domain only' => array('test@com'),
1144 'dash as second level domain' => array('foo@-.com'),
1145 'domain part starting with dash' => array('foo@-foo.com'),
1146 'domain part ending with dash' => array('foo@foo-.com'),
1147 'number as top level domain' => array('foo@bar.123'),
1148 // Fix / change if TYPO3 php requirement changed: Address not ok with 5.2.6, but ok with 5.3.2 (?)
1149 // 'dash as top level domain' => array('foo@bar.-'),
1150 'dot at beginning of domain part' => array('test@.com'),
1151 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
1152 // 'local part ends with dot' => array('e.x.a.m.p.l.e.@example.com'),
1153 'trailing whitespace' => array('test@example.com '),
1154 'trailing carriage return' => array('test@example.com' . CR
),
1155 'trailing linefeed' => array('test@example.com' . LF
),
1156 'trailing carriage return linefeed' => array('test@example.com' . CRLF
),
1157 'trailing tab' => array('test@example.com' . TAB
),
1163 * @dataProvider validEmailInvalidDataProvider
1165 public function validEmailReturnsFalseForInvalidMailAddress($address) {
1166 $this->assertFalse(t3lib_div
::validEmail($address));
1169 //////////////////////////////////
1170 // Tests concerning inArray
1171 //////////////////////////////////
1175 * @dataProvider inArrayDataProvider
1177 public function inArrayChecksStringExistenceWithinArray($array, $item, $expected) {
1178 $this->assertEquals($expected, t3lib_div
::inArray($array, $item));
1182 * Data provider for inArrayChecksStringExistenceWithinArray
1186 public function inArrayDataProvider() {
1188 'Empty array' => array(array(), 'search', FALSE),
1189 'One item array no match' => array(array('one'), 'two', FALSE),
1190 'One item array match' => array(array('one'), 'one', TRUE),
1191 'Multiple items array no match' => array(array('one', 2, 'three', 4), 'four', FALSE),
1192 'Multiple items array match' => array(array('one', 2, 'three', 4), 'three', TRUE),
1193 'Integer search items can match string values' => array(array('0', '1', '2'), 1, TRUE),
1194 'Search item is not casted to integer for a match' => array(array(4), '4a', FALSE),
1195 'Empty item won\'t match - in contrast to the php-builtin ' => array(array(0, 1, 2), '', FALSE),
1199 //////////////////////////////////
1200 // Tests concerning intExplode
1201 //////////////////////////////////
1206 public function intExplodeConvertsStringsToInteger() {
1207 $testString = '1,foo,2';
1208 $expectedArray = array(1, 0, 2);
1209 $actualArray = t3lib_div
::intExplode(',', $testString);
1211 $this->assertEquals($expectedArray, $actualArray);
1214 //////////////////////////////////
1215 // Tests concerning keepItemsInArray
1216 //////////////////////////////////
1220 * @dataProvider keepItemsInArrayWorksWithOneArgumentDataProvider
1222 public function keepItemsInArrayWorksWithOneArgument($search, $array, $expected) {
1223 $this->assertEquals($expected, t3lib_div
::keepItemsInArray($array, $search));
1227 * Data provider for keepItemsInArrayWorksWithOneArgument
1231 public function keepItemsInArrayWorksWithOneArgumentDataProvider() {
1238 'Empty argument will match "all" elements' => array(NULL, $array, $array),
1239 'No match' => array('four', $array, array()),
1240 'One match' => array('two', $array, array('two' => 'two')),
1241 'Multiple matches' => array('two,one', $array, array('one' => 'one', 'two' => 'two')),
1242 'Argument can be an array' => array(array('three'), $array, array('three' => 'three'))
1247 * Shows the exmaple from the doc comment where
1248 * a function is used to reduce the sub arrays to one item which
1249 * is then used for the matching.
1253 public function keepItemsInArrayCanUseCallbackOnSearchArray() {
1255 'aa' => array('first', 'second'),
1256 'bb' => array('third', 'fourth'),
1257 'cc' => array('fifth', 'sixth')
1259 $expected = array('bb' => array('third', 'fourth'));
1260 $keepItems = 'third';
1261 $getValueFunc = create_function('$value', 'return $value[0];');
1263 $match = t3lib_div
::keepItemsInArray($array, $keepItems, $getValueFunc);
1264 $this->assertEquals($expected, $match);
1267 //////////////////////////////////
1268 // Tests concerning implodeArrayForUrl / explodeUrl2Array
1269 //////////////////////////////////
1272 * Data provider for implodeArrayForUrlBuildsValidParameterString and
1273 * explodeUrl2ArrayTransformsParameterStringToArray
1277 public function implodeArrayForUrlDataProvider() {
1278 $valueArray = array('one' => '√', 'two' => 2);
1281 => array('foo', array(), ''),
1283 => array('foo', $valueArray, '&foo[one]=%E2%88%9A&foo[two]=2'),
1284 'Nested array parameters'
1285 => array('foo', array($valueArray), '&foo[0][one]=%E2%88%9A&foo[0][two]=2'),
1286 'Keep blank parameters'
1287 => array('foo', array('one'=> '√', ''), '&foo[one]=%E2%88%9A&foo[0]=')
1293 * @dataProvider implodeArrayForUrlDataProvider
1295 public function implodeArrayForUrlBuildsValidParameterString($name, $input, $expected) {
1296 $this->assertSame($expected, t3lib_div
::implodeArrayForUrl($name, $input));
1302 public function implodeArrayForUrlCanSkipEmptyParameters() {
1303 $input = array('one'=> '√', '');
1304 $expected = '&foo[one]=%E2%88%9A';
1305 $this->assertSame($expected, t3lib_div
::implodeArrayForUrl('foo', $input, '', TRUE));
1311 public function implodeArrayForUrlCanUrlEncodeKeyNames() {
1312 $input = array('one'=> '√', '');
1313 $expected = '&foo%5Bone%5D=%E2%88%9A&foo%5B0%5D=';
1314 $this->assertSame($expected, t3lib_div
::implodeArrayForUrl('foo', $input, '', FALSE, TRUE));
1319 * @dataProvider implodeArrayForUrlDataProvider
1321 public function explodeUrl2ArrayTransformsParameterStringToNestedArray($name, $array, $input) {
1322 $expected = $array ?
array($name => $array) : array();
1323 $this->assertEquals($expected, t3lib_div
::explodeUrl2Array($input, TRUE));
1328 * @dataProvider explodeUrl2ArrayDataProvider
1330 public function explodeUrl2ArrayTransformsParameterStringToFlatArray($input, $expected) {
1331 $this->assertEquals($expected, t3lib_div
::explodeUrl2Array($input, FALSE));
1335 * Data provider for explodeUrl2ArrayTransformsParameterStringToFlatArray
1339 public function explodeUrl2ArrayDataProvider() {
1342 => array('', array()),
1343 'Simple parameter string'
1344 => array('&one=%E2%88%9A&two=2', array('one' => '√', 'two' => 2)),
1345 'Nested parameter string'
1346 => array('&foo[one]=%E2%88%9A&two=2', array('foo[one]' => '√', 'two' => 2))
1350 //////////////////////////////////
1351 // Tests concerning compileSelectedGetVarsFromArray
1352 //////////////////////////////////
1357 public function compileSelectedGetVarsFromArrayFiltersIncomingData() {
1358 $filter = 'foo,bar';
1359 $getArray = array('foo' => 1, 'cake' => 'lie');
1360 $expected = array('foo' => 1);
1361 $result = t3lib_div
::compileSelectedGetVarsFromArray($filter, $getArray, FALSE);
1362 $this->assertSame($expected, $result);
1368 public function compileSelectedGetVarsFromArrayUsesGetPostDataFallback() {
1370 $filter = 'foo,bar';
1371 $getArray = array('foo' => 1, 'cake' => 'lie');
1372 $expected = array('foo' => 1, 'bar' => '2');
1373 $result = t3lib_div
::compileSelectedGetVarsFromArray($filter, $getArray, TRUE);
1374 $this->assertSame($expected, $result);
1377 //////////////////////////////////
1378 // Tests concerning remapArrayKeys
1379 //////////////////////////////////
1384 public function remapArrayKeysExchangesKeysWithGivenMapping() {
1390 $keyMapping = array(
1400 t3lib_div
::remapArrayKeys($array, $keyMapping);
1401 $this->assertEquals($expected, $array);
1404 //////////////////////////////////
1405 // Tests concerning array_merge
1406 //////////////////////////////////
1409 * Test demonstrating array_merge. This is actually
1410 * a native PHP operator, therefore this test is mainly used to
1411 * show how this function can be used.
1415 public function arrayMergeKeepsIndexesAfterMerge() {
1416 $array1 = array(10 => 'FOO', '20' => 'BAR');
1417 $array2 = array('5' => 'PLONK');
1418 $expected = array('5' => 'PLONK', 10 => 'FOO', '20' => 'BAR');
1419 $this->assertEquals($expected, t3lib_div
::array_merge($array1, $array2));
1423 //////////////////////////////////
1424 // Tests concerning int_from_ver
1425 //////////////////////////////////
1427 * Data Provider for intFromVerConvertsVersionNumbersToIntegersDataProvider
1431 public function intFromVerConvertsVersionNumbersToIntegersDataProvider() {
1433 array('4003003', '4.3.3'),
1434 array('4012003', '4.12.3'),
1435 array('5000000', '5.0.0'),
1436 array('3008001', '3.8.1'),
1437 array('1012', '0.1.12')
1443 * @dataProvider intFromVerConvertsVersionNumbersToIntegersDataProvider
1445 public function intFromVerConvertsVersionNumbersToIntegers($expected, $version) {
1446 $this->assertEquals($expected, t3lib_div
::int_from_ver($version));
1449 //////////////////////////////////
1450 // Tests concerning revExplode
1451 //////////////////////////////////
1456 public function revExplodeExplodesString() {
1457 $testString = 'my:words:here';
1458 $expectedArray = array('my:words', 'here');
1459 $actualArray = t3lib_div
::revExplode(':', $testString, 2);
1461 $this->assertEquals($expectedArray, $actualArray);
1465 //////////////////////////////////
1466 // Tests concerning trimExplode
1467 //////////////////////////////////
1472 public function checkTrimExplodeTrimsSpacesAtElementStartAndEnd() {
1473 $testString = ' a , b , c ,d ,, e,f,';
1474 $expectedArray = array('a', 'b', 'c', 'd', '', 'e', 'f', '');
1475 $actualArray = t3lib_div
::trimExplode(',', $testString);
1477 $this->assertEquals($expectedArray, $actualArray);
1483 public function checkTrimExplodeRemovesNewLines() {
1484 $testString = ' a , b , ' . LF
. ' ,d ,, e,f,';
1485 $expectedArray = array('a', 'b', 'd', 'e', 'f');
1486 $actualArray = t3lib_div
::trimExplode(',', $testString, TRUE);
1488 $this->assertEquals($expectedArray, $actualArray);
1494 public function checkTrimExplodeRemovesEmptyElements() {
1495 $testString = 'a , b , c , ,d ,, ,e,f,';
1496 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f');
1497 $actualArray = t3lib_div
::trimExplode(',', $testString, TRUE);
1499 $this->assertEquals($expectedArray, $actualArray);
1505 public function checkTrimExplodeKeepsRemainingResultsWithEmptyItemsAfterReachingLimitWithPositiveParameter() {
1506 $testString = ' a , b , c , , d,, ,e ';
1507 $expectedArray = array('a', 'b', 'c,,d,,,e');
1508 // Limiting returns the rest of the string as the last element
1509 $actualArray = t3lib_div
::trimExplode(',', $testString, FALSE, 3);
1511 $this->assertEquals($expectedArray, $actualArray);
1517 public function checkTrimExplodeKeepsRemainingResultsWithoutEmptyItemsAfterReachingLimitWithPositiveParameter() {
1518 $testString = ' a , b , c , , d,, ,e ';
1519 $expectedArray = array('a', 'b', 'c,d,e');
1520 // Limiting returns the rest of the string as the last element
1521 $actualArray = t3lib_div
::trimExplode(',', $testString, TRUE, 3);
1523 $this->assertEquals($expectedArray, $actualArray);
1529 public function checkTrimExplodeKeepsRamainingResultsWithEmptyItemsAfterReachingLimitWithNegativeParameter() {
1530 $testString = ' a , b , c , d, ,e, f , , ';
1531 $expectedArray = array('a', 'b', 'c', 'd', '', 'e');
1532 // limiting returns the rest of the string as the last element
1533 $actualArray = t3lib_div
::trimExplode(',', $testString, FALSE, -3);
1535 $this->assertEquals($expectedArray, $actualArray);
1541 public function checkTrimExplodeKeepsRamainingResultsWithoutEmptyItemsAfterReachingLimitWithNegativeParameter() {
1542 $testString = ' a , b , c , d, ,e, f , , ';
1543 $expectedArray = array('a', 'b', 'c');
1544 // Limiting returns the rest of the string as the last element
1545 $actualArray = t3lib_div
::trimExplode(',', $testString, TRUE, -3);
1547 $this->assertEquals($expectedArray, $actualArray);
1553 public function checkTrimExplodeReturnsExactResultsWithoutReachingLimitWithPositiveParameter() {
1554 $testString = ' a , b , , c , , , ';
1555 $expectedArray = array('a', 'b', 'c');
1556 // Limiting returns the rest of the string as the last element
1557 $actualArray = t3lib_div
::trimExplode(',', $testString, TRUE, 4);
1559 $this->assertEquals($expectedArray, $actualArray);
1565 public function checkTrimExplodeKeepsZeroAsString() {
1566 $testString = 'a , b , c , ,d ,, ,e,f, 0 ,';
1567 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f', '0');
1568 $actualArray = t3lib_div
::trimExplode(',', $testString, TRUE);
1570 $this->assertEquals($expectedArray, $actualArray);
1574 //////////////////////////////////
1575 // Tests concerning removeArrayEntryByValue
1576 //////////////////////////////////
1581 public function checkRemoveArrayEntryByValueRemovesEntriesFromOneDimensionalArray() {
1582 $inputArray = array(
1588 $compareValue = 'test2';
1589 $expectedResult = array(
1593 $actualResult = t3lib_div
::removeArrayEntryByValue($inputArray, $compareValue);
1594 $this->assertEquals($expectedResult, $actualResult);
1600 public function checkRemoveArrayEntryByValueRemovesEntriesFromMultiDimensionalArray() {
1601 $inputArray = array(
1608 $compareValue = 'bar';
1609 $expectedResult = array(
1613 $actualResult = t3lib_div
::removeArrayEntryByValue($inputArray, $compareValue);
1614 $this->assertEquals($expectedResult, $actualResult);
1620 public function checkRemoveArrayEntryByValueRemovesEntryWithEmptyString() {
1621 $inputArray = array(
1627 $expectedResult = array(
1631 $actualResult = t3lib_div
::removeArrayEntryByValue($inputArray, $compareValue);
1632 $this->assertEquals($expectedResult, $actualResult);
1635 //////////////////////////////////
1636 // Tests concerning getBytesFromSizeMeasurement
1637 //////////////////////////////////
1640 * Data provider for getBytesFromSizeMeasurement
1642 * @return array expected value, input string
1644 public function getBytesFromSizeMeasurementDataProvider() {
1646 '100 kilo Bytes' => array('102400', '100k'),
1647 '100 mega Bytes' => array('104857600', '100m'),
1648 '100 giga Bytes' => array('107374182400', '100g'),
1654 * @dataProvider getBytesFromSizeMeasurementDataProvider
1656 public function getBytesFromSizeMeasurementCalculatesCorrectByteValue($expected, $byteString) {
1657 $this->assertEquals($expected, t3lib_div
::getBytesFromSizeMeasurement($byteString));
1661 //////////////////////////////////
1662 // Tests concerning getIndpEnv
1663 //////////////////////////////////
1668 public function getIndpEnvTypo3SitePathReturnNonEmptyString() {
1669 $this->assertTrue(strlen(t3lib_div
::getIndpEnv('TYPO3_SITE_PATH')) >= 1);
1675 public function getIndpEnvTypo3SitePathReturnsStringStartingWithSlash() {
1676 $result = t3lib_div
::getIndpEnv('TYPO3_SITE_PATH');
1677 $this->assertEquals('/', $result[0]);
1683 public function getIndpEnvTypo3SitePathReturnsStringEndingWithSlash() {
1684 $result = t3lib_div
::getIndpEnv('TYPO3_SITE_PATH');
1685 $this->assertEquals('/', $result[strlen($result) - 1]);
1691 public static function hostnameAndPortDataProvider() {
1693 'localhost ipv4 without port' => array('127.0.0.1', '127.0.0.1', ''),
1694 'localhost ipv4 with port' => array('127.0.0.1:81', '127.0.0.1', '81'),
1695 'localhost ipv6 without port' => array('[::1]', '[::1]', ''),
1696 'localhost ipv6 with port' => array('[::1]:81', '[::1]', '81'),
1697 'ipv6 without port' => array('[2001:DB8::1]', '[2001:DB8::1]', ''),
1698 'ipv6 with port' => array('[2001:DB8::1]:81', '[2001:DB8::1]', '81'),
1699 'hostname without port' => array('lolli.did.this', 'lolli.did.this', ''),
1700 'hostname with port' => array('lolli.did.this:42', 'lolli.did.this', '42'),
1706 * @dataProvider hostnameAndPortDataProvider
1708 public function getIndpEnvTypo3HostOnlyParsesHostnamesAndIpAdresses($httpHost, $expectedIp) {
1709 $_SERVER['HTTP_HOST'] = $httpHost;
1710 $this->assertEquals($expectedIp, t3lib_div
::getIndpEnv('TYPO3_HOST_ONLY'));
1715 * @dataProvider hostnameAndPortDataProvider
1717 public function getIndpEnvTypo3PortParsesHostnamesAndIpAdresses($httpHost, $dummy, $expectedPort) {
1718 $_SERVER['HTTP_HOST'] = $httpHost;
1719 $this->assertEquals($expectedPort, t3lib_div
::getIndpEnv('TYPO3_PORT'));
1723 //////////////////////////////////
1724 // Tests concerning underscoredToUpperCamelCase
1725 //////////////////////////////////
1728 * Data provider for underscoredToUpperCamelCase
1730 * @return array expected, input string
1732 public function underscoredToUpperCamelCaseDataProvider() {
1734 'single word' => array('Blogexample', 'blogexample'),
1735 'multiple words' => array('BlogExample', 'blog_example'),
1741 * @dataProvider underscoredToUpperCamelCaseDataProvider
1743 public function underscoredToUpperCamelCase($expected, $inputString) {
1744 $this->assertEquals($expected, t3lib_div
::underscoredToUpperCamelCase($inputString));
1748 //////////////////////////////////
1749 // Tests concerning underscoredToLowerCamelCase
1750 //////////////////////////////////
1753 * Data provider for underscoredToLowerCamelCase
1755 * @return array expected, input string
1757 public function underscoredToLowerCamelCaseDataProvider() {
1759 'single word' => array('minimalvalue', 'minimalvalue'),
1760 'multiple words' => array('minimalValue', 'minimal_value'),
1766 * @dataProvider underscoredToLowerCamelCaseDataProvider
1768 public function underscoredToLowerCamelCase($expected, $inputString) {
1769 $this->assertEquals($expected, t3lib_div
::underscoredToLowerCamelCase($inputString));
1772 //////////////////////////////////
1773 // Tests concerning camelCaseToLowerCaseUnderscored
1774 //////////////////////////////////
1777 * Data provider for camelCaseToLowerCaseUnderscored
1779 * @return array expected, input string
1781 public function camelCaseToLowerCaseUnderscoredDataProvider() {
1783 'single word' => array('blogexample', 'blogexample'),
1784 'single word starting upper case' => array('blogexample', 'Blogexample'),
1785 'two words starting lower case' => array('minimal_value', 'minimalValue'),
1786 'two words starting upper case' => array('blog_example', 'BlogExample'),
1792 * @dataProvider camelCaseToLowerCaseUnderscoredDataProvider
1794 public function camelCaseToLowerCaseUnderscored($expected, $inputString) {
1795 $this->assertEquals($expected, t3lib_div
::camelCaseToLowerCaseUnderscored($inputString));
1799 //////////////////////////////////
1800 // Tests concerning lcFirst
1801 //////////////////////////////////
1804 * Data provider for lcFirst
1806 * @return array expected, input string
1808 public function lcfirstDataProvider() {
1810 'single word' => array('blogexample', 'blogexample'),
1811 'single Word starting upper case' => array('blogexample', 'Blogexample'),
1812 'two words' => array('blogExample', 'BlogExample'),
1818 * @dataProvider lcfirstDataProvider
1820 public function lcFirst($expected, $inputString) {
1821 $this->assertEquals($expected, t3lib_div
::lcfirst($inputString));
1825 //////////////////////////////////
1826 // Tests concerning encodeHeader
1827 //////////////////////////////////
1832 public function encodeHeaderEncodesWhitespacesInQuotedPrintableMailHeader() {
1833 $this->assertEquals(
1834 '=?utf-8?Q?We_test_whether_the_copyright_character_=C2=A9_is_encoded_correctly?=',
1835 t3lib_div
::encodeHeader(
1836 "We test whether the copyright character \xc2\xa9 is encoded correctly",
1846 public function encodeHeaderEncodesQuestionmarksInQuotedPrintableMailHeader() {
1847 $this->assertEquals(
1848 '=?utf-8?Q?Is_the_copyright_character_=C2=A9_really_encoded_correctly=3F_Really=3F?=',
1849 t3lib_div
::encodeHeader(
1850 "Is the copyright character \xc2\xa9 really encoded correctly? Really?",
1858 //////////////////////////////////
1859 // Tests concerning isValidUrl
1860 //////////////////////////////////
1863 * Data provider for valid isValidUrl's
1865 * @return array Valid ressource
1867 public function validUrlValidRessourceDataProvider() {
1869 'http' => array('http://www.example.org/'),
1870 'http without trailing slash' => array('http://qwe'),
1871 'http directory with trailing slash' => array('http://www.example/img/dir/'),
1872 'http directory without trailing slash' => array('http://www.example/img/dir'),
1873 'http index.html' => array('http://example.com/index.html'),
1874 'http index.php' => array('http://www.example.com/index.php'),
1875 'http test.png' => array('http://www.example/img/test.png'),
1876 'http username password querystring and ancher' => array('https://user:pw@www.example.org:80/path?arg=value#fragment'),
1877 'file' => array('file:///tmp/test.c'),
1878 'file directory' => array('file://foo/bar'),
1879 'ftp directory' => array('ftp://ftp.example.com/tmp/'),
1880 'mailto' => array('mailto:foo@bar.com'),
1881 'news' => array('news:news.php.net'),
1882 'telnet'=> array('telnet://192.0.2.16:80/'),
1883 'ldap' => array('ldap://[2001:db8::7]/c=GB?objectClass?one'),
1884 'http punycode domain name' => array('http://www.xn--bb-eka.at'),
1885 'http punicode subdomain' => array('http://xn--h-zfa.oebb.at'),
1886 'http domain-name umlauts' => array('http://www.öbb.at'),
1887 'http subdomain umlauts' => array('http://äh.oebb.at'),
1888 'http directory umlauts' => array('http://www.oebb.at/äöü/'),
1894 * @dataProvider validUrlValidRessourceDataProvider
1896 public function validURLReturnsTrueForValidRessource($url) {
1897 $this->assertTrue(t3lib_div
::isValidUrl($url));
1901 * Data provider for invalid isValidUrl's
1903 * @return array Invalid ressource
1905 public function isValidUrlInvalidRessourceDataProvider() {
1907 'http missing colon' => array('http//www.example/wrong/url/'),
1908 'http missing slash' => array('http:/www.example'),
1909 'hostname only' => array('www.example.org/'),
1910 'file missing protocol specification' => array('/tmp/test.c'),
1911 'slash only' => array('/'),
1912 'string http://' => array('http://'),
1913 'string http:/' => array('http:/'),
1914 'string http:' => array('http:'),
1915 'string http' => array('http'),
1916 'empty string' => array(''),
1917 'string -1' => array('-1'),
1918 'string array()' => array('array()'),
1919 'random string' => array('qwe'),
1925 * @dataProvider isValidUrlInvalidRessourceDataProvider
1927 public function validURLReturnsFalseForInvalidRessoure($url) {
1928 $this->assertFalse(t3lib_div
::isValidUrl($url));
1932 //////////////////////////////////
1933 // Tests concerning isOnCurrentHost
1934 //////////////////////////////////
1939 public function isOnCurrentHostReturnsTrueWithCurrentHost() {
1940 $testUrl = t3lib_div
::getIndpEnv('TYPO3_REQUEST_URL');
1941 $this->assertTrue(t3lib_div
::isOnCurrentHost($testUrl));
1945 * Data provider for invalid isOnCurrentHost's
1947 * @return array Invalid Hosts
1949 public function checkisOnCurrentHostInvalidHosts() {
1951 'empty string' => array(''),
1952 'arbitrary string' => array('arbitrary string'),
1953 'localhost IP' => array('127.0.0.1'),
1954 'relative path' => array('./relpath/file.txt'),
1955 'absolute path' => array('/abspath/file.txt?arg=value'),
1956 'differnt host' => array(t3lib_div
::getIndpEnv('TYPO3_REQUEST_HOST') . '.example.org'),
1961 ////////////////////////////////////////
1962 // Tests concerning sanitizeLocalUrl
1963 ////////////////////////////////////////
1966 * Data provider for valid sanitizeLocalUrl's
1968 * @return array Valid url
1970 public function sanitizeLocalUrlValidUrlDataProvider() {
1971 $subDirectory = t3lib_div
::getIndpEnv('TYPO3_SITE_PATH');
1972 $typo3SiteUrl = t3lib_div
::getIndpEnv('TYPO3_SITE_URL');
1973 $typo3RequestHost = t3lib_div
::getIndpEnv('TYPO3_REQUEST_HOST');
1976 'alt_intro.php' => array('alt_intro.php'),
1977 'alt_intro.php?foo=1&bar=2' => array('alt_intro.php?foo=1&bar=2'),
1978 $subDirectory . 'typo3/alt_intro.php' => array($subDirectory . 'typo3/alt_intro.php'),
1979 $subDirectory . 'index.php' => array($subDirectory . 'index.php'),
1980 '../index.php' => array('../index.php'),
1981 '../typo3/alt_intro.php' => array('../typo3/alt_intro.php'),
1982 '../~userDirectory/index.php' => array('../~userDirectory/index.php'),
1983 '../typo3/mod.php?var1=test-case&var2=~user' => array('../typo3/mod.php?var1=test-case&var2=~user'),
1984 PATH_site
. 'typo3/alt_intro.php' => array(PATH_site
. 'typo3/alt_intro.php'),
1985 $typo3SiteUrl . 'typo3/alt_intro.php' => array($typo3SiteUrl . 'typo3/alt_intro.php'),
1986 $typo3RequestHost . $subDirectory . '/index.php' => array($typo3RequestHost . $subDirectory . '/index.php'),
1992 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
1994 public function sanitizeLocalUrlAcceptsNotEncodedValidUrls($url) {
1995 $this->assertEquals($url, t3lib_div
::sanitizeLocalUrl($url));
2000 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
2002 public function sanitizeLocalUrlAcceptsEncodedValidUrls($url) {
2003 $this->assertEquals(rawurlencode($url), t3lib_div
::sanitizeLocalUrl(rawurlencode($url)));
2007 * Data provider for invalid sanitizeLocalUrl's
2009 * @return array Valid url
2011 public function sanitizeLocalUrlInvalidDataProvider() {
2013 'empty string' => array(''),
2014 'http domain' => array('http://www.google.de/'),
2015 'https domain' => array('https://www.google.de/'),
2016 'relative path with XSS' => array('../typo3/whatever.php?argument=javascript:alert(0)'),
2022 * @dataProvider sanitizeLocalUrlInvalidDataProvider
2024 public function sanitizeLocalUrlDeniesPlainInvalidUrls($url) {
2025 $this->assertEquals('', t3lib_div
::sanitizeLocalUrl($url));
2030 * @dataProvider sanitizeLocalUrlInvalidDataProvider
2032 public function sanitizeLocalUrlDeniesEncodedInvalidUrls($url) {
2033 $this->assertEquals('', t3lib_div
::sanitizeLocalUrl(rawurlencode($url)));
2037 //////////////////////////////////////
2038 // Tests concerning addSlashesOnArray
2039 //////////////////////////////////////
2044 public function addSlashesOnArrayAddsSlashesRecursive() {
2045 $inputArray = array(
2047 'key11' => "val'ue1",
2048 'key12' => 'val"ue2',
2050 'key2' => 'val\ue3',
2052 $expectedResult = array(
2054 'key11' => "val\'ue1",
2055 'key12' => 'val\"ue2',
2057 'key2' => 'val\\\\ue3',
2059 t3lib_div
::addSlashesOnArray($inputArray);
2060 $this->assertEquals(
2067 //////////////////////////////////////
2068 // Tests concerning addSlashesOnArray
2069 //////////////////////////////////////
2074 public function stripSlashesOnArrayStripsSlashesRecursive() {
2075 $inputArray = array(
2077 'key11' => "val\'ue1",
2078 'key12' => 'val\"ue2',
2080 'key2' => 'val\\\\ue3',
2082 $expectedResult = array(
2084 'key11' => "val'ue1",
2085 'key12' => 'val"ue2',
2087 'key2' => 'val\ue3',
2089 t3lib_div
::stripSlashesOnArray($inputArray);
2090 $this->assertEquals(
2097 //////////////////////////////////////
2098 // Tests concerning arrayDiffAssocRecursive
2099 //////////////////////////////////////
2104 public function arrayDiffAssocRecursiveHandlesOneDimensionalArrays() {
2114 $expectedResult = array(
2117 $actualResult = t3lib_div
::arrayDiffAssocRecursive($array1, $array2);
2118 $this->assertEquals($expectedResult, $actualResult);
2124 public function arrayDiffAssocRecursiveHandlesMultiDimensionalArrays() {
2128 'key21' => 'value21',
2129 'key22' => 'value22',
2131 'key231' => 'value231',
2132 'key232' => 'value232',
2139 'key21' => 'value21',
2141 'key231' => 'value231',
2145 $expectedResult = array(
2147 'key22' => 'value22',
2149 'key232' => 'value232',
2153 $actualResult = t3lib_div
::arrayDiffAssocRecursive($array1, $array2);
2154 $this->assertEquals($expectedResult, $actualResult);
2160 public function arrayDiffAssocRecursiveHandlesMixedArrays() {
2163 'key11' => 'value11',
2164 'key12' => 'value12',
2172 'key21' => 'value21',
2175 $expectedResult = array(
2178 $actualResult = t3lib_div
::arrayDiffAssocRecursive($array1, $array2);
2179 $this->assertEquals($expectedResult, $actualResult);
2183 //////////////////////////////////////
2184 // Tests concerning removeDotsFromTS
2185 //////////////////////////////////////
2190 public function removeDotsFromTypoScriptSucceedsWithDottedArray() {
2191 $typoScript = array(
2192 'propertyA.' => array(
2201 $expectedResult = array(
2202 'propertyA' => array(
2211 $this->assertEquals($expectedResult, t3lib_div
::removeDotsFromTS($typoScript));
2217 public function removeDotsFromTypoScriptOverridesSubArray() {
2218 $typoScript = array(
2219 'propertyA.' => array(
2220 'keyA' => 'getsOverridden',
2229 $expectedResult = array(
2230 'propertyA' => array(
2239 $this->assertEquals($expectedResult, t3lib_div
::removeDotsFromTS($typoScript));
2245 public function removeDotsFromTypoScriptOverridesWithScalar() {
2246 $typoScript = array(
2247 'propertyA.' => array(
2251 'keyA' => 'willOverride',
2257 $expectedResult = array(
2258 'propertyA' => array(
2259 'keyA' => 'willOverride',
2265 $this->assertEquals($expectedResult, t3lib_div
::removeDotsFromTS($typoScript));
2268 //////////////////////////////////////
2269 // Tests concerning naturalKeySortRecursive
2270 //////////////////////////////////////
2275 public function naturalKeySortRecursiveReturnsFalseIfInputIsNotAnArray() {
2276 $testValues = array(
2281 foreach($testValues as $testValue) {
2282 $this->assertFalse(t3lib_div
::naturalKeySortRecursive($testValue));
2289 public function naturalKeySortRecursiveSortsOneDimensionalArrayByNaturalOrder() {
2303 $expectedResult = array(
2316 t3lib_div
::naturalKeySortRecursive($testArray);
2317 $this->assertEquals($expectedResult, array_values($testArray));
2323 public function naturalKeySortRecursiveSortsMultiDimensionalArrayByNaturalOrder() {
2362 $expectedResult = array(
2375 t3lib_div
::naturalKeySortRecursive($testArray);
2377 $this->assertEquals($expectedResult, array_values(array_keys($testArray['aaa']['bad'])));
2378 $this->assertEquals($expectedResult, array_values(array_keys($testArray['aaa'])));
2379 $this->assertEquals($expectedResult, array_values(array_keys($testArray)));
2382 //////////////////////////////////////
2383 // Tests concerning get_dirs
2384 //////////////////////////////////////
2389 public function getDirsReturnsArrayOfDirectoriesFromGivenDirectory() {
2391 $directories = t3lib_div
::get_dirs($path);
2393 $this->assertInternalType(PHPUnit_Framework_Constraint_IsType
::TYPE_ARRAY
, $directories);
2399 public function getDirsReturnsStringErrorOnPathFailure() {
2401 $result = t3lib_div
::get_dirs($path);
2402 $expectedResult = 'error';
2404 $this->assertEquals($expectedResult, $result);
2408 //////////////////////////////////
2409 // Tests concerning hmac
2410 //////////////////////////////////
2415 public function hmacReturnsHashOfProperLength() {
2416 $hmac = t3lib_div
::hmac('message');
2417 $this->assertTrue(!empty($hmac) && is_string($hmac));
2418 $this->assertTrue(strlen($hmac) == 40);
2424 public function hmacReturnsEqualHashesForEqualInput() {
2427 $this->assertEquals(t3lib_div
::hmac($msg0), t3lib_div
::hmac($msg1));
2433 public function hmacReturnsNoEqualHashesForNonEqualInput() {
2436 $this->assertNotEquals(t3lib_div
::hmac($msg0), t3lib_div
::hmac($msg1));
2440 //////////////////////////////////
2441 // Tests concerning quoteJSvalue
2442 //////////////////////////////////
2447 public function quoteJSvalueHtmlspecialcharsDataByDefault() {
2448 $this->assertContains(
2450 t3lib_div
::quoteJSvalue('>')
2457 public function quoteJSvaluetHtmlspecialcharsDataWithinCDataSetToFalse() {
2458 $this->assertContains(
2460 t3lib_div
::quoteJSvalue('>', FALSE)
2467 public function quoteJSvaluetNotHtmlspecialcharsDataWithinCDataSetToTrue() {
2468 $this->assertContains(
2470 t3lib_div
::quoteJSvalue('>', TRUE)
2477 public function quoteJSvalueReturnsEmptyStringQuotedInSingleQuotes() {
2478 $this->assertEquals(
2480 t3lib_div
::quoteJSvalue("", TRUE)
2487 public function quoteJSvalueNotModifiesStringWithoutSpecialCharacters() {
2488 $this->assertEquals(
2490 t3lib_div
::quoteJSvalue("Hello world!", TRUE)
2497 public function quoteJSvalueEscapesSingleQuote() {
2498 $this->assertEquals(
2500 t3lib_div
::quoteJSvalue("'", TRUE)
2507 public function quoteJSvalueEscapesDoubleQuoteWithinCDataSetToTrue() {
2508 $this->assertEquals(
2510 t3lib_div
::quoteJSvalue('"', TRUE)
2517 public function quoteJSvalueEscapesAndHtmlspecialcharsDoubleQuoteWithinCDataSetToFalse() {
2518 $this->assertEquals(
2520 t3lib_div
::quoteJSvalue('"', FALSE)
2527 public function quoteJSvalueEscapesTab() {
2528 $this->assertEquals(
2530 t3lib_div
::quoteJSvalue(TAB
)
2537 public function quoteJSvalueEscapesLinefeed() {
2538 $this->assertEquals(
2540 t3lib_div
::quoteJSvalue(LF
)
2547 public function quoteJSvalueEscapesCarriageReturn() {
2548 $this->assertEquals(
2550 t3lib_div
::quoteJSvalue(CR
)
2557 public function quoteJSvalueEscapesBackslah() {
2558 $this->assertEquals(
2560 t3lib_div
::quoteJSvalue('\\')
2564 //////////////////////////////////
2565 // Tests concerning readLLfile
2566 //////////////////////////////////
2571 public function readLLfileHandlesLocallangXMLOverride() {
2572 $unique = uniqid('locallangXMLOverrideTest');
2574 $xml = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2577 <languageKey index="default" type="array">
2578 <label index="buttons.logout">EXIT</label>
2583 $file = PATH_site
. 'typo3temp/' . $unique . '.xml';
2584 t3lib_div
::writeFileToTypo3tempDir($file, $xml);
2586 // Make sure there is no cached version of the label
2587 $GLOBALS['typo3CacheManager']->getCache('t3lib_l10n')->flush();
2589 // Get default value
2590 $defaultLL = t3lib_div
::readLLfile('EXT:lang/locallang_core.xml', 'default');
2592 // Clear language cache again
2593 $GLOBALS['typo3CacheManager']->getCache('t3lib_l10n')->flush();
2595 // Set override file
2596 $GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['EXT:lang/locallang_core.xml'][$unique] = $file;
2598 /** @var $store t3lib_l10n_Store */
2599 $store = t3lib_div
::makeInstance('t3lib_l10n_Store');
2600 $store->flushData('EXT:lang/locallang_core.xml');
2602 // Get override value
2603 $overrideLL = t3lib_div
::readLLfile('EXT:lang/locallang_core.xml', 'default');
2608 $this->assertNotEquals($overrideLL['default']['buttons.logout'][0]['target'], '');
2609 $this->assertNotEquals($defaultLL['default']['buttons.logout'][0]['target'], $overrideLL['default']['buttons.logout'][0]['target']);
2610 $this->assertEquals($overrideLL['default']['buttons.logout'][0]['target'], 'EXIT');
2614 ///////////////////////////////
2615 // Tests concerning _GETset()
2616 ///////////////////////////////
2621 public function getSetWritesArrayToGetSystemVariable() {
2623 $GLOBALS['HTTP_GET_VARS'] = array();
2625 $getParameters = array('foo' => 'bar');
2626 t3lib_div
::_GETset($getParameters);
2627 $this->assertSame($getParameters, $_GET);
2633 public function getSetWritesArrayToGlobalsHttpGetVars() {
2635 $GLOBALS['HTTP_GET_VARS'] = array();
2637 $getParameters = array('foo' => 'bar');
2638 t3lib_div
::_GETset($getParameters);
2639 $this->assertSame($getParameters, $GLOBALS['HTTP_GET_VARS']);
2645 public function getSetForArrayDropsExistingValues() {
2647 $GLOBALS['HTTP_GET_VARS'] = array();
2649 t3lib_div
::_GETset(array('foo' => 'bar'));
2651 t3lib_div
::_GETset(array('oneKey' => 'oneValue'));
2653 $this->assertEquals(
2654 array('oneKey' => 'oneValue'),
2655 $GLOBALS['HTTP_GET_VARS']
2662 public function getSetAssignsOneValueToOneKey() {
2664 $GLOBALS['HTTP_GET_VARS'] = array();
2666 t3lib_div
::_GETset('oneValue', 'oneKey');
2668 $this->assertEquals(
2670 $GLOBALS['HTTP_GET_VARS']['oneKey']
2677 public function getSetForOneValueDoesNotDropUnrelatedValues() {
2679 $GLOBALS['HTTP_GET_VARS'] = array();
2681 t3lib_div
::_GETset(array('foo' => 'bar'));
2682 t3lib_div
::_GETset('oneValue', 'oneKey');
2684 $this->assertEquals(
2685 array('foo' => 'bar', 'oneKey' => 'oneValue'),
2686 $GLOBALS['HTTP_GET_VARS']
2693 public function getSetCanAssignsAnArrayToASpecificArrayElement() {
2695 $GLOBALS['HTTP_GET_VARS'] = array();
2697 t3lib_div
::_GETset(array('childKey' => 'oneValue'), 'parentKey');
2699 $this->assertEquals(
2700 array('parentKey' => array('childKey' => 'oneValue')),
2701 $GLOBALS['HTTP_GET_VARS']
2708 public function getSetCanAssignAStringValueToASpecificArrayChildElement() {
2710 $GLOBALS['HTTP_GET_VARS'] = array();
2712 t3lib_div
::_GETset('oneValue', 'parentKey|childKey');
2714 $this->assertEquals(
2715 array('parentKey' => array('childKey' => 'oneValue')),
2716 $GLOBALS['HTTP_GET_VARS']
2723 public function getSetCanAssignAnArrayToASpecificArrayChildElement() {
2725 $GLOBALS['HTTP_GET_VARS'] = array();
2728 array('key1' => 'value1', 'key2' => 'value2'),
2729 'parentKey|childKey'
2732 $this->assertEquals(
2734 'parentKey' => array(
2735 'childKey' => array('key1' => 'value1', 'key2' => 'value2')
2738 $GLOBALS['HTTP_GET_VARS']
2743 ///////////////////////////
2744 // Tests concerning getUrl
2745 ///////////////////////////
2750 public function getUrlWithAdditionalRequestHeadersProvidesHttpHeaderOnError() {
2751 $url = 'http://typo3.org/i-do-not-exist-' . time();
2760 $this->assertContains(
2769 public function getUrlProvidesWithoutAdditionalRequestHeadersHttpHeaderOnError() {
2770 $url = 'http://typo3.org/i-do-not-exist-' . time();
2779 $this->assertContains(
2782 'Did not provide the HTTP response header when requesting a failing URL.'
2787 ///////////////////////////////
2788 // Tests concerning fixPermissions
2789 ///////////////////////////////
2794 public function fixPermissionsSetsGroup() {
2795 if (TYPO3_OS
== 'WIN') {
2796 $this->markTestSkipped('fixPermissionsSetsGroup() tests not available on Windows');
2798 if (!function_exists('posix_getegid')) {
2799 $this->markTestSkipped('Function posix_getegid() not available, fixPermissionsSetsGroup() tests skipped');
2801 if (posix_getegid() === -1) {
2802 $this->markTestSkipped(
2803 'The fixPermissionsSetsGroup() is not available on Mac OS because posix_getegid() always returns -1 on Mac OS.'
2807 // Create and prepare test file
2808 $filename = PATH_site
. 'typo3temp/' . uniqid('test_');
2809 t3lib_div
::writeFileToTypo3tempDir($filename, '42');
2811 $currentGroupId = posix_getegid();
2813 // Set target group and run method
2814 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = $currentGroupId;
2815 $fixPermissionsResult = t3lib_div
::fixPermissions($filename);
2818 $resultFileGroup = filegroup($filename);
2821 $this->assertEquals($resultFileGroup, $currentGroupId);
2827 public function fixPermissionsSetsPermissionsToFile() {
2828 if (TYPO3_OS
== 'WIN') {
2829 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2832 // Create and prepare test file
2833 $filename = PATH_site
. 'typo3temp/' . uniqid('test_');
2834 t3lib_div
::writeFileToTypo3tempDir($filename, '42');
2835 chmod($filename, 0742);
2837 // Set target permissions and run method
2838 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2839 $fixPermissionsResult = t3lib_div
::fixPermissions($filename);
2841 // Get actual permissions and clean up
2843 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
2846 // Test if everything was ok
2847 $this->assertTrue($fixPermissionsResult);
2848 $this->assertEquals($resultFilePermissions, '0660');
2854 public function fixPermissionsSetsPermissionsToHiddenFile() {
2855 if (TYPO3_OS
== 'WIN') {
2856 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2859 // Create and prepare test file
2860 $filename = PATH_site
. 'typo3temp/' . uniqid('.test_');
2861 t3lib_div
::writeFileToTypo3tempDir($filename, '42');
2862 chmod($filename, 0742);
2864 // Set target permissions and run method
2865 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2866 $fixPermissionsResult = t3lib_div
::fixPermissions($filename);
2868 // Get actual permissions and clean up
2870 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
2873 // Test if everything was ok
2874 $this->assertTrue($fixPermissionsResult);
2875 $this->assertEquals($resultFilePermissions, '0660');
2881 public function fixPermissionsSetsPermissionsToDirectory() {
2882 if (TYPO3_OS
== 'WIN') {
2883 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2886 // Create and prepare test directory
2887 $directory = PATH_site
. 'typo3temp/' . uniqid('test_');
2888 t3lib_div
::mkdir($directory);
2889 chmod($directory, 1551);
2891 // Set target permissions and run method
2892 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2893 $fixPermissionsResult = t3lib_div
::fixPermissions($directory);
2895 // Get actual permissions and clean up
2897 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2898 t3lib_div
::rmdir($directory);
2900 // Test if everything was ok
2901 $this->assertTrue($fixPermissionsResult);
2902 $this->assertEquals($resultDirectoryPermissions, '0770');
2908 public function fixPermissionsSetsPermissionsToDirectoryWithTrailingSlash() {
2909 if (TYPO3_OS
== 'WIN') {
2910 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2913 // Create and prepare test directory
2914 $directory = PATH_site
. 'typo3temp/' . uniqid('test_');
2915 t3lib_div
::mkdir($directory);
2916 chmod($directory, 1551);
2918 // Set target permissions and run method
2919 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2920 $fixPermissionsResult = t3lib_div
::fixPermissions($directory . '/');
2922 // Get actual permissions and clean up
2924 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2925 t3lib_div
::rmdir($directory);
2927 // Test if everything was ok
2928 $this->assertTrue($fixPermissionsResult);
2929 $this->assertEquals($resultDirectoryPermissions, '0770');
2935 public function fixPermissionsSetsPermissionsToHiddenDirectory() {
2936 if (TYPO3_OS
== 'WIN') {
2937 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2940 // Create and prepare test directory
2941 $directory = PATH_site
. 'typo3temp/' . uniqid('.test_');
2942 t3lib_div
::mkdir($directory);
2943 chmod($directory, 1551);
2945 // Set target permissions and run method
2946 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2947 $fixPermissionsResult = t3lib_div
::fixPermissions($directory);
2949 // Get actual permissions and clean up
2951 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2952 t3lib_div
::rmdir($directory);
2954 // Test if everything was ok
2955 $this->assertTrue($fixPermissionsResult);
2956 $this->assertEquals($resultDirectoryPermissions, '0770');
2962 public function fixPermissionsCorrectlySetsPermissionsRecursive() {
2963 if (TYPO3_OS
== 'WIN') {
2964 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2967 // Create and prepare test directory and file structure
2968 $baseDirectory = PATH_site
. 'typo3temp/' . uniqid('test_');
2969 t3lib_div
::mkdir($baseDirectory);
2970 chmod($baseDirectory, 1751);
2971 t3lib_div
::writeFileToTypo3tempDir($baseDirectory . '/file', '42');
2972 chmod($baseDirectory . '/file', 0742);
2973 t3lib_div
::mkdir($baseDirectory . '/foo');
2974 chmod($baseDirectory . '/foo', 1751);
2975 t3lib_div
::writeFileToTypo3tempDir($baseDirectory . '/foo/file', '42');
2976 chmod($baseDirectory . '/foo/file', 0742);
2977 t3lib_div
::mkdir($baseDirectory . '/.bar');
2978 chmod($baseDirectory . '/.bar', 1751);
2979 // Use this if writeFileToTypo3tempDir is fixed to create hidden files in subdirectories
2980 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/.file', '42');
2981 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/..file2', '42');
2982 touch($baseDirectory . '/.bar/.file', '42');
2983 chmod($baseDirectory . '/.bar/.file', 0742);
2984 touch($baseDirectory . '/.bar/..file2', '42');
2985 chmod($baseDirectory . '/.bar/..file2', 0742);
2987 // Set target permissions and run method
2988 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2989 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2990 $fixPermissionsResult = t3lib_div
::fixPermissions($baseDirectory, TRUE);
2992 // Get actual permissions
2994 $resultBaseDirectoryPermissions = substr(decoct(fileperms($baseDirectory)), 1);
2995 $resultBaseFilePermissions = substr(decoct(fileperms($baseDirectory . '/file')), 2);
2996 $resultFooDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/foo')), 1);
2997 $resultFooFilePermissions = substr(decoct(fileperms($baseDirectory . '/foo/file')), 2);
2998 $resultBarDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/.bar')), 1);
2999 $resultBarFilePermissions = substr(decoct(fileperms($baseDirectory . '/.bar/.file')), 2);
3000 $resultBarFile2Permissions = substr(decoct(fileperms($baseDirectory . '/.bar/..file2')), 2);
3003 unlink($baseDirectory . '/file');
3004 unlink($baseDirectory . '/foo/file');
3005 unlink($baseDirectory . '/.bar/.file');
3006 unlink($baseDirectory . '/.bar/..file2');
3007 t3lib_div
::rmdir($baseDirectory . '/foo');
3008 t3lib_div
::rmdir($baseDirectory . '/.bar');
3009 t3lib_div
::rmdir($baseDirectory);
3011 // Test if everything was ok
3012 $this->assertTrue($fixPermissionsResult);
3013 $this->assertEquals($resultBaseDirectoryPermissions, '0770');
3014 $this->assertEquals($resultBaseFilePermissions, '0660');
3015 $this->assertEquals($resultFooDirectoryPermissions, '0770');
3016 $this->assertEquals($resultFooFilePermissions, '0660');
3017 $this->assertEquals($resultBarDirectoryPermissions, '0770');
3018 $this->assertEquals($resultBarFilePermissions, '0660');
3019 $this->assertEquals($resultBarFile2Permissions, '0660');
3025 public function fixPermissionsDoesNotSetPermissionsToNotAllowedPath() {
3026 if (TYPO3_OS
== 'WIN') {
3027 $this->markTestSkipped('fixPermissions() tests not available on Windows');
3030 // Create and prepare test file
3031 $filename = PATH_site
. 'typo3temp/../typo3temp/' . uniqid('test_');
3033 chmod($filename, 0742);
3035 // Set target permissions and run method
3036 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
3037 $fixPermissionsResult = t3lib_div
::fixPermissions($filename);
3039 // Get actual permissions and clean up
3041 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
3044 // Test if everything was ok
3045 $this->assertFalse($fixPermissionsResult);
3051 public function fixPermissionsSetsPermissionsWithRelativeFileReference() {
3052 if (TYPO3_OS
== 'WIN') {
3053 $this->markTestSkipped('fixPermissions() tests not available on Windows');
3056 $filename = 'typo3temp/' . uniqid('test_');
3057 t3lib_div
::writeFileToTypo3tempDir(PATH_site
. $filename, '42');
3058 chmod(PATH_site
. $filename, 0742);
3060 // Set target permissions and run method
3061 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
3062 $fixPermissionsResult = t3lib_div
::fixPermissions($filename);
3064 // Get actual permissions and clean up
3066 $resultFilePermissions = substr(decoct(fileperms(PATH_site
. $filename)), 2);
3067 unlink(PATH_site
. $filename);
3069 // Test if everything was ok
3070 $this->assertTrue($fixPermissionsResult);
3071 $this->assertEquals($resultFilePermissions, '0660');
3075 ///////////////////////////////
3076 // Tests concerning mkdir
3077 ///////////////////////////////
3082 public function mkdirCreatesDirectory() {
3083 $directory = PATH_site
. 'typo3temp/' . uniqid('test_');
3084 $mkdirResult = t3lib_div
::mkdir($directory);
3086 $directoryCreated = is_dir($directory);
3088 $this->assertTrue($mkdirResult);
3089 $this->assertTrue($directoryCreated);
3095 public function mkdirCreatesHiddenDirectory() {
3096 $directory = PATH_site
. 'typo3temp/' . uniqid('.test_');
3097 $mkdirResult = t3lib_div
::mkdir($directory);
3099 $directoryCreated = is_dir($directory);
3101 $this->assertTrue($mkdirResult);
3102 $this->assertTrue($directoryCreated);
3108 public function mkdirCreatesDirectoryWithTrailingSlash() {
3109 $directory = PATH_site
. 'typo3temp/' . uniqid('test_') . '/';
3110 $mkdirResult = t3lib_div
::mkdir($directory);
3112 $directoryCreated = is_dir($directory);
3114 $this->assertTrue($mkdirResult);
3115 $this->assertTrue($directoryCreated);
3121 public function mkdirSetsPermissionsOfCreatedDirectory() {
3122 if (TYPO3_OS
== 'WIN') {
3123 $this->markTestSkipped('mkdirSetsPermissionsOfCreatedDirectory() test not available on Windows');
3126 $directory = PATH_site
. 'typo3temp/' . uniqid('test_');
3127 $oldUmask = umask(023);
3128 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0772';
3129 t3lib_div
::mkdir($directory);
3131 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
3134 $this->assertEquals($resultDirectoryPermissions, '0772');
3140 public function mkdirSetsGroupOwnershipOfCreatedDirectory() {
3141 if (!function_exists('posix_getegid')) {
3142 $this->markTestSkipped('Function posix_getegid() not available, mkdirSetsGroupOwnershipOfCreatedDirectory() tests skipped');
3144 if (posix_getegid() === -1) {
3145 $this->markTestSkipped(
3146 'The mkdirSetsGroupOwnershipOfCreatedDirectory() is not available on Mac OS because posix_getegid() always returns -1 on Mac OS.'
3149 $swapGroup = $this->checkGroups(__FUNCTION__
);
3150 if ($swapGroup !== FALSE) {
3151 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = $swapGroup;
3152 $directory = uniqid('mkdirtest_');
3153 t3lib_div
::mkdir(PATH_site
. 'typo3temp/' . $directory);
3155 $resultDirectoryGroupInfo = posix_getgrgid((filegroup(PATH_site
. 'typo3temp/' . $directory)));
3156 $resultDirectoryGroup = $resultDirectoryGroupInfo['name'];
3157 @rmdir
(PATH_site
. 'typo3temp/' . $directory);
3158 $this->assertEquals($resultDirectoryGroup, $swapGroup);
3162 ///////////////////////////////
3163 // Helper function for filesystem ownership tests
3164 ///////////////////////////////
3167 * Check if test on filesystem group ownership can be done in this environment
3168 * If so, return second group of webserver user
3169 * @param string calling method name
3170 * @return mixed FALSE if test cannot be run, string name of the second group of webserver user
3172 private function checkGroups($methodName) {
3173 if (TYPO3_OS
== 'WIN') {
3174 $this->markTestSkipped($methodName . '() test not available on Windows.');
3177 if (!function_exists('posix_getgroups')) {
3178 $this->markTestSkipped('Function posix_getgroups() not available, ' . $methodName . '() tests skipped');
3181 $groups = posix_getgroups();
3182 if (count($groups) <= 1) {
3183 $this->markTestSkipped($methodName . '() test cannot be done when the web server user is only member of 1 group.');
3186 $groupInfo = posix_getgrgid($groups[1]);
3187 return $groupInfo['name'];
3190 ///////////////////////////////
3191 // Tests concerning mkdir_deep
3192 ///////////////////////////////
3197 public function mkdirDeepCreatesDirectory() {
3198 $directory = 'typo3temp/' . uniqid('test_');
3199 t3lib_div
::mkdir_deep(PATH_site
, $directory);
3200 $isDirectoryCreated = is_dir(PATH_site
. $directory);
3201 rmdir(PATH_site
. $directory);
3202 $this->assertTrue($isDirectoryCreated);
3208 public function mkdirDeepCreatesSubdirectoriesRecursive() {
3209 $directory = 'typo3temp/' . uniqid('test_');
3210 $subDirectory = $directory . '/foo';
3211 t3lib_div
::mkdir_deep(PATH_site
, $subDirectory);
3212 $isDirectoryCreated = is_dir(PATH_site
. $subDirectory);
3213 rmdir(PATH_site
. $subDirectory);
3214 rmdir(PATH_site
. $directory);
3215 $this->assertTrue($isDirectoryCreated);
3221 public function mkdirDeepFixesPermissionsOfCreatedDirectory() {
3222 if (TYPO3_OS
== 'WIN') {
3223 $this->markTestSkipped('mkdirDeepFixesPermissionsOfCreatedDirectory() test not available on Windows.');
3226 $directory = uniqid('mkdirdeeptest_');
3227 $oldUmask = umask(023);
3228 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0777';
3229 t3lib_div
::mkdir_deep(PATH_site
. 'typo3temp/', $director