[BUGFIX] t3lib_div::getUrl() providing wrong error information
[Packages/TYPO3.CMS.git] / tests / t3lib / class.t3lib_divTest.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009-2011 Ingo Renner <ingo@typo3.org>
6 * All rights reserved
7 *
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.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
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.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 /**
26 * Testcase for class t3lib_div
27 *
28 * @author Ingo Renner <ingo@typo3.org>
29 * @author Oliver Klee <typo3-coding@oliverklee.de>
30 *
31 * @package TYPO3
32 * @subpackage t3lib
33 */
34 class t3lib_divTest extends tx_phpunit_testcase {
35
36 /**
37 * Enable backup of global and system variables
38 *
39 * @var boolean
40 */
41 protected $backupGlobals = TRUE;
42
43 /**
44 * Exclude TYPO3_DB from backup/ restore of $GLOBALS
45 * because resource types cannot be handled during serializing
46 *
47 * @var array
48 */
49 protected $backupGlobalsBlacklist = array('TYPO3_DB');
50
51 public function tearDown() {
52 t3lib_div::purgeInstances();
53 }
54
55
56 ///////////////////////////////
57 // Tests concerning gif_compress
58 ///////////////////////////////
59
60 /**
61 * @test
62 */
63 public function gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() {
64 if (TYPO3_OS == 'WIN') {
65 $this->markTestSkipped('gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() test not available on Windows.');
66 }
67
68 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] || !$GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']) {
69 $this->markTestSkipped('gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() test not available without imagemagick setup.');
70 }
71
72 $testFinder = t3lib_div::makeInstance('Tx_Phpunit_Service_TestFinder');
73 $fixtureGifFile = $testFinder->getAbsoluteCoreTestsPath() . 't3lib/fixtures/clear.gif';
74
75 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gif_compress'] = TRUE;
76
77 // Copy file to unique filename in typo3temp, set target permissions and run method
78 $testFilename = PATH_site . 'typo3temp/' . uniqid('test_') . '.gif';
79 @copy($fixtureGifFile, $testFilename);
80 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
81 t3lib_div::gif_compress($testFilename, 'IM');
82
83 // Get actual permissions and clean up
84 clearstatcache();
85 $resultFilePermissions = substr(decoct(fileperms($testFilename)), 2);
86 t3lib_div::unlink_tempfile($testFilename);
87
88 $this->assertEquals($resultFilePermissions, '0777');
89 }
90
91 /**
92 * @test
93 */
94 public function gifCompressFixesPermissionOfConvertedFileIfUsingGd() {
95 if (TYPO3_OS == 'WIN') {
96 $this->markTestSkipped('gifCompressFixesPermissionOfConvertedFileIfUsingImagemagick() test not available on Windows.');
97 }
98
99 $testFinder = t3lib_div::makeInstance('Tx_Phpunit_Service_TestFinder');
100 $fixtureGifFile = $testFinder->getAbsoluteCoreTestsPath() . 't3lib/fixtures/clear.gif';
101
102 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib'] = TRUE;
103 $GLOBALS['TYPO3_CONF_VARS']['GFX']['gdlib_png'] = FALSE;
104
105 // Copy file to unique filename in typo3temp, set target permissions and run method
106 $testFilename = PATH_site . 'typo3temp/' . uniqid('test_') . '.gif';
107 @copy($fixtureGifFile, $testFilename);
108 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
109 t3lib_div::gif_compress($testFilename, 'GD');
110
111 // Get actual permissions and clean up
112 clearstatcache();
113 $resultFilePermissions = substr(decoct(fileperms($testFilename)), 2);
114 t3lib_div::unlink_tempfile($testFilename);
115
116 $this->assertEquals($resultFilePermissions, '0777');
117 }
118
119 ///////////////////////////////
120 // Tests concerning png_to_gif_by_imagemagick
121 ///////////////////////////////
122
123 /**
124 * @test
125 */
126 public function pngToGifByImagemagickFixesPermissionsOfConvertedFile() {
127 if (TYPO3_OS == 'WIN') {
128 $this->markTestSkipped('pngToGifByImagemagickFixesPermissionsOfConvertedFile() test not available on Windows.');
129 }
130
131 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im'] || !$GLOBALS['TYPO3_CONF_VARS']['GFX']['im_path_lzw']) {
132 $this->markTestSkipped('pngToGifByImagemagickFixesPermissionsOfConvertedFile() test not available without imagemagick setup.');
133 }
134
135 $testFinder = t3lib_div::makeInstance('Tx_Phpunit_Service_TestFinder');
136 $fixturePngFile = $testFinder->getAbsoluteCoreTestsPath() . 't3lib/fixtures/clear.png';
137
138 $GLOBALS['TYPO3_CONF_VARS']['FE']['png_to_gif'] = TRUE;
139
140 // Copy file to unique filename in typo3temp, set target permissions and run method
141 $testFilename = PATH_site . 'typo3temp/' . uniqid('test_') . '.png';
142 @copy($fixturePngFile, $testFilename);
143 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
144 $newGifFile = t3lib_div::png_to_gif_by_imagemagick($testFilename);
145
146 // Get actual permissions and clean up
147 clearstatcache();
148 $resultFilePermissions = substr(decoct(fileperms($newGifFile)), 2);
149 t3lib_div::unlink_tempfile($newGifFile);
150
151 $this->assertEquals($resultFilePermissions, '0777');
152 }
153
154 ///////////////////////////////
155 // Tests concerning read_png_gif
156 ///////////////////////////////
157
158 /**
159 * @test
160 */
161 public function readPngGifFixesPermissionsOfConvertedFile() {
162 if (TYPO3_OS == 'WIN') {
163 $this->markTestSkipped('readPngGifFixesPermissionsOfConvertedFile() test not available on Windows.');
164 }
165
166 if (!$GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) {
167 $this->markTestSkipped('readPngGifFixesPermissionsOfConvertedFile() test not available without imagemagick setup.');
168 }
169
170 $testFinder = t3lib_div::makeInstance('Tx_Phpunit_Service_TestFinder');
171 $testGifFile = $testFinder->getAbsoluteCoreTestsPath() . 't3lib/fixtures/clear.gif';
172
173 // Set target permissions and run method
174 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
175 $newPngFile = t3lib_div::read_png_gif($testGifFile, TRUE);
176
177 // Get actual permissions and clean up
178 clearstatcache();
179 $resultFilePermissions = substr(decoct(fileperms($newPngFile)), 2);
180 t3lib_div::unlink_tempfile($newPngFile);
181
182 $this->assertEquals($resultFilePermissions, '0777');
183 }
184
185 ///////////////////////////
186 // Tests concerning cmpIPv4
187 ///////////////////////////
188
189 /**
190 * Data provider for cmpIPv4ReturnsTrueForMatchingAddress
191 *
192 * @return array Data sets
193 */
194 public static function cmpIPv4DataProviderMatching() {
195 return array(
196 'host with full IP address' => array('127.0.0.1', '127.0.0.1'),
197 'host with two wildcards at the end' => array('127.0.0.1', '127.0.*.*'),
198 'host with wildcard at third octet' => array('127.0.0.1', '127.0.*.1'),
199 'host with wildcard at second octet' => array('127.0.0.1', '127.*.0.1'),
200 '/8 subnet' => array('127.0.0.1', '127.1.1.1/8'),
201 '/32 subnet (match only name)' => array('127.0.0.1', '127.0.0.1/32'),
202 '/30 subnet' => array('10.10.3.1', '10.10.3.3/30'),
203 'host with wildcard in list with IPv4/IPv6 addresses' => array('192.168.1.1', '127.0.0.1, 1234:5678::/126, 192.168.*'),
204 'host in list with IPv4/IPv6 addresses' => array('192.168.1.1', '::1, 1234:5678::/126, 192.168.1.1'),
205 );
206 }
207
208 /**
209 * @test
210 * @dataProvider cmpIPv4DataProviderMatching
211 */
212 public function cmpIPv4ReturnsTrueForMatchingAddress($ip, $list) {
213 $this->assertTrue(t3lib_div::cmpIPv4($ip, $list));
214 }
215
216 /**
217 * Data provider for cmpIPv4ReturnsFalseForNotMatchingAddress
218 *
219 * @return array Data sets
220 */
221 public static function cmpIPv4DataProviderNotMatching() {
222 return array(
223 'single host' => array('127.0.0.1', '127.0.0.2'),
224 'single host with wildcard' => array('127.0.0.1', '127.*.1.1'),
225 'single host with /32 subnet mask' => array('127.0.0.1', '127.0.0.2/32'),
226 '/31 subnet' => array('127.0.0.1', '127.0.0.2/31'),
227 'list with IPv4/IPv6 addresses' => array('127.0.0.1', '10.0.2.3, 192.168.1.1, ::1'),
228 'list with only IPv6 addresses' => array('10.20.30.40', '::1, 1234:5678::/127'),
229 );
230 }
231
232 /**
233 * @test
234 * @dataProvider cmpIPv4DataProviderNotMatching
235 */
236 public function cmpIPv4ReturnsFalseForNotMatchingAddress($ip, $list) {
237 $this->assertFalse(t3lib_div::cmpIPv4($ip, $list));
238 }
239 ///////////////////////////
240 // Tests concerning cmpIPv6
241 ///////////////////////////
242
243 /**
244 * Data provider for cmpIPv6ReturnsTrueForMatchingAddress
245 *
246 * @return array Data sets
247 */
248 public static function cmpIPv6DataProviderMatching() {
249 return array(
250 'empty address' => array('::', '::'),
251 'empty with netmask in list' => array('::', '::/0'),
252 'empty with netmask 0 and host-bits set in list' => array('::', '::123/0'),
253 'localhost' => array('::1', '::1'),
254 'localhost with leading zero blocks' => array('::1', '0:0::1'),
255 'host with submask /128' => array('::1', '0:0::1/128'),
256 '/16 subnet' => array('1234::1', '1234:5678::/16'),
257 '/126 subnet' => array('1234:5678::3', '1234:5678::/126'),
258 '/126 subnet with host-bits in list set' => array('1234:5678::3', '1234:5678::2/126'),
259 'list with IPv4/IPv6 addresses' => array('1234:5678::3', '::1, 127.0.0.1, 1234:5678::/126, 192.168.1.1'),
260 );
261 }
262
263 /**
264 * @test
265 * @dataProvider cmpIPv6DataProviderMatching
266 */
267 public function cmpIPv6ReturnsTrueForMatchingAddress($ip, $list) {
268 $this->assertTrue(t3lib_div::cmpIPv6($ip, $list));
269 }
270
271 /**
272 * Data provider for cmpIPv6ReturnsFalseForNotMatchingAddress
273 *
274 * @return array Data sets
275 */
276 public static function cmpIPv6DataProviderNotMatching() {
277 return array(
278 'empty against localhost' => array('::', '::1'),
279 'empty against localhost with /128 netmask' => array('::', '::1/128'),
280 'localhost against different host' => array('::1', '::2'),
281 'localhost against host with prior bits set' => array('::1', '::1:1'),
282 'host against different /17 subnet' => array('1234::1', '1234:f678::/17'),
283 'host against different /127 subnet' => array('1234:5678::3', '1234:5678::/127'),
284 'host against IPv4 address list' => array('1234:5678::3', '127.0.0.1, 192.168.1.1'),
285 'host against mixed list with IPv6 host in different subnet' => array('1234:5678::3', '::1, 1234:5678::/127'),
286 );
287 }
288
289 /**
290 * @test
291 * @dataProvider cmpIPv6DataProviderNotMatching
292 */
293 public function cmpIPv6ReturnsFalseForNotMatchingAddress($ip, $list) {
294 $this->assertFalse(t3lib_div::cmpIPv6($ip, $list));
295 }
296
297 ///////////////////////////////
298 // Tests concerning IPv6Hex2Bin
299 ///////////////////////////////
300
301 /**
302 * Data provider for IPv6Hex2BinCorrect
303 *
304 * @return array Data sets
305 */
306 public static function IPv6Hex2BinDataProviderCorrect() {
307 return array(
308 'empty 1' => array('::', str_pad('', 16, "\x00")),
309 'empty 2, already normalized' => array('0000:0000:0000:0000:0000:0000:0000:0000', str_pad('', 16, "\x00")),
310 'already normalized' => array('0102:0304:0000:0000:0000:0000:0506:0078', "\x01\x02\x03\x04" . str_pad('', 8, "\x00") . "\x05\x06\x00\x78"),
311 'expansion in middle 1' => array('1::2', "\x00\x01" . str_pad('', 12, "\x00") . "\x00\x02"),
312 'expansion in middle 2' => array('beef::fefa', "\xbe\xef" . str_pad('', 12, "\x00") . "\xfe\xfa"),
313 );
314 }
315
316 /**
317 * @test
318 * @dataProvider IPv6Hex2BinDataProviderCorrect
319 */
320 public function IPv6Hex2BinCorrectlyConvertsAddresses($hex, $binary) {
321 $this->assertTrue(t3lib_div::IPv6Hex2Bin($hex) === $binary);
322 }
323
324 ///////////////////////////////
325 // Tests concerning IPv6Bin2Hex
326 ///////////////////////////////
327
328 /**
329 * Data provider for IPv6Bin2HexCorrect
330 *
331 * @return array Data sets
332 */
333 public static function IPv6Bin2HexDataProviderCorrect() {
334 return array(
335 'empty' => array(str_pad('', 16, "\x00"), '::'),
336 'non-empty front' => array("\x01" . str_pad('', 15, "\x00"), '100::'),
337 'non-empty back' => array(str_pad('', 15, "\x00") . "\x01", '::1'),
338 'normalized' => array("\x01\x02\x03\x04" . str_pad('', 8, "\x00") . "\x05\x06\x00\x78", '102:304::506:78'),
339 'expansion in middle 1' => array("\x00\x01" . str_pad('', 12, "\x00") . "\x00\x02", '1::2'),
340 'expansion in middle 2' => array("\xbe\xef" . str_pad('', 12, "\x00") . "\xfe\xfa", 'beef::fefa'),
341 );
342 }
343
344 /**
345 * @test
346 * @dataProvider IPv6Bin2HexDataProviderCorrect
347 */
348 public function IPv6Bin2HexCorrectlyConvertsAddresses($binary, $hex) {
349 $this->assertEquals(t3lib_div::IPv6Bin2Hex($binary), $hex);
350 }
351
352 ////////////////////////////////////////////////
353 // Tests concerning normalizeIPv6 / compressIPv6
354 ////////////////////////////////////////////////
355
356 /**
357 * Data provider for normalizeIPv6ReturnsCorrectlyNormalizedFormat
358 *
359 * @return array Data sets
360 */
361 public static function normalizeCompressIPv6DataProviderCorrect() {
362 return array(
363 'empty' => array('::', '0000:0000:0000:0000:0000:0000:0000:0000'),
364 'localhost' => array('::1', '0000:0000:0000:0000:0000:0000:0000:0001'),
365 'some address on right side' => array('::f0f', '0000:0000:0000:0000:0000:0000:0000:0f0f'),
366 'expansion in middle 1' => array('1::2', '0001:0000:0000:0000:0000:0000:0000:0002'),
367 'expansion in middle 2' => array('1:2::3', '0001:0002:0000:0000:0000:0000:0000:0003'),
368 'expansion in middle 3' => array('1::2:3', '0001:0000:0000:0000:0000:0000:0002:0003'),
369 'expansion in middle 4' => array('1:2::3:4:5', '0001:0002:0000:0000:0000:0003:0004:0005'),
370 );
371 }
372
373 /**
374 * @test
375 * @dataProvider normalizeCompressIPv6DataProviderCorrect
376 */
377 public function normalizeIPv6CorrectlyNormalizesAddresses($compressed, $normalized) {
378 $this->assertEquals(t3lib_div::normalizeIPv6($compressed), $normalized);
379 }
380
381 /**
382 * @test
383 * @dataProvider normalizeCompressIPv6DataProviderCorrect
384 */
385 public function compressIPv6CorrectlyCompressesAdresses($compressed, $normalized) {
386 $this->assertEquals(t3lib_div::compressIPv6($normalized), $compressed);
387 }
388
389 ///////////////////////////////
390 // Tests concerning validIP
391 ///////////////////////////////
392
393 /**
394 * Data provider for checkValidIpReturnsTrueForValidIp
395 *
396 * @return array Data sets
397 */
398 public static function validIpDataProvider() {
399 return array(
400 '0.0.0.0' => array('0.0.0.0'),
401 'private IPv4 class C' => array('192.168.0.1'),
402 'private IPv4 class A' => array('10.0.13.1'),
403 'private IPv6' => array('fe80::daa2:5eff:fe8b:7dfb'),
404 );
405 }
406
407 /**
408 * @test
409 * @dataProvider validIpDataProvider
410 */
411 public function validIpReturnsTrueForValidIp($ip) {
412 $this->assertTrue(t3lib_div::validIP($ip));
413 }
414
415 /**
416 * Data provider for checkValidIpReturnsFalseForInvalidIp
417 *
418 * @return array Data sets
419 */
420 public static function invalidIpDataProvider() {
421 return array(
422 'null' => array(NULL),
423 'zero' => array(0),
424 'string' => array('test'),
425 'string empty' => array(''),
426 'string NULL' => array('NULL'),
427 'out of bounds IPv4' => array('300.300.300.300'),
428 'dotted decimal notation with only two dots' => array('127.0.1'),
429 );
430 }
431
432 /**
433 * @test
434 * @dataProvider invalidIpDataProvider
435 */
436 public function validIpReturnsFalseForInvalidIp($ip) {
437 $this->assertFalse(t3lib_div::validIP($ip));
438 }
439
440 ///////////////////////////////
441 // Tests concerning cmpFQDN
442 ///////////////////////////////
443
444 /**
445 * Data provider for cmpFqdnReturnsTrue
446 *
447 * @return array Data sets
448 */
449 public static function cmpFqdnValidDataProvider() {
450 return array(
451 'localhost should usually resolve, IPv4' => array('127.0.0.1', '*'),
452 'localhost should usually resolve, IPv6' => array('::1', '*'),
453 // other testcases with resolving not possible since it would
454 // require a working IPv4/IPv6-connectivity
455 'aaa.bbb.ccc.ddd.eee, full' => array('aaa.bbb.ccc.ddd.eee', 'aaa.bbb.ccc.ddd.eee'),
456 'aaa.bbb.ccc.ddd.eee, wildcard first' => array('aaa.bbb.ccc.ddd.eee', '*.ccc.ddd.eee'),
457 'aaa.bbb.ccc.ddd.eee, wildcard last' => array('aaa.bbb.ccc.ddd.eee', 'aaa.bbb.ccc.*'),
458 'aaa.bbb.ccc.ddd.eee, wildcard middle' => array('aaa.bbb.ccc.ddd.eee', 'aaa.*.eee'),
459 'list-matches, 1' => array('aaa.bbb.ccc.ddd.eee', 'xxx, yyy, zzz, aaa.*.eee'),
460 'list-matches, 2' => array('aaa.bbb.ccc.ddd.eee', '127:0:0:1,,aaa.*.eee,::1'),
461 );
462 }
463
464 /**
465 * @test
466 * @dataProvider cmpFqdnValidDataProvider
467 */
468 public function cmpFqdnReturnsTrue($baseHost, $list) {
469 $this->assertTrue(t3lib_div::cmpFQDN($baseHost, $list));
470 }
471
472 /**
473 * Data provider for cmpFqdnReturnsFalse
474 *
475 * @return array Data sets
476 */
477 public static function cmpFqdnInvalidDataProvider() {
478 return array(
479 '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'),
480 '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'),
481 );
482 }
483
484 /**
485 * @test
486 * @dataProvider cmpFqdnInvalidDataProvider
487 */
488 public function cmpFqdnReturnsFalse($baseHost, $list) {
489 $this->assertFalse(t3lib_div::cmpFQDN($baseHost, $list));
490 }
491
492
493 ///////////////////////////////
494 // Tests concerning testInt
495 ///////////////////////////////
496
497 /**
498 * Data provider for testIntReturnsTrue
499 *
500 * @return array Data sets
501 */
502 public function functionTestIntValidDataProvider() {
503 return array(
504 'int' => array(32425),
505 'negative int' => array(-32425),
506 'largest int' => array(PHP_INT_MAX),
507 'int as string' => array('32425'),
508 'negative int as string' => array('-32425'),
509 'zero' => array(0),
510 'zero as string' => array('0'),
511 );
512 }
513
514 /**
515 * @test
516 * @dataProvider functionTestIntValidDataProvider
517 */
518 public function testIntReturnsTrue($int) {
519 $this->assertTrue(t3lib_utility_Math::canBeInterpretedAsInteger($int));
520 }
521
522 /**
523 * Data provider for testIntReturnsFalse
524 *
525 * @return array Data sets
526 */
527 public function functionTestIntInvalidDataProvider() {
528 return array(
529 'int as string with leading zero' => array('01234'),
530 'positive int as string with plus modifier' => array('+1234'),
531 'negative int as string with leading zero' => array('-01234'),
532 'largest int plus one' => array(PHP_INT_MAX + 1),
533 'string' => array('testInt'),
534 'empty string' => array(''),
535 'int in string' => array('5 times of testInt'),
536 'int as string with space after' => array('5 '),
537 'int as string with space before' => array(' 5'),
538 'int as string with many spaces before' => array(' 5'),
539 'float' => array(3.14159),
540 'float as string' => array('3.14159'),
541 'float as string only a dot' => array('10.'),
542 'float as string trailing zero would evaluate to int 10' => array('10.0'),
543 'float as string trailing zeros would evaluate to int 10' => array('10.00'),
544 'null' => array(NULL),
545 'empty array' => array(array()),
546 'int in array' => array(array(32425)),
547 'int as string in array' => array(array('32425')),
548 );
549 }
550
551 /**
552 * @test
553 * @dataProvider functionTestIntInvalidDataProvider
554 */
555 public function testIntReturnsFalse($int) {
556 $this->assertFalse(t3lib_utility_Math::canBeInterpretedAsInteger($int));
557 }
558
559
560 ///////////////////////////////
561 // Tests concerning isFirstPartOfStr
562 ///////////////////////////////
563
564 /**
565 * Data provider for isFirstPartOfStrReturnsTrueForMatchingFirstParts
566 *
567 * @return array
568 */
569 public function isFirstPartOfStrReturnsTrueForMatchingFirstPartDataProvider() {
570 return array(
571 'match first part of string' => array('hello world', 'hello'),
572 'match whole string' => array('hello', 'hello'),
573 'integer is part of string with same number' => array('24', 24),
574 'string is part of integer with same number' => array(24, '24'),
575 'integer is part of string starting with same number' => array('24 beer please', 24),
576 );
577 }
578
579 /**
580 * @test
581 * @dataProvider isFirstPartOfStrReturnsTrueForMatchingFirstPartDataProvider
582 */
583 public function isFirstPartOfStrReturnsTrueForMatchingFirstPart($string, $part) {
584 $this->assertTrue(t3lib_div::isFirstPartOfStr($string, $part));
585 }
586
587 /**
588 * Data provider for checkIsFirstPartOfStrReturnsFalseForNotMatchingFirstParts
589 *
590 * @return array
591 */
592 public function isFirstPartOfStrReturnsFalseForNotMatchingFirstPartDataProvider() {
593 return array(
594 'no string match' => array('hello', 'bye'),
595 'no case sensitive string match' => array('hello world', 'Hello'),
596 'array is not part of string' => array('string', array()),
597 'string is not part of array' => array(array(), 'string'),
598 'NULL is not part of string' => array('string', NULL),
599 'string is not part of array' => array(NULL, 'string'),
600 'NULL is not part of array' => array(array(), NULL),
601 'array is not part of string' => array(NULL, array()),
602 'empty string is not part of empty string' => array('', ''),
603 'NULL is not part of empty string' => array('', NULL),
604 'false is not part of empty string' => array('', FALSE),
605 'empty string is not part of NULL' => array(NULL, ''),
606 'empty string is not part of false' => array(FALSE, ''),
607 'empty string is not part of zero integer' => array(0, ''),
608 'zero integer is not part of NULL' => array(NULL, 0),
609 'zero integer is not part of empty string' => array('', 0),
610 );
611 }
612
613 /**
614 * @test
615 * @dataProvider isFirstPartOfStrReturnsFalseForNotMatchingFirstPartDataProvider
616 */
617 public function isFirstPartOfStrReturnsFalseForNotMatchingFirstPart($string, $part) {
618 $this->assertFalse(t3lib_div::isFirstPartOfStr($string, $part));
619 }
620
621
622 ///////////////////////////////
623 // Tests concerning splitCalc
624 ///////////////////////////////
625
626 /**
627 * Data provider for splitCalc
628 *
629 * @return array expected values, arithmetic expression
630 */
631 public function splitCalcDataProvider() {
632 return array(
633 'empty string returns empty array' => array(
634 array(),
635 '',
636 ),
637 'number without operator returns array with plus and number' => array(
638 array(array('+', 42)),
639 '42',
640 ),
641 'two numbers with asterisk return first number with plus and second number with asterisk' => array(
642 array(array('+', 42), array('*', 31)),
643 '42 * 31',
644 ),
645 );
646 }
647
648 /**
649 * @test
650 * @dataProvider splitCalcDataProvider
651 */
652 public function splitCalcCorrectlySplitsExpression($expected, $expression) {
653 $this->assertEquals($expected, t3lib_div::splitCalc($expression, '+-*/'));
654 }
655
656
657 //////////////////////////////////
658 // Tests concerning calcPriority
659 //////////////////////////////////
660
661 /**
662 * Data provider for calcPriority
663 *
664 * @return array expected values, arithmetic expression
665 */
666 public function calcPriorityDataProvider() {
667 return array(
668 'add' => array(9, '6 + 3'),
669 'substract with positive result' => array(3, '6 - 3'),
670 'substract with negative result' => array(-3, '3 - 6'),
671 'multiply' => array(6, '2 * 3'),
672 'divide' => array(2.5, '5 / 2'),
673 'modulus' => array(1, '5 % 2'),
674 'power' => array(8, '2 ^ 3'),
675 'three operands with non integer result' => array(6.5, '5 + 3 / 2'),
676 'three operands with power' => array(14, '5 + 3 ^ 2'),
677 'three operads with modulus' => array(4, '5 % 2 + 3'),
678 'four operands' => array(3, '2 + 6 / 2 - 2'),
679 'division by zero when dividing' => array('ERROR: dividing by zero', '2 / 0'),
680 'division by zero with modulus' => array('ERROR: dividing by zero', '2 % 0')
681 );
682 }
683
684 /**
685 * @test
686 * @dataProvider calcPriorityDataProvider
687 */
688 public function calcPriorityCorrectlyCalculatesExpression($expected, $expression) {
689 $this->assertEquals($expected, t3lib_div::calcPriority($expression));
690 }
691
692 //////////////////////////////////
693 // Tests concerning calcParenthesis
694 //////////////////////////////////
695
696 /**
697 * Data provider for calcParenthesis
698 *
699 * @return array expected values, arithmetic expression
700 */
701 public function calcParenthesisDataProvider() {
702 return array(
703 'starts with parenthesis' => array(18, '(6 + 3) * 2'),
704 'ends with parenthesis' => array(6, '2 * (6 - 3)'),
705 'multiple parentheses' => array(-6, '(3 - 6) * (4 - 2)'),
706 'nested parentheses' => array(22, '2 * (3 + 2 + (3 * 2))'),
707 'parenthesis with division' => array(15, '5 / 2 * (3 * 2)'),
708 );
709 }
710
711 /**
712 * @test
713 * @dataProvider calcParenthesisDataProvider
714 */
715 public function calcParenthesisCorrectlyCalculatesExpression($expected, $expression) {
716 $this->assertEquals($expected, t3lib_div::calcParenthesis($expression));
717 }
718
719 //////////////////////////////////
720 // Tests concerning calcPriority
721 //////////////////////////////////
722
723 /**
724 * Data provider for valid validEmail's
725 *
726 * @return array Valid email addresses
727 */
728 public function validEmailValidDataProvider() {
729 return array(
730 'short mail address' => array('a@b.c'),
731 'simple mail address' => array('test@example.com'),
732 'uppercase characters' => array('QWERTYUIOPASDFGHJKLZXCVBNM@QWERTYUIOPASDFGHJKLZXCVBNM.NET'),
733 // 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
734 // 'equal sign in local part' => array('test=mail@example.com'),
735 'dash in local part' => array('test-mail@example.com'),
736 'plus in local part' => array('test+mail@example.com'),
737 // 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
738 // 'question mark in local part' => array('test?mail@example.com'),
739 'slash in local part' => array('foo/bar@example.com'),
740 'hash in local part' => array('foo#bar@example.com'),
741 // 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
742 // 'dot in local part' => array('firstname.lastname@employee.2something.com'),
743 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
744 // 'dash as local part' => array('-@foo.com'),
745 'umlauts in local part' => array('äöüfoo@bar.com'),
746 'umlauts in domain part' => array('foo@äöüfoo.com'),
747 );
748 }
749
750 /**
751 * @test
752 * @dataProvider validEmailValidDataProvider
753 */
754 public function validEmailReturnsTrueForValidMailAddress($address) {
755 $this->assertTrue(t3lib_div::validEmail($address));
756 }
757
758 /**
759 * Data provider for invalid validEmail's
760 *
761 * @return array Invalid email addresses
762 */
763 public function validEmailInvalidDataProvider() {
764 return array(
765 '@ sign only' => array('@'),
766 'duplicate @' => array('test@@example.com'),
767 'duplicate @ combined with further special characters in local part' => array('test!.!@#$%^&*@example.com'),
768 'opening parenthesis in local part' => array('foo(bar@example.com'),
769 'closing parenthesis in local part' => array('foo)bar@example.com'),
770 'opening square bracket in local part' => array('foo[bar@example.com'),
771 'closing square bracket as local part' => array(']@example.com'),
772 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
773 // 'top level domain only' => array('test@com'),
774 'dash as second level domain' => array('foo@-.com'),
775 'domain part starting with dash' => array('foo@-foo.com'),
776 'domain part ending with dash' => array('foo@foo-.com'),
777 'number as top level domain' => array('foo@bar.123'),
778 // Fix / change if TYPO3 php requirement changed: Address not ok with 5.2.6, but ok with 5.3.2 (?)
779 // 'dash as top level domain' => array('foo@bar.-'),
780 'dot at beginning of domain part' => array('test@.com'),
781 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
782 // 'local part ends with dot' => array('e.x.a.m.p.l.e.@example.com'),
783 'trailing whitespace' => array('test@example.com '),
784 'trailing carriage return' => array('test@example.com' . CR),
785 'trailing linefeed' => array('test@example.com' . LF),
786 'trailing carriage return linefeed' => array('test@example.com' . CRLF),
787 'trailing tab' => array('test@example.com' . TAB),
788 );
789 }
790
791 /**
792 * @test
793 * @dataProvider validEmailInvalidDataProvider
794 */
795 public function validEmailReturnsFalseForInvalidMailAddress($address) {
796 $this->assertFalse(t3lib_div::validEmail($address));
797 }
798
799
800 //////////////////////////////////
801 // Tests concerning intExplode
802 //////////////////////////////////
803
804 /**
805 * @test
806 */
807 public function intExplodeConvertsStringsToInteger() {
808 $testString = '1,foo,2';
809 $expectedArray = array(1, 0, 2);
810 $actualArray = t3lib_div::intExplode(',', $testString);
811
812 $this->assertEquals($expectedArray, $actualArray);
813 }
814
815 //////////////////////////////////
816 // Tests concerning intInRange
817 //////////////////////////////////
818 /**
819 * Data provider for intInRangeForcesIntegerIntoBoundaries
820 *
821 * @return array expected values, arithmetic expression
822 */
823 public function intInRangeForcesIntegerIntoDefaultBoundariesDataProvider() {
824 return array(
825 'negativeValue' => array(0, -10),
826 'normalValue' => array(30, 30),
827 'veryHighValue' => array(2000000000, 3000000001),
828 'zeroValue' => array(0, 0),
829 'anotherNormalValue' => array(12309, 12309)
830 );
831 }
832
833 /**
834 * @test
835 * @dataProvider intInRangeForcesIntegerIntoDefaultBoundariesDataProvider
836 */
837 public function intInRangeForcesIntegerIntoDefaultBoundaries($expected, $value) {
838 $this->assertEquals($expected, t3lib_div::intInRange($value, 0));
839 }
840
841 /**
842 * @test
843 */
844 public function intInRangeSetsDefaultValueIfZeroValueIsGiven() {
845 $this->assertEquals(42, t3lib_div::intInRange('', 0, 2000000000, 42));
846 }
847
848 //////////////////////////////////
849 // Tests concerning intval_positive
850 //////////////////////////////////
851 /**
852 * @test
853 */
854 public function intvalPositiveReturnsZeroForNegativeValues() {
855 $this->assertEquals(0, t3lib_div::intval_positive(-123));
856 }
857
858 /**
859 * @test
860 */
861 public function intvalPositiveReturnsTheInputValueForPositiveValues() {
862 $this->assertEquals(123, t3lib_div::intval_positive(123));
863 }
864
865 //////////////////////////////////
866 // Tests concerning int_from_ver
867 //////////////////////////////////
868 /**
869 * Data Provider for intFromVerConvertsVersionNumbersToIntegersDataProvider
870 *
871 * return array
872 */
873 public function intFromVerConvertsVersionNumbersToIntegersDataProvider() {
874 return array(
875 array('4003003', '4.3.3'),
876 array('4012003', '4.12.3'),
877 array('5000000', '5.0.0'),
878 array('3008001', '3.8.1'),
879 array('1012', '0.1.12')
880 );
881 }
882
883 /**
884 * @test
885 * @dataProvider intFromVerConvertsVersionNumbersToIntegersDataProvider
886 */
887 public function intFromVerConvertsVersionNumbersToIntegers($expected, $version) {
888 $this->assertEquals($expected, t3lib_div::int_from_ver($version));
889 }
890
891 //////////////////////////////////
892 // Tests concerning revExplode
893 //////////////////////////////////
894
895 /**
896 * @test
897 */
898 public function revExplodeExplodesString() {
899 $testString = 'my:words:here';
900 $expectedArray = array('my:words', 'here');
901 $actualArray = t3lib_div::revExplode(':', $testString, 2);
902
903 $this->assertEquals($expectedArray, $actualArray);
904 }
905
906
907 //////////////////////////////////
908 // Tests concerning trimExplode
909 //////////////////////////////////
910
911 /**
912 * @test
913 */
914 public function checkTrimExplodeTrimsSpacesAtElementStartAndEnd() {
915 $testString = ' a , b , c ,d ,, e,f,';
916 $expectedArray = array('a', 'b', 'c', 'd', '', 'e', 'f', '');
917 $actualArray = t3lib_div::trimExplode(',', $testString);
918
919 $this->assertEquals($expectedArray, $actualArray);
920 }
921
922 /**
923 * @test
924 */
925 public function checkTrimExplodeRemovesNewLines() {
926 $testString = ' a , b , ' . LF . ' ,d ,, e,f,';
927 $expectedArray = array('a', 'b', 'd', 'e', 'f');
928 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
929
930 $this->assertEquals($expectedArray, $actualArray);
931 }
932
933 /**
934 * @test
935 */
936 public function checkTrimExplodeRemovesEmptyElements() {
937 $testString = 'a , b , c , ,d ,, ,e,f,';
938 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f');
939 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
940
941 $this->assertEquals($expectedArray, $actualArray);
942 }
943
944 /**
945 * @test
946 */
947 public function checkTrimExplodeKeepsRemainingResultsWithEmptyItemsAfterReachingLimitWithPositiveParameter() {
948 $testString = ' a , b , c , , d,, ,e ';
949 $expectedArray = array('a', 'b', 'c,,d,,,e');
950 // Limiting returns the rest of the string as the last element
951 $actualArray = t3lib_div::trimExplode(',', $testString, FALSE, 3);
952
953 $this->assertEquals($expectedArray, $actualArray);
954 }
955
956 /**
957 * @test
958 */
959 public function checkTrimExplodeKeepsRemainingResultsWithoutEmptyItemsAfterReachingLimitWithPositiveParameter() {
960 $testString = ' a , b , c , , d,, ,e ';
961 $expectedArray = array('a', 'b', 'c,d,e');
962 // Limiting returns the rest of the string as the last element
963 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, 3);
964
965 $this->assertEquals($expectedArray, $actualArray);
966 }
967
968 /**
969 * @test
970 */
971 public function checkTrimExplodeKeepsRamainingResultsWithEmptyItemsAfterReachingLimitWithNegativeParameter() {
972 $testString = ' a , b , c , d, ,e, f , , ';
973 $expectedArray = array('a', 'b', 'c', 'd', '', 'e');
974 // limiting returns the rest of the string as the last element
975 $actualArray = t3lib_div::trimExplode(',', $testString, FALSE, -3);
976
977 $this->assertEquals($expectedArray, $actualArray);
978 }
979
980 /**
981 * @test
982 */
983 public function checkTrimExplodeKeepsRamainingResultsWithoutEmptyItemsAfterReachingLimitWithNegativeParameter() {
984 $testString = ' a , b , c , d, ,e, f , , ';
985 $expectedArray = array('a', 'b', 'c');
986 // Limiting returns the rest of the string as the last element
987 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, -3);
988
989 $this->assertEquals($expectedArray, $actualArray);
990 }
991
992 /**
993 * @test
994 */
995 public function checkTrimExplodeReturnsExactResultsWithoutReachingLimitWithPositiveParameter() {
996 $testString = ' a , b , , c , , , ';
997 $expectedArray = array('a', 'b', 'c');
998 // Limiting returns the rest of the string as the last element
999 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, 4);
1000
1001 $this->assertEquals($expectedArray, $actualArray);
1002 }
1003
1004 /**
1005 * @test
1006 */
1007 public function checkTrimExplodeKeepsZeroAsString() {
1008 $testString = 'a , b , c , ,d ,, ,e,f, 0 ,';
1009 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f', '0');
1010 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
1011
1012 $this->assertEquals($expectedArray, $actualArray);
1013 }
1014
1015
1016 //////////////////////////////////
1017 // Tests concerning removeArrayEntryByValue
1018 //////////////////////////////////
1019
1020 /**
1021 * @test
1022 */
1023 public function checkRemoveArrayEntryByValueRemovesEntriesFromOneDimensionalArray() {
1024 $inputArray = array(
1025 '0' => 'test1',
1026 '1' => 'test2',
1027 '2' => 'test3',
1028 '3' => 'test2',
1029 );
1030 $compareValue = 'test2';
1031 $expectedResult = array(
1032 '0' => 'test1',
1033 '2' => 'test3',
1034 );
1035 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
1036 $this->assertEquals($expectedResult, $actualResult);
1037 }
1038
1039 /**
1040 * @test
1041 */
1042 public function checkRemoveArrayEntryByValueRemovesEntriesFromMultiDimensionalArray() {
1043 $inputArray = array(
1044 '0' => 'foo',
1045 '1' => array(
1046 '10' => 'bar',
1047 ),
1048 '2' => 'bar',
1049 );
1050 $compareValue = 'bar';
1051 $expectedResult = array(
1052 '0' => 'foo',
1053 '1' => array(),
1054 );
1055 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
1056 $this->assertEquals($expectedResult, $actualResult);
1057 }
1058
1059 /**
1060 * @test
1061 */
1062 public function checkRemoveArrayEntryByValueRemovesEntryWithEmptyString() {
1063 $inputArray = array(
1064 '0' => 'foo',
1065 '1' => '',
1066 '2' => 'bar',
1067 );
1068 $compareValue = '';
1069 $expectedResult = array(
1070 '0' => 'foo',
1071 '2' => 'bar',
1072 );
1073 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
1074 $this->assertEquals($expectedResult, $actualResult);
1075 }
1076
1077 //////////////////////////////////
1078 // Tests concerning getBytesFromSizeMeasurement
1079 //////////////////////////////////
1080
1081 /**
1082 * Data provider for getBytesFromSizeMeasurement
1083 *
1084 * @return array expected value, input string
1085 */
1086 public function getBytesFromSizeMeasurementDataProvider() {
1087 return array(
1088 '100 kilo Bytes' => array('102400', '100k'),
1089 '100 mega Bytes' => array('104857600', '100m'),
1090 '100 giga Bytes' => array('107374182400', '100g'),
1091 );
1092 }
1093
1094 /**
1095 * @test
1096 * @dataProvider getBytesFromSizeMeasurementDataProvider
1097 */
1098 public function getBytesFromSizeMeasurementCalculatesCorrectByteValue($expected, $byteString) {
1099 $this->assertEquals($expected, t3lib_div::getBytesFromSizeMeasurement($byteString));
1100 }
1101
1102
1103 //////////////////////////////////
1104 // Tests concerning getIndpEnv
1105 //////////////////////////////////
1106
1107 /**
1108 * @test
1109 */
1110 public function getIndpEnvTypo3SitePathReturnNonEmptyString() {
1111 $this->assertTrue(strlen(t3lib_div::getIndpEnv('TYPO3_SITE_PATH')) >= 1);
1112 }
1113
1114 /**
1115 * @test
1116 */
1117 public function getIndpEnvTypo3SitePathReturnsStringStartingWithSlash() {
1118 $result = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
1119 $this->assertEquals('/', $result[0]);
1120 }
1121
1122 /**
1123 * @test
1124 */
1125 public function getIndpEnvTypo3SitePathReturnsStringEndingWithSlash() {
1126 $result = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
1127 $this->assertEquals('/', $result[strlen($result) - 1]);
1128 }
1129
1130 /**
1131 * @return array
1132 */
1133 public static function hostnameAndPortDataProvider() {
1134 return array(
1135 'localhost ipv4 without port' => array('127.0.0.1', '127.0.0.1', ''),
1136 'localhost ipv4 with port' => array('127.0.0.1:81', '127.0.0.1', '81'),
1137 'localhost ipv6 without port' => array('[::1]', '[::1]', ''),
1138 'localhost ipv6 with port' => array('[::1]:81', '[::1]', '81'),
1139 'ipv6 without port' => array('[2001:DB8::1]', '[2001:DB8::1]', ''),
1140 'ipv6 with port' => array('[2001:DB8::1]:81', '[2001:DB8::1]', '81'),
1141 'hostname without port' => array('lolli.did.this', 'lolli.did.this', ''),
1142 'hostname with port' => array('lolli.did.this:42', 'lolli.did.this', '42'),
1143 );
1144 }
1145
1146 /**
1147 * @test
1148 * @dataProvider hostnameAndPortDataProvider
1149 */
1150 public function getIndpEnvTypo3HostOnlyParsesHostnamesAndIpAdresses($httpHost, $expectedIp) {
1151 $_SERVER['HTTP_HOST'] = $httpHost;
1152 $this->assertEquals($expectedIp, t3lib_div::getIndpEnv('TYPO3_HOST_ONLY'));
1153 }
1154
1155 /**
1156 * @test
1157 * @dataProvider hostnameAndPortDataProvider
1158 */
1159 public function getIndpEnvTypo3PortParsesHostnamesAndIpAdresses($httpHost, $dummy, $expectedPort) {
1160 $_SERVER['HTTP_HOST'] = $httpHost;
1161 $this->assertEquals($expectedPort, t3lib_div::getIndpEnv('TYPO3_PORT'));
1162 }
1163
1164
1165 //////////////////////////////////
1166 // Tests concerning underscoredToUpperCamelCase
1167 //////////////////////////////////
1168
1169 /**
1170 * Data provider for underscoredToUpperCamelCase
1171 *
1172 * @return array expected, input string
1173 */
1174 public function underscoredToUpperCamelCaseDataProvider() {
1175 return array(
1176 'single word' => array('Blogexample', 'blogexample'),
1177 'multiple words' => array('BlogExample', 'blog_example'),
1178 );
1179 }
1180
1181 /**
1182 * @test
1183 * @dataProvider underscoredToUpperCamelCaseDataProvider
1184 */
1185 public function underscoredToUpperCamelCase($expected, $inputString) {
1186 $this->assertEquals($expected, t3lib_div::underscoredToUpperCamelCase($inputString));
1187 }
1188
1189
1190 //////////////////////////////////
1191 // Tests concerning underscoredToLowerCamelCase
1192 //////////////////////////////////
1193
1194 /**
1195 * Data provider for underscoredToLowerCamelCase
1196 *
1197 * @return array expected, input string
1198 */
1199 public function underscoredToLowerCamelCaseDataProvider() {
1200 return array(
1201 'single word' => array('minimalvalue', 'minimalvalue'),
1202 'multiple words' => array('minimalValue', 'minimal_value'),
1203 );
1204 }
1205
1206 /**
1207 * @test
1208 * @dataProvider underscoredToLowerCamelCaseDataProvider
1209 */
1210 public function underscoredToLowerCamelCase($expected, $inputString) {
1211 $this->assertEquals($expected, t3lib_div::underscoredToLowerCamelCase($inputString));
1212 }
1213
1214 //////////////////////////////////
1215 // Tests concerning camelCaseToLowerCaseUnderscored
1216 //////////////////////////////////
1217
1218 /**
1219 * Data provider for camelCaseToLowerCaseUnderscored
1220 *
1221 * @return array expected, input string
1222 */
1223 public function camelCaseToLowerCaseUnderscoredDataProvider() {
1224 return array(
1225 'single word' => array('blogexample', 'blogexample'),
1226 'single word starting upper case' => array('blogexample', 'Blogexample'),
1227 'two words starting lower case' => array('minimal_value', 'minimalValue'),
1228 'two words starting upper case' => array('blog_example', 'BlogExample'),
1229 );
1230 }
1231
1232 /**
1233 * @test
1234 * @dataProvider camelCaseToLowerCaseUnderscoredDataProvider
1235 */
1236 public function camelCaseToLowerCaseUnderscored($expected, $inputString) {
1237 $this->assertEquals($expected, t3lib_div::camelCaseToLowerCaseUnderscored($inputString));
1238 }
1239
1240
1241 //////////////////////////////////
1242 // Tests concerning lcFirst
1243 //////////////////////////////////
1244
1245 /**
1246 * Data provider for lcFirst
1247 *
1248 * @return array expected, input string
1249 */
1250 public function lcfirstDataProvider() {
1251 return array(
1252 'single word' => array('blogexample', 'blogexample'),
1253 'single Word starting upper case' => array('blogexample', 'Blogexample'),
1254 'two words' => array('blogExample', 'BlogExample'),
1255 );
1256 }
1257
1258 /**
1259 * @test
1260 * @dataProvider lcfirstDataProvider
1261 */
1262 public function lcFirst($expected, $inputString) {
1263 $this->assertEquals($expected, t3lib_div::lcfirst($inputString));
1264 }
1265
1266
1267 //////////////////////////////////
1268 // Tests concerning encodeHeader
1269 //////////////////////////////////
1270
1271 /**
1272 * @test
1273 */
1274 public function encodeHeaderEncodesWhitespacesInQuotedPrintableMailHeader() {
1275 $this->assertEquals(
1276 '=?utf-8?Q?We_test_whether_the_copyright_character_=C2=A9_is_encoded_correctly?=',
1277 t3lib_div::encodeHeader(
1278 "We test whether the copyright character \xc2\xa9 is encoded correctly",
1279 'quoted-printable',
1280 'utf-8'
1281 )
1282 );
1283 }
1284
1285 /**
1286 * @test
1287 */
1288 public function encodeHeaderEncodesQuestionmarksInQuotedPrintableMailHeader() {
1289 $this->assertEquals(
1290 '=?utf-8?Q?Is_the_copyright_character_=C2=A9_really_encoded_correctly=3F_Really=3F?=',
1291 t3lib_div::encodeHeader(
1292 "Is the copyright character \xc2\xa9 really encoded correctly? Really?",
1293 'quoted-printable',
1294 'utf-8'
1295 )
1296 );
1297 }
1298
1299
1300 //////////////////////////////////
1301 // Tests concerning isValidUrl
1302 //////////////////////////////////
1303
1304 /**
1305 * Data provider for valid isValidUrl's
1306 *
1307 * @return array Valid ressource
1308 */
1309 public function validUrlValidRessourceDataProvider() {
1310 return array(
1311 'http' => array('http://www.example.org/'),
1312 'http without trailing slash' => array('http://qwe'),
1313 'http directory with trailing slash' => array('http://www.example/img/dir/'),
1314 'http directory without trailing slash' => array('http://www.example/img/dir'),
1315 'http index.html' => array('http://example.com/index.html'),
1316 'http index.php' => array('http://www.example.com/index.php'),
1317 'http test.png' => array('http://www.example/img/test.png'),
1318 'http username password querystring and ancher' => array('https://user:pw@www.example.org:80/path?arg=value#fragment'),
1319 'file' => array('file:///tmp/test.c'),
1320 'file directory' => array('file://foo/bar'),
1321 'ftp directory' => array('ftp://ftp.example.com/tmp/'),
1322 'mailto' => array('mailto:foo@bar.com'),
1323 'news' => array('news:news.php.net'),
1324 'telnet'=> array('telnet://192.0.2.16:80/'),
1325 'ldap' => array('ldap://[2001:db8::7]/c=GB?objectClass?one'),
1326 'http punycode domain name' => array('http://www.xn--bb-eka.at'),
1327 'http punicode subdomain' => array('http://xn--h-zfa.oebb.at'),
1328 'http domain-name umlauts' => array('http://www.öbb.at'),
1329 'http subdomain umlauts' => array('http://äh.oebb.at'),
1330 'http directory umlauts' => array('http://www.oebb.at/äöü/'),
1331 );
1332 }
1333
1334 /**
1335 * @test
1336 * @dataProvider validUrlValidRessourceDataProvider
1337 */
1338 public function validURLReturnsTrueForValidRessource($url) {
1339 $this->assertTrue(t3lib_div::isValidUrl($url));
1340 }
1341
1342 /**
1343 * Data provider for invalid isValidUrl's
1344 *
1345 * @return array Invalid ressource
1346 */
1347 public function isValidUrlInvalidRessourceDataProvider() {
1348 return array(
1349 'http missing colon' => array('http//www.example/wrong/url/'),
1350 'http missing slash' => array('http:/www.example'),
1351 'hostname only' => array('www.example.org/'),
1352 'file missing protocol specification' => array('/tmp/test.c'),
1353 'slash only' => array('/'),
1354 'string http://' => array('http://'),
1355 'string http:/' => array('http:/'),
1356 'string http:' => array('http:'),
1357 'string http' => array('http'),
1358 'empty string' => array(''),
1359 'string -1' => array('-1'),
1360 'string array()' => array('array()'),
1361 'random string' => array('qwe'),
1362 );
1363 }
1364
1365 /**
1366 * @test
1367 * @dataProvider isValidUrlInvalidRessourceDataProvider
1368 */
1369 public function validURLReturnsFalseForInvalidRessoure($url) {
1370 $this->assertFalse(t3lib_div::isValidUrl($url));
1371 }
1372
1373
1374 //////////////////////////////////
1375 // Tests concerning isOnCurrentHost
1376 //////////////////////////////////
1377
1378 /**
1379 * @test
1380 */
1381 public function isOnCurrentHostReturnsTrueWithCurrentHost() {
1382 $testUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_URL');
1383 $this->assertTrue(t3lib_div::isOnCurrentHost($testUrl));
1384 }
1385
1386 /**
1387 * Data provider for invalid isOnCurrentHost's
1388 *
1389 * @return array Invalid Hosts
1390 */
1391 public function checkisOnCurrentHostInvalidHosts() {
1392 return array(
1393 'empty string' => array(''),
1394 'arbitrary string' => array('arbitrary string'),
1395 'localhost IP' => array('127.0.0.1'),
1396 'relative path' => array('./relpath/file.txt'),
1397 'absolute path' => array('/abspath/file.txt?arg=value'),
1398 'differnt host' => array(t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST') . '.example.org'),
1399 );
1400 }
1401
1402
1403 ////////////////////////////////////////
1404 // Tests concerning sanitizeLocalUrl
1405 ////////////////////////////////////////
1406
1407 /**
1408 * Data provider for valid sanitizeLocalUrl's
1409 *
1410 * @return array Valid url
1411 */
1412 public function sanitizeLocalUrlValidUrlDataProvider() {
1413 $subDirectory = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
1414 $typo3SiteUrl = t3lib_div::getIndpEnv('TYPO3_SITE_URL');
1415 $typo3RequestHost = t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST');
1416
1417 return array(
1418 'alt_intro.php' => array('alt_intro.php'),
1419 'alt_intro.php?foo=1&bar=2' => array('alt_intro.php?foo=1&bar=2'),
1420 $subDirectory . 'typo3/alt_intro.php' => array($subDirectory . 'typo3/alt_intro.php'),
1421 $subDirectory . 'index.php' => array($subDirectory . 'index.php'),
1422 '../index.php' => array('../index.php'),
1423 '../typo3/alt_intro.php' => array('../typo3/alt_intro.php'),
1424 '../~userDirectory/index.php' => array('../~userDirectory/index.php'),
1425 '../typo3/mod.php?var1=test-case&var2=~user' => array('../typo3/mod.php?var1=test-case&var2=~user'),
1426 PATH_site . 'typo3/alt_intro.php' => array(PATH_site . 'typo3/alt_intro.php'),
1427 $typo3SiteUrl . 'typo3/alt_intro.php' => array($typo3SiteUrl . 'typo3/alt_intro.php'),
1428 $typo3RequestHost . $subDirectory . '/index.php' => array($typo3RequestHost . $subDirectory . '/index.php'),
1429 );
1430 }
1431
1432 /**
1433 * @test
1434 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
1435 */
1436 public function sanitizeLocalUrlAcceptsNotEncodedValidUrls($url) {
1437 $this->assertEquals($url, t3lib_div::sanitizeLocalUrl($url));
1438 }
1439
1440 /**
1441 * @test
1442 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
1443 */
1444 public function sanitizeLocalUrlAcceptsEncodedValidUrls($url) {
1445 $this->assertEquals(rawurlencode($url), t3lib_div::sanitizeLocalUrl(rawurlencode($url)));
1446 }
1447
1448 /**
1449 * Data provider for invalid sanitizeLocalUrl's
1450 *
1451 * @return array Valid url
1452 */
1453 public function sanitizeLocalUrlInvalidDataProvider() {
1454 return array(
1455 'empty string' => array(''),
1456 'http domain' => array('http://www.google.de/'),
1457 'https domain' => array('https://www.google.de/'),
1458 'relative path with XSS' => array('../typo3/whatever.php?argument=javascript:alert(0)'),
1459 );
1460 }
1461
1462 /**
1463 * @test
1464 * @dataProvider sanitizeLocalUrlInvalidDataProvider
1465 */
1466 public function sanitizeLocalUrlDeniesPlainInvalidUrls($url) {
1467 $this->assertEquals('', t3lib_div::sanitizeLocalUrl($url));
1468 }
1469
1470 /**
1471 * @test
1472 * @dataProvider sanitizeLocalUrlInvalidDataProvider
1473 */
1474 public function sanitizeLocalUrlDeniesEncodedInvalidUrls($url) {
1475 $this->assertEquals('', t3lib_div::sanitizeLocalUrl(rawurlencode($url)));
1476 }
1477
1478
1479 //////////////////////////////////////
1480 // Tests concerning addSlashesOnArray
1481 //////////////////////////////////////
1482
1483 /**
1484 * @test
1485 */
1486 public function addSlashesOnArrayAddsSlashesRecursive() {
1487 $inputArray = array(
1488 'key1' => array(
1489 'key11' => "val'ue1",
1490 'key12' => 'val"ue2',
1491 ),
1492 'key2' => 'val\ue3',
1493 );
1494 $expectedResult = array(
1495 'key1' => array(
1496 'key11' => "val\'ue1",
1497 'key12' => 'val\"ue2',
1498 ),
1499 'key2' => 'val\\\\ue3',
1500 );
1501 t3lib_div::addSlashesOnArray($inputArray);
1502 $this->assertEquals(
1503 $expectedResult,
1504 $inputArray
1505 );
1506 }
1507
1508
1509 //////////////////////////////////////
1510 // Tests concerning addSlashesOnArray
1511 //////////////////////////////////////
1512
1513 /**
1514 * @test
1515 */
1516 public function stripSlashesOnArrayStripsSlashesRecursive() {
1517 $inputArray = array(
1518 'key1' => array(
1519 'key11' => "val\'ue1",
1520 'key12' => 'val\"ue2',
1521 ),
1522 'key2' => 'val\\\\ue3',
1523 );
1524 $expectedResult = array(
1525 'key1' => array(
1526 'key11' => "val'ue1",
1527 'key12' => 'val"ue2',
1528 ),
1529 'key2' => 'val\ue3',
1530 );
1531 t3lib_div::stripSlashesOnArray($inputArray);
1532 $this->assertEquals(
1533 $expectedResult,
1534 $inputArray
1535 );
1536 }
1537
1538
1539 //////////////////////////////////////
1540 // Tests concerning arrayDiffAssocRecursive
1541 //////////////////////////////////////
1542
1543 /**
1544 * @test
1545 */
1546 public function arrayDiffAssocRecursiveHandlesOneDimensionalArrays() {
1547 $array1 = array(
1548 'key1' => 'value1',
1549 'key2' => 'value2',
1550 'key3' => 'value3',
1551 );
1552 $array2 = array(
1553 'key1' => 'value1',
1554 'key3' => 'value3',
1555 );
1556 $expectedResult = array(
1557 'key2' => 'value2',
1558 );
1559 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1560 $this->assertEquals($expectedResult, $actualResult);
1561 }
1562
1563 /**
1564 * @test
1565 */
1566 public function arrayDiffAssocRecursiveHandlesMultiDimensionalArrays() {
1567 $array1 = array(
1568 'key1' => 'value1',
1569 'key2' => array(
1570 'key21' => 'value21',
1571 'key22' => 'value22',
1572 'key23' => array(
1573 'key231' => 'value231',
1574 'key232' => 'value232',
1575 ),
1576 ),
1577 );
1578 $array2 = array(
1579 'key1' => 'value1',
1580 'key2' => array(
1581 'key21' => 'value21',
1582 'key23' => array(
1583 'key231' => 'value231',
1584 ),
1585 ),
1586 );
1587 $expectedResult = array(
1588 'key2' => array(
1589 'key22' => 'value22',
1590 'key23' => array(
1591 'key232' => 'value232',
1592 ),
1593 ),
1594 );
1595 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1596 $this->assertEquals($expectedResult, $actualResult);
1597 }
1598
1599 /**
1600 * @test
1601 */
1602 public function arrayDiffAssocRecursiveHandlesMixedArrays() {
1603 $array1 = array(
1604 'key1' => array(
1605 'key11' => 'value11',
1606 'key12' => 'value12',
1607 ),
1608 'key2' => 'value2',
1609 'key3' => 'value3',
1610 );
1611 $array2 = array(
1612 'key1' => 'value1',
1613 'key2' => array(
1614 'key21' => 'value21',
1615 ),
1616 );
1617 $expectedResult = array(
1618 'key3' => 'value3',
1619 );
1620 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1621 $this->assertEquals($expectedResult, $actualResult);
1622 }
1623
1624
1625 //////////////////////////////////////
1626 // Tests concerning removeDotsFromTS
1627 //////////////////////////////////////
1628
1629 /**
1630 * @test
1631 */
1632 public function removeDotsFromTypoScriptSucceedsWithDottedArray() {
1633 $typoScript = array(
1634 'propertyA.' => array(
1635 'keyA.' => array(
1636 'valueA' => 1,
1637 ),
1638 'keyB' => 2,
1639 ),
1640 'propertyB' => 3,
1641 );
1642
1643 $expectedResult = array(
1644 'propertyA' => array(
1645 'keyA' => array(
1646 'valueA' => 1,
1647 ),
1648 'keyB' => 2,
1649 ),
1650 'propertyB' => 3,
1651 );
1652
1653 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1654 }
1655
1656 /**
1657 * @test
1658 */
1659 public function removeDotsFromTypoScriptOverridesSubArray() {
1660 $typoScript = array(
1661 'propertyA.' => array(
1662 'keyA' => 'getsOverridden',
1663 'keyA.' => array(
1664 'valueA' => 1,
1665 ),
1666 'keyB' => 2,
1667 ),
1668 'propertyB' => 3,
1669 );
1670
1671 $expectedResult = array(
1672 'propertyA' => array(
1673 'keyA' => array(
1674 'valueA' => 1,
1675 ),
1676 'keyB' => 2,
1677 ),
1678 'propertyB' => 3,
1679 );
1680
1681 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1682 }
1683
1684 /**
1685 * @test
1686 */
1687 public function removeDotsFromTypoScriptOverridesWithScalar() {
1688 $typoScript = array(
1689 'propertyA.' => array(
1690 'keyA.' => array(
1691 'valueA' => 1,
1692 ),
1693 'keyA' => 'willOverride',
1694 'keyB' => 2,
1695 ),
1696 'propertyB' => 3,
1697 );
1698
1699 $expectedResult = array(
1700 'propertyA' => array(
1701 'keyA' => 'willOverride',
1702 'keyB' => 2,
1703 ),
1704 'propertyB' => 3,
1705 );
1706
1707 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1708 }
1709
1710 //////////////////////////////////////
1711 // Tests concerning naturalKeySortRecursive
1712 //////////////////////////////////////
1713
1714 /**
1715 * @test
1716 */
1717 public function naturalKeySortRecursiveReturnsFalseIfInputIsNotAnArray() {
1718 $testValues = array(
1719 1,
1720 'string',
1721 FALSE
1722 );
1723 foreach($testValues as $testValue) {
1724 $this->assertFalse(t3lib_div::naturalKeySortRecursive($testValue));
1725 }
1726 }
1727
1728 /**
1729 * @test
1730 */
1731 public function naturalKeySortRecursiveSortsOneDimensionalArrayByNaturalOrder() {
1732 $testArray = array(
1733 'bb' => 'bb',
1734 'ab' => 'ab',
1735 '123' => '123',
1736 'aaa' => 'aaa',
1737 'abc' => 'abc',
1738 '23' => '23',
1739 'ba' => 'ba',
1740 'bad' => 'bad',
1741 '2' => '2',
1742 'zap' => 'zap',
1743 '210' => '210'
1744 );
1745 $expectedResult = array(
1746 '2',
1747 '23',
1748 '123',
1749 '210',
1750 'aaa',
1751 'ab',
1752 'abc',
1753 'ba',
1754 'bad',
1755 'bb',
1756 'zap'
1757 );
1758 t3lib_div::naturalKeySortRecursive($testArray);
1759 $this->assertEquals($expectedResult, array_values($testArray));
1760 }
1761
1762 /**
1763 * @test
1764 */
1765 public function naturalKeySortRecursiveSortsMultiDimensionalArrayByNaturalOrder() {
1766 $testArray = array(
1767 '2' => '2',
1768 'bb' => 'bb',
1769 'ab' => 'ab',
1770 '23' => '23',
1771 'aaa' => array(
1772 'bb' => 'bb',
1773 'ab' => 'ab',
1774 '123' => '123',
1775 'aaa' => 'aaa',
1776 '2' => '2',
1777 'abc' => 'abc',
1778 'ba' => 'ba',
1779 '23' => '23',
1780 'bad' => array(
1781 'bb' => 'bb',
1782 'ab' => 'ab',
1783 '123' => '123',
1784 'aaa' => 'aaa',
1785 'abc' => 'abc',
1786 '23' => '23',
1787 'ba' => 'ba',
1788 'bad' => 'bad',
1789 '2' => '2',
1790 'zap' => 'zap',
1791 '210' => '210'
1792 ),
1793 '210' => '210',
1794 'zap' => 'zap'
1795 ),
1796 'abc' => 'abc',
1797 'ba' => 'ba',
1798 '210' => '210',
1799 'bad' => 'bad',
1800 '123' => '123',
1801 'zap' => 'zap'
1802 );
1803
1804 $expectedResult = array(
1805 '2',
1806 '23',
1807 '123',
1808 '210',
1809 'aaa',
1810 'ab',
1811 'abc',
1812 'ba',
1813 'bad',
1814 'bb',
1815 'zap'
1816 );
1817 t3lib_div::naturalKeySortRecursive($testArray);
1818
1819 $this->assertEquals($expectedResult, array_values(array_keys($testArray['aaa']['bad'])));
1820 $this->assertEquals($expectedResult, array_values(array_keys($testArray['aaa'])));
1821 $this->assertEquals($expectedResult, array_values(array_keys($testArray)));
1822 }
1823
1824 //////////////////////////////////////
1825 // Tests concerning get_dirs
1826 //////////////////////////////////////
1827
1828 /**
1829 * @test
1830 */
1831 public function getDirsReturnsArrayOfDirectoriesFromGivenDirectory() {
1832 $path = PATH_t3lib;
1833 $directories = t3lib_div::get_dirs($path);
1834
1835 $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $directories);
1836 }
1837
1838 /**
1839 * @test
1840 */
1841 public function getDirsReturnsStringErrorOnPathFailure() {
1842 $path = 'foo';
1843 $result = t3lib_div::get_dirs($path);
1844 $expectedResult = 'error';
1845
1846 $this->assertEquals($expectedResult, $result);
1847 }
1848
1849
1850 //////////////////////////////////
1851 // Tests concerning hmac
1852 //////////////////////////////////
1853
1854 /**
1855 * @test
1856 */
1857 public function hmacReturnsHashOfProperLength() {
1858 $hmac = t3lib_div::hmac('message');
1859 $this->assertTrue(!empty($hmac) && is_string($hmac));
1860 $this->assertTrue(strlen($hmac) == 40);
1861 }
1862
1863 /**
1864 * @test
1865 */
1866 public function hmacReturnsEqualHashesForEqualInput() {
1867 $msg0 = 'message';
1868 $msg1 = 'message';
1869 $this->assertEquals(t3lib_div::hmac($msg0), t3lib_div::hmac($msg1));
1870 }
1871
1872 /**
1873 * @test
1874 */
1875 public function hmacReturnsNoEqualHashesForNonEqualInput() {
1876 $msg0 = 'message0';
1877 $msg1 = 'message1';
1878 $this->assertNotEquals(t3lib_div::hmac($msg0), t3lib_div::hmac($msg1));
1879 }
1880
1881
1882 //////////////////////////////////
1883 // Tests concerning quoteJSvalue
1884 //////////////////////////////////
1885
1886 /**
1887 * @test
1888 */
1889 public function quoteJSvalueHtmlspecialcharsDataByDefault() {
1890 $this->assertContains(
1891 '&gt;',
1892 t3lib_div::quoteJSvalue('>')
1893 );
1894 }
1895
1896 /**
1897 * @test
1898 */
1899 public function quoteJSvaluetHtmlspecialcharsDataWithinCDataSetToFalse() {
1900 $this->assertContains(
1901 '&gt;',
1902 t3lib_div::quoteJSvalue('>', FALSE)
1903 );
1904 }
1905
1906 /**
1907 * @test
1908 */
1909 public function quoteJSvaluetNotHtmlspecialcharsDataWithinCDataSetToTrue() {
1910 $this->assertContains(
1911 '>',
1912 t3lib_div::quoteJSvalue('>', TRUE)
1913 );
1914 }
1915
1916 /**
1917 * @test
1918 */
1919 public function quoteJSvalueReturnsEmptyStringQuotedInSingleQuotes() {
1920 $this->assertEquals(
1921 "''",
1922 t3lib_div::quoteJSvalue("", TRUE)
1923 );
1924 }
1925
1926 /**
1927 * @test
1928 */
1929 public function quoteJSvalueNotModifiesStringWithoutSpecialCharacters() {
1930 $this->assertEquals(
1931 "'Hello world!'",
1932 t3lib_div::quoteJSvalue("Hello world!", TRUE)
1933 );
1934 }
1935
1936 /**
1937 * @test
1938 */
1939 public function quoteJSvalueEscapesSingleQuote() {
1940 $this->assertEquals(
1941 "'\\''",
1942 t3lib_div::quoteJSvalue("'", TRUE)
1943 );
1944 }
1945
1946 /**
1947 * @test
1948 */
1949 public function quoteJSvalueEscapesDoubleQuoteWithinCDataSetToTrue() {
1950 $this->assertEquals(
1951 "'\\\"'",
1952 t3lib_div::quoteJSvalue('"', TRUE)
1953 );
1954 }
1955
1956 /**
1957 * @test
1958 */
1959 public function quoteJSvalueEscapesAndHtmlspecialcharsDoubleQuoteWithinCDataSetToFalse() {
1960 $this->assertEquals(
1961 "'\\&quot;'",
1962 t3lib_div::quoteJSvalue('"', FALSE)
1963 );
1964 }
1965
1966 /**
1967 * @test
1968 */
1969 public function quoteJSvalueEscapesTab() {
1970 $this->assertEquals(
1971 "'" . '\t' . "'",
1972 t3lib_div::quoteJSvalue(TAB)
1973 );
1974 }
1975
1976 /**
1977 * @test
1978 */
1979 public function quoteJSvalueEscapesLinefeed() {
1980 $this->assertEquals(
1981 "'" . '\n' . "'",
1982 t3lib_div::quoteJSvalue(LF)
1983 );
1984 }
1985
1986 /**
1987 * @test
1988 */
1989 public function quoteJSvalueEscapesCarriageReturn() {
1990 $this->assertEquals(
1991 "'" . '\r' . "'",
1992 t3lib_div::quoteJSvalue(CR)
1993 );
1994 }
1995
1996 /**
1997 * @test
1998 */
1999 public function quoteJSvalueEscapesBackslah() {
2000 $this->assertEquals(
2001 "'\\\\'",
2002 t3lib_div::quoteJSvalue('\\')
2003 );
2004 }
2005
2006 //////////////////////////////////
2007 // Tests concerning readLLfile
2008 //////////////////////////////////
2009
2010 /**
2011 * @test
2012 */
2013 public function readLLfileHandlesLocallangXMLOverride() {
2014 $unique = uniqid('locallangXMLOverrideTest');
2015
2016 $xml = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2017 <T3locallang>
2018 <data type="array">
2019 <languageKey index="default" type="array">
2020 <label index="buttons.logout">EXIT</label>
2021 </languageKey>
2022 </data>
2023 </T3locallang>';
2024
2025 $file = PATH_site . 'typo3temp/' . $unique . '.xml';
2026 t3lib_div::writeFileToTypo3tempDir($file, $xml);
2027
2028 // Make sure there is no cached version of the label
2029 $GLOBALS['typo3CacheManager']->getCache('t3lib_l10n')->flush();
2030
2031 // Get default value
2032 $defaultLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
2033
2034 // Clear language cache again
2035 $GLOBALS['typo3CacheManager']->getCache('t3lib_l10n')->flush();
2036
2037 // Set override file
2038 $GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['EXT:lang/locallang_core.xml'][$unique] = $file;
2039
2040 /** @var $store t3lib_l10n_Store */
2041 $store = t3lib_div::makeInstance('t3lib_l10n_Store');
2042 $store->flushData('EXT:lang/locallang_core.xml');
2043
2044 // Get override value
2045 $overrideLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
2046
2047 // Clean up again
2048 unlink($file);
2049
2050 $this->assertNotEquals($overrideLL['default']['buttons.logout'][0]['target'], '');
2051 $this->assertNotEquals($defaultLL['default']['buttons.logout'][0]['target'], $overrideLL['default']['buttons.logout'][0]['target']);
2052 $this->assertEquals($overrideLL['default']['buttons.logout'][0]['target'], 'EXIT');
2053 }
2054
2055
2056 ///////////////////////////////
2057 // Tests concerning _GETset()
2058 ///////////////////////////////
2059
2060 /**
2061 * @test
2062 */
2063 public function getSetWritesArrayToGetSystemVariable() {
2064 $_GET = array();
2065 $GLOBALS['HTTP_GET_VARS'] = array();
2066
2067 $getParameters = array('foo' => 'bar');
2068 t3lib_div::_GETset($getParameters);
2069 $this->assertSame($getParameters, $_GET);
2070 }
2071
2072 /**
2073 * @test
2074 */
2075 public function getSetWritesArrayToGlobalsHttpGetVars() {
2076 $_GET = array();
2077 $GLOBALS['HTTP_GET_VARS'] = array();
2078
2079 $getParameters = array('foo' => 'bar');
2080 t3lib_div::_GETset($getParameters);
2081 $this->assertSame($getParameters, $GLOBALS['HTTP_GET_VARS']);
2082 }
2083
2084 /**
2085 * @test
2086 */
2087 public function getSetForArrayDropsExistingValues() {
2088 $_GET = array();
2089 $GLOBALS['HTTP_GET_VARS'] = array();
2090
2091 t3lib_div::_GETset(array('foo' => 'bar'));
2092
2093 t3lib_div::_GETset(array('oneKey' => 'oneValue'));
2094
2095 $this->assertEquals(
2096 array('oneKey' => 'oneValue'),
2097 $GLOBALS['HTTP_GET_VARS']
2098 );
2099 }
2100
2101 /**
2102 * @test
2103 */
2104 public function getSetAssignsOneValueToOneKey() {
2105 $_GET = array();
2106 $GLOBALS['HTTP_GET_VARS'] = array();
2107
2108 t3lib_div::_GETset('oneValue', 'oneKey');
2109
2110 $this->assertEquals(
2111 'oneValue',
2112 $GLOBALS['HTTP_GET_VARS']['oneKey']
2113 );
2114 }
2115
2116 /**
2117 * @test
2118 */
2119 public function getSetForOneValueDoesNotDropUnrelatedValues() {
2120 $_GET = array();
2121 $GLOBALS['HTTP_GET_VARS'] = array();
2122
2123 t3lib_div::_GETset(array('foo' => 'bar'));
2124 t3lib_div::_GETset('oneValue', 'oneKey');
2125
2126 $this->assertEquals(
2127 array('foo' => 'bar', 'oneKey' => 'oneValue'),
2128 $GLOBALS['HTTP_GET_VARS']
2129 );
2130 }
2131
2132 /**
2133 * @test
2134 */
2135 public function getSetCanAssignsAnArrayToASpecificArrayElement() {
2136 $_GET = array();
2137 $GLOBALS['HTTP_GET_VARS'] = array();
2138
2139 t3lib_div::_GETset(array('childKey' => 'oneValue'), 'parentKey');
2140
2141 $this->assertEquals(
2142 array('parentKey' => array('childKey' => 'oneValue')),
2143 $GLOBALS['HTTP_GET_VARS']
2144 );
2145 }
2146
2147 /**
2148 * @test
2149 */
2150 public function getSetCanAssignAStringValueToASpecificArrayChildElement() {
2151 $_GET = array();
2152 $GLOBALS['HTTP_GET_VARS'] = array();
2153
2154 t3lib_div::_GETset('oneValue', 'parentKey|childKey');
2155
2156 $this->assertEquals(
2157 array('parentKey' => array('childKey' => 'oneValue')),
2158 $GLOBALS['HTTP_GET_VARS']
2159 );
2160 }
2161
2162 /**
2163 * @test
2164 */
2165 public function getSetCanAssignAnArrayToASpecificArrayChildElement() {
2166 $_GET = array();
2167 $GLOBALS['HTTP_GET_VARS'] = array();
2168
2169 t3lib_div::_GETset(
2170 array('key1' => 'value1', 'key2' => 'value2'),
2171 'parentKey|childKey'
2172 );
2173
2174 $this->assertEquals(
2175 array(
2176 'parentKey' => array(
2177 'childKey' => array('key1' => 'value1', 'key2' => 'value2')
2178 )
2179 ),
2180 $GLOBALS['HTTP_GET_VARS']
2181 );
2182 }
2183
2184
2185 ///////////////////////////
2186 // Tests concerning getUrl
2187 ///////////////////////////
2188
2189 /**
2190 * @test
2191 */
2192 public function getUrlWithAdditionalRequestHeadersProvidesHttpHeaderOnError() {
2193 $url = 'http://typo3.org/i-do-not-exist-' . time();
2194
2195 $report = array();
2196 t3lib_div::getUrl(
2197 $url,
2198 0,
2199 array(),
2200 $report
2201 );
2202 $this->assertContains(
2203 '404',
2204 $report['message']
2205 );
2206 }
2207
2208 /**
2209 * @test
2210 */
2211 public function getUrlProvidesWithoutAdditionalRequestHeadersHttpHeaderOnError() {
2212 $url = 'http://typo3.org/i-do-not-exist-' . time();
2213
2214 $report = array();
2215 t3lib_div::getUrl(
2216 $url,
2217 0,
2218 FALSE,
2219 $report
2220 );
2221 $this->assertContains(
2222 '404',
2223 $report['message'],
2224 'Did not provide the HTTP response header when requesting a failing URL.'
2225 );
2226 }
2227
2228
2229 ///////////////////////////////
2230 // Tests concerning fixPermissions
2231 ///////////////////////////////
2232
2233 /**
2234 * @test
2235 */
2236 public function fixPermissionsSetsGroup() {
2237 if (TYPO3_OS == 'WIN') {
2238 $this->markTestSkipped('fixPermissionsSetsGroup() tests not available on Windows');
2239 }
2240 if (!function_exists('posix_getegid')) {
2241 $this->markTestSkipped('Function posix_getegid() not available, fixPermissionsSetsGroup() tests skipped');
2242 }
2243 if (posix_getegid() === -1) {
2244 $this->markTestSkipped(
2245 'The fixPermissionsSetsGroup() is not available on Mac OS because posix_getegid() always returns -1 on Mac OS.'
2246 );
2247 }
2248
2249 // Create and prepare test file
2250 $filename = PATH_site . 'typo3temp/' . uniqid('test_');
2251 t3lib_div::writeFileToTypo3tempDir($filename, '42');
2252
2253 $currentGroupId = posix_getegid();
2254
2255 // Set target group and run method
2256 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = $currentGroupId;
2257 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
2258
2259 clearstatcache();
2260 $resultFileGroup = filegroup($filename);
2261 unlink($filename);
2262
2263 $this->assertEquals($resultFileGroup, $currentGroupId);
2264 }
2265
2266 /**
2267 * @test
2268 */
2269 public function fixPermissionsSetsPermissionsToFile() {
2270 if (TYPO3_OS == 'WIN') {
2271 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2272 }
2273
2274 // Create and prepare test file
2275 $filename = PATH_site . 'typo3temp/' . uniqid('test_');
2276 t3lib_div::writeFileToTypo3tempDir($filename, '42');
2277 chmod($filename, 0742);
2278
2279 // Set target permissions and run method
2280 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2281 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
2282
2283 // Get actual permissions and clean up
2284 clearstatcache();
2285 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
2286 unlink($filename);
2287
2288 // Test if everything was ok
2289 $this->assertTrue($fixPermissionsResult);
2290 $this->assertEquals($resultFilePermissions, '0660');
2291 }
2292
2293 /**
2294 * @test
2295 */
2296 public function fixPermissionsSetsPermissionsToHiddenFile() {
2297 if (TYPO3_OS == 'WIN') {
2298 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2299 }
2300
2301 // Create and prepare test file
2302 $filename = PATH_site . 'typo3temp/' . uniqid('.test_');
2303 t3lib_div::writeFileToTypo3tempDir($filename, '42');
2304 chmod($filename, 0742);
2305
2306 // Set target permissions and run method
2307 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2308 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
2309
2310 // Get actual permissions and clean up
2311 clearstatcache();
2312 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
2313 unlink($filename);
2314
2315 // Test if everything was ok
2316 $this->assertTrue($fixPermissionsResult);
2317 $this->assertEquals($resultFilePermissions, '0660');
2318 }
2319
2320 /**
2321 * @test
2322 */
2323 public function fixPermissionsSetsPermissionsToDirectory() {
2324 if (TYPO3_OS == 'WIN') {
2325 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2326 }
2327
2328 // Create and prepare test directory
2329 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
2330 t3lib_div::mkdir($directory);
2331 chmod($directory, 1551);
2332
2333 // Set target permissions and run method
2334 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2335 $fixPermissionsResult = t3lib_div::fixPermissions($directory);
2336
2337 // Get actual permissions and clean up
2338 clearstatcache();
2339 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2340 t3lib_div::rmdir($directory);
2341
2342 // Test if everything was ok
2343 $this->assertTrue($fixPermissionsResult);
2344 $this->assertEquals($resultDirectoryPermissions, '0770');
2345 }
2346
2347 /**
2348 * @test
2349 */
2350 public function fixPermissionsSetsPermissionsToDirectoryWithTrailingSlash() {
2351 if (TYPO3_OS == 'WIN') {
2352 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2353 }
2354
2355 // Create and prepare test directory
2356 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
2357 t3lib_div::mkdir($directory);
2358 chmod($directory, 1551);
2359
2360 // Set target permissions and run method
2361 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2362 $fixPermissionsResult = t3lib_div::fixPermissions($directory . '/');
2363
2364 // Get actual permissions and clean up
2365 clearstatcache();
2366 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2367 t3lib_div::rmdir($directory);
2368
2369 // Test if everything was ok
2370 $this->assertTrue($fixPermissionsResult);
2371 $this->assertEquals($resultDirectoryPermissions, '0770');
2372 }
2373
2374 /**
2375 * @test
2376 */
2377 public function fixPermissionsSetsPermissionsToHiddenDirectory() {
2378 if (TYPO3_OS == 'WIN') {
2379 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2380 }
2381
2382 // Create and prepare test directory
2383 $directory = PATH_site . 'typo3temp/' . uniqid('.test_');
2384 t3lib_div::mkdir($directory);
2385 chmod($directory, 1551);
2386
2387 // Set target permissions and run method
2388 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2389 $fixPermissionsResult = t3lib_div::fixPermissions($directory);
2390
2391 // Get actual permissions and clean up
2392 clearstatcache();
2393 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2394 t3lib_div::rmdir($directory);
2395
2396 // Test if everything was ok
2397 $this->assertTrue($fixPermissionsResult);
2398 $this->assertEquals($resultDirectoryPermissions, '0770');
2399 }
2400
2401 /**
2402 * @test
2403 */
2404 public function fixPermissionsCorrectlySetsPermissionsRecursive() {
2405 if (TYPO3_OS == 'WIN') {
2406 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2407 }
2408
2409 // Create and prepare test directory and file structure
2410 $baseDirectory = PATH_site . 'typo3temp/' . uniqid('test_');
2411 t3lib_div::mkdir($baseDirectory);
2412 chmod($baseDirectory, 1751);
2413 t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/file', '42');
2414 chmod($baseDirectory . '/file', 0742);
2415 t3lib_div::mkdir($baseDirectory . '/foo');
2416 chmod($baseDirectory . '/foo', 1751);
2417 t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/foo/file', '42');
2418 chmod($baseDirectory . '/foo/file', 0742);
2419 t3lib_div::mkdir($baseDirectory . '/.bar');
2420 chmod($baseDirectory . '/.bar', 1751);
2421 // Use this if writeFileToTypo3tempDir is fixed to create hidden files in subdirectories
2422 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/.file', '42');
2423 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/..file2', '42');
2424 touch($baseDirectory . '/.bar/.file', '42');
2425 chmod($baseDirectory . '/.bar/.file', 0742);
2426 touch($baseDirectory . '/.bar/..file2', '42');
2427 chmod($baseDirectory . '/.bar/..file2', 0742);
2428
2429 // Set target permissions and run method
2430 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2431 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2432 $fixPermissionsResult = t3lib_div::fixPermissions($baseDirectory, TRUE);
2433
2434 // Get actual permissions
2435 clearstatcache();
2436 $resultBaseDirectoryPermissions = substr(decoct(fileperms($baseDirectory)), 1);
2437 $resultBaseFilePermissions = substr(decoct(fileperms($baseDirectory . '/file')), 2);
2438 $resultFooDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/foo')), 1);
2439 $resultFooFilePermissions = substr(decoct(fileperms($baseDirectory . '/foo/file')), 2);
2440 $resultBarDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/.bar')), 1);
2441 $resultBarFilePermissions = substr(decoct(fileperms($baseDirectory . '/.bar/.file')), 2);
2442 $resultBarFile2Permissions = substr(decoct(fileperms($baseDirectory . '/.bar/..file2')), 2);
2443
2444 // Clean up
2445 unlink($baseDirectory . '/file');
2446 unlink($baseDirectory . '/foo/file');
2447 unlink($baseDirectory . '/.bar/.file');
2448 unlink($baseDirectory . '/.bar/..file2');
2449 t3lib_div::rmdir($baseDirectory . '/foo');
2450 t3lib_div::rmdir($baseDirectory . '/.bar');
2451 t3lib_div::rmdir($baseDirectory);
2452
2453 // Test if everything was ok
2454 $this->assertTrue($fixPermissionsResult);
2455 $this->assertEquals($resultBaseDirectoryPermissions, '0770');
2456 $this->assertEquals($resultBaseFilePermissions, '0660');
2457 $this->assertEquals($resultFooDirectoryPermissions, '0770');
2458 $this->assertEquals($resultFooFilePermissions, '0660');
2459 $this->assertEquals($resultBarDirectoryPermissions, '0770');
2460 $this->assertEquals($resultBarFilePermissions, '0660');
2461 $this->assertEquals($resultBarFile2Permissions, '0660');
2462 }
2463
2464 /**
2465 * @test
2466 */
2467 public function fixPermissionsDoesNotSetPermissionsToNotAllowedPath() {
2468 if (TYPO3_OS == 'WIN') {
2469 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2470 }
2471
2472 // Create and prepare test file
2473 $filename = PATH_site . 'typo3temp/../typo3temp/' . uniqid('test_');
2474 touch($filename);
2475 chmod($filename, 0742);
2476
2477 // Set target permissions and run method
2478 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2479 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
2480
2481 // Get actual permissions and clean up
2482 clearstatcache();
2483 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
2484 unlink($filename);
2485
2486 // Test if everything was ok
2487 $this->assertFalse($fixPermissionsResult);
2488 }
2489
2490 /**
2491 * @test
2492 */
2493 public function fixPermissionsSetsPermissionsWithRelativeFileReference() {
2494 if (TYPO3_OS == 'WIN') {
2495 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2496 }
2497
2498 $filename = 'typo3temp/' . uniqid('test_');
2499 t3lib_div::writeFileToTypo3tempDir(PATH_site . $filename, '42');
2500 chmod(PATH_site . $filename, 0742);
2501
2502 // Set target permissions and run method
2503 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2504 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
2505
2506 // Get actual permissions and clean up
2507 clearstatcache();
2508 $resultFilePermissions = substr(decoct(fileperms(PATH_site . $filename)), 2);
2509 unlink(PATH_site . $filename);
2510
2511 // Test if everything was ok
2512 $this->assertTrue($fixPermissionsResult);
2513 $this->assertEquals($resultFilePermissions, '0660');
2514 }
2515
2516
2517 ///////////////////////////////
2518 // Tests concerning mkdir
2519 ///////////////////////////////
2520
2521 /**
2522 * @test
2523 */
2524 public function mkdirCreatesDirectory() {
2525 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
2526 $mkdirResult = t3lib_div::mkdir($directory);
2527 clearstatcache();
2528 $directoryCreated = is_dir($directory);
2529 @rmdir($directory);
2530 $this->assertTrue($mkdirResult);
2531 $this->assertTrue($directoryCreated);
2532 }
2533
2534 /**
2535 * @test
2536 */
2537 public function mkdirCreatesHiddenDirectory() {
2538 $directory = PATH_site . 'typo3temp/' . uniqid('.test_');
2539 $mkdirResult = t3lib_div::mkdir($directory);
2540 clearstatcache();
2541 $directoryCreated = is_dir($directory);
2542 @rmdir($directory);
2543 $this->assertTrue($mkdirResult);
2544 $this->assertTrue($directoryCreated);
2545 }
2546
2547 /**
2548 * @test
2549 */
2550 public function mkdirCreatesDirectoryWithTrailingSlash() {
2551 $directory = PATH_site . 'typo3temp/' . uniqid('test_') . '/';
2552 $mkdirResult = t3lib_div::mkdir($directory);
2553 clearstatcache();
2554 $directoryCreated = is_dir($directory);
2555 @rmdir($directory);
2556 $this->assertTrue($mkdirResult);
2557 $this->assertTrue($directoryCreated);
2558 }
2559
2560 /**
2561 * @test
2562 */
2563 public function mkdirSetsPermissionsOfCreatedDirectory() {
2564 if (TYPO3_OS == 'WIN') {
2565 $this->markTestSkipped('mkdirSetsPermissionsOfCreatedDirectory() test not available on Windows');
2566 }
2567
2568 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
2569 $oldUmask = umask(023);
2570 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0772';
2571 t3lib_div::mkdir($directory);
2572 clearstatcache();
2573 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2574 umask($oldUmask);
2575 rmdir($directory);
2576 $this->assertEquals($resultDirectoryPermissions, '0772');
2577 }
2578
2579 /**
2580 * @test
2581 */
2582 public function mkdirSetsGroupOwnershipOfCreatedDirectory() {
2583 if (!function_exists('posix_getegid')) {
2584 $this->markTestSkipped('Function posix_getegid() not available, mkdirSetsGroupOwnershipOfCreatedDirectory() tests skipped');
2585 }
2586 if (posix_getegid() === -1) {
2587 $this->markTestSkipped(
2588 'The mkdirSetsGroupOwnershipOfCreatedDirectory() is not available on Mac OS because posix_getegid() always returns -1 on Mac OS.'
2589 );
2590 }
2591 $swapGroup = $this->checkGroups(__FUNCTION__);
2592 if ($swapGroup !== FALSE) {
2593 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = $swapGroup;
2594 $directory = uniqid('mkdirtest_');
2595 t3lib_div::mkdir(PATH_site . 'typo3temp/' . $directory);
2596 clearstatcache();
2597 $resultDirectoryGroupInfo = posix_getgrgid((filegroup(PATH_site . 'typo3temp/' . $directory)));
2598 $resultDirectoryGroup = $resultDirectoryGroupInfo['name'];
2599 @rmdir(PATH_site . 'typo3temp/' . $directory);
2600 $this->assertEquals($resultDirectoryGroup, $swapGroup);
2601 }
2602 }
2603
2604 ///////////////////////////////
2605 // Helper function for filesystem ownership tests
2606 ///////////////////////////////
2607
2608 /**
2609 * Check if test on filesystem group ownership can be done in this environment
2610 * If so, return second group of webserver user
2611 * @param string calling method name
2612 * @return mixed FALSE if test cannot be run, string name of the second group of webserver user
2613 */
2614 private function checkGroups($methodName) {
2615 if (TYPO3_OS == 'WIN') {
2616 $this->markTestSkipped($methodName . '() test not available on Windows.');
2617 return FALSE;
2618 }
2619 if (!function_exists('posix_getgroups')) {
2620 $this->markTestSkipped('Function posix_getgroups() not available, ' . $methodName . '() tests skipped');
2621 }
2622
2623 $groups = posix_getgroups();
2624 if (count($groups) <= 1) {
2625 $this->markTestSkipped($methodName . '() test cannot be done when the web server user is only member of 1 group.');
2626 return FALSE;
2627 }
2628 $groupInfo = posix_getgrgid($groups[1]);
2629 return $groupInfo['name'];
2630 }
2631
2632 ///////////////////////////////
2633 // Tests concerning mkdir_deep
2634 ///////////////////////////////
2635
2636 /**
2637 * @test
2638 */
2639 public function mkdirDeepCreatesDirectory() {
2640 $directory = 'typo3temp/' . uniqid('test_');
2641 t3lib_div::mkdir_deep(PATH_site, $directory);
2642 $isDirectoryCreated = is_dir(PATH_site . $directory);
2643 rmdir(PATH_site . $directory);
2644 $this->assertTrue($isDirectoryCreated);
2645 }
2646
2647 /**
2648 * @test
2649 */
2650 public function mkdirDeepCreatesSubdirectoriesRecursive() {
2651 $directory = 'typo3temp/' . uniqid('test_');
2652 $subDirectory = $directory . '/foo';
2653 t3lib_div::mkdir_deep(PATH_site, $subDirectory);
2654 $isDirectoryCreated = is_dir(PATH_site . $subDirectory);
2655 rmdir(PATH_site . $subDirectory);
2656 rmdir(PATH_site . $directory);
2657 $this->assertTrue($isDirectoryCreated);
2658 }
2659
2660 /**
2661 * @test
2662 */
2663 public function mkdirDeepFixesPermissionsOfCreatedDirectory() {
2664 if (TYPO3_OS == 'WIN') {
2665 $this->markTestSkipped('mkdirDeepFixesPermissionsOfCreatedDirectory() test not available on Windows.');
2666 }
2667
2668 $directory = uniqid('mkdirdeeptest_');
2669 $oldUmask = umask(023);
2670 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0777';
2671 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/', $directory);
2672 clearstatcache();
2673 $resultDirectoryPermissions = substr(decoct(fileperms(PATH_site . 'typo3temp/' . $directory)), -3, 3);
2674 @rmdir(PATH_site . 'typo3temp/' . $directory);
2675 umask($oldUmask);
2676 $this->assertEquals($resultDirectoryPermissions, '777');
2677 }
2678
2679 /**
2680 * @test
2681 */
2682 public function mkdirDeepFixesPermissionsOnNewParentDirectory() {
2683 if (TYPO3_OS == 'WIN') {
2684 $this->markTestSkipped('mkdirDeepFixesPermissionsOnNewParentDirectory() test not available on Windows.');
2685 }
2686
2687 $directory = uniqid('mkdirdeeptest_');
2688 $subDirectory = $directory . '/bar';
2689 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0777';
2690 $oldUmask = umask(023);
2691 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/', $subDirectory);
2692 clearstatcache();
2693 $resultDirectoryPermissions = substr(decoct(fileperms(PATH_site . 'typo3temp/' . $directory)), -3, 3);
2694 @rmdir(PATH_site . 'typo3temp/' . $subDirectory);
2695 @rmdir(PATH_site . 'typo3temp/' . $directory);
2696 umask($oldUmask);
2697 $this->assertEquals($resultDirectoryPermissions, '777');
2698 }
2699
2700 /**
2701 * @test
2702 */
2703 public function mkdirDeepDoesNotChangePermissionsOfExistingSubDirectories() {
2704 if (TYPO3_OS == 'WIN') {
2705 $this->markTestSkipped('mkdirDeepDoesNotChangePermissionsOfExistingSubDirectories() test not available on Windows.');
2706 }
2707
2708 $baseDirectory = PATH_site . 'typo3temp/';
2709 $existingDirectory = uniqid('test_existing_') . '/';
2710 $newSubDirectory = uniqid('test_new_');
2711 @mkdir($baseDirectory . $existingDirectory);
2712 chmod($baseDirectory . $existingDirectory, 0742);
2713 t3lib_div::mkdir_deep($baseDirectory, $existingDirectory . $newSubDirectory);
2714 $resultExistingDirectoryPermissions = substr(decoct(fileperms($baseDirectory . $existingDirectory)), 2);
2715 @rmdir($baseDirectory, $existingDirectory . $newSubDirectory);
2716 @rmdir($baseDirectory, $existingDirectory);
2717 $this->assertEquals($resultExistingDirectoryPermissions, '0742');
2718 }
2719
2720 /**
2721 * @test
2722 */
2723 public function mkdirDeepSetsGroupOwnershipOfCreatedDirectory() {
2724 $swapGroup = $this->checkGroups(__FUNCTION__);
2725 if ($swapGroup!==FALSE) {
2726 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = $swapGroup;
2727 $directory = uniqid('mkdirdeeptest_');
2728 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/', $directory);
2729 clearstatcache();
2730 $resultDirectoryGroupInfo = posix_getgrgid((filegroup(PATH_site . 'typo3temp/' . $directory)));
2731 $resultDirectoryGroup = $resultDirectoryGroupInfo['name'];
2732 @rmdir(PATH_site . 'typo3temp/' . $directory);
2733 $this->assertEquals($resultDirectoryGroup, $swapGroup);
2734 }
2735 }
2736
2737 /**
2738 * @test
2739 */
2740 public function mkdirDeepSetsGroupOwnershipOfCreatedParentDirectory() {
2741 $swapGroup = $this->checkGroups(__FUNCTION__);
2742 if ($swapGroup!==FALSE) {
2743 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = $swapGroup;
2744 $directory = uniqid('mkdirdeeptest_');
2745 $subDirectory = $directory . '/bar';
2746 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/', $subDirectory);
2747 clearstatcache();
2748 $resultDirectoryGroupInfo = posix_getgrgid((filegroup(PATH_site . 'typo3temp/' . $directory)));
2749 $resultDirectoryGroup = $resultDirectoryGroupInfo['name'];
2750 @rmdir(PATH_site . 'typo3temp/' . $subDirectory);
2751 @rmdir(PATH_site . 'typo3temp/' . $directory);
2752 $this->assertEquals($resultDirectoryGroup, $swapGroup);
2753 }
2754 }
2755
2756 /**
2757 * @test
2758 */
2759 public function mkdirDeepSetsGroupOwnershipOnNewSubDirectory() {
2760 $swapGroup = $this->checkGroups(__FUNCTION__);
2761 if ($swapGroup!==FALSE) {
2762 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = $swapGroup;
2763 $directory = uniqid('mkdirdeeptest_');
2764 $subDirectory = $directory . '/bar';
2765 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/', $subDirectory);
2766 clearstatcache();
2767 $resultDirectoryGroupInfo = posix_getgrgid((filegroup(PATH_site . 'typo3temp/' . $subDirectory)));
2768 $resultDirectoryGroup = $resultDirectoryGroupInfo['name'];
2769 @rmdir(PATH_site . 'typo3temp/' . $subDirectory);
2770 @rmdir(PATH_site . 'typo3temp/' . $directory);
2771 $this->assertEquals($resultDirectoryGroup, $swapGroup);
2772 }
2773 }
2774
2775 /**
2776 * @test
2777 */
2778 public function mkdirDeepCreatesDirectoryInVfsStream() {
2779 if (!class_exists('\vfsStreamWrapper')) {
2780 $this->markTestSkipped('mkdirDeepCreatesDirectoryInVfsStream() test not available with this phpunit version.');
2781 }
2782
2783 \vfsStreamWrapper::register();
2784 $baseDirectory = uniqid('test_');
2785 \vfsStreamWrapper::setRoot(new \vfsStreamDirectory($baseDirectory));
2786 t3lib_div::mkdir_deep('vfs://' . $baseDirectory . '/', 'sub');
2787 $this->assertTrue(is_dir('vfs://' . $baseDirectory . '/sub'));
2788 }
2789
2790 /**
2791 * @test
2792 * @expectedException \RuntimeException
2793 */
2794 public function mkdirDeepThrowsExceptionIfDirectoryCreationFails() {
2795 t3lib_div::mkdir_deep('http://localhost');
2796 }
2797
2798 /**
2799 * @test
2800 * @expectedException \InvalidArgumentException
2801 */
2802 public function mkdirDeepThrowsExceptionIfBaseDirectoryIsNotOfTypeString() {
2803 t3lib_div::mkdir_deep(array());
2804 }
2805
2806 /**
2807 * @test
2808 * @expectedException \InvalidArgumentException
2809 */
2810 public function mkdirDeepThrowsExceptionIfDeepDirectoryIsNotOfTypeString() {
2811 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/foo', array());
2812 }
2813
2814
2815 ///////////////////////////////
2816 // Tests concerning unQuoteFilenames
2817 ///////////////////////////////
2818
2819 /**
2820 * Data provider for ImageMagick shell commands
2821 * @see explodeAndUnquoteImageMagickCommands
2822 */
2823 public function imageMagickCommandsDataProvider() {
2824 return array(
2825 // Some theoretical tests first
2826 array(
2827 'aa bb "cc" "dd"',
2828 array('aa', 'bb', '"cc"', '"dd"'),
2829 array('aa', 'bb', 'cc', 'dd'),
2830 ),
2831 array(
2832 'aa bb "cc dd"',
2833 array('aa', 'bb', '"cc dd"'),
2834 array('aa', 'bb', 'cc dd'),
2835 ),
2836 array(
2837 '\'aa bb\' "cc dd"',
2838 array('\'aa bb\'', '"cc dd"'),
2839 array('aa bb', 'cc dd'),
2840 ),
2841 array(
2842 '\'aa bb\' cc "dd"',
2843 array('\'aa bb\'', 'cc', '"dd"'),
2844 array('aa bb', 'cc', 'dd'),
2845 ),
2846 // Now test against some real world examples
2847 array(
2848 '/opt/local/bin/gm.exe convert +profile \'*\' -geometry 170x136! -negate "C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]" "C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"',
2849 array(
2850 '/opt/local/bin/gm.exe',
2851 'convert',
2852 '+profile',
2853 '\'*\'',
2854 '-geometry',
2855 '170x136!',
2856 '-negate',
2857 '"C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2858 '"C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2859 ),
2860 array(
2861 '/opt/local/bin/gm.exe',
2862 'convert',
2863 '+profile',
2864 '*',
2865 '-geometry',
2866 '170x136!',
2867 '-negate',
2868 'C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2869 'C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2870 ),
2871 ),
2872 array(
2873 'C:/opt/local/bin/gm.exe convert +profile \'*\' -geometry 170x136! -negate "C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]" "C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"',
2874 array(
2875 'C:/opt/local/bin/gm.exe',
2876 'convert',
2877 '+profile',
2878 '\'*\'',
2879 '-geometry',
2880 '170x136!',
2881 '-negate',
2882 '"C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2883 '"C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2884 ),
2885 array(
2886 'C:/opt/local/bin/gm.exe',
2887 'convert',
2888 '+profile',
2889 '*',
2890 '-geometry',
2891 '170x136!',
2892 '-negate',
2893 'C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2894 'C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2895 ),
2896 ),
2897 array(
2898 '/usr/bin/gm convert +profile \'*\' -geometry 170x136! -negate "/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]" "/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"',
2899 array(
2900 '/usr/bin/gm',
2901 'convert',
2902 '+profile',
2903 '\'*\'',
2904 '-geometry',
2905 '170x136!',
2906 '-negate',
2907 '"/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2908 '"/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2909 ),
2910 array(
2911 '/usr/bin/gm',
2912 'convert',
2913 '+profile',
2914 '*',
2915 '-geometry',
2916 '170x136!',
2917 '-negate',
2918 '/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2919 '/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2920 ),
2921 ),
2922 array(
2923 '/usr/bin/gm convert +profile \'*\' -geometry 170x136! -negate "/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]" "/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"',
2924 array(
2925 '/usr/bin/gm',
2926 'convert',
2927 '+profile',
2928 '\'*\'',
2929 '-geometry',
2930 '170x136!',
2931 '-negate',
2932 '"/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2933 '"/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2934 ),
2935 array(
2936 '/usr/bin/gm',
2937 'convert',
2938 '+profile',
2939 '*',
2940 '-geometry',
2941 '170x136!',
2942 '-negate',
2943 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2944 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2945 ),
2946 ),
2947 array(
2948 '/usr/bin/gm convert +profile \'*\' -geometry 170x136! -negate \'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]\' \'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif\'',
2949 array(
2950 '/usr/bin/gm',
2951 'convert',
2952 '+profile',
2953 '\'*\'',
2954 '-geometry',
2955 '170x136!',
2956 '-negate',
2957 '\'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]\'',
2958 '\'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif\''
2959 ),
2960 array(
2961 '/usr/bin/gm',
2962 'convert',
2963 '+profile',
2964 '*',
2965 '-geometry',
2966 '170x136!',
2967 '-negate',
2968 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2969 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2970 ),
2971 ),
2972 );
2973 }
2974
2975 /**
2976 * Tests if the commands are exploded and unquoted correctly
2977 *
2978 * @dataProvider imageMagickCommandsDataProvider
2979 * @test
2980 */
2981 public function explodeAndUnquoteImageMagickCommands($source, $expectedQuoted, $expectedUnquoted) {
2982 $actualQuoted = t3lib_div::unQuoteFilenames($source);
2983 $acutalUnquoted = t3lib_div::unQuoteFilenames($source, TRUE);
2984
2985 $this->assertEquals($expectedQuoted, $actualQuoted, 'The exploded command does not match the expected');
2986 $this->assertEquals($expectedUnquoted, $acutalUnquoted, 'The exploded and unquoted command does not match the expected');
2987 }
2988
2989
2990 ///////////////////////////////
2991 // Tests concerning split_fileref
2992 ///////////////////////////////
2993
2994 /**
2995 * @test
2996 */
2997 public function splitFileRefReturnsFileTypeNotForFolders(){
2998 $directoryName = uniqid('test_') . '.com';
2999 $directoryPath = PATH_site . 'typo3temp/';
3000 $directory = $directoryPath . $directoryName;
3001 mkdir($directory, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']));
3002
3003 $fileInfo = t3lib_div::split_fileref($directory);
3004
3005 $directoryCreated = is_dir($directory);
3006 rmdir($directory);
3007
3008 $this->assertTrue($directoryCreated);
3009 $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
3010 $this->assertEquals($directoryPath, $fileInfo['path']);
3011 $this->assertEquals($directoryName, $fileInfo['file']);
3012 $this->assertEquals($directoryName, $fileInfo['filebody']);
3013 $this->assertEquals('', $fileInfo['fileext']);
3014 $this->assertArrayNotHasKey('realFileext', $fileInfo);
3015 }
3016
3017 /**
3018 * @test
3019 */
3020 public function splitFileRefReturnsFileTypeForFilesWithoutPathSite() {
3021 $testFile = 'fileadmin/media/someFile.png';
3022
3023 $fileInfo = t3lib_div::split_fileref($testFile);
3024 $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
3025 $this->assertEquals('fileadmin/media/', $fileInfo['path']);
3026 $this->assertEquals('someFile.png', $fileInfo['file']);
3027 $this->assertEquals('someFile', $fileInfo['filebody']);
3028 $this->assertEquals('png', $fileInfo['fileext']);
3029 }
3030
3031
3032 /////////////////////////////
3033 // Tests concerning dirname
3034 /////////////////////////////
3035
3036 /**
3037 * @see dirnameWithDataProvider
3038 *
3039 * @return array<array>
3040 */
3041 public function dirnameDataProvider() {
3042 return array(
3043 'absolute path with multiple part and file' => array('/dir1/dir2/script.php', '/dir1/dir2'),
3044 'absolute path with one part' => array('/dir1/', '/dir1'),
3045 'absolute path to file without extension' => array('/dir1/something', '/dir1'),
3046 'relative path with one part and file' => array('dir1/script.php', 'dir1'),
3047 'relative one-character path with one part and file' => array('d/script.php', 'd'),
3048 'absolute zero-part path with file' => array('/script.php', ''),
3049 'empty string' => array('', ''),
3050 );
3051 }
3052
3053 /**
3054 * @test
3055 *
3056 * @dataProvider dirnameDataProvider
3057 *
3058 * @param string $input the input for dirname
3059 * @param string $expectedValue the expected return value expected from dirname
3060 */
3061 public function dirnameWithDataProvider($input, $expectedValue) {
3062 $this->assertEquals(
3063 $expectedValue,
3064 t3lib_div::dirname($input)
3065 );
3066 }
3067
3068
3069 /////////////////////////////////////
3070 // Tests concerning resolveBackPath
3071 /////////////////////////////////////
3072
3073 /**
3074 * @see resolveBackPathWithDataProvider
3075 *
3076 * @return array<array>
3077 */
3078 public function resolveBackPathDataProvider() {
3079 return array(
3080 'empty path' => array('', ''),
3081 'this directory' => array('./', './'),
3082 'relative directory without ..' => array('dir1/dir2/dir3/', 'dir1/dir2/dir3/'),
3083 'relative path without ..' => array('dir1/dir2/script.php', 'dir1/dir2/script.php'),
3084 'absolute directory without ..' => array('/dir1/dir2/dir3/', '/dir1/dir2/dir3/'),
3085 'absolute path without ..' => array('/dir1/dir2/script.php', '/dir1/dir2/script.php'),
3086 'only one directory upwards without trailing slash' => array('..', '..'),
3087 'only one directory upwards with trailing slash' => array('../', '../'),
3088 'one level with trailing ..' => array('dir1/..', ''),
3089 'one level with trailing ../' => array('dir1/../', ''),
3090 'two levels with trailing ..' => array('dir1/dir2/..', 'dir1'),
3091 'two levels with trailing ../' => array('dir1/dir2/../', 'dir1/'),
3092 'leading ../ without trailing /' => array('../dir1', '../dir1'),
3093 'leading ../ with trailing /' => array('../dir1/', '../dir1/'),
3094 'leading ../ and inside path' => array('../dir1/dir2/../dir3/', '../dir1/dir3/'),
3095 'one times ../ in relative directory' => array('dir1/../dir2/', 'dir2/'),
3096 'one times ../ in absolute directory' => array('/dir1/../dir2/', '/dir2/'),
3097 'one times ../ in relative path' => array('dir1/../dir2/script.php', 'dir2/script.php'),
3098 'one times ../ in absolute path' => array('/dir1/../dir2/script.php', '/dir2/script.php'),
3099 'consecutive ../' => array('dir1/dir2/dir3/../../../dir4', 'dir4'),
3100 'distrubuted ../ with trailing /' => array('dir1/../dir2/dir3/../', 'dir2/'),
3101 'distributed ../ without trailing /' => array('dir1/../dir2/dir3/..', 'dir2'),
3102 'multiple distributed and consecutive ../ together' => array('dir1/dir2/dir3/dir4/../../dir5/dir6/dir7/../dir8/', 'dir1/dir2/dir5/dir6/dir8/'),
3103 'multiple distributed and consecutive ../ together' => array('dir1/dir2/dir3/dir4/../../dir5/dir6/dir7/../dir8/', 'dir1/dir2/dir5/dir6/dir8/'),
3104 'dirname with leading ..' => array('dir1/..dir2/dir3/', 'dir1/..dir2/dir3/'),
3105 'dirname with trailing ..' => array('dir1/dir2../dir3/', 'dir1/dir2../dir3/'),
3106 'more times upwards than downwards in directory' => array('dir1/../../', '../'),
3107 'more times upwards than downwards in path' => array('dir1/../../script.php', '../script.php'),
3108 );
3109 }
3110
3111 /**
3112 * @test
3113 *
3114 * @dataProvider resolveBackPathDataProvider
3115 *
3116 * @param string $input the input for resolveBackPath
3117 * @param $expectedValue the expected return value from resolveBackPath
3118 */
3119 public function resolveBackPathWithDataProvider($input, $expectedValue) {
3120 $this->assertEquals(
3121 $expectedValue,
3122 t3lib_div::resolveBackPath($input)
3123 );
3124 }
3125
3126
3127 /////////////////////////////////////////////////////////////////////////////////////
3128 // Tests concerning makeInstance, setSingletonInstance, addInstance, purgeInstances
3129 /////////////////////////////////////////////////////////////////////////////////////
3130
3131 /**
3132 * @test
3133 * @expectedException InvalidArgumentException
3134 */
3135 public function makeInstanceWithEmptyClassNameThrowsException() {
3136 t3lib_div::makeInstance('');
3137 }
3138
3139 /**
3140 * @test
3141 * @expectedException InvalidArgumentException
3142 */
3143 public function makeInstanceWithNullClassNameThrowsException() {
3144 t3lib_div::makeInstance(NULL);
3145 }
3146
3147 /**
3148 * @test
3149 * @expectedException InvalidArgumentException
3150 */
3151 public function makeInstanceWithZeroStringClassNameThrowsException() {
3152 t3lib_div::makeInstance(0);
3153 }
3154
3155 /**
3156 * @test
3157 * @expectedException InvalidArgumentException
3158 */
3159 public function makeInstanceWithEmptyArrayThrowsException() {
3160 t3lib_div::makeInstance(array());
3161 }
3162
3163 /**
3164 * @test
3165 * @expectedException InvalidArgumentException
3166 */
3167 public function makeInstanceWithNonEmptyArrayThrowsException() {
3168 t3lib_div::makeInstance(array('foo'));
3169 }
3170
3171 /**
3172 * @test
3173 */
3174 public function makeInstanceReturnsClassInstance() {
3175 $className = get_class($this->getMock('foo'));
3176
3177 $this->assertTrue(
3178 t3lib_div::makeInstance($className) instanceof $className
3179 );
3180 }
3181
3182 /**
3183 * @test
3184 */
3185 public function makeInstancePassesParametersToConstructor() {
3186 $className = 'testingClass' . uniqid();
3187 if (!class_exists($className, FALSE)) {
3188 eval(
3189 'class ' . $className . ' {' .
3190 ' public $constructorParameter1;' .
3191 ' public $constructorParameter2;' .
3192 ' public function __construct($parameter1, $parameter2) {' .
3193 ' $this->constructorParameter1 = $parameter1;' .
3194 ' $this->constructorParameter2 = $parameter2;' .
3195 ' }' .
3196 '}'
3197 );
3198 }
3199
3200 $instance = t3lib_div::makeInstance($className, 'one parameter', 'another parameter');
3201
3202 $this->assertEquals(
3203 'one parameter',
3204 $instance->constructorParameter1,
3205 'The first constructor parameter has not been set.'
3206 );
3207 $this->assertEquals(
3208 'another parameter',
3209 $instance->constructorParameter2,
3210 'The second constructor parameter has not been set.'
3211 );
3212 }
3213
3214 /**
3215 * @test
3216 */
3217 public function makeInstanceCalledTwoTimesForNonSingletonClassReturnsDifferentInstances() {
3218 $className = get_class($this->getMock('foo'));
3219
3220 $this->assertNotSame(
3221 t3lib_div::makeInstance($className),
3222 t3lib_div::makeInstance($className)
3223 );
3224 }
3225
3226 /**
3227 * @test
3228 */
3229 public function makeInstanceCalledTwoTimesForSingletonClassReturnsSameInstance() {
3230 $className = get_class($this->getMock('t3lib_Singleton'));
3231
3232 $this->assertSame(
3233 t3lib_div::makeInstance($className),
3234 t3lib_div::makeInstance($className)
3235 );
3236 }
3237
3238 /**
3239 * @test
3240 */
3241 public function makeInstanceCalledTwoTimesForSingletonClassWithPurgeInstancesInbetweenReturnsDifferentInstances() {
3242 $className = get_class($this->getMock('t3lib_Singleton'));
3243
3244 $instance = t3lib_div::makeInstance($className);
3245 t3lib_div::purgeInstances();
3246
3247 $this->assertNotSame(
3248 $instance,
3249 t3lib_div::makeInstance($className)
3250 );
3251 }
3252
3253 /**
3254 * @test
3255 * @expectedException InvalidArgumentException
3256 */
3257 public function setSingletonInstanceForEmptyClassNameThrowsException() {
3258 $instance = $this->getMock('t3lib_Singleton');
3259
3260 t3lib_div::setSingletonInstance('', $instance);
3261 }
3262
3263 /**
3264 * @test
3265 * @expectedException InvalidArgumentException
3266 */
3267 public function setSingletonInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
3268 $instance = $this->getMock('t3lib_Singleton', array('foo'));
3269 $singletonClassName = get_class($this->getMock('t3lib_Singleton'));
3270
3271 t3lib_div::setSingletonInstance($singletonClassName, $instance);
3272 }
3273
3274 /**
3275 * @test
3276 */
3277 public function setSingletonInstanceMakesMakeInstanceReturnThatInstance() {
3278 $instance = $this->getMock('t3lib_Singleton');
3279 $singletonClassName = get_class($instance);
3280
3281 t3lib_div::setSingletonInstance($singletonClassName, $instance);
3282
3283 $this->assertSame(
3284 $instance,
3285 t3lib_div::makeInstance($singletonClassName)
3286 );
3287 }
3288
3289 /**
3290 * @test
3291 */
3292 public function setSingletonInstanceCalledTwoTimesMakesMakeInstanceReturnLastSetInstance() {
3293 $instance1 = $this->getMock('t3lib_Singleton');
3294 $singletonClassName = get_class($instance1);
3295 $instance2 = new $singletonClassName();
3296
3297 t3lib_div::setSingletonInstance($singletonClassName, $instance1);
3298 t3lib_div::setSingletonInstance($singletonClassName, $instance2);
3299
3300 $this->assertSame(
3301 $instance2,
3302 t3lib_div::makeInstance($singletonClassName)
3303 );
3304 }
3305
3306 /**
3307 * @test
3308 * @expectedException InvalidArgumentException
3309 */
3310 public function addInstanceForEmptyClassNameThrowsException() {
3311 $instance = $this->getMock('foo');
3312
3313 t3lib_div::addInstance('', $instance);
3314 }
3315
3316 /**
3317 * @test
3318 * @expectedException InvalidArgumentException
3319 */
3320 public function addInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
3321 $instance = $this->getMock('foo', array('bar'));
3322 $singletonClassName = get_class($this->getMock('foo'));
3323
3324 t3lib_div::addInstance($singletonClassName, $instance);
3325 }
3326
3327 /**
3328 * @test
3329 * @expectedException InvalidArgumentException
3330 */
3331 public function addInstanceWithSingletonInstanceThrowsException() {
3332 $instance = $this->getMock('t3lib_Singleton');
3333
3334 t3lib_div::addInstance(get_class($instance), $instance);
3335 }
3336
3337 /**
3338 * @test
3339 */
3340 public function addInstanceMakesMakeInstanceReturnThatInstance() {