3c772b8afa32ec0c1a984a83052f6c94b979da82
[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 );
746 }
747
748 /**
749 * @test
750 * @dataProvider validEmailValidDataProvider
751 */
752 public function validEmailReturnsTrueForValidMailAddress($address) {
753 $this->assertTrue(t3lib_div::validEmail($address));
754 }
755
756 /**
757 * Data provider for invalid validEmail's
758 *
759 * @return array Invalid email addresses
760 */
761 public function validEmailInvalidDataProvider() {
762 return array(
763 '@ sign only' => array('@'),
764 'duplicate @' => array('test@@example.com'),
765 'duplicate @ combined with further special characters in local part' => array('test!.!@#$%^&*@example.com'),
766 'opening parenthesis in local part' => array('foo(bar@example.com'),
767 'closing parenthesis in local part' => array('foo)bar@example.com'),
768 'opening square bracket in local part' => array('foo[bar@example.com'),
769 'closing square bracket as local part' => array(']@example.com'),
770 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
771 // 'top level domain only' => array('test@com'),
772 'dash as second level domain' => array('foo@-.com'),
773 'domain part starting with dash' => array('foo@-foo.com'),
774 'domain part ending with dash' => array('foo@foo-.com'),
775 'number as top level domain' => array('foo@bar.123'),
776 // Fix / change if TYPO3 php requirement changed: Address not ok with 5.2.6, but ok with 5.3.2 (?)
777 // 'dash as top level domain' => array('foo@bar.-'),
778 'dot at beginning of domain part' => array('test@.com'),
779 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
780 // 'local part ends with dot' => array('e.x.a.m.p.l.e.@example.com'),
781 'trailing whitespace' => array('test@example.com '),
782 'trailing carriage return' => array('test@example.com' . CR),
783 'trailing linefeed' => array('test@example.com' . LF),
784 'trailing carriage return linefeed' => array('test@example.com' . CRLF),
785 'trailing tab' => array('test@example.com' . TAB),
786 );
787 }
788
789 /**
790 * @test
791 * @dataProvider validEmailInvalidDataProvider
792 */
793 public function validEmailReturnsFalseForInvalidMailAddress($address) {
794 $this->assertFalse(t3lib_div::validEmail($address));
795 }
796
797
798 //////////////////////////////////
799 // Tests concerning intExplode
800 //////////////////////////////////
801
802 /**
803 * @test
804 */
805 public function intExplodeConvertsStringsToInteger() {
806 $testString = '1,foo,2';
807 $expectedArray = array(1, 0, 2);
808 $actualArray = t3lib_div::intExplode(',', $testString);
809
810 $this->assertEquals($expectedArray, $actualArray);
811 }
812
813 //////////////////////////////////
814 // Tests concerning intInRange
815 //////////////////////////////////
816 /**
817 * Data provider for intInRangeForcesIntegerIntoBoundaries
818 *
819 * @return array expected values, arithmetic expression
820 */
821 public function intInRangeForcesIntegerIntoDefaultBoundariesDataProvider() {
822 return array(
823 'negativeValue' => array(0, -10),
824 'normalValue' => array(30, 30),
825 'veryHighValue' => array(2000000000, 3000000001),
826 'zeroValue' => array(0, 0),
827 'anotherNormalValue' => array(12309, 12309)
828 );
829 }
830
831 /**
832 * @test
833 * @dataProvider intInRangeForcesIntegerIntoDefaultBoundariesDataProvider
834 */
835 public function intInRangeForcesIntegerIntoDefaultBoundaries($expected, $value) {
836 $this->assertEquals($expected, t3lib_div::intInRange($value, 0));
837 }
838
839 /**
840 * @test
841 */
842 public function intInRangeSetsDefaultValueIfZeroValueIsGiven() {
843 $this->assertEquals(42, t3lib_div::intInRange('', 0, 2000000000, 42));
844 }
845
846 //////////////////////////////////
847 // Tests concerning intval_positive
848 //////////////////////////////////
849 /**
850 * @test
851 */
852 public function intvalPositiveReturnsZeroForNegativeValues() {
853 $this->assertEquals(0, t3lib_div::intval_positive(-123));
854 }
855
856 /**
857 * @test
858 */
859 public function intvalPositiveReturnsTheInputValueForPositiveValues() {
860 $this->assertEquals(123, t3lib_div::intval_positive(123));
861 }
862
863 //////////////////////////////////
864 // Tests concerning int_from_ver
865 //////////////////////////////////
866 /**
867 * Data Provider for intFromVerConvertsVersionNumbersToIntegersDataProvider
868 *
869 * return array
870 */
871 public function intFromVerConvertsVersionNumbersToIntegersDataProvider() {
872 return array(
873 array('4003003', '4.3.3'),
874 array('4012003', '4.12.3'),
875 array('5000000', '5.0.0'),
876 array('3008001', '3.8.1'),
877 array('1012', '0.1.12')
878 );
879 }
880
881 /**
882 * @test
883 * @dataProvider intFromVerConvertsVersionNumbersToIntegersDataProvider
884 */
885 public function intFromVerConvertsVersionNumbersToIntegers($expected, $version) {
886 $this->assertEquals($expected, t3lib_div::int_from_ver($version));
887 }
888
889 //////////////////////////////////
890 // Tests concerning revExplode
891 //////////////////////////////////
892
893 /**
894 * @test
895 */
896 public function revExplodeExplodesString() {
897 $testString = 'my:words:here';
898 $expectedArray = array('my:words', 'here');
899 $actualArray = t3lib_div::revExplode(':', $testString, 2);
900
901 $this->assertEquals($expectedArray, $actualArray);
902 }
903
904
905 //////////////////////////////////
906 // Tests concerning trimExplode
907 //////////////////////////////////
908
909 /**
910 * @test
911 */
912 public function checkTrimExplodeTrimsSpacesAtElementStartAndEnd() {
913 $testString = ' a , b , c ,d ,, e,f,';
914 $expectedArray = array('a', 'b', 'c', 'd', '', 'e', 'f', '');
915 $actualArray = t3lib_div::trimExplode(',', $testString);
916
917 $this->assertEquals($expectedArray, $actualArray);
918 }
919
920 /**
921 * @test
922 */
923 public function checkTrimExplodeRemovesNewLines() {
924 $testString = ' a , b , ' . LF . ' ,d ,, e,f,';
925 $expectedArray = array('a', 'b', 'd', 'e', 'f');
926 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
927
928 $this->assertEquals($expectedArray, $actualArray);
929 }
930
931 /**
932 * @test
933 */
934 public function checkTrimExplodeRemovesEmptyElements() {
935 $testString = 'a , b , c , ,d ,, ,e,f,';
936 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f');
937 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
938
939 $this->assertEquals($expectedArray, $actualArray);
940 }
941
942 /**
943 * @test
944 */
945 public function checkTrimExplodeKeepsRemainingResultsWithEmptyItemsAfterReachingLimitWithPositiveParameter() {
946 $testString = ' a , b , c , , d,, ,e ';
947 $expectedArray = array('a', 'b', 'c,,d,,,e');
948 // Limiting returns the rest of the string as the last element
949 $actualArray = t3lib_div::trimExplode(',', $testString, FALSE, 3);
950
951 $this->assertEquals($expectedArray, $actualArray);
952 }
953
954 /**
955 * @test
956 */
957 public function checkTrimExplodeKeepsRemainingResultsWithoutEmptyItemsAfterReachingLimitWithPositiveParameter() {
958 $testString = ' a , b , c , , d,, ,e ';
959 $expectedArray = array('a', 'b', 'c,d,e');
960 // Limiting returns the rest of the string as the last element
961 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, 3);
962
963 $this->assertEquals($expectedArray, $actualArray);
964 }
965
966 /**
967 * @test
968 */
969 public function checkTrimExplodeKeepsRamainingResultsWithEmptyItemsAfterReachingLimitWithNegativeParameter() {
970 $testString = ' a , b , c , d, ,e, f , , ';
971 $expectedArray = array('a', 'b', 'c', 'd', '', 'e');
972 // limiting returns the rest of the string as the last element
973 $actualArray = t3lib_div::trimExplode(',', $testString, FALSE, -3);
974
975 $this->assertEquals($expectedArray, $actualArray);
976 }
977
978 /**
979 * @test
980 */
981 public function checkTrimExplodeKeepsRamainingResultsWithoutEmptyItemsAfterReachingLimitWithNegativeParameter() {
982 $testString = ' a , b , c , d, ,e, f , , ';
983 $expectedArray = array('a', 'b', 'c');
984 // Limiting returns the rest of the string as the last element
985 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, -3);
986
987 $this->assertEquals($expectedArray, $actualArray);
988 }
989
990 /**
991 * @test
992 */
993 public function checkTrimExplodeReturnsExactResultsWithoutReachingLimitWithPositiveParameter() {
994 $testString = ' a , b , , c , , , ';
995 $expectedArray = array('a', 'b', 'c');
996 // Limiting returns the rest of the string as the last element
997 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, 4);
998
999 $this->assertEquals($expectedArray, $actualArray);
1000 }
1001
1002 /**
1003 * @test
1004 */
1005 public function checkTrimExplodeKeepsZeroAsString() {
1006 $testString = 'a , b , c , ,d ,, ,e,f, 0 ,';
1007 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f', '0');
1008 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
1009
1010 $this->assertEquals($expectedArray, $actualArray);
1011 }
1012
1013
1014 //////////////////////////////////
1015 // Tests concerning removeArrayEntryByValue
1016 //////////////////////////////////
1017
1018 /**
1019 * @test
1020 */
1021 public function checkRemoveArrayEntryByValueRemovesEntriesFromOneDimensionalArray() {
1022 $inputArray = array(
1023 '0' => 'test1',
1024 '1' => 'test2',
1025 '2' => 'test3',
1026 '3' => 'test2',
1027 );
1028 $compareValue = 'test2';
1029 $expectedResult = array(
1030 '0' => 'test1',
1031 '2' => 'test3',
1032 );
1033 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
1034 $this->assertEquals($expectedResult, $actualResult);
1035 }
1036
1037 /**
1038 * @test
1039 */
1040 public function checkRemoveArrayEntryByValueRemovesEntriesFromMultiDimensionalArray() {
1041 $inputArray = array(
1042 '0' => 'foo',
1043 '1' => array(
1044 '10' => 'bar',
1045 ),
1046 '2' => 'bar',
1047 );
1048 $compareValue = 'bar';
1049 $expectedResult = array(
1050 '0' => 'foo',
1051 '1' => array(),
1052 );
1053 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
1054 $this->assertEquals($expectedResult, $actualResult);
1055 }
1056
1057 /**
1058 * @test
1059 */
1060 public function checkRemoveArrayEntryByValueRemovesEntryWithEmptyString() {
1061 $inputArray = array(
1062 '0' => 'foo',
1063 '1' => '',
1064 '2' => 'bar',
1065 );
1066 $compareValue = '';
1067 $expectedResult = array(
1068 '0' => 'foo',
1069 '2' => 'bar',
1070 );
1071 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
1072 $this->assertEquals($expectedResult, $actualResult);
1073 }
1074
1075 //////////////////////////////////
1076 // Tests concerning getBytesFromSizeMeasurement
1077 //////////////////////////////////
1078
1079 /**
1080 * Data provider for getBytesFromSizeMeasurement
1081 *
1082 * @return array expected value, input string
1083 */
1084 public function getBytesFromSizeMeasurementDataProvider() {
1085 return array(
1086 '100 kilo Bytes' => array('102400', '100k'),
1087 '100 mega Bytes' => array('104857600', '100m'),
1088 '100 giga Bytes' => array('107374182400', '100g'),
1089 );
1090 }
1091
1092 /**
1093 * @test
1094 * @dataProvider getBytesFromSizeMeasurementDataProvider
1095 */
1096 public function getBytesFromSizeMeasurementCalculatesCorrectByteValue($expected, $byteString) {
1097 $this->assertEquals($expected, t3lib_div::getBytesFromSizeMeasurement($byteString));
1098 }
1099
1100
1101 //////////////////////////////////
1102 // Tests concerning getIndpEnv
1103 //////////////////////////////////
1104
1105 /**
1106 * @test
1107 */
1108 public function getIndpEnvTypo3SitePathReturnNonEmptyString() {
1109 $this->assertTrue(strlen(t3lib_div::getIndpEnv('TYPO3_SITE_PATH')) >= 1);
1110 }
1111
1112 /**
1113 * @test
1114 */
1115 public function getIndpEnvTypo3SitePathReturnsStringStartingWithSlash() {
1116 $result = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
1117 $this->assertEquals('/', $result[0]);
1118 }
1119
1120 /**
1121 * @test
1122 */
1123 public function getIndpEnvTypo3SitePathReturnsStringEndingWithSlash() {
1124 $result = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
1125 $this->assertEquals('/', $result[strlen($result) - 1]);
1126 }
1127
1128 /**
1129 * @return array
1130 */
1131 public static function hostnameAndPortDataProvider() {
1132 return array(
1133 'localhost ipv4 without port' => array('127.0.0.1', '127.0.0.1', ''),
1134 'localhost ipv4 with port' => array('127.0.0.1:81', '127.0.0.1', '81'),
1135 'localhost ipv6 without port' => array('[::1]', '[::1]', ''),
1136 'localhost ipv6 with port' => array('[::1]:81', '[::1]', '81'),
1137 'ipv6 without port' => array('[2001:DB8::1]', '[2001:DB8::1]', ''),
1138 'ipv6 with port' => array('[2001:DB8::1]:81', '[2001:DB8::1]', '81'),
1139 'hostname without port' => array('lolli.did.this', 'lolli.did.this', ''),
1140 'hostname with port' => array('lolli.did.this:42', 'lolli.did.this', '42'),
1141 );
1142 }
1143
1144 /**
1145 * @test
1146 * @dataProvider hostnameAndPortDataProvider
1147 */
1148 public function getIndpEnvTypo3HostOnlyParsesHostnamesAndIpAdresses($httpHost, $expectedIp) {
1149 $_SERVER['HTTP_HOST'] = $httpHost;
1150 $this->assertEquals($expectedIp, t3lib_div::getIndpEnv('TYPO3_HOST_ONLY'));
1151 }
1152
1153 /**
1154 * @test
1155 * @dataProvider hostnameAndPortDataProvider
1156 */
1157 public function getIndpEnvTypo3PortParsesHostnamesAndIpAdresses($httpHost, $dummy, $expectedPort) {
1158 $_SERVER['HTTP_HOST'] = $httpHost;
1159 $this->assertEquals($expectedPort, t3lib_div::getIndpEnv('TYPO3_PORT'));
1160 }
1161
1162
1163 //////////////////////////////////
1164 // Tests concerning underscoredToUpperCamelCase
1165 //////////////////////////////////
1166
1167 /**
1168 * Data provider for underscoredToUpperCamelCase
1169 *
1170 * @return array expected, input string
1171 */
1172 public function underscoredToUpperCamelCaseDataProvider() {
1173 return array(
1174 'single word' => array('Blogexample', 'blogexample'),
1175 'multiple words' => array('BlogExample', 'blog_example'),
1176 );
1177 }
1178
1179 /**
1180 * @test
1181 * @dataProvider underscoredToUpperCamelCaseDataProvider
1182 */
1183 public function underscoredToUpperCamelCase($expected, $inputString) {
1184 $this->assertEquals($expected, t3lib_div::underscoredToUpperCamelCase($inputString));
1185 }
1186
1187
1188 //////////////////////////////////
1189 // Tests concerning underscoredToLowerCamelCase
1190 //////////////////////////////////
1191
1192 /**
1193 * Data provider for underscoredToLowerCamelCase
1194 *
1195 * @return array expected, input string
1196 */
1197 public function underscoredToLowerCamelCaseDataProvider() {
1198 return array(
1199 'single word' => array('minimalvalue', 'minimalvalue'),
1200 'multiple words' => array('minimalValue', 'minimal_value'),
1201 );
1202 }
1203
1204 /**
1205 * @test
1206 * @dataProvider underscoredToLowerCamelCaseDataProvider
1207 */
1208 public function underscoredToLowerCamelCase($expected, $inputString) {
1209 $this->assertEquals($expected, t3lib_div::underscoredToLowerCamelCase($inputString));
1210 }
1211
1212 //////////////////////////////////
1213 // Tests concerning camelCaseToLowerCaseUnderscored
1214 //////////////////////////////////
1215
1216 /**
1217 * Data provider for camelCaseToLowerCaseUnderscored
1218 *
1219 * @return array expected, input string
1220 */
1221 public function camelCaseToLowerCaseUnderscoredDataProvider() {
1222 return array(
1223 'single word' => array('blogexample', 'blogexample'),
1224 'single word starting upper case' => array('blogexample', 'Blogexample'),
1225 'two words starting lower case' => array('minimal_value', 'minimalValue'),
1226 'two words starting upper case' => array('blog_example', 'BlogExample'),
1227 );
1228 }
1229
1230 /**
1231 * @test
1232 * @dataProvider camelCaseToLowerCaseUnderscoredDataProvider
1233 */
1234 public function camelCaseToLowerCaseUnderscored($expected, $inputString) {
1235 $this->assertEquals($expected, t3lib_div::camelCaseToLowerCaseUnderscored($inputString));
1236 }
1237
1238
1239 //////////////////////////////////
1240 // Tests concerning lcFirst
1241 //////////////////////////////////
1242
1243 /**
1244 * Data provider for lcFirst
1245 *
1246 * @return array expected, input string
1247 */
1248 public function lcfirstDataProvider() {
1249 return array(
1250 'single word' => array('blogexample', 'blogexample'),
1251 'single Word starting upper case' => array('blogexample', 'Blogexample'),
1252 'two words' => array('blogExample', 'BlogExample'),
1253 );
1254 }
1255
1256 /**
1257 * @test
1258 * @dataProvider lcfirstDataProvider
1259 */
1260 public function lcFirst($expected, $inputString) {
1261 $this->assertEquals($expected, t3lib_div::lcfirst($inputString));
1262 }
1263
1264
1265 //////////////////////////////////
1266 // Tests concerning encodeHeader
1267 //////////////////////////////////
1268
1269 /**
1270 * @test
1271 */
1272 public function encodeHeaderEncodesWhitespacesInQuotedPrintableMailHeader() {
1273 $this->assertEquals(
1274 '=?utf-8?Q?We_test_whether_the_copyright_character_=C2=A9_is_encoded_correctly?=',
1275 t3lib_div::encodeHeader(
1276 "We test whether the copyright character \xc2\xa9 is encoded correctly",
1277 'quoted-printable',
1278 'utf-8'
1279 )
1280 );
1281 }
1282
1283 /**
1284 * @test
1285 */
1286 public function encodeHeaderEncodesQuestionmarksInQuotedPrintableMailHeader() {
1287 $this->assertEquals(
1288 '=?utf-8?Q?Is_the_copyright_character_=C2=A9_really_encoded_correctly=3F_Really=3F?=',
1289 t3lib_div::encodeHeader(
1290 "Is the copyright character \xc2\xa9 really encoded correctly? Really?",
1291 'quoted-printable',
1292 'utf-8'
1293 )
1294 );
1295 }
1296
1297
1298 //////////////////////////////////
1299 // Tests concerning isValidUrl
1300 //////////////////////////////////
1301
1302 /**
1303 * Data provider for valid isValidUrl's
1304 *
1305 * @return array Valid ressource
1306 */
1307 public function validUrlValidRessourceDataProvider() {
1308 return array(
1309 'http' => array('http://www.example.org/'),
1310 'http without trailing slash' => array('http://qwe'),
1311 'http directory with trailing slash' => array('http://www.example/img/dir/'),
1312 'http directory without trailing slash' => array('http://www.example/img/dir'),
1313 'http index.html' => array('http://example.com/index.html'),
1314 'http index.php' => array('http://www.example.com/index.php'),
1315 'http test.png' => array('http://www.example/img/test.png'),
1316 'http username password querystring and ancher' => array('https://user:pw@www.example.org:80/path?arg=value#fragment'),
1317 'file' => array('file:///tmp/test.c'),
1318 'file directory' => array('file://foo/bar'),
1319 'ftp directory' => array('ftp://ftp.example.com/tmp/'),
1320 'mailto' => array('mailto:foo@bar.com'),
1321 'news' => array('news:news.php.net'),
1322 'telnet'=> array('telnet://192.0.2.16:80/'),
1323 'ldap' => array('ldap://[2001:db8::7]/c=GB?objectClass?one'),
1324 );
1325 }
1326
1327 /**
1328 * @test
1329 * @dataProvider validUrlValidRessourceDataProvider
1330 */
1331 public function validURLReturnsTrueForValidRessource($url) {
1332 $this->assertTrue(t3lib_div::isValidUrl($url));
1333 }
1334
1335 /**
1336 * Data provider for invalid isValidUrl's
1337 *
1338 * @return array Invalid ressource
1339 */
1340 public function isValidUrlInvalidRessourceDataProvider() {
1341 return array(
1342 'http missing colon' => array('http//www.example/wrong/url/'),
1343 'http missing slash' => array('http:/www.example'),
1344 'hostname only' => array('www.example.org/'),
1345 'file missing protocol specification' => array('/tmp/test.c'),
1346 'slash only' => array('/'),
1347 'string http://' => array('http://'),
1348 'string http:/' => array('http:/'),
1349 'string http:' => array('http:'),
1350 'string http' => array('http'),
1351 'empty string' => array(''),
1352 'string -1' => array('-1'),
1353 'string array()' => array('array()'),
1354 'random string' => array('qwe'),
1355 );
1356 }
1357
1358 /**
1359 * @test
1360 * @dataProvider isValidUrlInvalidRessourceDataProvider
1361 */
1362 public function validURLReturnsFalseForInvalidRessoure($url) {
1363 $this->assertFalse(t3lib_div::isValidUrl($url));
1364 }
1365
1366
1367 //////////////////////////////////
1368 // Tests concerning isOnCurrentHost
1369 //////////////////////////////////
1370
1371 /**
1372 * @test
1373 */
1374 public function isOnCurrentHostReturnsTrueWithCurrentHost() {
1375 $testUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_URL');
1376 $this->assertTrue(t3lib_div::isOnCurrentHost($testUrl));
1377 }
1378
1379 /**
1380 * Data provider for invalid isOnCurrentHost's
1381 *
1382 * @return array Invalid Hosts
1383 */
1384 public function checkisOnCurrentHostInvalidHosts() {
1385 return array(
1386 'empty string' => array(''),
1387 'arbitrary string' => array('arbitrary string'),
1388 'localhost IP' => array('127.0.0.1'),
1389 'relative path' => array('./relpath/file.txt'),
1390 'absolute path' => array('/abspath/file.txt?arg=value'),
1391 'differnt host' => array(t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST') . '.example.org'),
1392 );
1393 }
1394
1395
1396 ////////////////////////////////////////
1397 // Tests concerning sanitizeLocalUrl
1398 ////////////////////////////////////////
1399
1400 /**
1401 * Data provider for valid sanitizeLocalUrl's
1402 *
1403 * @return array Valid url
1404 */
1405 public function sanitizeLocalUrlValidUrlDataProvider() {
1406 $subDirectory = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
1407 $typo3SiteUrl = t3lib_div::getIndpEnv('TYPO3_SITE_URL');
1408 $typo3RequestHost = t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST');
1409
1410 return array(
1411 'alt_intro.php' => array('alt_intro.php'),
1412 'alt_intro.php?foo=1&bar=2' => array('alt_intro.php?foo=1&bar=2'),
1413 $subDirectory . 'typo3/alt_intro.php' => array($subDirectory . 'typo3/alt_intro.php'),
1414 $subDirectory . 'index.php' => array($subDirectory . 'index.php'),
1415 '../index.php' => array('../index.php'),
1416 '../typo3/alt_intro.php' => array('../typo3/alt_intro.php'),
1417 '../~userDirectory/index.php' => array('../~userDirectory/index.php'),
1418 '../typo3/mod.php?var1=test-case&var2=~user' => array('../typo3/mod.php?var1=test-case&var2=~user'),
1419 PATH_site . 'typo3/alt_intro.php' => array(PATH_site . 'typo3/alt_intro.php'),
1420 $typo3SiteUrl . 'typo3/alt_intro.php' => array($typo3SiteUrl . 'typo3/alt_intro.php'),
1421 $typo3RequestHost . $subDirectory . '/index.php' => array($typo3RequestHost . $subDirectory . '/index.php'),
1422 );
1423 }
1424
1425 /**
1426 * @test
1427 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
1428 */
1429 public function sanitizeLocalUrlAcceptsNotEncodedValidUrls($url) {
1430 $this->assertEquals($url, t3lib_div::sanitizeLocalUrl($url));
1431 }
1432
1433 /**
1434 * @test
1435 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
1436 */
1437 public function sanitizeLocalUrlAcceptsEncodedValidUrls($url) {
1438 $this->assertEquals(rawurlencode($url), t3lib_div::sanitizeLocalUrl(rawurlencode($url)));
1439 }
1440
1441 /**
1442 * Data provider for invalid sanitizeLocalUrl's
1443 *
1444 * @return array Valid url
1445 */
1446 public function sanitizeLocalUrlInvalidDataProvider() {
1447 return array(
1448 'empty string' => array(''),
1449 'http domain' => array('http://www.google.de/'),
1450 'https domain' => array('https://www.google.de/'),
1451 'relative path with XSS' => array('../typo3/whatever.php?argument=javascript:alert(0)'),
1452 );
1453 }
1454
1455 /**
1456 * @test
1457 * @dataProvider sanitizeLocalUrlInvalidDataProvider
1458 */
1459 public function sanitizeLocalUrlDeniesPlainInvalidUrls($url) {
1460 $this->assertEquals('', t3lib_div::sanitizeLocalUrl($url));
1461 }
1462
1463 /**
1464 * @test
1465 * @dataProvider sanitizeLocalUrlInvalidDataProvider
1466 */
1467 public function sanitizeLocalUrlDeniesEncodedInvalidUrls($url) {
1468 $this->assertEquals('', t3lib_div::sanitizeLocalUrl(rawurlencode($url)));
1469 }
1470
1471
1472 //////////////////////////////////////
1473 // Tests concerning addSlashesOnArray
1474 //////////////////////////////////////
1475
1476 /**
1477 * @test
1478 */
1479 public function addSlashesOnArrayAddsSlashesRecursive() {
1480 $inputArray = array(
1481 'key1' => array(
1482 'key11' => "val'ue1",
1483 'key12' => 'val"ue2',
1484 ),
1485 'key2' => 'val\ue3',
1486 );
1487 $expectedResult = array(
1488 'key1' => array(
1489 'key11' => "val\'ue1",
1490 'key12' => 'val\"ue2',
1491 ),
1492 'key2' => 'val\\\\ue3',
1493 );
1494 t3lib_div::addSlashesOnArray($inputArray);
1495 $this->assertEquals(
1496 $expectedResult,
1497 $inputArray
1498 );
1499 }
1500
1501
1502 //////////////////////////////////////
1503 // Tests concerning addSlashesOnArray
1504 //////////////////////////////////////
1505
1506 /**
1507 * @test
1508 */
1509 public function stripSlashesOnArrayStripsSlashesRecursive() {
1510 $inputArray = array(
1511 'key1' => array(
1512 'key11' => "val\'ue1",
1513 'key12' => 'val\"ue2',
1514 ),
1515 'key2' => 'val\\\\ue3',
1516 );
1517 $expectedResult = array(
1518 'key1' => array(
1519 'key11' => "val'ue1",
1520 'key12' => 'val"ue2',
1521 ),
1522 'key2' => 'val\ue3',
1523 );
1524 t3lib_div::stripSlashesOnArray($inputArray);
1525 $this->assertEquals(
1526 $expectedResult,
1527 $inputArray
1528 );
1529 }
1530
1531
1532 //////////////////////////////////////
1533 // Tests concerning arrayDiffAssocRecursive
1534 //////////////////////////////////////
1535
1536 /**
1537 * @test
1538 */
1539 public function arrayDiffAssocRecursiveHandlesOneDimensionalArrays() {
1540 $array1 = array(
1541 'key1' => 'value1',
1542 'key2' => 'value2',
1543 'key3' => 'value3',
1544 );
1545 $array2 = array(
1546 'key1' => 'value1',
1547 'key3' => 'value3',
1548 );
1549 $expectedResult = array(
1550 'key2' => 'value2',
1551 );
1552 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1553 $this->assertEquals($expectedResult, $actualResult);
1554 }
1555
1556 /**
1557 * @test
1558 */
1559 public function arrayDiffAssocRecursiveHandlesMultiDimensionalArrays() {
1560 $array1 = array(
1561 'key1' => 'value1',
1562 'key2' => array(
1563 'key21' => 'value21',
1564 'key22' => 'value22',
1565 'key23' => array(
1566 'key231' => 'value231',
1567 'key232' => 'value232',
1568 ),
1569 ),
1570 );
1571 $array2 = array(
1572 'key1' => 'value1',
1573 'key2' => array(
1574 'key21' => 'value21',
1575 'key23' => array(
1576 'key231' => 'value231',
1577 ),
1578 ),
1579 );
1580 $expectedResult = array(
1581 'key2' => array(
1582 'key22' => 'value22',
1583 'key23' => array(
1584 'key232' => 'value232',
1585 ),
1586 ),
1587 );
1588 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1589 $this->assertEquals($expectedResult, $actualResult);
1590 }
1591
1592 /**
1593 * @test
1594 */
1595 public function arrayDiffAssocRecursiveHandlesMixedArrays() {
1596 $array1 = array(
1597 'key1' => array(
1598 'key11' => 'value11',
1599 'key12' => 'value12',
1600 ),
1601 'key2' => 'value2',
1602 'key3' => 'value3',
1603 );
1604 $array2 = array(
1605 'key1' => 'value1',
1606 'key2' => array(
1607 'key21' => 'value21',
1608 ),
1609 );
1610 $expectedResult = array(
1611 'key3' => 'value3',
1612 );
1613 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1614 $this->assertEquals($expectedResult, $actualResult);
1615 }
1616
1617
1618 //////////////////////////////////////
1619 // Tests concerning removeDotsFromTS
1620 //////////////////////////////////////
1621
1622 /**
1623 * @test
1624 */
1625 public function removeDotsFromTypoScriptSucceedsWithDottedArray() {
1626 $typoScript = array(
1627 'propertyA.' => array(
1628 'keyA.' => array(
1629 'valueA' => 1,
1630 ),
1631 'keyB' => 2,
1632 ),
1633 'propertyB' => 3,
1634 );
1635
1636 $expectedResult = array(
1637 'propertyA' => array(
1638 'keyA' => array(
1639 'valueA' => 1,
1640 ),
1641 'keyB' => 2,
1642 ),
1643 'propertyB' => 3,
1644 );
1645
1646 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1647 }
1648
1649 /**
1650 * @test
1651 */
1652 public function removeDotsFromTypoScriptOverridesSubArray() {
1653 $typoScript = array(
1654 'propertyA.' => array(
1655 'keyA' => 'getsOverridden',
1656 'keyA.' => array(
1657 'valueA' => 1,
1658 ),
1659 'keyB' => 2,
1660 ),
1661 'propertyB' => 3,
1662 );
1663
1664 $expectedResult = array(
1665 'propertyA' => array(
1666 'keyA' => array(
1667 'valueA' => 1,
1668 ),
1669 'keyB' => 2,
1670 ),
1671 'propertyB' => 3,
1672 );
1673
1674 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1675 }
1676
1677 /**
1678 * @test
1679 */
1680 public function removeDotsFromTypoScriptOverridesWithScalar() {
1681 $typoScript = array(
1682 'propertyA.' => array(
1683 'keyA.' => array(
1684 'valueA' => 1,
1685 ),
1686 'keyA' => 'willOverride',
1687 'keyB' => 2,
1688 ),
1689 'propertyB' => 3,
1690 );
1691
1692 $expectedResult = array(
1693 'propertyA' => array(
1694 'keyA' => 'willOverride',
1695 'keyB' => 2,
1696 ),
1697 'propertyB' => 3,
1698 );
1699
1700 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1701 }
1702
1703 //////////////////////////////////////
1704 // Tests concerning naturalKeySortRecursive
1705 //////////////////////////////////////
1706
1707 /**
1708 * @test
1709 */
1710 public function naturalKeySortRecursiveReturnsFalseIfInputIsNotAnArray() {
1711 $testValues = array(
1712 1,
1713 'string',
1714 FALSE
1715 );
1716 foreach($testValues as $testValue) {
1717 $this->assertFalse(t3lib_div::naturalKeySortRecursive($testValue));
1718 }
1719 }
1720
1721 /**
1722 * @test
1723 */
1724 public function naturalKeySortRecursiveSortsOneDimensionalArrayByNaturalOrder() {
1725 $testArray = array(
1726 'bb' => 'bb',
1727 'ab' => 'ab',
1728 '123' => '123',
1729 'aaa' => 'aaa',
1730 'abc' => 'abc',
1731 '23' => '23',
1732 'ba' => 'ba',
1733 'bad' => 'bad',
1734 '2' => '2',
1735 'zap' => 'zap',
1736 '210' => '210'
1737 );
1738 $expectedResult = array(
1739 '2',
1740 '23',
1741 '123',
1742 '210',
1743 'aaa',
1744 'ab',
1745 'abc',
1746 'ba',
1747 'bad',
1748 'bb',
1749 'zap'
1750 );
1751 t3lib_div::naturalKeySortRecursive($testArray);
1752 $this->assertEquals($expectedResult, array_values($testArray));
1753 }
1754
1755 /**
1756 * @test
1757 */
1758 public function naturalKeySortRecursiveSortsMultiDimensionalArrayByNaturalOrder() {
1759 $testArray = array(
1760 '2' => '2',
1761 'bb' => 'bb',
1762 'ab' => 'ab',
1763 '23' => '23',
1764 'aaa' => array(
1765 'bb' => 'bb',
1766 'ab' => 'ab',
1767 '123' => '123',
1768 'aaa' => 'aaa',
1769 '2' => '2',
1770 'abc' => 'abc',
1771 'ba' => 'ba',
1772 '23' => '23',
1773 'bad' => array(
1774 'bb' => 'bb',
1775 'ab' => 'ab',
1776 '123' => '123',
1777 'aaa' => 'aaa',
1778 'abc' => 'abc',
1779 '23' => '23',
1780 'ba' => 'ba',
1781 'bad' => 'bad',
1782 '2' => '2',
1783 'zap' => 'zap',
1784 '210' => '210'
1785 ),
1786 '210' => '210',
1787 'zap' => 'zap'
1788 ),
1789 'abc' => 'abc',
1790 'ba' => 'ba',
1791 '210' => '210',
1792 'bad' => 'bad',
1793 '123' => '123',
1794 'zap' => 'zap'
1795 );
1796
1797 $expectedResult = array(
1798 '2',
1799 '23',
1800 '123',
1801 '210',
1802 'aaa',
1803 'ab',
1804 'abc',
1805 'ba',
1806 'bad',
1807 'bb',
1808 'zap'
1809 );
1810 t3lib_div::naturalKeySortRecursive($testArray);
1811
1812 $this->assertEquals($expectedResult, array_values(array_keys($testArray['aaa']['bad'])));
1813 $this->assertEquals($expectedResult, array_values(array_keys($testArray['aaa'])));
1814 $this->assertEquals($expectedResult, array_values(array_keys($testArray)));
1815 }
1816
1817 //////////////////////////////////////
1818 // Tests concerning get_dirs
1819 //////////////////////////////////////
1820
1821 /**
1822 * @test
1823 */
1824 public function getDirsReturnsArrayOfDirectoriesFromGivenDirectory() {
1825 $path = PATH_t3lib;
1826 $directories = t3lib_div::get_dirs($path);
1827
1828 $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $directories);
1829 }
1830
1831 /**
1832 * @test
1833 */
1834 public function getDirsReturnsStringErrorOnPathFailure() {
1835 $path = 'foo';
1836 $result = t3lib_div::get_dirs($path);
1837 $expectedResult = 'error';
1838
1839 $this->assertEquals($expectedResult, $result);
1840 }
1841
1842
1843 //////////////////////////////////
1844 // Tests concerning hmac
1845 //////////////////////////////////
1846
1847 /**
1848 * @test
1849 */
1850 public function hmacReturnsHashOfProperLength() {
1851 $hmac = t3lib_div::hmac('message');
1852 $this->assertTrue(!empty($hmac) && is_string($hmac));
1853 $this->assertTrue(strlen($hmac) == 40);
1854 }
1855
1856 /**
1857 * @test
1858 */
1859 public function hmacReturnsEqualHashesForEqualInput() {
1860 $msg0 = 'message';
1861 $msg1 = 'message';
1862 $this->assertEquals(t3lib_div::hmac($msg0), t3lib_div::hmac($msg1));
1863 }
1864
1865 /**
1866 * @test
1867 */
1868 public function hmacReturnsNoEqualHashesForNonEqualInput() {
1869 $msg0 = 'message0';
1870 $msg1 = 'message1';
1871 $this->assertNotEquals(t3lib_div::hmac($msg0), t3lib_div::hmac($msg1));
1872 }
1873
1874
1875 //////////////////////////////////
1876 // Tests concerning quoteJSvalue
1877 //////////////////////////////////
1878
1879 /**
1880 * @test
1881 */
1882 public function quoteJSvalueHtmlspecialcharsDataByDefault() {
1883 $this->assertContains(
1884 '&gt;',
1885 t3lib_div::quoteJSvalue('>')
1886 );
1887 }
1888
1889 /**
1890 * @test
1891 */
1892 public function quoteJSvaluetHtmlspecialcharsDataWithinCDataSetToFalse() {
1893 $this->assertContains(
1894 '&gt;',
1895 t3lib_div::quoteJSvalue('>', FALSE)
1896 );
1897 }
1898
1899 /**
1900 * @test
1901 */
1902 public function quoteJSvaluetNotHtmlspecialcharsDataWithinCDataSetToTrue() {
1903 $this->assertContains(
1904 '>',
1905 t3lib_div::quoteJSvalue('>', TRUE)
1906 );
1907 }
1908
1909 /**
1910 * @test
1911 */
1912 public function quoteJSvalueReturnsEmptyStringQuotedInSingleQuotes() {
1913 $this->assertEquals(
1914 "''",
1915 t3lib_div::quoteJSvalue("", TRUE)
1916 );
1917 }
1918
1919 /**
1920 * @test
1921 */
1922 public function quoteJSvalueNotModifiesStringWithoutSpecialCharacters() {
1923 $this->assertEquals(
1924 "'Hello world!'",
1925 t3lib_div::quoteJSvalue("Hello world!", TRUE)
1926 );
1927 }
1928
1929 /**
1930 * @test
1931 */
1932 public function quoteJSvalueEscapesSingleQuote() {
1933 $this->assertEquals(
1934 "'\\''",
1935 t3lib_div::quoteJSvalue("'", TRUE)
1936 );
1937 }
1938
1939 /**
1940 * @test
1941 */
1942 public function quoteJSvalueEscapesDoubleQuoteWithinCDataSetToTrue() {
1943 $this->assertEquals(
1944 "'\\\"'",
1945 t3lib_div::quoteJSvalue('"', TRUE)
1946 );
1947 }
1948
1949 /**
1950 * @test
1951 */
1952 public function quoteJSvalueEscapesAndHtmlspecialcharsDoubleQuoteWithinCDataSetToFalse() {
1953 $this->assertEquals(
1954 "'\\&quot;'",
1955 t3lib_div::quoteJSvalue('"', FALSE)
1956 );
1957 }
1958
1959 /**
1960 * @test
1961 */
1962 public function quoteJSvalueEscapesTab() {
1963 $this->assertEquals(
1964 "'" . '\t' . "'",
1965 t3lib_div::quoteJSvalue(TAB)
1966 );
1967 }
1968
1969 /**
1970 * @test
1971 */
1972 public function quoteJSvalueEscapesLinefeed() {
1973 $this->assertEquals(
1974 "'" . '\n' . "'",
1975 t3lib_div::quoteJSvalue(LF)
1976 );
1977 }
1978
1979 /**
1980 * @test
1981 */
1982 public function quoteJSvalueEscapesCarriageReturn() {
1983 $this->assertEquals(
1984 "'" . '\r' . "'",
1985 t3lib_div::quoteJSvalue(CR)
1986 );
1987 }
1988
1989 /**
1990 * @test
1991 */
1992 public function quoteJSvalueEscapesBackslah() {
1993 $this->assertEquals(
1994 "'\\\\'",
1995 t3lib_div::quoteJSvalue('\\')
1996 );
1997 }
1998
1999 //////////////////////////////////
2000 // Tests concerning readLLfile
2001 //////////////////////////////////
2002
2003 /**
2004 * @test
2005 */
2006 public function readLLfileHandlesLocallangXMLOverride() {
2007 $unique = uniqid('locallangXMLOverrideTest');
2008
2009 $xml = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
2010 <T3locallang>
2011 <data type="array">
2012 <languageKey index="default" type="array">
2013 <label index="buttons.logout">EXIT</label>
2014 </languageKey>
2015 </data>
2016 </T3locallang>';
2017
2018 $file = PATH_site . 'typo3temp/' . $unique . '.xml';
2019 t3lib_div::writeFileToTypo3tempDir($file, $xml);
2020
2021 // Make sure there is no cached version of the label
2022 $GLOBALS['typo3CacheManager']->getCache('t3lib_l10n')->flush();
2023
2024 // Get default value
2025 $defaultLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
2026
2027 // Clear language cache again
2028 $GLOBALS['typo3CacheManager']->getCache('t3lib_l10n')->flush();
2029
2030 // Set override file
2031 $GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['EXT:lang/locallang_core.xml'][$unique] = $file;
2032
2033 /** @var $store t3lib_l10n_Store */
2034 $store = t3lib_div::makeInstance('t3lib_l10n_Store');
2035 $store->flushData('EXT:lang/locallang_core.xml');
2036
2037 // Get override value
2038 $overrideLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
2039
2040 // Clean up again
2041 unlink($file);
2042
2043 $this->assertNotEquals($overrideLL['default']['buttons.logout'][0]['target'], '');
2044 $this->assertNotEquals($defaultLL['default']['buttons.logout'][0]['target'], $overrideLL['default']['buttons.logout'][0]['target']);
2045 $this->assertEquals($overrideLL['default']['buttons.logout'][0]['target'], 'EXIT');
2046 }
2047
2048
2049 ///////////////////////////////
2050 // Tests concerning _GETset()
2051 ///////////////////////////////
2052
2053 /**
2054 * @test
2055 */
2056 public function getSetWritesArrayToGetSystemVariable() {
2057 $_GET = array();
2058 $GLOBALS['HTTP_GET_VARS'] = array();
2059
2060 $getParameters = array('foo' => 'bar');
2061 t3lib_div::_GETset($getParameters);
2062 $this->assertSame($getParameters, $_GET);
2063 }
2064
2065 /**
2066 * @test
2067 */
2068 public function getSetWritesArrayToGlobalsHttpGetVars() {
2069 $_GET = array();
2070 $GLOBALS['HTTP_GET_VARS'] = array();
2071
2072 $getParameters = array('foo' => 'bar');
2073 t3lib_div::_GETset($getParameters);
2074 $this->assertSame($getParameters, $GLOBALS['HTTP_GET_VARS']);
2075 }
2076
2077 /**
2078 * @test
2079 */
2080 public function getSetForArrayDropsExistingValues() {
2081 $_GET = array();
2082 $GLOBALS['HTTP_GET_VARS'] = array();
2083
2084 t3lib_div::_GETset(array('foo' => 'bar'));
2085
2086 t3lib_div::_GETset(array('oneKey' => 'oneValue'));
2087
2088 $this->assertEquals(
2089 array('oneKey' => 'oneValue'),
2090 $GLOBALS['HTTP_GET_VARS']
2091 );
2092 }
2093
2094 /**
2095 * @test
2096 */
2097 public function getSetAssignsOneValueToOneKey() {
2098 $_GET = array();
2099 $GLOBALS['HTTP_GET_VARS'] = array();
2100
2101 t3lib_div::_GETset('oneValue', 'oneKey');
2102
2103 $this->assertEquals(
2104 'oneValue',
2105 $GLOBALS['HTTP_GET_VARS']['oneKey']
2106 );
2107 }
2108
2109 /**
2110 * @test
2111 */
2112 public function getSetForOneValueDoesNotDropUnrelatedValues() {
2113 $_GET = array();
2114 $GLOBALS['HTTP_GET_VARS'] = array();
2115
2116 t3lib_div::_GETset(array('foo' => 'bar'));
2117 t3lib_div::_GETset('oneValue', 'oneKey');
2118
2119 $this->assertEquals(
2120 array('foo' => 'bar', 'oneKey' => 'oneValue'),
2121 $GLOBALS['HTTP_GET_VARS']
2122 );
2123 }
2124
2125 /**
2126 * @test
2127 */
2128 public function getSetCanAssignsAnArrayToASpecificArrayElement() {
2129 $_GET = array();
2130 $GLOBALS['HTTP_GET_VARS'] = array();
2131
2132 t3lib_div::_GETset(array('childKey' => 'oneValue'), 'parentKey');
2133
2134 $this->assertEquals(
2135 array('parentKey' => array('childKey' => 'oneValue')),
2136 $GLOBALS['HTTP_GET_VARS']
2137 );
2138 }
2139
2140 /**
2141 * @test
2142 */
2143 public function getSetCanAssignAStringValueToASpecificArrayChildElement() {
2144 $_GET = array();
2145 $GLOBALS['HTTP_GET_VARS'] = array();
2146
2147 t3lib_div::_GETset('oneValue', 'parentKey|childKey');
2148
2149 $this->assertEquals(
2150 array('parentKey' => array('childKey' => 'oneValue')),
2151 $GLOBALS['HTTP_GET_VARS']
2152 );
2153 }
2154
2155 /**
2156 * @test
2157 */
2158 public function getSetCanAssignAnArrayToASpecificArrayChildElement() {
2159 $_GET = array();
2160 $GLOBALS['HTTP_GET_VARS'] = array();
2161
2162 t3lib_div::_GETset(
2163 array('key1' => 'value1', 'key2' => 'value2'),
2164 'parentKey|childKey'
2165 );
2166
2167 $this->assertEquals(
2168 array(
2169 'parentKey' => array(
2170 'childKey' => array('key1' => 'value1', 'key2' => 'value2')
2171 )
2172 ),
2173 $GLOBALS['HTTP_GET_VARS']
2174 );
2175 }
2176
2177
2178 ///////////////////////////////
2179 // Tests concerning fixPermissions
2180 ///////////////////////////////
2181
2182 /**
2183 * @test
2184 */
2185 public function fixPermissionsSetsGroup() {
2186 if (TYPO3_OS == 'WIN') {
2187 $this->markTestSkipped('fixPermissionsSetsGroup() tests not available on Windows');
2188 }
2189 if (!function_exists('posix_getegid')) {
2190 $this->markTestSkipped('Function posix_getegid() not available, fixPermissionsSetsGroup() tests skipped');
2191 }
2192 if (posix_getegid() === -1) {
2193 $this->markTestSkipped(
2194 'The fixPermissionsSetsGroup() is not available on Mac OS because posix_getegid() always returns -1 on Mac OS.'
2195 );
2196 }
2197
2198 // Create and prepare test file
2199 $filename = PATH_site . 'typo3temp/' . uniqid('test_');
2200 t3lib_div::writeFileToTypo3tempDir($filename, '42');
2201
2202 $currentGroupId = posix_getegid();
2203
2204 // Set target group and run method
2205 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = $currentGroupId;
2206 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
2207
2208 clearstatcache();
2209 $resultFileGroup = filegroup($filename);
2210 unlink($filename);
2211
2212 $this->assertEquals($resultFileGroup, $currentGroupId);
2213 }
2214
2215 /**
2216 * @test
2217 */
2218 public function fixPermissionsSetsPermissionsToFile() {
2219 if (TYPO3_OS == 'WIN') {
2220 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2221 }
2222
2223 // Create and prepare test file
2224 $filename = PATH_site . 'typo3temp/' . uniqid('test_');
2225 t3lib_div::writeFileToTypo3tempDir($filename, '42');
2226 chmod($filename, 0742);
2227
2228 // Set target permissions and run method
2229 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2230 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
2231
2232 // Get actual permissions and clean up
2233 clearstatcache();
2234 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
2235 unlink($filename);
2236
2237 // Test if everything was ok
2238 $this->assertTrue($fixPermissionsResult);
2239 $this->assertEquals($resultFilePermissions, '0660');
2240 }
2241
2242 /**
2243 * @test
2244 */
2245 public function fixPermissionsSetsPermissionsToHiddenFile() {
2246 if (TYPO3_OS == 'WIN') {
2247 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2248 }
2249
2250 // Create and prepare test file
2251 $filename = PATH_site . 'typo3temp/' . uniqid('.test_');
2252 t3lib_div::writeFileToTypo3tempDir($filename, '42');
2253 chmod($filename, 0742);
2254
2255 // Set target permissions and run method
2256 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2257 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
2258
2259 // Get actual permissions and clean up
2260 clearstatcache();
2261 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
2262 unlink($filename);
2263
2264 // Test if everything was ok
2265 $this->assertTrue($fixPermissionsResult);
2266 $this->assertEquals($resultFilePermissions, '0660');
2267 }
2268
2269 /**
2270 * @test
2271 */
2272 public function fixPermissionsSetsPermissionsToDirectory() {
2273 if (TYPO3_OS == 'WIN') {
2274 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2275 }
2276
2277 // Create and prepare test directory
2278 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
2279 t3lib_div::mkdir($directory);
2280 chmod($directory, 1551);
2281
2282 // Set target permissions and run method
2283 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2284 $fixPermissionsResult = t3lib_div::fixPermissions($directory);
2285
2286 // Get actual permissions and clean up
2287 clearstatcache();
2288 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2289 t3lib_div::rmdir($directory);
2290
2291 // Test if everything was ok
2292 $this->assertTrue($fixPermissionsResult);
2293 $this->assertEquals($resultDirectoryPermissions, '0770');
2294 }
2295
2296 /**
2297 * @test
2298 */
2299 public function fixPermissionsSetsPermissionsToDirectoryWithTrailingSlash() {
2300 if (TYPO3_OS == 'WIN') {
2301 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2302 }
2303
2304 // Create and prepare test directory
2305 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
2306 t3lib_div::mkdir($directory);
2307 chmod($directory, 1551);
2308
2309 // Set target permissions and run method
2310 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2311 $fixPermissionsResult = t3lib_div::fixPermissions($directory . '/');
2312
2313 // Get actual permissions and clean up
2314 clearstatcache();
2315 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2316 t3lib_div::rmdir($directory);
2317
2318 // Test if everything was ok
2319 $this->assertTrue($fixPermissionsResult);
2320 $this->assertEquals($resultDirectoryPermissions, '0770');
2321 }
2322
2323 /**
2324 * @test
2325 */
2326 public function fixPermissionsSetsPermissionsToHiddenDirectory() {
2327 if (TYPO3_OS == 'WIN') {
2328 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2329 }
2330
2331 // Create and prepare test directory
2332 $directory = PATH_site . 'typo3temp/' . uniqid('.test_');
2333 t3lib_div::mkdir($directory);
2334 chmod($directory, 1551);
2335
2336 // Set target permissions and run method
2337 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2338 $fixPermissionsResult = t3lib_div::fixPermissions($directory);
2339
2340 // Get actual permissions and clean up
2341 clearstatcache();
2342 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2343 t3lib_div::rmdir($directory);
2344
2345 // Test if everything was ok
2346 $this->assertTrue($fixPermissionsResult);
2347 $this->assertEquals($resultDirectoryPermissions, '0770');
2348 }
2349
2350 /**
2351 * @test
2352 */
2353 public function fixPermissionsCorrectlySetsPermissionsRecursive() {
2354 if (TYPO3_OS == 'WIN') {
2355 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2356 }
2357
2358 // Create and prepare test directory and file structure
2359 $baseDirectory = PATH_site . 'typo3temp/' . uniqid('test_');
2360 t3lib_div::mkdir($baseDirectory);
2361 chmod($baseDirectory, 1751);
2362 t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/file', '42');
2363 chmod($baseDirectory . '/file', 0742);
2364 t3lib_div::mkdir($baseDirectory . '/foo');
2365 chmod($baseDirectory . '/foo', 1751);
2366 t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/foo/file', '42');
2367 chmod($baseDirectory . '/foo/file', 0742);
2368 t3lib_div::mkdir($baseDirectory . '/.bar');
2369 chmod($baseDirectory . '/.bar', 1751);
2370 // Use this if writeFileToTypo3tempDir is fixed to create hidden files in subdirectories
2371 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/.file', '42');
2372 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/..file2', '42');
2373 touch($baseDirectory . '/.bar/.file', '42');
2374 chmod($baseDirectory . '/.bar/.file', 0742);
2375 touch($baseDirectory . '/.bar/..file2', '42');
2376 chmod($baseDirectory . '/.bar/..file2', 0742);
2377
2378 // Set target permissions and run method
2379 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2380 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2381 $fixPermissionsResult = t3lib_div::fixPermissions($baseDirectory, TRUE);
2382
2383 // Get actual permissions
2384 clearstatcache();
2385 $resultBaseDirectoryPermissions = substr(decoct(fileperms($baseDirectory)), 1);
2386 $resultBaseFilePermissions = substr(decoct(fileperms($baseDirectory . '/file')), 2);
2387 $resultFooDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/foo')), 1);
2388 $resultFooFilePermissions = substr(decoct(fileperms($baseDirectory . '/foo/file')), 2);
2389 $resultBarDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/.bar')), 1);
2390 $resultBarFilePermissions = substr(decoct(fileperms($baseDirectory . '/.bar/.file')), 2);
2391 $resultBarFile2Permissions = substr(decoct(fileperms($baseDirectory . '/.bar/..file2')), 2);
2392
2393 // Clean up
2394 unlink($baseDirectory . '/file');
2395 unlink($baseDirectory . '/foo/file');
2396 unlink($baseDirectory . '/.bar/.file');
2397 unlink($baseDirectory . '/.bar/..file2');
2398 t3lib_div::rmdir($baseDirectory . '/foo');
2399 t3lib_div::rmdir($baseDirectory . '/.bar');
2400 t3lib_div::rmdir($baseDirectory);
2401
2402 // Test if everything was ok
2403 $this->assertTrue($fixPermissionsResult);
2404 $this->assertEquals($resultBaseDirectoryPermissions, '0770');
2405 $this->assertEquals($resultBaseFilePermissions, '0660');
2406 $this->assertEquals($resultFooDirectoryPermissions, '0770');
2407 $this->assertEquals($resultFooFilePermissions, '0660');
2408 $this->assertEquals($resultBarDirectoryPermissions, '0770');
2409 $this->assertEquals($resultBarFilePermissions, '0660');
2410 $this->assertEquals($resultBarFile2Permissions, '0660');
2411 }
2412
2413 /**
2414 * @test
2415 */
2416 public function fixPermissionsDoesNotSetPermissionsToNotAllowedPath() {
2417 if (TYPO3_OS == 'WIN') {
2418 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2419 }
2420
2421 // Create and prepare test file
2422 $filename = PATH_site . 'typo3temp/../typo3temp/' . uniqid('test_');
2423 touch($filename);
2424 chmod($filename, 0742);
2425
2426 // Set target permissions and run method
2427 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2428 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
2429
2430 // Get actual permissions and clean up
2431 clearstatcache();
2432 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
2433 unlink($filename);
2434
2435 // Test if everything was ok
2436 $this->assertFalse($fixPermissionsResult);
2437 }
2438
2439 /**
2440 * @test
2441 */
2442 public function fixPermissionsSetsPermissionsWithRelativeFileReference() {
2443 if (TYPO3_OS == 'WIN') {
2444 $this->markTestSkipped('fixPermissions() tests not available on Windows');
2445 }
2446
2447 $filename = 'typo3temp/' . uniqid('test_');
2448 t3lib_div::writeFileToTypo3tempDir(PATH_site . $filename, '42');
2449 chmod(PATH_site . $filename, 0742);
2450
2451 // Set target permissions and run method
2452 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
2453 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
2454
2455 // Get actual permissions and clean up
2456 clearstatcache();
2457 $resultFilePermissions = substr(decoct(fileperms(PATH_site . $filename)), 2);
2458 unlink(PATH_site . $filename);
2459
2460 // Test if everything was ok
2461 $this->assertTrue($fixPermissionsResult);
2462 $this->assertEquals($resultFilePermissions, '0660');
2463 }
2464
2465
2466 ///////////////////////////////
2467 // Tests concerning mkdir
2468 ///////////////////////////////
2469
2470 /**
2471 * @test
2472 */
2473 public function mkdirCreatesDirectory() {
2474 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
2475 $mkdirResult = t3lib_div::mkdir($directory);
2476 clearstatcache();
2477 $directoryCreated = is_dir($directory);
2478 @rmdir($directory);
2479 $this->assertTrue($mkdirResult);
2480 $this->assertTrue($directoryCreated);
2481 }
2482
2483 /**
2484 * @test
2485 */
2486 public function mkdirCreatesHiddenDirectory() {
2487 $directory = PATH_site . 'typo3temp/' . uniqid('.test_');
2488 $mkdirResult = t3lib_div::mkdir($directory);
2489 clearstatcache();
2490 $directoryCreated = is_dir($directory);
2491 @rmdir($directory);
2492 $this->assertTrue($mkdirResult);
2493 $this->assertTrue($directoryCreated);
2494 }
2495
2496 /**
2497 * @test
2498 */
2499 public function mkdirCreatesDirectoryWithTrailingSlash() {
2500 $directory = PATH_site . 'typo3temp/' . uniqid('test_') . '/';
2501 $mkdirResult = t3lib_div::mkdir($directory);
2502 clearstatcache();
2503 $directoryCreated = is_dir($directory);
2504 @rmdir($directory);
2505 $this->assertTrue($mkdirResult);
2506 $this->assertTrue($directoryCreated);
2507 }
2508
2509 /**
2510 * @test
2511 */
2512 public function mkdirSetsPermissionsOfCreatedDirectory() {
2513 if (TYPO3_OS == 'WIN') {
2514 $this->markTestSkipped('mkdirSetsPermissionsOfCreatedDirectory() test not available on Windows');
2515 }
2516
2517 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
2518 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
2519 t3lib_div::mkdir($directory);
2520 clearstatcache();
2521 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2522 rmdir($directory);
2523 $this->assertEquals($resultDirectoryPermissions, '0770');
2524 }
2525
2526
2527 ///////////////////////////////
2528 // Tests concerning mkdir_deep
2529 ///////////////////////////////
2530
2531 /**
2532 * @test
2533 */
2534 public function mkdirDeepCreatesDirectory() {
2535 $directory = 'typo3temp/' . uniqid('test_');
2536 t3lib_div::mkdir_deep(PATH_site, $directory);
2537 $isDirectoryCreated = is_dir(PATH_site . $directory);
2538 rmdir(PATH_site . $directory);
2539 $this->assertTrue($isDirectoryCreated);
2540 }
2541
2542 /**
2543 * @test
2544 */
2545 public function mkdirDeepCreatesSubdirectoriesRecursive() {
2546 $directory = 'typo3temp/' . uniqid('test_');
2547 $subDirectory = $directory . '/foo';
2548 t3lib_div::mkdir_deep(PATH_site, $subDirectory);
2549 $isDirectoryCreated = is_dir(PATH_site . $subDirectory);
2550 rmdir(PATH_site . $subDirectory);
2551 rmdir(PATH_site . $directory);
2552 $this->assertTrue($isDirectoryCreated);
2553 }
2554
2555 /**
2556 * @test
2557 */
2558 public function mkdirDeepFixesPermissionsOnNewDirectory() {
2559 if (TYPO3_OS == 'WIN') {
2560 $this->markTestSkipped('mkdirDeepFixesPermissionsOnNewDirectory() test not available on Windows.');
2561 }
2562
2563 $directory = uniqid('mkdirdeeptest_');
2564 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0750';
2565 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/', $directory);
2566 clearstatcache();
2567 $resultDirectoryPermissions = substr(decoct(fileperms(PATH_site . 'typo3temp/' . $directory)), -3, 3);
2568 @rmdir(PATH_site . 'typo3temp/' . $directory);
2569 $this->assertEquals($resultDirectoryPermissions, '750');
2570 }
2571
2572 /**
2573 * @test
2574 */
2575 public function mkdirDeepDoesNotChangePermissionsOfExistingSubDirectories() {
2576 if (TYPO3_OS == 'WIN') {
2577 $this->markTestSkipped('mkdirDeepDoesNotChangePermissionsOfExistingSubDirectories() test not available on Windows.');
2578 }
2579
2580 $baseDirectory = PATH_site . 'typo3temp/';
2581 $existingDirectory = uniqid('test_existing_') . '/';
2582 $newSubDirectory = uniqid('test_new_');
2583 @mkdir($baseDirectory . $existingDirectory);
2584 chmod($baseDirectory . $existingDirectory, 0742);
2585 t3lib_div::mkdir_deep($baseDirectory, $existingDirectory . $newSubDirectory);
2586 $resultExistingDirectoryPermissions = substr(decoct(fileperms($baseDirectory . $existingDirectory)), 2);
2587 @rmdir($baseDirectory, $existingDirectory . $newSubDirectory);
2588 @rmdir($baseDirectory, $existingDirectory);
2589 $this->assertEquals($resultExistingDirectoryPermissions, '0742');
2590 }
2591
2592 /**
2593 * @test
2594 */
2595 public function mkdirDeepCreatesDirectoryInVfsStream() {
2596 if (!class_exists('\vfsStreamWrapper')) {
2597 $this->markTestSkipped('mkdirDeepCreatesDirectoryInVfsStream() test not available with this phpunit version.');
2598 }
2599
2600 \vfsStreamWrapper::register();
2601 $baseDirectory = uniqid('test_');
2602 \vfsStreamWrapper::setRoot(new \vfsStreamDirectory($baseDirectory));
2603 t3lib_div::mkdir_deep('vfs://' . $baseDirectory . '/', 'sub');
2604 $this->assertTrue(is_dir('vfs://' . $baseDirectory . '/sub'));
2605 }
2606
2607 /**
2608 * @test
2609 * @expectedException \RuntimeException
2610 */
2611 public function mkdirDeepThrowsExceptionIfDirectoryCreationFails() {
2612 t3lib_div::mkdir_deep('http://localhost');
2613 }
2614
2615 /**
2616 * @test
2617 * @expectedException \InvalidArgumentException
2618 */
2619 public function mkdirDeepThrowsExceptionIfBaseDirectoryIsNotOfTypeString() {
2620 t3lib_div::mkdir_deep(array());
2621 }
2622
2623 /**
2624 * @test
2625 * @expectedException \InvalidArgumentException
2626 */
2627 public function mkdirDeepThrowsExceptionIfDeepDirectoryIsNotOfTypeString() {
2628 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/foo', array());
2629 }
2630
2631
2632 ///////////////////////////////
2633 // Tests concerning unQuoteFilenames
2634 ///////////////////////////////
2635
2636 /**
2637 * Data provider for ImageMagick shell commands
2638 * @see explodeAndUnquoteImageMagickCommands
2639 */
2640 public function imageMagickCommandsDataProvider() {
2641 return array(
2642 // Some theoretical tests first
2643 array(
2644 'aa bb "cc" "dd"',
2645 array('aa', 'bb', '"cc"', '"dd"'),
2646 array('aa', 'bb', 'cc', 'dd'),
2647 ),
2648 array(
2649 'aa bb "cc dd"',
2650 array('aa', 'bb', '"cc dd"'),
2651 array('aa', 'bb', 'cc dd'),
2652 ),
2653 array(
2654 '\'aa bb\' "cc dd"',
2655 array('\'aa bb\'', '"cc dd"'),
2656 array('aa bb', 'cc dd'),
2657 ),
2658 array(
2659 '\'aa bb\' cc "dd"',
2660 array('\'aa bb\'', 'cc', '"dd"'),
2661 array('aa bb', 'cc', 'dd'),
2662 ),
2663 // Now test against some real world examples
2664 array(
2665 '/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"',
2666 array(
2667 '/opt/local/bin/gm.exe',
2668 'convert',
2669 '+profile',
2670 '\'*\'',
2671 '-geometry',
2672 '170x136!',
2673 '-negate',
2674 '"C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2675 '"C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2676 ),
2677 array(
2678 '/opt/local/bin/gm.exe',
2679 'convert',
2680 '+profile',
2681 '*',
2682 '-geometry',
2683 '170x136!',
2684 '-negate',
2685 'C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2686 'C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2687 ),
2688 ),
2689 array(
2690 '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"',
2691 array(
2692 'C:/opt/local/bin/gm.exe',
2693 'convert',
2694 '+profile',
2695 '\'*\'',
2696 '-geometry',
2697 '170x136!',
2698 '-negate',
2699 '"C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2700 '"C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2701 ),
2702 array(
2703 'C:/opt/local/bin/gm.exe',
2704 'convert',
2705 '+profile',
2706 '*',
2707 '-geometry',
2708 '170x136!',
2709 '-negate',
2710 'C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2711 'C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2712 ),
2713 ),
2714 array(
2715 '/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"',
2716 array(
2717 '/usr/bin/gm',
2718 'convert',
2719 '+profile',
2720 '\'*\'',
2721 '-geometry',
2722 '170x136!',
2723 '-negate',
2724 '"/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2725 '"/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2726 ),
2727 array(
2728 '/usr/bin/gm',
2729 'convert',
2730 '+profile',
2731 '*',
2732 '-geometry',
2733 '170x136!',
2734 '-negate',
2735 '/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2736 '/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2737 ),
2738 ),
2739 array(
2740 '/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"',
2741 array(
2742 '/usr/bin/gm',
2743 'convert',
2744 '+profile',
2745 '\'*\'',
2746 '-geometry',
2747 '170x136!',
2748 '-negate',
2749 '"/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2750 '"/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2751 ),
2752 array(
2753 '/usr/bin/gm',
2754 'convert',
2755 '+profile',
2756 '*',
2757 '-geometry',
2758 '170x136!',
2759 '-negate',
2760 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2761 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2762 ),
2763 ),
2764 array(
2765 '/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\'',
2766 array(
2767 '/usr/bin/gm',
2768 'convert',
2769 '+profile',
2770 '\'*\'',
2771 '-geometry',
2772 '170x136!',
2773 '-negate',
2774 '\'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]\'',
2775 '\'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif\''
2776 ),
2777 array(
2778 '/usr/bin/gm',
2779 'convert',
2780 '+profile',
2781 '*',
2782 '-geometry',
2783 '170x136!',
2784 '-negate',
2785 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2786 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2787 ),
2788 ),
2789 );
2790 }
2791
2792 /**
2793 * Tests if the commands are exploded and unquoted correctly
2794 *
2795 * @dataProvider imageMagickCommandsDataProvider
2796 * @test
2797 */
2798 public function explodeAndUnquoteImageMagickCommands($source, $expectedQuoted, $expectedUnquoted) {
2799 $actualQuoted = t3lib_div::unQuoteFilenames($source);
2800 $acutalUnquoted = t3lib_div::unQuoteFilenames($source, TRUE);
2801
2802 $this->assertEquals($expectedQuoted, $actualQuoted, 'The exploded command does not match the expected');
2803 $this->assertEquals($expectedUnquoted, $acutalUnquoted, 'The exploded and unquoted command does not match the expected');
2804 }
2805
2806
2807 ///////////////////////////////
2808 // Tests concerning split_fileref
2809 ///////////////////////////////
2810
2811 /**
2812 * @test
2813 */
2814 public function splitFileRefReturnsFileTypeNotForFolders(){
2815 $directoryName = uniqid('test_') . '.com';
2816 $directoryPath = PATH_site . 'typo3temp/';
2817 $directory = $directoryPath . $directoryName;
2818 mkdir($directory, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']));
2819
2820 $fileInfo = t3lib_div::split_fileref($directory);
2821
2822 $directoryCreated = is_dir($directory);
2823 rmdir($directory);
2824
2825 $this->assertTrue($directoryCreated);
2826 $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
2827 $this->assertEquals($directoryPath, $fileInfo['path']);
2828 $this->assertEquals($directoryName, $fileInfo['file']);
2829 $this->assertEquals($directoryName, $fileInfo['filebody']);
2830 $this->assertEquals('', $fileInfo['fileext']);
2831 $this->assertArrayNotHasKey('realFileext', $fileInfo);
2832 }
2833
2834 /**
2835 * @test
2836 */
2837 public function splitFileRefReturnsFileTypeForFilesWithoutPathSite() {
2838 $testFile = 'fileadmin/media/someFile.png';
2839
2840 $fileInfo = t3lib_div::split_fileref($testFile);
2841 $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
2842 $this->assertEquals('fileadmin/media/', $fileInfo['path']);
2843 $this->assertEquals('someFile.png', $fileInfo['file']);
2844 $this->assertEquals('someFile', $fileInfo['filebody']);
2845 $this->assertEquals('png', $fileInfo['fileext']);
2846 }
2847
2848
2849 /////////////////////////////
2850 // Tests concerning dirname
2851 /////////////////////////////
2852
2853 /**
2854 * @see dirnameWithDataProvider
2855 *
2856 * @return array<array>
2857 */
2858 public function dirnameDataProvider() {
2859 return array(
2860 'absolute path with multiple part and file' => array('/dir1/dir2/script.php', '/dir1/dir2'),
2861 'absolute path with one part' => array('/dir1/', '/dir1'),
2862 'absolute path to file without extension' => array('/dir1/something', '/dir1'),
2863 'relative path with one part and file' => array('dir1/script.php', 'dir1'),
2864 'relative one-character path with one part and file' => array('d/script.php', 'd'),
2865 'absolute zero-part path with file' => array('/script.php', ''),
2866 'empty string' => array('', ''),
2867 );
2868 }
2869
2870 /**
2871 * @test
2872 *
2873 * @dataProvider dirnameDataProvider
2874 *
2875 * @param string $input the input for dirname
2876 * @param string $expectedValue the expected return value expected from dirname
2877 */
2878 public function dirnameWithDataProvider($input, $expectedValue) {
2879 $this->assertEquals(
2880 $expectedValue,
2881 t3lib_div::dirname($input)
2882 );
2883 }
2884
2885
2886 /////////////////////////////////////
2887 // Tests concerning resolveBackPath
2888 /////////////////////////////////////
2889
2890 /**
2891 * @see resolveBackPathWithDataProvider
2892 *
2893 * @return array<array>
2894 */
2895 public function resolveBackPathDataProvider() {
2896 return array(
2897 'empty path' => array('', ''),
2898 'this directory' => array('./', './'),
2899 'relative directory without ..' => array('dir1/dir2/dir3/', 'dir1/dir2/dir3/'),
2900 'relative path without ..' => array('dir1/dir2/script.php', 'dir1/dir2/script.php'),
2901 'absolute directory without ..' => array('/dir1/dir2/dir3/', '/dir1/dir2/dir3/'),
2902 'absolute path without ..' => array('/dir1/dir2/script.php', '/dir1/dir2/script.php'),
2903 'only one directory upwards without trailing slash' => array('..', '..'),
2904 'only one directory upwards with trailing slash' => array('../', '../'),
2905 'one level with trailing ..' => array('dir1/..', ''),
2906 'one level with trailing ../' => array('dir1/../', ''),
2907 'two levels with trailing ..' => array('dir1/dir2/..', 'dir1'),
2908 'two levels with trailing ../' => array('dir1/dir2/../', 'dir1/'),
2909 'leading ../ without trailing /' => array('../dir1', '../dir1'),
2910 'leading ../ with trailing /' => array('../dir1/', '../dir1/'),
2911 'leading ../ and inside path' => array('../dir1/dir2/../dir3/', '../dir1/dir3/'),
2912 'one times ../ in relative directory' => array('dir1/../dir2/', 'dir2/'),
2913 'one times ../ in absolute directory' => array('/dir1/../dir2/', '/dir2/'),
2914 'one times ../ in relative path' => array('dir1/../dir2/script.php', 'dir2/script.php'),
2915 'one times ../ in absolute path' => array('/dir1/../dir2/script.php', '/dir2/script.php'),
2916 'consecutive ../' => array('dir1/dir2/dir3/../../../dir4', 'dir4'),
2917 'distrubuted ../ with trailing /' => array('dir1/../dir2/dir3/../', 'dir2/'),
2918 'distributed ../ without trailing /' => array('dir1/../dir2/dir3/..', 'dir2'),
2919 'multiple distributed and consecutive ../ together' => array('dir1/dir2/dir3/dir4/../../dir5/dir6/dir7/../dir8/', 'dir1/dir2/dir5/dir6/dir8/'),
2920 'multiple distributed and consecutive ../ together' => array('dir1/dir2/dir3/dir4/../../dir5/dir6/dir7/../dir8/', 'dir1/dir2/dir5/dir6/dir8/'),
2921 'dirname with leading ..' => array('dir1/..dir2/dir3/', 'dir1/..dir2/dir3/'),
2922 'dirname with trailing ..' => array('dir1/dir2../dir3/', 'dir1/dir2../dir3/'),
2923 'more times upwards than downwards in directory' => array('dir1/../../', '../'),
2924 'more times upwards than downwards in path' => array('dir1/../../script.php', '../script.php'),
2925 );
2926 }
2927
2928 /**
2929 * @test
2930 *
2931 * @dataProvider resolveBackPathDataProvider
2932 *
2933 * @param string $input the input for resolveBackPath
2934 * @param $expectedValue the expected return value from resolveBackPath
2935 */
2936 public function resolveBackPathWithDataProvider($input, $expectedValue) {
2937 $this->assertEquals(
2938 $expectedValue,
2939 t3lib_div::resolveBackPath($input)
2940 );
2941 }
2942
2943
2944 /////////////////////////////////////////////////////////////////////////////////////
2945 // Tests concerning makeInstance, setSingletonInstance, addInstance, purgeInstances
2946 /////////////////////////////////////////////////////////////////////////////////////
2947
2948 /**
2949 * @test
2950 * @expectedException InvalidArgumentException
2951 */
2952 public function makeInstanceWithEmptyClassNameThrowsException() {
2953 t3lib_div::makeInstance('');
2954 }
2955
2956 /**
2957 * @test
2958 * @expectedException InvalidArgumentException
2959 */
2960 public function makeInstanceWithNullClassNameThrowsException() {
2961 t3lib_div::makeInstance(NULL);
2962 }
2963
2964 /**
2965 * @test
2966 * @expectedException InvalidArgumentException
2967 */
2968 public function makeInstanceWithZeroStringClassNameThrowsException() {
2969 t3lib_div::makeInstance(0);
2970 }
2971
2972 /**
2973 * @test
2974 * @expectedException InvalidArgumentException
2975 */
2976 public function makeInstanceWithEmptyArrayThrowsException() {
2977 t3lib_div::makeInstance(array());
2978 }
2979
2980 /**
2981 * @test
2982 * @expectedException InvalidArgumentException
2983 */
2984 public function makeInstanceWithNonEmptyArrayThrowsException() {
2985 t3lib_div::makeInstance(array('foo'));
2986 }
2987
2988 /**
2989 * @test
2990 */
2991 public function makeInstanceReturnsClassInstance() {
2992 $className = get_class($this->getMock('foo'));
2993
2994 $this->assertTrue(
2995 t3lib_div::makeInstance($className) instanceof $className
2996 );
2997 }
2998
2999 /**
3000 * @test
3001 */
3002 public function makeInstancePassesParametersToConstructor() {
3003 $className = 'testingClass' . uniqid();
3004 if (!class_exists($className, FALSE)) {
3005 eval(
3006 'class ' . $className . ' {' .
3007 ' public $constructorParameter1;' .
3008 ' public $constructorParameter2;' .
3009 ' public function __construct($parameter1, $parameter2) {' .
3010 ' $this->constructorParameter1 = $parameter1;' .
3011 ' $this->constructorParameter2 = $parameter2;' .
3012 ' }' .
3013 '}'
3014 );
3015 }
3016
3017 $instance = t3lib_div::makeInstance($className, 'one parameter', 'another parameter');
3018
3019 $this->assertEquals(
3020 'one parameter',
3021 $instance->constructorParameter1,
3022 'The first constructor parameter has not been set.'
3023 );
3024 $this->assertEquals(
3025 'another parameter',
3026 $instance->constructorParameter2,
3027 'The second constructor parameter has not been set.'
3028 );
3029 }
3030
3031 /**
3032 * @test
3033 */
3034 public function makeInstanceCalledTwoTimesForNonSingletonClassReturnsDifferentInstances() {
3035 $className = get_class($this->getMock('foo'));
3036
3037 $this->assertNotSame(
3038 t3lib_div::makeInstance($className),
3039 t3lib_div::makeInstance($className)
3040 );
3041 }
3042
3043 /**
3044 * @test
3045 */
3046 public function makeInstanceCalledTwoTimesForSingletonClassReturnsSameInstance() {
3047 $className = get_class($this->getMock('t3lib_Singleton'));
3048
3049 $this->assertSame(
3050 t3lib_div::makeInstance($className),
3051 t3lib_div::makeInstance($className)
3052 );
3053 }
3054
3055 /**
3056 * @test
3057 */
3058 public function makeInstanceCalledTwoTimesForSingletonClassWithPurgeInstancesInbetweenReturnsDifferentInstances() {
3059 $className = get_class($this->getMock('t3lib_Singleton'));
3060
3061 $instance = t3lib_div::makeInstance($className);
3062 t3lib_div::purgeInstances();
3063
3064 $this->assertNotSame(
3065 $instance,
3066 t3lib_div::makeInstance($className)
3067 );
3068 }
3069
3070 /**
3071 * @test
3072 * @expectedException InvalidArgumentException
3073 */
3074 public function setSingletonInstanceForEmptyClassNameThrowsException() {
3075 $instance = $this->getMock('t3lib_Singleton');
3076
3077 t3lib_div::setSingletonInstance('', $instance);
3078 }
3079
3080 /**
3081 * @test
3082 * @expectedException InvalidArgumentException
3083 */
3084 public function setSingletonInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
3085 $instance = $this->getMock('t3lib_Singleton', array('foo'));
3086 $singletonClassName = get_class($this->getMock('t3lib_Singleton'));
3087
3088 t3lib_div::setSingletonInstance($singletonClassName, $instance);
3089 }
3090
3091 /**
3092 * @test
3093 */
3094 public function setSingletonInstanceMakesMakeInstanceReturnThatInstance() {
3095 $instance = $this->getMock('t3lib_Singleton');
3096 $singletonClassName = get_class($instance);
3097
3098 t3lib_div::setSingletonInstance($singletonClassName, $instance);
3099
3100 $this->assertSame(
3101 $instance,
3102 t3lib_div::makeInstance($singletonClassName)
3103 );
3104 }
3105
3106 /**
3107 * @test
3108 */
3109 public function setSingletonInstanceCalledTwoTimesMakesMakeInstanceReturnLastSetInstance() {
3110 $instance1 = $this->getMock('t3lib_Singleton');
3111 $singletonClassName = get_class($instance1);
3112 $instance2 = new $singletonClassName();
3113
3114 t3lib_div::setSingletonInstance($singletonClassName, $instance1);
3115 t3lib_div::setSingletonInstance($singletonClassName, $instance2);
3116
3117 $this->assertSame(
3118 $instance2,
3119 t3lib_div::makeInstance($singletonClassName)
3120 );
3121 }
3122
3123 /**
3124 * @test
3125 * @expectedException InvalidArgumentException
3126 */
3127 public function addInstanceForEmptyClassNameThrowsException() {
3128 $instance = $this->getMock('foo');
3129
3130 t3lib_div::addInstance('', $instance);
3131 }
3132
3133 /**
3134 * @test
3135 * @expectedException InvalidArgumentException
3136 */
3137 public function addInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
3138 $instance = $this->getMock('foo', array('bar'));
3139 $singletonClassName = get_class($this->getMock('foo'));
3140
3141 t3lib_div::addInstance($singletonClassName, $instance);
3142 }
3143
3144 /**
3145 * @test
3146 * @expectedException InvalidArgumentException
3147 */
3148 public function addInstanceWithSingletonInstanceThrowsException() {
3149 $instance = $this->getMock('t3lib_Singleton');
3150
3151 t3lib_div::addInstance(get_class($instance), $instance);
3152 }
3153
3154 /**
3155 * @test
3156 */
3157 public function addInstanceMakesMakeInstanceReturnThatInstance() {
3158 $instance = $this->getMock('foo');
3159 $className = get_class($instance);
3160
3161 t3lib_div::addInstance($className, $instance);
3162
3163 $this->assertSame(
3164 $instance,
3165 t3lib_div::makeInstance($className)
3166 );
3167 }
3168
3169 /**
3170 * @test
3171 */
3172 public function makeInstanceCalledTwoTimesAfterAddInstanceReturnTwoDifferentInstances() {
3173 $instance = $this->getMock('foo');
3174 $className = get_class($instance);
3175
3176 t3lib_div::addInstance($className, $instance);
3177
3178 $this->assertNotSame(
3179 t3lib_div::makeInstance($className),
3180 t3lib_div::makeInstance($className)
3181 );
3182 }
3183
3184 /**
3185 * @test
3186 */
3187 public function addInstanceCalledTwoTimesMakesMakeInstanceReturnBothInstancesInAddingOrder() {
3188 $instance1 = $this->getMock('foo');
3189 $className = get_class($instance1);
3190 t3lib_div::addInstance($className, $instance1);
3191
3192 $instance2 = new $className();
3193 t3lib_div::addInstance($className, $instance2);
3194
3195 $this->assertSame(
3196 $instance1,
3197 t3lib_div::makeInstance($className),
3198 'The first returned instance does not match the first added instance.'
3199 );
3200 $this->assertSame(
3201 $instance2,
3202 t3lib_div::makeInstance($className),
3203 'The second returned instance does not match the second added instance.'
3204 );
3205 }
3206
3207 /**
3208 * @test
3209 */
3210 public function purgeInstancesDropsAddedInstance() {
3211 $instance = $this->getMock('foo');
3212 $className = get_class($instance);
3213
3214 t3lib_div::addInstance($className, $instance);
3215 t3lib_div::purgeInstances();
3216
3217 $this->assertNotSame(
3218 $instance,
3219 t3lib_div::makeInstance($className)
3220 );
3221 }
3222
3223 /**
3224 * Data provider for validPathStrDetectsInvalidCharacters.
3225 *
3226 * @return array
3227 */
3228 public function validPathStrInvalidCharactersDataProvider() {
3229 return array(
3230 'double slash in path' => array('path//path'),
3231 'backslash in path' => array('path\\path'),
3232 'directory up in path' => array('path/../path'),
3233 'directory up at the beginning' => array('../path'),
3234 'NUL character in path' => array("path\x00path"),
3235 'BS character in path' => array("path\x08path"),
3236 );
3237 }
3238
3239 /**
3240 * Tests whether invalid characters are detected.
3241 *
3242 * @param string $path
3243 * @dataProvider validPathStrInvalidCharactersDataProvider
3244 * @test
3245 */
3246 public function validPathStrDetectsInvalidCharacters($path) {
3247 $this->assertNull(t3lib_div::validPathStr($path));
3248 }
3249
3250 /**
3251 * Tests whether verifyFilenameAgainstDenyPattern detects the NULL character.
3252 *
3253 * @test
3254 */
3255 public function verifyFilenameAgainstDenyPatternDetectsNullCharacter() {
3256 $this->assertFalse(t3lib_div::verifyFilenameAgainstDenyPattern("image\x00.gif"));
3257 }
3258
3259
3260 /////////////////////////////////////////////////////////////////////////////////////
3261 // Tests concerning sysLog
3262 /////////////////////////////////////////////////////////////////////////////////////
3263
3264 /**
3265 * @test
3266 */
3267 public function syslogFixesPermissionsOnFileIfUsingFileLogging() {
3268 if (TYPO3_OS == 'WIN') {
3269 $this->markTestSkipped('syslogFixesPermissionsOnFileIfUsingFileLogging() test not available on Windows.');
3270 }
3271
3272 // Fake all required settings
3273 $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLogLevel'] = 0;
3274 $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLogInit'] = TRUE;
3275 unset($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['t3lib/class.t3lib_div.php']['systemLog']);
3276 $testLogFilename = PATH_site . 'typo3temp/' . uniqid('test_') . '.txt';
3277 $GLOBALS['TYPO3_CONF_VARS']['SYS']['systemLog'] = 'file,' . $testLogFilename . ',0';
3278 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0777';
3279
3280 // Call method, get actual permissions and clean up
3281 t3lib_div::syslog('testLog', 'test', 1);
3282 clearstatcache();
3283 $resultFilePermissions = substr(decoct(fileperms($testLogFilename)), 2);
3284 t3lib_div::unlink_tempfile($testLogFilename);
3285
3286 $this->assertEquals($resultFilePermissions, '0777');
3287 }
3288
3289 /**
3290 * @test
3291 */
3292 public function deprecationLogFixesPermissionsOnLogFile<