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