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