[TASK] Additional unit tests for t3lib_div::mkdir and mkdir_deep
[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 $oldUmask = umask(023);
2519 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0772';
2520 t3lib_div::mkdir($directory);
2521 clearstatcache();
2522 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
2523 umask($oldUmask);
2524 rmdir($directory);
2525 $this->assertEquals($resultDirectoryPermissions, '0772');
2526 }
2527
2528 /**
2529 * @test
2530 */
2531 public function mkdirSetsGroupOwnershipOfCreatedDirectory() {
2532 $swapGroup = $this->checkGroups(__FUNCTION__);
2533 if ($swapGroup !== FALSE) {
2534 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = $swapGroup;
2535 $directory = uniqid('mkdirtest_');
2536 t3lib_div::mkdir(PATH_site . 'typo3temp/' . $directory);
2537 clearstatcache();
2538 $resultDirectoryGroupInfo = posix_getgrgid((filegroup(PATH_site . 'typo3temp/' . $directory)));
2539 $resultDirectoryGroup = $resultDirectoryGroupInfo['name'];
2540 @rmdir(PATH_site . 'typo3temp/' . $directory);
2541 $this->assertEquals($resultDirectoryGroup, $swapGroup);
2542 }
2543 }
2544
2545 ///////////////////////////////
2546 // Helper function for filesystem ownership tests
2547 ///////////////////////////////
2548
2549 /**
2550 * Check if test on filesystem group ownership can be done in this environment
2551 * If so, return second group of webserver user
2552 * @param string calling method name
2553 * @return mixed FALSE if test cannot be run, string name of the second group of webserver user
2554 */
2555 private function checkGroups($methodName) {
2556 if (TYPO3_OS == 'WIN') {
2557 $this->markTestSkipped($methodName . '() test not available on Windows.');
2558 return FALSE;
2559 }
2560
2561 $groups = posix_getgroups();
2562 if (count($groups) <= 1) {
2563 $this->markTestSkipped($methodName . '() test cannot be done when the web server user is only member of 1 group.');
2564 return FALSE;
2565 }
2566 $groupInfo = posix_getgrgid($groups[1]);
2567 return $groupInfo['name'];
2568 }
2569
2570 ///////////////////////////////
2571 // Tests concerning mkdir_deep
2572 ///////////////////////////////
2573
2574 /**
2575 * @test
2576 */
2577 public function mkdirDeepCreatesDirectory() {
2578 $directory = 'typo3temp/' . uniqid('test_');
2579 t3lib_div::mkdir_deep(PATH_site, $directory);
2580 $isDirectoryCreated = is_dir(PATH_site . $directory);
2581 rmdir(PATH_site . $directory);
2582 $this->assertTrue($isDirectoryCreated);
2583 }
2584
2585 /**
2586 * @test
2587 */
2588 public function mkdirDeepCreatesSubdirectoriesRecursive() {
2589 $directory = 'typo3temp/' . uniqid('test_');
2590 $subDirectory = $directory . '/foo';
2591 t3lib_div::mkdir_deep(PATH_site, $subDirectory);
2592 $isDirectoryCreated = is_dir(PATH_site . $subDirectory);
2593 rmdir(PATH_site . $subDirectory);
2594 rmdir(PATH_site . $directory);
2595 $this->assertTrue($isDirectoryCreated);
2596 }
2597
2598 /**
2599 * @test
2600 */
2601 public function mkdirDeepFixesPermissionsOfCreatedDirectory() {
2602 if (TYPO3_OS == 'WIN') {
2603 $this->markTestSkipped('mkdirDeepFixesPermissionsOfCreatedDirectory() test not available on Windows.');
2604 }
2605
2606 $directory = uniqid('mkdirdeeptest_');
2607 $oldUmask = umask(023);
2608 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0777';
2609 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/', $directory);
2610 clearstatcache();
2611 $resultDirectoryPermissions = substr(decoct(fileperms(PATH_site . 'typo3temp/' . $directory)), -3, 3);
2612 @rmdir(PATH_site . 'typo3temp/' . $directory);
2613 umask($oldUmask);
2614 $this->assertEquals($resultDirectoryPermissions, '777');
2615 }
2616
2617 /**
2618 * @test
2619 */
2620 public function mkdirDeepFixesPermissionsOnNewParentDirectory() {
2621 if (TYPO3_OS == 'WIN') {
2622 $this->markTestSkipped('mkdirDeepFixesPermissionsOnNewParentDirectory() test not available on Windows.');
2623 }
2624
2625 $directory = uniqid('mkdirdeeptest_');
2626 $subDirectory = $directory . '/bar';
2627 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0777';
2628 $oldUmask = umask(023);
2629 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/', $subDirectory);
2630 clearstatcache();
2631 $resultDirectoryPermissions = substr(decoct(fileperms(PATH_site . 'typo3temp/' . $directory)), -3, 3);
2632 @rmdir(PATH_site . 'typo3temp/' . $subDirectory);
2633 @rmdir(PATH_site . 'typo3temp/' . $directory);
2634 umask($oldUmask);
2635 $this->assertEquals($resultDirectoryPermissions, '777');
2636 }
2637
2638 /**
2639 * @test
2640 */
2641 public function mkdirDeepDoesNotChangePermissionsOfExistingSubDirectories() {
2642 if (TYPO3_OS == 'WIN') {
2643 $this->markTestSkipped('mkdirDeepDoesNotChangePermissionsOfExistingSubDirectories() test not available on Windows.');
2644 }
2645
2646 $baseDirectory = PATH_site . 'typo3temp/';
2647 $existingDirectory = uniqid('test_existing_') . '/';
2648 $newSubDirectory = uniqid('test_new_');
2649 @mkdir($baseDirectory . $existingDirectory);
2650 chmod($baseDirectory . $existingDirectory, 0742);
2651 t3lib_div::mkdir_deep($baseDirectory, $existingDirectory . $newSubDirectory);
2652 $resultExistingDirectoryPermissions = substr(decoct(fileperms($baseDirectory . $existingDirectory)), 2);
2653 @rmdir($baseDirectory, $existingDirectory . $newSubDirectory);
2654 @rmdir($baseDirectory, $existingDirectory);
2655 $this->assertEquals($resultExistingDirectoryPermissions, '0742');
2656 }
2657
2658 /**
2659 * @test
2660 */
2661 public function mkdirDeepSetsGroupOwnershipOfCreatedDirectory() {
2662 $swapGroup = $this->checkGroups(__FUNCTION__);
2663 if ($swapGroup!==FALSE) {
2664 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = $swapGroup;
2665 $directory = uniqid('mkdirdeeptest_');
2666 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/', $directory);
2667 clearstatcache();
2668 $resultDirectoryGroupInfo = posix_getgrgid((filegroup(PATH_site . 'typo3temp/' . $directory)));
2669 $resultDirectoryGroup = $resultDirectoryGroupInfo['name'];
2670 @rmdir(PATH_site . 'typo3temp/' . $directory);
2671 $this->assertEquals($resultDirectoryGroup, $swapGroup);
2672 }
2673 }
2674
2675 /**
2676 * @test
2677 */
2678 public function mkdirDeepSetsGroupOwnershipOfCreatedParentDirectory() {
2679 $swapGroup = $this->checkGroups(__FUNCTION__);
2680 if ($swapGroup!==FALSE) {
2681 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = $swapGroup;
2682 $directory = uniqid('mkdirdeeptest_');
2683 $subDirectory = $directory . '/bar';
2684 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/', $subDirectory);
2685 clearstatcache();
2686 $resultDirectoryGroupInfo = posix_getgrgid((filegroup(PATH_site . 'typo3temp/' . $directory)));
2687 $resultDirectoryGroup = $resultDirectoryGroupInfo['name'];
2688 @rmdir(PATH_site . 'typo3temp/' . $subDirectory);
2689 @rmdir(PATH_site . 'typo3temp/' . $directory);
2690 $this->assertEquals($resultDirectoryGroup, $swapGroup);
2691 }
2692 }
2693
2694 /**
2695 * @test
2696 */
2697 public function mkdirDeepSetsGroupOwnershipOnNewSubDirectory() {
2698 $swapGroup = $this->checkGroups(__FUNCTION__);
2699 if ($swapGroup!==FALSE) {
2700 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = $swapGroup;
2701 $directory = uniqid('mkdirdeeptest_');
2702 $subDirectory = $directory . '/bar';
2703 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/', $subDirectory);
2704 clearstatcache();
2705 $resultDirectoryGroupInfo = posix_getgrgid((filegroup(PATH_site . 'typo3temp/' . $subDirectory)));
2706 $resultDirectoryGroup = $resultDirectoryGroupInfo['name'];
2707 @rmdir(PATH_site . 'typo3temp/' . $subDirectory);
2708 @rmdir(PATH_site . 'typo3temp/' . $directory);
2709 $this->assertEquals($resultDirectoryGroup, $swapGroup);
2710 }
2711 }
2712
2713 /**
2714 * @test
2715 */
2716 public function mkdirDeepCreatesDirectoryInVfsStream() {
2717 if (!class_exists('\vfsStreamWrapper')) {
2718 $this->markTestSkipped('mkdirDeepCreatesDirectoryInVfsStream() test not available with this phpunit version.');
2719 }
2720
2721 \vfsStreamWrapper::register();
2722 $baseDirectory = uniqid('test_');
2723 \vfsStreamWrapper::setRoot(new \vfsStreamDirectory($baseDirectory));
2724 t3lib_div::mkdir_deep('vfs://' . $baseDirectory . '/', 'sub');
2725 $this->assertTrue(is_dir('vfs://' . $baseDirectory . '/sub'));
2726 }
2727
2728 /**
2729 * @test
2730 * @expectedException \RuntimeException
2731 */
2732 public function mkdirDeepThrowsExceptionIfDirectoryCreationFails() {
2733 t3lib_div::mkdir_deep('http://localhost');
2734 }
2735
2736 /**
2737 * @test
2738 * @expectedException \InvalidArgumentException
2739 */
2740 public function mkdirDeepThrowsExceptionIfBaseDirectoryIsNotOfTypeString() {
2741 t3lib_div::mkdir_deep(array());
2742 }
2743
2744 /**
2745 * @test
2746 * @expectedException \InvalidArgumentException
2747 */
2748 public function mkdirDeepThrowsExceptionIfDeepDirectoryIsNotOfTypeString() {
2749 t3lib_div::mkdir_deep(PATH_site . 'typo3temp/foo', array());
2750 }
2751
2752
2753 ///////////////////////////////
2754 // Tests concerning unQuoteFilenames
2755 ///////////////////////////////
2756
2757 /**
2758 * Data provider for ImageMagick shell commands
2759 * @see explodeAndUnquoteImageMagickCommands
2760 */
2761 public function imageMagickCommandsDataProvider() {
2762 return array(
2763 // Some theoretical tests first
2764 array(
2765 'aa bb "cc" "dd"',
2766 array('aa', 'bb', '"cc"', '"dd"'),
2767 array('aa', 'bb', 'cc', 'dd'),
2768 ),
2769 array(
2770 'aa bb "cc dd"',
2771 array('aa', 'bb', '"cc dd"'),
2772 array('aa', 'bb', 'cc dd'),
2773 ),
2774 array(
2775 '\'aa bb\' "cc dd"',
2776 array('\'aa bb\'', '"cc dd"'),
2777 array('aa bb', 'cc dd'),
2778 ),
2779 array(
2780 '\'aa bb\' cc "dd"',
2781 array('\'aa bb\'', 'cc', '"dd"'),
2782 array('aa bb', 'cc', 'dd'),
2783 ),
2784 // Now test against some real world examples
2785 array(
2786 '/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"',
2787 array(
2788 '/opt/local/bin/gm.exe',
2789 'convert',
2790 '+profile',
2791 '\'*\'',
2792 '-geometry',
2793 '170x136!',
2794 '-negate',
2795 '"C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2796 '"C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2797 ),
2798 array(
2799 '/opt/local/bin/gm.exe',
2800 'convert',
2801 '+profile',
2802 '*',
2803 '-geometry',
2804 '170x136!',
2805 '-negate',
2806 'C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2807 'C:/Users/Someuser.Domain/Documents/Htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2808 ),
2809 ),
2810 array(
2811 '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"',
2812 array(
2813 'C:/opt/local/bin/gm.exe',
2814 'convert',
2815 '+profile',
2816 '\'*\'',
2817 '-geometry',
2818 '170x136!',
2819 '-negate',
2820 '"C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2821 '"C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2822 ),
2823 array(
2824 'C:/opt/local/bin/gm.exe',
2825 'convert',
2826 '+profile',
2827 '*',
2828 '-geometry',
2829 '170x136!',
2830 '-negate',
2831 'C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2832 'C:/Program Files/Apache2/htdocs/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2833 ),
2834 ),
2835 array(
2836 '/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"',
2837 array(
2838 '/usr/bin/gm',
2839 'convert',
2840 '+profile',
2841 '\'*\'',
2842 '-geometry',
2843 '170x136!',
2844 '-negate',
2845 '"/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2846 '"/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2847 ),
2848 array(
2849 '/usr/bin/gm',
2850 'convert',
2851 '+profile',
2852 '*',
2853 '-geometry',
2854 '170x136!',
2855 '-negate',
2856 '/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2857 '/Shared Items/Data/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2858 ),
2859 ),
2860 array(
2861 '/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"',
2862 array(
2863 '/usr/bin/gm',
2864 'convert',
2865 '+profile',
2866 '\'*\'',
2867 '-geometry',
2868 '170x136!',
2869 '-negate',
2870 '"/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]"',
2871 '"/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif"'
2872 ),
2873 array(
2874 '/usr/bin/gm',
2875 'convert',
2876 '+profile',
2877 '*',
2878 '-geometry',
2879 '170x136!',
2880 '-negate',
2881 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2882 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2883 ),
2884 ),
2885 array(
2886 '/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\'',
2887 array(
2888 '/usr/bin/gm',
2889 'convert',
2890 '+profile',
2891 '\'*\'',
2892 '-geometry',
2893 '170x136!',
2894 '-negate',
2895 '\'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]\'',
2896 '\'/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif\''
2897 ),
2898 array(
2899 '/usr/bin/gm',
2900 'convert',
2901 '+profile',
2902 '*',
2903 '-geometry',
2904 '170x136!',
2905 '-negate',
2906 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif[0]',
2907 '/Network/Servers/server01.internal/Projects/typo3temp/temp/61401f5c16c63d58e1d92e8a2449f2fe_maskNT.gif'
2908 ),
2909 ),
2910 );
2911 }
2912
2913 /**
2914 * Tests if the commands are exploded and unquoted correctly
2915 *
2916 * @dataProvider imageMagickCommandsDataProvider
2917 * @test
2918 */
2919 public function explodeAndUnquoteImageMagickCommands($source, $expectedQuoted, $expectedUnquoted) {
2920 $actualQuoted = t3lib_div::unQuoteFilenames($source);
2921 $acutalUnquoted = t3lib_div::unQuoteFilenames($source, TRUE);
2922
2923 $this->assertEquals($expectedQuoted, $actualQuoted, 'The exploded command does not match the expected');
2924 $this->assertEquals($expectedUnquoted, $acutalUnquoted, 'The exploded and unquoted command does not match the expected');
2925 }
2926
2927
2928 ///////////////////////////////
2929 // Tests concerning split_fileref
2930 ///////////////////////////////
2931
2932 /**
2933 * @test
2934 */
2935 public function splitFileRefReturnsFileTypeNotForFolders(){
2936 $directoryName = uniqid('test_') . '.com';
2937 $directoryPath = PATH_site . 'typo3temp/';
2938 $directory = $directoryPath . $directoryName;
2939 mkdir($directory, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']));
2940
2941 $fileInfo = t3lib_div::split_fileref($directory);
2942
2943 $directoryCreated = is_dir($directory);
2944 rmdir($directory);
2945
2946 $this->assertTrue($directoryCreated);
2947 $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
2948 $this->assertEquals($directoryPath, $fileInfo['path']);
2949 $this->assertEquals($directoryName, $fileInfo['file']);
2950 $this->assertEquals($directoryName, $fileInfo['filebody']);
2951 $this->assertEquals('', $fileInfo['fileext']);
2952 $this->assertArrayNotHasKey('realFileext', $fileInfo);
2953 }
2954
2955 /**
2956 * @test
2957 */
2958 public function splitFileRefReturnsFileTypeForFilesWithoutPathSite() {
2959 $testFile = 'fileadmin/media/someFile.png';
2960
2961 $fileInfo = t3lib_div::split_fileref($testFile);
2962 $this->assertInternalType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
2963 $this->assertEquals('fileadmin/media/', $fileInfo['path']);
2964 $this->assertEquals('someFile.png', $fileInfo['file']);
2965 $this->assertEquals('someFile', $fileInfo['filebody']);
2966 $this->assertEquals('png', $fileInfo['fileext']);
2967 }
2968
2969
2970 /////////////////////////////
2971 // Tests concerning dirname
2972 /////////////////////////////
2973
2974 /**
2975 * @see dirnameWithDataProvider
2976 *
2977 * @return array<array>
2978 */
2979 public function dirnameDataProvider() {
2980 return array(
2981 'absolute path with multiple part and file' => array('/dir1/dir2/script.php', '/dir1/dir2'),
2982 'absolute path with one part' => array('/dir1/', '/dir1'),
2983 'absolute path to file without extension' => array('/dir1/something', '/dir1'),
2984 'relative path with one part and file' => array('dir1/script.php', 'dir1'),
2985 'relative one-character path with one part and file' => array('d/script.php', 'd'),
2986 'absolute zero-part path with file' => array('/script.php', ''),
2987 'empty string' => array('', ''),
2988 );
2989 }
2990
2991 /**
2992 * @test
2993 *
2994 * @dataProvider dirnameDataProvider
2995 *
2996 * @param string $input the input for dirname
2997 * @param string $expectedValue the expected return value expected from dirname
2998 */
2999 public function dirnameWithDataProvider($input, $expectedValue) {
3000 $this->assertEquals(
3001 $expectedValue,
3002 t3lib_div::dirname($input)
3003 );
3004 }
3005
3006
3007 /////////////////////////////////////
3008 // Tests concerning resolveBackPath
3009 /////////////////////////////////////
3010
3011 /**
3012 * @see resolveBackPathWithDataProvider
3013 *
3014 * @return array<array>
3015 */
3016 public function resolveBackPathDataProvider() {
3017 return array(
3018 'empty path' => array('', ''),
3019 'this directory' => array('./', './'),
3020 'relative directory without ..' => array('dir1/dir2/dir3/', 'dir1/dir2/dir3/'),
3021 'relative path without ..' => array('dir1/dir2/script.php', 'dir1/dir2/script.php'),
3022 'absolute directory without ..' => array('/dir1/dir2/dir3/', '/dir1/dir2/dir3/'),
3023 'absolute path without ..' => array('/dir1/dir2/script.php', '/dir1/dir2/script.php'),
3024 'only one directory upwards without trailing slash' => array('..', '..'),
3025 'only one directory upwards with trailing slash' => array('../', '../'),
3026 'one level with trailing ..' => array('dir1/..', ''),
3027 'one level with trailing ../' => array('dir1/../', ''),
3028 'two levels with trailing ..' => array('dir1/dir2/..', 'dir1'),
3029 'two levels with trailing ../' => array('dir1/dir2/../', 'dir1/'),
3030 'leading ../ without trailing /' => array('../dir1', '../dir1'),
3031 'leading ../ with trailing /' => array('../dir1/', '../dir1/'),
3032 'leading ../ and inside path' => array('../dir1/dir2/../dir3/', '../dir1/dir3/'),
3033 'one times ../ in relative directory' => array('dir1/../dir2/', 'dir2/'),
3034 'one times ../ in absolute directory' => array('/dir1/../dir2/', '/dir2/'),
3035 'one times ../ in relative path' => array('dir1/../dir2/script.php', 'dir2/script.php'),
3036 'one times ../ in absolute path' => array('/dir1/../dir2/script.php', '/dir2/script.php'),
3037 'consecutive ../' => array('dir1/dir2/dir3/../../../dir4', 'dir4'),
3038 'distrubuted ../ with trailing /' => array('dir1/../dir2/dir3/../', 'dir2/'),
3039 'distributed ../ without trailing /' => array('dir1/../dir2/dir3/..', 'dir2'),
3040 'multiple distributed and consecutive ../ together' => array('dir1/dir2/dir3/dir4/../../dir5/dir6/dir7/../dir8/', 'dir1/dir2/dir5/dir6/dir8/'),
3041 'multiple distributed and consecutive ../ together' => array('dir1/dir2/dir3/dir4/../../dir5/dir6/dir7/../dir8/', 'dir1/dir2/dir5/dir6/dir8/'),
3042 'dirname with leading ..' => array('dir1/..dir2/dir3/', 'dir1/..dir2/dir3/'),
3043 'dirname with trailing ..' => array('dir1/dir2../dir3/', 'dir1/dir2../dir3/'),
3044 'more times upwards than downwards in directory' => array('dir1/../../', '../'),
3045 'more times upwards than downwards in path' => array('dir1/../../script.php', '../script.php'),
3046 );
3047 }
3048
3049 /**
3050 * @test
3051 *
3052 * @dataProvider resolveBackPathDataProvider
3053 *
3054 * @param string $input the input for resolveBackPath
3055 * @param $expectedValue the expected return value from resolveBackPath
3056 */
3057 public function resolveBackPathWithDataProvider($input, $expectedValue) {
3058 $this->assertEquals(
3059 $expectedValue,
3060 t3lib_div::resolveBackPath($input)
3061 );
3062 }
3063
3064
3065 /////////////////////////////////////////////////////////////////////////////////////
3066 // Tests concerning makeInstance, setSingletonInstance, addInstance, purgeInstances
3067 /////////////////////////////////////////////////////////////////////////////////////
3068
3069 /**
3070 * @test
3071 * @expectedException InvalidArgumentException
3072 */
3073 public function makeInstanceWithEmptyClassNameThrowsException() {
3074 t3lib_div::makeInstance('');
3075 }
3076
3077 /**
3078 * @test
3079 * @expectedException InvalidArgumentException
3080 */
3081 public function makeInstanceWithNullClassNameThrowsException() {
3082 t3lib_div::makeInstance(NULL);
3083 }
3084
3085 /**
3086 * @test
3087 * @expectedException InvalidArgumentException
3088 */
3089 public function makeInstanceWithZeroStringClassNameThrowsException() {
3090 t3lib_div::makeInstance(0);
3091 }
3092
3093 /**
3094 * @test
3095 * @expectedException InvalidArgumentException
3096 */
3097 public function makeInstanceWithEmptyArrayThrowsException() {
3098 t3lib_div::makeInstance(array());
3099 }
3100
3101 /**
3102 * @test
3103 * @expectedException InvalidArgumentException
3104 */
3105 public function makeInstanceWithNonEmptyArrayThrowsException() {
3106 t3lib_div::makeInstance(array('foo'));
3107 }
3108
3109 /**
3110 * @test
3111 */
3112 public function makeInstanceReturnsClassInstance() {
3113 $className = get_class($this->getMock('foo'));
3114
3115 $this->assertTrue(
3116 t3lib_div::makeInstance($className) instanceof $className
3117 );
3118 }
3119
3120 /**
3121 * @test
3122 */
3123 public function makeInstancePassesParametersToConstructor() {
3124 $className = 'testingClass' . uniqid();
3125 if (!class_exists($className, FALSE)) {
3126 eval(
3127 'class ' . $className . ' {' .
3128 ' public $constructorParameter1;' .
3129 ' public $constructorParameter2;' .
3130 ' public function __construct($parameter1, $parameter2) {' .
3131 ' $this->constructorParameter1 = $parameter1;' .
3132 ' $this->constructorParameter2 = $parameter2;' .
3133 ' }' .
3134 '}'
3135 );
3136 }
3137
3138 $instance = t3lib_div::makeInstance($className, 'one parameter', 'another parameter');
3139
3140 $this->assertEquals(
3141 'one parameter',
3142 $instance->constructorParameter1,
3143 'The first constructor parameter has not been set.'
3144 );
3145 $this->assertEquals(
3146 'another parameter',
3147 $instance->constructorParameter2,
3148 'The second constructor parameter has not been set.'
3149 );
3150 }
3151
3152 /**
3153 * @test
3154 */
3155 public function makeInstanceCalledTwoTimesForNonSingletonClassReturnsDifferentInstances() {
3156 $className = get_class($this->getMock('foo'));
3157
3158 $this->assertNotSame(
3159 t3lib_div::makeInstance($className),
3160 t3lib_div::makeInstance($className)
3161 );
3162 }
3163
3164 /**
3165 * @test
3166 */
3167 public function makeInstanceCalledTwoTimesForSingletonClassReturnsSameInstance() {
3168 $className = get_class($this->getMock('t3lib_Singleton'));
3169
3170 $this->assertSame(
3171 t3lib_div::makeInstance($className),
3172 t3lib_div::makeInstance($className)
3173 );
3174 }
3175
3176 /**
3177 * @test
3178 */
3179 public function makeInstanceCalledTwoTimesForSingletonClassWithPurgeInstancesInbetweenReturnsDifferentInstances() {
3180 $className = get_class($this->getMock('t3lib_Singleton'));
3181
3182 $instance = t3lib_div::makeInstance($className);
3183 t3lib_div::purgeInstances();
3184
3185 $this->assertNotSame(
3186 $instance,
3187 t3lib_div::makeInstance($className)
3188 );
3189 }
3190
3191 /**
3192 * @test
3193 * @expectedException InvalidArgumentException
3194 */
3195 public function setSingletonInstanceForEmptyClassNameThrowsException() {
3196 $instance = $this->getMock('t3lib_Singleton');
3197
3198 t3lib_div::setSingletonInstance('', $instance);
3199 }
3200
3201 /**
3202 * @test
3203 * @expectedException InvalidArgumentException
3204 */
3205 public function setSingletonInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
3206 $instance = $this->getMock('t3lib_Singleton', array('foo'));
3207 $singletonClassName = get_class($this->getMock('t3lib_Singleton'));
3208
3209 t3lib_div::setSingletonInstance($singletonClassName, $instance);
3210 }
3211
3212 /**
3213 * @test
3214 */
3215 public function setSingletonInstanceMakesMakeInstanceReturnThatInstance() {
3216 $instance = $this->getMock('t3lib_Singleton');
3217 $singletonClassName = get_class($instance);
3218
3219 t3lib_div::setSingletonInstance($singletonClassName, $instance);
3220
3221 $this->assertSame(
3222 $instance,
3223 t3lib_div::makeInstance($singletonClassName)
3224 );
3225 }
3226
3227 /**
3228 * @test
3229 */
3230 public function setSingletonInstanceCalledTwoTimesMakesMakeInstanceReturnLastSetInstance() {
3231 $instance1 = $this->getMock('t3lib_Singleton');
3232 $singletonClassName = get_class($instance1);
3233 $instance2 = new $singletonClassName();
3234
3235 t3lib_div::setSingletonInstance($singletonClassName, $instance1);
3236 t3lib_div::setSingletonInstance($singletonClassName, $instance2);
3237
3238 $this->assertSame(
3239 $instance2,
3240 t3lib_div::makeInstance($singletonClassName)
3241 );
3242 }
3243
3244 /**
3245 * @test
3246 * @expectedException InvalidArgumentException
3247 */
3248 public function addInstanceForEmptyClassNameThrowsException() {
3249 $instance = $this->getMock('foo');
3250
3251 t3lib_div::addInstance('', $instance);
3252 }
3253
3254 /**
3255 * @test
3256 * @expectedException InvalidArgumentException
3257 */
3258 public function addInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
3259 $instance = $this->getMock('foo', array('bar'));
3260 $singletonClassName = get_class($this->getMock('foo'));
3261
3262 t3lib_div::addInstance($singletonClassName, $instance);
3263 }
3264
3265 /**
3266 * @test
3267 * @expectedException InvalidArgumentException
3268 */
3269 public function addInstanceWithSingletonInstanceThrowsException() {
3270 $instance = $this->getMock('t3lib_Singleton');
3271
3272 t3lib_div::addInstance(get_class($instance), $instance);
3273 }
3274
3275 /**
3276 * @test
3277 */
3278 public function addInstanceMakesMakeInstanceReturnThatInstance() {
3279 $instance = $this->getMock('foo');
3280 $className = get_class($instance);