Fixed bug #16267 Add functions to provide mocks for makeInstance (Thanks to Oliver...
[Packages/TYPO3.CMS.git] / tests / t3lib / t3lib_divTest.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 2009-2010 Ingo Renner <ingo@typo3.org>
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 *
17 * This script is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * This copyright notice MUST APPEAR in all copies of the script!
23 ***************************************************************/
24
25 /**
26 * Testcase for class t3lib_div
27 *
28 * @author Ingo Renner <ingo@typo3.org>
29 * @author Oliver Klee <typo3-coding@oliverklee.de>
30 *
31 * @package TYPO3
32 * @subpackage t3lib
33 */
34 class t3lib_divTest extends tx_phpunit_testcase {
35
36 /**
37 * Enable backup of global and system variables
38 *
39 * @var boolean
40 */
41 protected $backupGlobals = TRUE;
42
43 /**
44 * Exclude TYPO3_DB from backup/ restore of $GLOBALS
45 * because resource types cannot be handled during serializing
46 *
47 * @var array
48 */
49 protected $backupGlobalsBlacklist = array('TYPO3_DB');
50
51 public function tearDown() {
52 t3lib_div::purgeInstances();
53 }
54
55
56 ///////////////////////////////
57 // Tests concerning validIP
58 ///////////////////////////////
59
60 /**
61 * Data provider for checkValidIpReturnsTrueForValidIp
62 *
63 * @return array Data sets
64 */
65 public static function validIpDataProvider() {
66 return array(
67 '0.0.0.0' => array('0.0.0.0'),
68 'private IPv4 class C' => array('192.168.0.1'),
69 'private IPv4 class A' => array('10.0.13.1'),
70 'private IPv6' => array('fe80::daa2:5eff:fe8b:7dfb'),
71 );
72 }
73
74 /**
75 * @test
76 * @dataProvider validIpDataProvider
77 */
78 public function validIpReturnsTrueForValidIp($ip) {
79 $this->assertTrue(t3lib_div::validIP($ip));
80 }
81
82 /**
83 * Data provider for checkValidIpReturnsFalseForInvalidIp
84 *
85 * @return array Data sets
86 */
87 public static function invalidIpDataProvider() {
88 return array(
89 'null' => array(null),
90 'zero' => array(0),
91 'string' => array('test'),
92 'string empty' => array(''),
93 'string null' => array('null'),
94 'out of bounds IPv4' => array('300.300.300.300'),
95 'dotted decimal notation with only two dots' => array('127.0.1'),
96 );
97 }
98
99 /**
100 * @test
101 * @dataProvider invalidIpDataProvider
102 */
103 public function validIpReturnsFalseForInvalidIp($ip) {
104 $this->assertFalse(t3lib_div::validIP($ip));
105 }
106
107
108 ///////////////////////////////
109 // Tests concerning testInt
110 ///////////////////////////////
111
112 /**
113 * Data provider for testIntReturnsTrue
114 *
115 * @return array Data sets
116 */
117 public function functionTestIntValidDataProvider() {
118 return array(
119 'int' => array(32425),
120 'negative int' => array(-32425),
121 'largest int' => array(PHP_INT_MAX),
122 'int as string' => array('32425'),
123 'negative int as string' => array('-32425'),
124 'zero' => array(0),
125 'zero as string' => array('0'),
126 );
127 }
128
129 /**
130 * @test
131 * @dataProvider functionTestIntValidDataProvider
132 */
133 public function testIntReturnsTrue($int) {
134 $this->assertTrue(t3lib_div::testInt($int));
135 }
136
137 /**
138 * Data provider for testIntReturnsFalse
139 *
140 * @return array Data sets
141 */
142 public function functionTestIntInvalidDataProvider() {
143 return array(
144 'int as string with leading zero' => array('01234'),
145 'positive int as string with plus modifier' => array('+1234'),
146 'negative int as string with leading zero' => array('-01234'),
147 'largest int plus one' => array(PHP_INT_MAX + 1),
148 'string' => array('testInt'),
149 'empty string' => array(''),
150 'int in string' => array('5 times of testInt'),
151 'int as string with space after' => array('5 '),
152 'int as string with space before' => array(' 5'),
153 'int as string with many spaces before' => array(' 5'),
154 'float' => array(3.14159),
155 'float as string' => array('3.14159'),
156 'float as string only a dot' => array('10.'),
157 'float as string trailing zero would evaluate to int 10' => array('10.0'),
158 'float as string trailing zeros would evaluate to int 10' => array('10.00'),
159 'null' => array(NULL),
160 'empty array' => array(array()),
161 'int in array' => array(array(32425)),
162 'int as string in array' => array(array('32425')),
163 );
164 }
165
166 /**
167 * @test
168 * @dataProvider functionTestIntInvalidDataProvider
169 */
170 public function testIntReturnsFalse($int) {
171 $this->assertFalse(t3lib_div::testInt($int));
172 }
173
174
175 ///////////////////////////////
176 // Tests concerning isFirstPartOfStr
177 ///////////////////////////////
178
179 /**
180 * Data provider for isFirstPartOfStrReturnsTrueForMatchingFirstParts
181 *
182 * @return array
183 */
184 public function isFirstPartOfStrReturnsTrueForMatchingFirstPartDataProvider() {
185 return array(
186 'match first part of string' => array('hello world', 'hello'),
187 'match whole string' => array('hello', 'hello'),
188 'integer is part of string with same number' => array('24', 24),
189 'string is part of integer with same number' => array(24, '24'),
190 'integer is part of string starting with same number' => array('24 beer please', 24),
191 );
192 }
193
194 /**
195 * @test
196 * @dataProvider isFirstPartOfStrReturnsTrueForMatchingFirstPartDataProvider
197 */
198 public function isFirstPartOfStrReturnsTrueForMatchingFirstPart($string, $part) {
199 $this->assertTrue(t3lib_div::isFirstPartOfStr($string, $part));
200 }
201
202 /**
203 * Data provider for checkIsFirstPartOfStrReturnsFalseForNotMatchingFirstParts
204 *
205 * @return array
206 */
207 public function isFirstPartOfStrReturnsFalseForNotMatchingFirstPartDataProvider() {
208 return array(
209 'no string match' => array('hello', 'bye'),
210 'no case sensitive string match' => array('hello world', 'Hello'),
211 'array is not part of string' => array('string', array()),
212 'string is not part of array' => array(array(), 'string'),
213 'null is not part of string' => array('string', NULL),
214 'string is not part of array' => array(NULL, 'string'),
215 'null is not part of array' => array(array(), NULL),
216 'array is not part of string' => array(NULL, array()),
217 'empty string is not part of empty string' => array('', ''),
218 'null is not part of empty string' => array('', NULL),
219 'false is not part of empty string' => array('', FALSE),
220 'empty string is not part of null' => array(NULL, ''),
221 'empty string is not part of false' => array(FALSE, ''),
222 'empty string is not part of zero integer' => array(0, ''),
223 'zero integer is not part of null' => array(NULL, 0),
224 'zero integer is not part of empty string' => array('', 0),
225 );
226 }
227
228 /**
229 * @test
230 * @dataProvider isFirstPartOfStrReturnsFalseForNotMatchingFirstPartDataProvider
231 */
232 public function isFirstPartOfStrReturnsFalseForNotMatchingFirstPart($string, $part) {
233 $this->assertFalse(t3lib_div::isFirstPartOfStr($string, $part));
234 }
235
236
237 ///////////////////////////////
238 // Tests concerning splitCalc
239 ///////////////////////////////
240
241 /**
242 * Data provider for splitCalc
243 *
244 * @return array expected values, arithmetic expression
245 */
246 public function splitCalcDataProvider() {
247 return array(
248 'empty string returns empty array' => array(
249 array(),
250 '',
251 ),
252 'number without operator returns array with plus and number' => array(
253 array(array('+', 42)),
254 '42',
255 ),
256 'two numbers with asterisk return first number with plus and second number with asterisk' => array(
257 array(array('+', 42), array('*', 31)),
258 '42 * 31',
259 ),
260 );
261 }
262
263 /**
264 * @test
265 * @dataProvider splitCalcDataProvider
266 */
267 public function splitCalcCorrectlySplitsExpression($expected, $expression) {
268 $this->assertEquals($expected, t3lib_div::splitCalc($expression, '+-*/'));
269 }
270
271
272 //////////////////////////////////
273 // Tests concerning calcPriority
274 //////////////////////////////////
275
276 /**
277 * Data provider for calcPriority
278 *
279 * @return array expected values, arithmetic expression
280 */
281 public function calcPriorityDataProvider() {
282 return array(
283 'add' => array(9, '6 + 3'),
284 'substract with positive result' => array(3, '6 - 3'),
285 'substract with negative result' => array(-3, '3 - 6'),
286 'multiply' => array(6, '2 * 3'),
287 'divide' => array(2.5, '5 / 2'),
288 'modulus' => array(1, '5 % 2'),
289 'power' => array(8, '2 ^ 3'),
290 'three operands with non integer result' => array(6.5, '5 + 3 / 2'),
291 'three operands with power' => array(14, '5 + 3 ^ 2'),
292 'three operads with modulus' => array(4, '5 % 2 + 3'),
293 'four operands' => array(3, '2 + 6 / 2 - 2'),
294 );
295 }
296
297 /**
298 * @test
299 * @dataProvider calcPriorityDataProvider
300 */
301 public function calcPriorityCorrectlyCalculatesExpression($expected, $expression) {
302 $this->assertEquals($expected, t3lib_div::calcPriority($expression));
303 }
304
305
306 //////////////////////////////////
307 // Tests concerning calcPriority
308 //////////////////////////////////
309
310 /**
311 * Data provider for valid validEmail's
312 *
313 * @return array Valid email addresses
314 */
315 public function validEmailValidDataProvider() {
316 return array(
317 'short mail address' => array('a@b.c'),
318 'simple mail address' => array('test@example.com'),
319 'uppercase characters' => array('QWERTYUIOPASDFGHJKLZXCVBNM@QWERTYUIOPASDFGHJKLZXCVBNM.NET'),
320 // 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
321 // 'equal sign in local part' => array('test=mail@example.com'),
322 'dash in local part' => array('test-mail@example.com'),
323 'plus in local part' => array('test+mail@example.com'),
324 // 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
325 // 'question mark in local part' => array('test?mail@example.com'),
326 'slash in local part' => array('foo/bar@example.com'),
327 'hash in local part' => array('foo#bar@example.com'),
328 // 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
329 // 'dot in local part' => array('firstname.lastname@employee.2something.com'),
330 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
331 // 'dash as local part' => array('-@foo.com'),
332 );
333 }
334
335 /**
336 * @test
337 * @dataProvider validEmailValidDataProvider
338 */
339 public function validEmailReturnsTrueForValidMailAddress($address) {
340 $this->assertTrue(t3lib_div::validEmail($address));
341 }
342
343 /**
344 * Data provider for invalid validEmail's
345 *
346 * @return array Invalid email addresses
347 */
348 public function validEmailInvalidDataProvider() {
349 return array(
350 '@ sign only' => array('@'),
351 'duplicate @' => array('test@@example.com'),
352 'duplicate @ combined with further special characters in local part' => array('test!.!@#$%^&*@example.com'),
353 'opening parenthesis in local part' => array('foo(bar@example.com'),
354 'closing parenthesis in local part' => array('foo)bar@example.com'),
355 'opening square bracket in local part' => array('foo[bar@example.com'),
356 'closing square bracket as local part' => array(']@example.com'),
357 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
358 // 'top level domain only' => array('test@com'),
359 'dash as second level domain' => array('foo@-.com'),
360 'domain part starting with dash' => array('foo@-foo.com'),
361 'domain part ending with dash' => array('foo@foo-.com'),
362 'number as top level domain' => array('foo@bar.123'),
363 // Fix / change if TYPO3 php requirement changed: Address not ok with 5.2.6, but ok with 5.3.2 (?)
364 // 'dash as top level domain' => array('foo@bar.-'),
365 'dot at beginning of domain part' => array('test@.com'),
366 // Fix / change if TYPO3 php requirement changed: Address ok with 5.2.6, but not ok with 5.3.2
367 // 'local part ends with dot' => array('e.x.a.m.p.l.e.@example.com'),
368 'trailing whitespace' => array('test@example.com '),
369 'trailing carriage return' => array('test@example.com' . CR),
370 'trailing linefeed' => array('test@example.com' . LF),
371 'trailing carriage return linefeed' => array('test@example.com' . CRLF),
372 'trailing tab' => array('test@example.com' . TAB),
373 );
374 }
375
376 /**
377 * @test
378 * @dataProvider validEmailInvalidDataProvider
379 */
380 public function validEmailReturnsFalseForInvalidMailAddress($address) {
381 $this->assertFalse(t3lib_div::validEmail($address));
382 }
383
384
385 //////////////////////////////////
386 // Tests concerning intExplode
387 //////////////////////////////////
388
389 /**
390 * @test
391 */
392 public function intExplodeConvertsStringsToInteger() {
393 $testString = '1,foo,2';
394 $expectedArray = array(1, 0, 2);
395 $actualArray = t3lib_div::intExplode(',', $testString);
396
397 $this->assertEquals($expectedArray, $actualArray);
398 }
399
400
401 //////////////////////////////////
402 // Tests concerning revExplode
403 //////////////////////////////////
404
405 /**
406 * @test
407 */
408 public function revExplodeExplodesString() {
409 $testString = 'my:words:here';
410 $expectedArray = array('my:words', 'here');
411 $actualArray = t3lib_div::revExplode(':', $testString, 2);
412
413 $this->assertEquals($expectedArray, $actualArray);
414 }
415
416
417 //////////////////////////////////
418 // Tests concerning trimExplode
419 //////////////////////////////////
420
421 /**
422 * @test
423 */
424 public function checkTrimExplodeTrimsSpacesAtElementStartAndEnd() {
425 $testString = ' a , b , c ,d ,, e,f,';
426 $expectedArray = array('a', 'b', 'c', 'd', '', 'e', 'f', '');
427 $actualArray = t3lib_div::trimExplode(',', $testString);
428
429 $this->assertEquals($expectedArray, $actualArray);
430 }
431
432 /**
433 * @test
434 */
435 public function checkTrimExplodeRemovesNewLines() {
436 $testString = ' a , b , ' . LF . ' ,d ,, e,f,';
437 $expectedArray = array('a', 'b', 'd', 'e', 'f');
438 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
439
440 $this->assertEquals($expectedArray, $actualArray);
441 }
442
443 /**
444 * @test
445 */
446 public function checkTrimExplodeRemovesEmptyElements() {
447 $testString = 'a , b , c , ,d ,, ,e,f,';
448 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f');
449 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
450
451 $this->assertEquals($expectedArray, $actualArray);
452 }
453
454 /**
455 * @test
456 */
457 public function checkTrimExplodeKeepsRemainingResultsWithEmptyItemsAfterReachingLimitWithPositiveParameter() {
458 $testString = ' a , b , c , , d,, ,e ';
459 $expectedArray = array('a', 'b', 'c,,d,,,e');
460 // Limiting returns the rest of the string as the last element
461 $actualArray = t3lib_div::trimExplode(',', $testString, FALSE, 3);
462
463 $this->assertEquals($expectedArray, $actualArray);
464 }
465
466 /**
467 * @test
468 */
469 public function checkTrimExplodeKeepsRemainingResultsWithoutEmptyItemsAfterReachingLimitWithPositiveParameter() {
470 $testString = ' a , b , c , , d,, ,e ';
471 $expectedArray = array('a', 'b', 'c,d,e');
472 // Limiting returns the rest of the string as the last element
473 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, 3);
474
475 $this->assertEquals($expectedArray, $actualArray);
476 }
477
478 /**
479 * @test
480 */
481 public function checkTrimExplodeKeepsRamainingResultsWithEmptyItemsAfterReachingLimitWithNegativeParameter() {
482 $testString = ' a , b , c , d, ,e, f , , ';
483 $expectedArray = array('a', 'b', 'c', 'd', '', 'e');
484 // limiting returns the rest of the string as the last element
485 $actualArray = t3lib_div::trimExplode(',', $testString, FALSE, -3);
486
487 $this->assertEquals($expectedArray, $actualArray);
488 }
489
490 /**
491 * @test
492 */
493 public function checkTrimExplodeKeepsRamainingResultsWithoutEmptyItemsAfterReachingLimitWithNegativeParameter() {
494 $testString = ' a , b , c , d, ,e, f , , ';
495 $expectedArray = array('a', 'b', 'c');
496 // Limiting returns the rest of the string as the last element
497 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, -3);
498
499 $this->assertEquals($expectedArray, $actualArray);
500 }
501
502 /**
503 * @test
504 */
505 public function checkTrimExplodeReturnsExactResultsWithoutReachingLimitWithPositiveParameter() {
506 $testString = ' a , b , , c , , , ';
507 $expectedArray = array('a', 'b', 'c');
508 // Limiting returns the rest of the string as the last element
509 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE, 4);
510
511 $this->assertEquals($expectedArray, $actualArray);
512 }
513
514 /**
515 * @test
516 */
517 public function checkTrimExplodeKeepsZeroAsString() {
518 $testString = 'a , b , c , ,d ,, ,e,f, 0 ,';
519 $expectedArray = array('a', 'b', 'c', 'd', 'e', 'f', '0');
520 $actualArray = t3lib_div::trimExplode(',', $testString, TRUE);
521
522 $this->assertEquals($expectedArray, $actualArray);
523 }
524
525
526 //////////////////////////////////
527 // Tests concerning removeArrayEntryByValue
528 //////////////////////////////////
529
530 /**
531 * @test
532 */
533 public function checkRemoveArrayEntryByValueRemovesEntriesFromOneDimensionalArray() {
534 $inputArray = array(
535 '0' => 'test1',
536 '1' => 'test2',
537 '2' => 'test3',
538 '3' => 'test2',
539 );
540 $compareValue = 'test2';
541 $expectedResult = array(
542 '0' => 'test1',
543 '2' => 'test3',
544 );
545 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
546 $this->assertEquals($expectedResult, $actualResult);
547 }
548
549 /**
550 * @test
551 */
552 public function checkRemoveArrayEntryByValueRemovesEntriesFromMultiDimensionalArray() {
553 $inputArray = array(
554 '0' => 'foo',
555 '1' => array(
556 '10' => 'bar',
557 ),
558 '2' => 'bar',
559 );
560 $compareValue = 'bar';
561 $expectedResult = array(
562 '0' => 'foo',
563 '1' => array(),
564 );
565 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
566 $this->assertEquals($expectedResult, $actualResult);
567 }
568
569 /**
570 * @test
571 */
572 public function checkRemoveArrayEntryByValueRemovesEntryWithEmptyString() {
573 $inputArray = array(
574 '0' => 'foo',
575 '1' => '',
576 '2' => 'bar',
577 );
578 $compareValue = '';
579 $expectedResult = array(
580 '0' => 'foo',
581 '2' => 'bar',
582 );
583 $actualResult = t3lib_div::removeArrayEntryByValue($inputArray, $compareValue);
584 $this->assertEquals($expectedResult, $actualResult);
585 }
586
587 //////////////////////////////////
588 // Tests concerning getBytesFromSizeMeasurement
589 //////////////////////////////////
590
591 /**
592 * Data provider for getBytesFromSizeMeasurement
593 *
594 * @return array expected value, input string
595 */
596 public function getBytesFromSizeMeasurementDataProvider() {
597 return array(
598 '100 kilo Bytes' => array('102400', '100k'),
599 '100 mega Bytes' => array('104857600', '100m'),
600 '100 giga Bytes' => array('107374182400', '100g'),
601 );
602 }
603
604 /**
605 * @test
606 * @dataProvider getBytesFromSizeMeasurementDataProvider
607 */
608 public function getBytesFromSizeMeasurementCalculatesCorrectByteValue($expected, $byteString) {
609 $this->assertEquals($expected, t3lib_div::getBytesFromSizeMeasurement($byteString));
610 }
611
612
613 //////////////////////////////////
614 // Tests concerning getIndpEnv
615 //////////////////////////////////
616
617 /**
618 * @test
619 */
620 public function getIndpEnvTypo3SitePathReturnNonEmptyString() {
621 $this->assertTrue(strlen(t3lib_div::getIndpEnv('TYPO3_SITE_PATH')) >= 1);
622 }
623
624 /**
625 * @test
626 */
627 public function getIndpEnvTypo3SitePathReturnsStringStartingWithSlash() {
628 $result = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
629 $this->assertEquals('/', $result[0]);
630 }
631
632 /**
633 * @test
634 */
635 public function getIndpEnvTypo3SitePathReturnsStringEndingWithSlash() {
636 $result = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
637 $this->assertEquals('/', $result[strlen($result) - 1]);
638 }
639
640
641 //////////////////////////////////
642 // Tests concerning underscoredToUpperCamelCase
643 //////////////////////////////////
644
645 /**
646 * Data provider for underscoredToUpperCamelCase
647 *
648 * @return array expected, input string
649 */
650 public function underscoredToUpperCamelCaseDataProvider() {
651 return array(
652 'single word' => array('Blogexample', 'blogexample'),
653 'multiple words' => array('BlogExample', 'blog_example'),
654 );
655 }
656
657 /**
658 * @test
659 * @dataProvider underscoredToUpperCamelCaseDataProvider
660 */
661 public function underscoredToUpperCamelCase($expected, $inputString) {
662 $this->assertEquals($expected, t3lib_div::underscoredToUpperCamelCase($inputString));
663 }
664
665
666 //////////////////////////////////
667 // Tests concerning underscoredToLowerCamelCase
668 //////////////////////////////////
669
670 /**
671 * Data provider for underscoredToLowerCamelCase
672 *
673 * @return array expected, input string
674 */
675 public function underscoredToLowerCamelCaseDataProvider() {
676 return array(
677 'single word' => array('minimalvalue', 'minimalvalue'),
678 'multiple words' => array('minimalValue', 'minimal_value'),
679 );
680 }
681
682 /**
683 * @test
684 * @dataProvider underscoredToLowerCamelCaseDataProvider
685 */
686 public function underscoredToLowerCamelCase($expected, $inputString) {
687 $this->assertEquals($expected, t3lib_div::underscoredToLowerCamelCase($inputString));
688 }
689
690 //////////////////////////////////
691 // Tests concerning camelCaseToLowerCaseUnderscored
692 //////////////////////////////////
693
694 /**
695 * Data provider for camelCaseToLowerCaseUnderscored
696 *
697 * @return array expected, input string
698 */
699 public function camelCaseToLowerCaseUnderscoredDataProvider() {
700 return array(
701 'single word' => array('blogexample', 'blogexample'),
702 'single word starting upper case' => array('blogexample', 'Blogexample'),
703 'two words starting lower case' => array('minimal_value', 'minimalValue'),
704 'two words starting upper case' => array('blog_example', 'BlogExample'),
705 );
706 }
707
708 /**
709 * @test
710 * @dataProvider camelCaseToLowerCaseUnderscoredDataProvider
711 */
712 public function camelCaseToLowerCaseUnderscored($expected, $inputString) {
713 $this->assertEquals($expected, t3lib_div::camelCaseToLowerCaseUnderscored($inputString));
714 }
715
716
717 //////////////////////////////////
718 // Tests concerning lcFirst
719 //////////////////////////////////
720
721 /**
722 * Data provider for lcFirst
723 *
724 * @return array expected, input string
725 */
726 public function lcfirstDataProvider() {
727 return array(
728 'single word' => array('blogexample', 'blogexample'),
729 'single Word starting upper case' => array('blogexample', 'Blogexample'),
730 'two words' => array('blogExample', 'BlogExample'),
731 );
732 }
733
734 /**
735 * @test
736 * @dataProvider lcfirstDataProvider
737 */
738 public function lcFirst($expected, $inputString) {
739 $this->assertEquals($expected, t3lib_div::lcfirst($inputString));
740 }
741
742
743 //////////////////////////////////
744 // Tests concerning encodeHeader
745 //////////////////////////////////
746
747 /**
748 * @test
749 */
750 public function encodeHeaderEncodesWhitespacesInQuotedPrintableMailHeader() {
751 $this->assertEquals(
752 '=?utf-8?Q?We_test_whether_the_copyright_character_=C2=A9_is_encoded_correctly?=',
753 t3lib_div::encodeHeader(
754 "We test whether the copyright character \xc2\xa9 is encoded correctly",
755 'quoted-printable',
756 'utf-8'
757 )
758 );
759 }
760
761 /**
762 * @test
763 */
764 public function encodeHeaderEncodesQuestionmarksInQuotedPrintableMailHeader() {
765 $this->assertEquals(
766 '=?utf-8?Q?Is_the_copyright_character_=C2=A9_really_encoded_correctly=3F_Really=3F?=',
767 t3lib_div::encodeHeader(
768 "Is the copyright character \xc2\xa9 really encoded correctly? Really?",
769 'quoted-printable',
770 'utf-8'
771 )
772 );
773 }
774
775
776 //////////////////////////////////
777 // Tests concerning isValidUrl
778 //////////////////////////////////
779
780 /**
781 * Data provider for valid isValidUrl's
782 *
783 * @return array Valid ressource
784 */
785 public function validUrlValidRessourceDataProvider() {
786 return array(
787 'http' => array('http://www.example.org/'),
788 'http without trailing slash' => array('http://qwe'),
789 'http directory with trailing slash' => array('http://www.example/img/dir/'),
790 'http directory without trailing slash' => array('http://www.example/img/dir'),
791 'http index.html' => array('http://example.com/index.html'),
792 'http index.php' => array('http://www.example.com/index.php'),
793 'http test.png' => array('http://www.example/img/test.png'),
794 'http username password querystring and ancher' => array('https://user:pw@www.example.org:80/path?arg=value#fragment'),
795 'file' => array('file:///tmp/test.c'),
796 'file directory' => array('file://foo/bar'),
797 'ftp directory' => array('ftp://ftp.example.com/tmp/'),
798 'mailto' => array('mailto:foo@bar.com'),
799 'news' => array('news:news.php.net'),
800 'telnet'=> array('telnet://192.0.2.16:80/'),
801 'ldap' => array('ldap://[2001:db8::7]/c=GB?objectClass?one'),
802 );
803 }
804
805 /**
806 * @test
807 * @dataProvider validUrlValidRessourceDataProvider
808 */
809 public function validURLReturnsTrueForValidRessource($url) {
810 $this->assertTrue(t3lib_div::isValidUrl($url));
811 }
812
813 /**
814 * Data provider for invalid isValidUrl's
815 *
816 * @return array Invalid ressource
817 */
818 public function isValidUrlInvalidRessourceDataProvider() {
819 return array(
820 'http missing colon' => array('http//www.example/wrong/url/'),
821 'http missing slash' => array('http:/www.example'),
822 'hostname only' => array('www.example.org/'),
823 'file missing protocol specification' => array('/tmp/test.c'),
824 'slash only' => array('/'),
825 'string http://' => array('http://'),
826 'string http:/' => array('http:/'),
827 'string http:' => array('http:'),
828 'string http' => array('http'),
829 'empty string' => array(''),
830 'string -1' => array('-1'),
831 'string array()' => array('array()'),
832 'random string' => array('qwe'),
833 );
834 }
835
836 /**
837 * @test
838 * @dataProvider isValidUrlInvalidRessourceDataProvider
839 */
840 public function validURLReturnsFalseForInvalidRessoure($url) {
841 $this->assertFalse(t3lib_div::isValidUrl($url));
842 }
843
844
845 //////////////////////////////////
846 // Tests concerning isOnCurrentHost
847 //////////////////////////////////
848
849 /**
850 * @test
851 */
852 public function isOnCurrentHostReturnsTrueWithCurrentHost() {
853 $testUrl = t3lib_div::getIndpEnv('TYPO3_REQUEST_URL');
854 $this->assertTrue(t3lib_div::isOnCurrentHost($testUrl));
855 }
856
857 /**
858 * Data provider for invalid isOnCurrentHost's
859 *
860 * @return array Invalid Hosts
861 */
862 public function checkisOnCurrentHostInvalidHosts() {
863 return array(
864 'empty string' => array(''),
865 'arbitrary string' => array('arbitrary string'),
866 'localhost IP' => array('127.0.0.1'),
867 'relative path' => array('./relpath/file.txt'),
868 'absolute path' => array('/abspath/file.txt?arg=value'),
869 'differnt host' => array(t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST') . '.example.org'),
870 );
871 }
872
873
874 ////////////////////////////////////////
875 // Tests concerning sanitizeLocalUrl
876 ////////////////////////////////////////
877
878 /**
879 * Data provider for valid sanitizeLocalUrl's
880 *
881 * @return array Valid url
882 */
883 public function sanitizeLocalUrlValidUrlDataProvider() {
884 $subDirectory = t3lib_div::getIndpEnv('TYPO3_SITE_PATH');
885 $typo3SiteUrl = t3lib_div::getIndpEnv('TYPO3_SITE_URL');
886 $typo3RequestHost = t3lib_div::getIndpEnv('TYPO3_REQUEST_HOST');
887
888 return array(
889 'alt_intro.php' => array('alt_intro.php'),
890 'alt_intro.php?foo=1&bar=2' => array('alt_intro.php?foo=1&bar=2'),
891 $subDirectory . 'typo3/alt_intro.php' => array($subDirectory . 'typo3/alt_intro.php'),
892 $subDirectory . 'index.php' => array($subDirectory . 'index.php'),
893 '../index.php' => array('../index.php'),
894 '../typo3/alt_intro.php' => array('../typo3/alt_intro.php'),
895 '../~userDirectory/index.php' => array('../~userDirectory/index.php'),
896 '../typo3/mod.php?var1=test-case&var2=~user' => array('../typo3/mod.php?var1=test-case&var2=~user'),
897 PATH_site . 'typo3/alt_intro.php' => array(PATH_site . 'typo3/alt_intro.php'),
898 $typo3SiteUrl . 'typo3/alt_intro.php' => array($typo3SiteUrl . 'typo3/alt_intro.php'),
899 $typo3RequestHost . $subDirectory . '/index.php' => array($typo3RequestHost . $subDirectory . '/index.php'),
900 );
901 }
902
903 /**
904 * @test
905 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
906 */
907 public function sanitizeLocalUrlAcceptsNotEncodedValidUrls($url) {
908 $this->assertEquals($url, t3lib_div::sanitizeLocalUrl($url));
909 }
910
911 /**
912 * @test
913 * @dataProvider sanitizeLocalUrlValidUrlDataProvider
914 */
915 public function sanitizeLocalUrlAcceptsEncodedValidUrls($url) {
916 $this->assertEquals(rawurlencode($url), t3lib_div::sanitizeLocalUrl(rawurlencode($url)));
917 }
918
919 /**
920 * Data provider for invalid sanitizeLocalUrl's
921 *
922 * @return array Valid url
923 */
924 public function sanitizeLocalUrlInvalidDataProvider() {
925 return array(
926 'empty string' => array(''),
927 'http domain' => array('http://www.google.de/'),
928 'https domain' => array('https://www.google.de/'),
929 'relative path with XSS' => array('../typo3/whatever.php?argument=javascript:alert(0)'),
930 );
931 }
932
933 /**
934 * @test
935 * @dataProvider sanitizeLocalUrlInvalidDataProvider
936 */
937 public function sanitizeLocalUrlDeniesPlainInvalidUrls($url) {
938 $this->assertEquals('', t3lib_div::sanitizeLocalUrl($url));
939 }
940
941 /**
942 * @test
943 * @dataProvider sanitizeLocalUrlInvalidDataProvider
944 */
945 public function sanitizeLocalUrlDeniesEncodedInvalidUrls($url) {
946 $this->assertEquals('', t3lib_div::sanitizeLocalUrl(rawurlencode($url)));
947 }
948
949
950 //////////////////////////////////////
951 // Tests concerning arrayDiffAssocRecursive
952 //////////////////////////////////////
953
954 /**
955 * @test
956 */
957 public function arrayDiffAssocRecursiveHandlesOneDimensionalArrays() {
958 $array1 = array(
959 'key1' => 'value1',
960 'key2' => 'value2',
961 'key3' => 'value3',
962 );
963 $array2 = array(
964 'key1' => 'value1',
965 'key3' => 'value3',
966 );
967 $expectedResult = array(
968 'key2' => 'value2',
969 );
970 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
971 $this->assertEquals($expectedResult, $actualResult);
972 }
973
974 /**
975 * @test
976 */
977 public function arrayDiffAssocRecursiveHandlesMultiDimensionalArrays() {
978 $array1 = array(
979 'key1' => 'value1',
980 'key2' => array(
981 'key21' => 'value21',
982 'key22' => 'value22',
983 'key23' => array(
984 'key231' => 'value231',
985 'key232' => 'value232',
986 ),
987 ),
988 );
989 $array2 = array(
990 'key1' => 'value1',
991 'key2' => array(
992 'key21' => 'value21',
993 'key23' => array(
994 'key231' => 'value231',
995 ),
996 ),
997 );
998 $expectedResult = array(
999 'key2' => array(
1000 'key22' => 'value22',
1001 'key23' => array(
1002 'key232' => 'value232',
1003 ),
1004 ),
1005 );
1006 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1007 $this->assertEquals($expectedResult, $actualResult);
1008 }
1009
1010 /**
1011 * @test
1012 */
1013 public function arrayDiffAssocRecursiveHandlesMixedArrays() {
1014 $array1 = array(
1015 'key1' => array(
1016 'key11' => 'value11',
1017 'key12' => 'value12',
1018 ),
1019 'key2' => 'value2',
1020 'key3' => 'value3',
1021 );
1022 $array2 = array(
1023 'key1' => 'value1',
1024 'key2' => array(
1025 'key21' => 'value21',
1026 ),
1027 );
1028 $expectedResult = array(
1029 'key3' => 'value3',
1030 );
1031 $actualResult = t3lib_div::arrayDiffAssocRecursive($array1, $array2);
1032 $this->assertEquals($expectedResult, $actualResult);
1033 }
1034
1035
1036 //////////////////////////////////////
1037 // Tests concerning removeDotsFromTS
1038 //////////////////////////////////////
1039
1040 /**
1041 * @test
1042 */
1043 public function removeDotsFromTypoScriptSucceedsWithDottedArray() {
1044 $typoScript = array(
1045 'propertyA.' => array(
1046 'keyA.' => array(
1047 'valueA' => 1,
1048 ),
1049 'keyB' => 2,
1050 ),
1051 'propertyB' => 3,
1052 );
1053
1054 $expectedResult = array(
1055 'propertyA' => array(
1056 'keyA' => array(
1057 'valueA' => 1,
1058 ),
1059 'keyB' => 2,
1060 ),
1061 'propertyB' => 3,
1062 );
1063
1064 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1065 }
1066
1067 /**
1068 * @test
1069 */
1070 public function removeDotsFromTypoScriptOverridesSubArray() {
1071 $typoScript = array(
1072 'propertyA.' => array(
1073 'keyA' => 'getsOverridden',
1074 'keyA.' => array(
1075 'valueA' => 1,
1076 ),
1077 'keyB' => 2,
1078 ),
1079 'propertyB' => 3,
1080 );
1081
1082 $expectedResult = array(
1083 'propertyA' => array(
1084 'keyA' => array(
1085 'valueA' => 1,
1086 ),
1087 'keyB' => 2,
1088 ),
1089 'propertyB' => 3,
1090 );
1091
1092 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1093 }
1094
1095 /**
1096 * @test
1097 */
1098 public function removeDotsFromTypoScriptOverridesWithScalar() {
1099 $typoScript = array(
1100 'propertyA.' => array(
1101 'keyA.' => array(
1102 'valueA' => 1,
1103 ),
1104 'keyA' => 'willOverride',
1105 'keyB' => 2,
1106 ),
1107 'propertyB' => 3,
1108 );
1109
1110 $expectedResult = array(
1111 'propertyA' => array(
1112 'keyA' => 'willOverride',
1113 'keyB' => 2,
1114 ),
1115 'propertyB' => 3,
1116 );
1117
1118 $this->assertEquals($expectedResult, t3lib_div::removeDotsFromTS($typoScript));
1119 }
1120
1121
1122 //////////////////////////////////////
1123 // Tests concerning get_dirs
1124 //////////////////////////////////////
1125
1126 /**
1127 * @test
1128 */
1129 public function getDirsReturnsArrayOfDirectoriesFromGivenDirectory() {
1130 $path = PATH_t3lib;
1131 $directories = t3lib_div::get_dirs($path);
1132
1133 $this->assertType('array', $directories);
1134 }
1135
1136 /**
1137 * @test
1138 */
1139 public function getDirsReturnsStringErrorOnPathFailure() {
1140 $path = 'foo';
1141 $result = t3lib_div::get_dirs($path);
1142 $expectedResult = 'error';
1143
1144 $this->assertEquals($expectedResult, $result);
1145 }
1146
1147
1148 //////////////////////////////////
1149 // Tests concerning hmac
1150 //////////////////////////////////
1151
1152 /**
1153 * @test
1154 */
1155 public function hmacReturnsHashOfProperLength() {
1156 $hmac = t3lib_div::hmac('message');
1157 $this->assertTrue(!empty($hmac) && is_string($hmac));
1158 $this->assertTrue(strlen($hmac) == 40);
1159 }
1160
1161 /**
1162 * @test
1163 */
1164 public function hmacReturnsEqualHashesForEqualInput() {
1165 $msg0 = 'message';
1166 $msg1 = 'message';
1167 $this->assertEquals(t3lib_div::hmac($msg0), t3lib_div::hmac($msg1));
1168 }
1169
1170 /**
1171 * @test
1172 */
1173 public function hmacReturnsNoEqualHashesForNonEqualInput() {
1174 $msg0 = 'message0';
1175 $msg1 = 'message1';
1176 $this->assertNotEquals(t3lib_div::hmac($msg0), t3lib_div::hmac($msg1));
1177 }
1178
1179
1180 //////////////////////////////////
1181 // Tests concerning quoteJSvalue
1182 //////////////////////////////////
1183
1184 /**
1185 * @test
1186 */
1187 public function quoteJSvalueHtmlspecialcharsDataByDefault() {
1188 $this->assertContains(
1189 '&gt;',
1190 t3lib_div::quoteJSvalue('>')
1191 );
1192 }
1193
1194 /**
1195 * @test
1196 */
1197 public function quoteJSvaluetHtmlspecialcharsDataWithinCDataSetToFalse() {
1198 $this->assertContains(
1199 '&gt;',
1200 t3lib_div::quoteJSvalue('>', false)
1201 );
1202 }
1203
1204 /**
1205 * @test
1206 */
1207 public function quoteJSvaluetNotHtmlspecialcharsDataWithinCDataSetToTrue() {
1208 $this->assertContains(
1209 '>',
1210 t3lib_div::quoteJSvalue('>', true)
1211 );
1212 }
1213
1214 /**
1215 * @test
1216 */
1217 public function quoteJSvalueReturnsEmptyStringQuotedInSingleQuotes() {
1218 $this->assertEquals(
1219 "''",
1220 t3lib_div::quoteJSvalue("", true)
1221 );
1222 }
1223
1224 /**
1225 * @test
1226 */
1227 public function quoteJSvalueNotModifiesStringWithoutSpecialCharacters() {
1228 $this->assertEquals(
1229 "'Hello world!'",
1230 t3lib_div::quoteJSvalue("Hello world!", true)
1231 );
1232 }
1233
1234 /**
1235 * @test
1236 */
1237 public function quoteJSvalueEscapesSingleQuote() {
1238 $this->assertEquals(
1239 "'\\''",
1240 t3lib_div::quoteJSvalue("'", true)
1241 );
1242 }
1243
1244 /**
1245 * @test
1246 */
1247 public function quoteJSvalueEscapesDoubleQuoteWithinCDataSetToTrue() {
1248 $this->assertEquals(
1249 "'\\\"'",
1250 t3lib_div::quoteJSvalue('"', true)
1251 );
1252 }
1253
1254 /**
1255 * @test
1256 */
1257 public function quoteJSvalueEscapesAndHtmlspecialcharsDoubleQuoteWithinCDataSetToFalse() {
1258 $this->assertEquals(
1259 "'\\&quot;'",
1260 t3lib_div::quoteJSvalue('"', false)
1261 );
1262 }
1263
1264 /**
1265 * @test
1266 */
1267 public function quoteJSvalueEscapesTab() {
1268 $this->assertEquals(
1269 "'" . '\t' . "'",
1270 t3lib_div::quoteJSvalue(TAB)
1271 );
1272 }
1273
1274 /**
1275 * @test
1276 */
1277 public function quoteJSvalueEscapesLinefeed() {
1278 $this->assertEquals(
1279 "'" . '\n' . "'",
1280 t3lib_div::quoteJSvalue(LF)
1281 );
1282 }
1283
1284 /**
1285 * @test
1286 */
1287 public function quoteJSvalueEscapesCarriageReturn() {
1288 $this->assertEquals(
1289 "'" . '\r' . "'",
1290 t3lib_div::quoteJSvalue(CR)
1291 );
1292 }
1293
1294 /**
1295 * @test
1296 */
1297 public function quoteJSvalueEscapesBackslah() {
1298 $this->assertEquals(
1299 "'\\\\'",
1300 t3lib_div::quoteJSvalue('\\')
1301 );
1302 }
1303
1304 //////////////////////////////////
1305 // Tests concerning readLLfile
1306 //////////////////////////////////
1307
1308 /**
1309 * @test
1310 */
1311 public function readLLfileHandlesLocallangXMLOverride() {
1312 $unique = uniqid('locallangXMLOverrideTest');
1313
1314 $xml = '<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
1315 <T3locallang>
1316 <data type="array">
1317 <languageKey index="default" type="array">
1318 <label index="buttons.logout">EXIT</label>
1319 </languageKey>
1320 </data>
1321 </T3locallang>';
1322
1323 $file = PATH_site . 'typo3temp/' . $unique . '.xml';
1324 t3lib_div::writeFileToTypo3tempDir($file, $xml);
1325
1326 // Get default value
1327 $defaultLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
1328
1329 // Set override file
1330 $GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['EXT:lang/locallang_core.xml'][$unique] = $file;
1331
1332 // Get override value
1333 $overrideLL = t3lib_div::readLLfile('EXT:lang/locallang_core.xml', 'default');
1334
1335 // Clean up again
1336 unlink($file);
1337
1338 $this->assertNotEquals($overrideLL['default']['buttons.logout'], '');
1339 $this->assertNotEquals($defaultLL['default']['buttons.logout'], $overrideLL['default']['buttons.logout']);
1340 $this->assertEquals($overrideLL['default']['buttons.logout'], 'EXIT');
1341 }
1342
1343
1344 ///////////////////////////////
1345 // Tests concerning _GETset()
1346 ///////////////////////////////
1347
1348 /**
1349 * @test
1350 */
1351 public function getSetWritesArrayToGetSystemVariable() {
1352 $_GET = array();
1353 $GLOBALS['HTTP_GET_VARS'] = array();
1354
1355 $getParameters = array('foo' => 'bar');
1356 t3lib_div::_GETset($getParameters);
1357 $this->assertSame($getParameters, $_GET);
1358 }
1359
1360 /**
1361 * @test
1362 */
1363 public function getSetWritesArrayToGlobalsHttpGetVars() {
1364 $_GET = array();
1365 $GLOBALS['HTTP_GET_VARS'] = array();
1366
1367 $getParameters = array('foo' => 'bar');
1368 t3lib_div::_GETset($getParameters);
1369 $this->assertSame($getParameters, $GLOBALS['HTTP_GET_VARS']);
1370 }
1371
1372 /**
1373 * @test
1374 */
1375 public function getSetForArrayDropsExistingValues() {
1376 $_GET = array();
1377 $GLOBALS['HTTP_GET_VARS'] = array();
1378
1379 t3lib_div::_GETset(array('foo' => 'bar'));
1380
1381 t3lib_div::_GETset(array('oneKey' => 'oneValue'));
1382
1383 $this->assertEquals(
1384 array('oneKey' => 'oneValue'),
1385 $GLOBALS['HTTP_GET_VARS']
1386 );
1387 }
1388
1389 /**
1390 * @test
1391 */
1392 public function getSetAssignsOneValueToOneKey() {
1393 $_GET = array();
1394 $GLOBALS['HTTP_GET_VARS'] = array();
1395
1396 t3lib_div::_GETset('oneValue', 'oneKey');
1397
1398 $this->assertEquals(
1399 'oneValue',
1400 $GLOBALS['HTTP_GET_VARS']['oneKey']
1401 );
1402 }
1403
1404 /**
1405 * @test
1406 */
1407 public function getSetForOneValueDoesNotDropUnrelatedValues() {
1408 $_GET = array();
1409 $GLOBALS['HTTP_GET_VARS'] = array();
1410
1411 t3lib_div::_GETset(array('foo' => 'bar'));
1412 t3lib_div::_GETset('oneValue', 'oneKey');
1413
1414 $this->assertEquals(
1415 array('foo' => 'bar', 'oneKey' => 'oneValue'),
1416 $GLOBALS['HTTP_GET_VARS']
1417 );
1418 }
1419
1420 /**
1421 * @test
1422 */
1423 public function getSetCanAssignsAnArrayToASpecificArrayElement() {
1424 $_GET = array();
1425 $GLOBALS['HTTP_GET_VARS'] = array();
1426
1427 t3lib_div::_GETset(array('childKey' => 'oneValue'), 'parentKey');
1428
1429 $this->assertEquals(
1430 array('parentKey' => array('childKey' => 'oneValue')),
1431 $GLOBALS['HTTP_GET_VARS']
1432 );
1433 }
1434
1435 /**
1436 * @test
1437 */
1438 public function getSetCanAssignAStringValueToASpecificArrayChildElement() {
1439 $_GET = array();
1440 $GLOBALS['HTTP_GET_VARS'] = array();
1441
1442 t3lib_div::_GETset('oneValue', 'parentKey|childKey');
1443
1444 $this->assertEquals(
1445 array('parentKey' => array('childKey' => 'oneValue')),
1446 $GLOBALS['HTTP_GET_VARS']
1447 );
1448 }
1449
1450 /**
1451 * @test
1452 */
1453 public function getSetCanAssignAnArrayToASpecificArrayChildElement() {
1454 $_GET = array();
1455 $GLOBALS['HTTP_GET_VARS'] = array();
1456
1457 t3lib_div::_GETset(
1458 array('key1' => 'value1', 'key2' => 'value2'),
1459 'parentKey|childKey'
1460 );
1461
1462 $this->assertEquals(
1463 array(
1464 'parentKey' => array(
1465 'childKey' => array('key1' => 'value1', 'key2' => 'value2')
1466 )
1467 ),
1468 $GLOBALS['HTTP_GET_VARS']
1469 );
1470 }
1471
1472
1473 ///////////////////////////////
1474 // Tests concerning fixPermissions
1475 ///////////////////////////////
1476
1477 /**
1478 * @test
1479 */
1480 public function fixPermissionsCorrectlySetsPermissionsToFile() {
1481 if (TYPO3_OS == 'WIN') {
1482 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1483 }
1484
1485 // Create and prepare test file
1486 $filename = PATH_site . 'typo3temp/' . uniqid('test_');
1487 t3lib_div::writeFileToTypo3tempDir($filename, '42');
1488 chmod($filename, 0742);
1489
1490 // Set target permissions and run method
1491 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1492 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1493 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
1494
1495 // Get actual permissions and clean up
1496 clearstatcache();
1497 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
1498 $resultFileGroup = filegroup($filename);
1499 unlink($filename);
1500
1501 // Test if everything was ok
1502 $this->assertTrue($fixPermissionsResult);
1503 $this->assertEquals($resultFilePermissions, '0660');
1504 $this->assertEquals($resultFileGroup, posix_getegid());
1505 }
1506
1507 /**
1508 * @test
1509 */
1510 public function fixPermissionsCorrectlySetsPermissionsToHiddenFile() {
1511 if (TYPO3_OS == 'WIN') {
1512 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1513 }
1514
1515 // Create and prepare test file
1516 $filename = PATH_site . 'typo3temp/' . uniqid('.test_');
1517 t3lib_div::writeFileToTypo3tempDir($filename, '42');
1518 chmod($filename, 0742);
1519
1520 // Set target permissions and run method
1521 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1522 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1523 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
1524
1525 // Get actual permissions and clean up
1526 clearstatcache();
1527 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
1528 $resultFileGroup = filegroup($filename);
1529 unlink($filename);
1530
1531 // Test if everything was ok
1532 $this->assertTrue($fixPermissionsResult);
1533 $this->assertEquals($resultFilePermissions, '0660');
1534 $this->assertEquals($resultFileGroup, posix_getegid());
1535 }
1536
1537 /**
1538 * @test
1539 */
1540 public function fixPermissionsCorrectlySetsPermissionsToDirectory() {
1541 if (TYPO3_OS == 'WIN') {
1542 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1543 }
1544
1545 // Create and prepare test directory
1546 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
1547 t3lib_div::mkdir($directory);
1548 chmod($directory, 1551);
1549
1550 // Set target permissions and run method
1551 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
1552 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1553 $fixPermissionsResult = t3lib_div::fixPermissions($directory . '/');
1554
1555 // Get actual permissions and clean up
1556 clearstatcache();
1557 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
1558 $resultDirectoryGroup = filegroup($directory);
1559 t3lib_div::rmdir($directory);
1560
1561 // Test if everything was ok
1562 $this->assertTrue($fixPermissionsResult);
1563 $this->assertEquals($resultDirectoryPermissions, '0770');
1564 $this->assertEquals($resultDirectoryGroup, posix_getegid());
1565 }
1566
1567 /**
1568 * @test
1569 */
1570 public function fixPermissionsCorrectlySetsPermissionsToHiddenDirectory() {
1571 if (TYPO3_OS == 'WIN') {
1572 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1573 }
1574
1575 // Create and prepare test directory
1576 $directory = PATH_site . 'typo3temp/' . uniqid('.test_');
1577 t3lib_div::mkdir($directory);
1578 chmod($directory, 1551);
1579
1580 // Set target permissions and run method
1581 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
1582 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1583 $fixPermissionsResult = t3lib_div::fixPermissions($directory);
1584
1585 // Get actual permissions and clean up
1586 clearstatcache();
1587 $resultDirectoryPermissions = substr(decoct(fileperms($directory)), 1);
1588 $resultDirectoryGroup = filegroup($directory);
1589 t3lib_div::rmdir($directory);
1590
1591 // Test if everything was ok
1592 $this->assertTrue($fixPermissionsResult);
1593 $this->assertEquals($resultDirectoryPermissions, '0770');
1594 $this->assertEquals($resultDirectoryGroup, posix_getegid());
1595 }
1596
1597 /**
1598 * @test
1599 */
1600 public function fixPermissionsCorrectlySetsPermissionsRecursive() {
1601 if (TYPO3_OS == 'WIN') {
1602 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1603 }
1604
1605 // Create and prepare test directory and file structure
1606 $baseDirectory = PATH_site . 'typo3temp/' . uniqid('test_');
1607 t3lib_div::mkdir($baseDirectory);
1608 chmod($baseDirectory, 1751);
1609 t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/file', '42');
1610 chmod($baseDirectory . '/file', 0742);
1611 t3lib_div::mkdir($baseDirectory . '/foo');
1612 chmod($baseDirectory . '/foo', 1751);
1613 t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/foo/file', '42');
1614 chmod($baseDirectory . '/foo/file', 0742);
1615 t3lib_div::mkdir($baseDirectory . '/.bar');
1616 chmod($baseDirectory . '/.bar', 1751);
1617 // Use this if writeFileToTypo3tempDir is fixed to create hidden files in subdirectories
1618 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/.file', '42');
1619 // t3lib_div::writeFileToTypo3tempDir($baseDirectory . '/.bar/..file2', '42');
1620 touch($baseDirectory . '/.bar/.file', '42');
1621 chmod($baseDirectory . '/.bar/.file', 0742);
1622 touch($baseDirectory . '/.bar/..file2', '42');
1623 chmod($baseDirectory . '/.bar/..file2', 0742);
1624
1625 // Set target permissions and run method
1626 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1627 $GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask'] = '0770';
1628 $GLOBALS['TYPO3_CONF_VARS']['BE']['createGroup'] = posix_getegid();
1629 $fixPermissionsResult = t3lib_div::fixPermissions($baseDirectory, TRUE);
1630
1631 // Get actual permissions
1632 clearstatcache();
1633 $resultBaseDirectoryPermissions = substr(decoct(fileperms($baseDirectory)), 1);
1634 $resultBaseDirectoryGroup = filegroup($baseDirectory);
1635 $resultBaseFilePermissions = substr(decoct(fileperms($baseDirectory . '/file')), 2);
1636 $resultBaseFileGroup = filegroup($baseDirectory . '/file');
1637 $resultFooDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/foo')), 1);
1638 $resultFooDirectoryGroup = filegroup($baseDirectory . '/foo');
1639 $resultFooFilePermissions = substr(decoct(fileperms($baseDirectory . '/foo/file')), 2);
1640 $resultFooFileGroup = filegroup($baseDirectory . '/foo/file');
1641 $resultBarDirectoryPermissions = substr(decoct(fileperms($baseDirectory . '/.bar')), 1);
1642 $resultBarDirectoryGroup = filegroup($baseDirectory . '/.bar');
1643 $resultBarFilePermissions = substr(decoct(fileperms($baseDirectory . '/.bar/.file')), 2);
1644 $resultBarFileGroup = filegroup($baseDirectory . '/.bar/.file');
1645 $resultBarFile2Permissions = substr(decoct(fileperms($baseDirectory . '/.bar/..file2')), 2);
1646 $resultBarFile2Group = filegroup($baseDirectory . '/.bar/..file2');
1647
1648 // Clean up
1649 unlink($baseDirectory . '/file');
1650 unlink($baseDirectory . '/foo/file');
1651 unlink($baseDirectory . '/.bar/.file');
1652 unlink($baseDirectory . '/.bar/..file2');
1653 t3lib_div::rmdir($baseDirectory . '/foo');
1654 t3lib_div::rmdir($baseDirectory . '/.bar');
1655 t3lib_div::rmdir($baseDirectory);
1656
1657 // Test if everything was ok
1658 $this->assertTrue($fixPermissionsResult);
1659 $this->assertEquals($resultBaseDirectoryPermissions, '0770');
1660 $this->assertEquals($resultBaseDirectoryGroup, posix_getegid());
1661 $this->assertEquals($resultBaseFilePermissions, '0660');
1662 $this->assertEquals($resultBaseFileGroup, posix_getegid());
1663 $this->assertEquals($resultFooDirectoryPermissions, '0770');
1664 $this->assertEquals($resultFooDirectoryGroup, posix_getegid());
1665 $this->assertEquals($resultFooFilePermissions, '0660');
1666 $this->assertEquals($resultFooFileGroup, posix_getegid());
1667 $this->assertEquals($resultBarDirectoryPermissions, '0770');
1668 $this->assertEquals($resultBarDirectoryGroup, posix_getegid());
1669 $this->assertEquals($resultBarFilePermissions, '0660');
1670 $this->assertEquals($resultBarFileGroup, posix_getegid());
1671 $this->assertEquals($resultBarFile2Permissions, '0660');
1672 $this->assertEquals($resultBarFile2Group, posix_getegid());
1673 }
1674
1675 /**
1676 * @test
1677 */
1678 public function fixPermissionsDoesNotSetPermissionsToNotAllowedPath() {
1679 if (TYPO3_OS == 'WIN') {
1680 $this->markTestSkipped('fixPermissions() tests not available on Windows');
1681 }
1682
1683 // Create and prepare test file
1684 $filename = PATH_site . 'typo3temp/../typo3temp/' . uniqid('test_');
1685 touch($filename);
1686 chmod($filename, 0742);
1687
1688 // Set target permissions and run method
1689 $GLOBALS['TYPO3_CONF_VARS']['BE']['fileCreateMask'] = '0660';
1690 $fixPermissionsResult = t3lib_div::fixPermissions($filename);
1691
1692 // Get actual permissions and clean up
1693 clearstatcache();
1694 $resultFilePermissions = substr(decoct(fileperms($filename)), 2);
1695 unlink($filename);
1696
1697 // Test if everything was ok
1698 $this->assertFalse($fixPermissionsResult);
1699 $this->assertEquals($resultFilePermissions, '0742');
1700 }
1701
1702
1703 ///////////////////////////////
1704 // Tests concerning mkdir
1705 ///////////////////////////////
1706
1707 /**
1708 * @test
1709 */
1710 public function mkdirCorrectlyCreatesDirectory() {
1711 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
1712 $mkdirResult = t3lib_div::mkdir($directory);
1713 $directoryCreated = is_dir($directory);
1714 t3lib_div::rmdir($directory);
1715 $this->assertTrue($mkdirResult);
1716 $this->assertTrue($directoryCreated);
1717 }
1718
1719 /**
1720 * @test
1721 */
1722 public function mkdirCorrectlyCreatesHiddenDirectory() {
1723 $directory = PATH_site . 'typo3temp/' . uniqid('.test_');
1724 $mkdirResult = t3lib_div::mkdir($directory);
1725 $directoryCreated = is_dir($directory);
1726 t3lib_div::rmdir($directory);
1727 $this->assertTrue($mkdirResult);
1728 $this->assertTrue($directoryCreated);
1729 }
1730
1731 /**
1732 * @test
1733 */
1734 public function mkdirCorrectlyCreatesDirectoryWithTrailingSlash() {
1735 $directory = PATH_site . 'typo3temp/' . uniqid('test_');
1736 $mkdirResult = t3lib_div::mkdir($directory);
1737 $directoryCreated = is_dir($directory);
1738 t3lib_div::rmdir($directory);
1739 $this->assertTrue($mkdirResult);
1740 $this->assertTrue($directoryCreated);
1741 }
1742
1743
1744 ///////////////////////////////
1745 // Tests concerning split_fileref
1746 ///////////////////////////////
1747
1748 /**
1749 * @test
1750 */
1751 public function splitFileRefReturnsFileTypeNotForFolders(){
1752 $directoryName = uniqid('test_') . '.com';
1753 $directoryPath = PATH_site . 'typo3temp/';
1754 $directory = $directoryPath . $directoryName;
1755 mkdir($directory, octdec($GLOBALS['TYPO3_CONF_VARS']['BE']['folderCreateMask']));
1756
1757 $fileInfo = t3lib_div::split_fileref($directory);
1758
1759 $directoryCreated = is_dir($directory);
1760 rmdir($directory);
1761
1762 $this->assertTrue($directoryCreated);
1763 $this->assertType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
1764 $this->assertEquals($directoryPath, $fileInfo['path']);
1765 $this->assertEquals($directoryName, $fileInfo['file']);
1766 $this->assertEquals($directoryName, $fileInfo['filebody']);
1767 $this->assertEquals('', $fileInfo['fileext']);
1768 $this->assertArrayNotHasKey('realFileext', $fileInfo);
1769 }
1770
1771 /**
1772 * @test
1773 */
1774 public function splitFileRefReturnsFileTypeForFilesWithoutPathSite() {
1775 $testFile = 'fileadmin/media/someFile.png';
1776
1777 $fileInfo = t3lib_div::split_fileref($testFile);
1778 $this->assertType(PHPUnit_Framework_Constraint_IsType::TYPE_ARRAY, $fileInfo);
1779 $this->assertEquals('fileadmin/media/', $fileInfo['path']);
1780 $this->assertEquals('someFile.png', $fileInfo['file']);
1781 $this->assertEquals('someFile', $fileInfo['filebody']);
1782 $this->assertEquals('png', $fileInfo['fileext']);
1783 }
1784
1785
1786 /////////////////////////////
1787 // Tests concerning dirname
1788 /////////////////////////////
1789
1790 /**
1791 * @see dirnameWithDataProvider
1792 *
1793 * @return array<array>
1794 */
1795 public function dirnameDataProvider() {
1796 return array(
1797 'absolute path with multiple part and file' => array('/dir1/dir2/script.php', '/dir1/dir2'),
1798 'absolute path with one part' => array('/dir1/', '/dir1'),
1799 'absolute path to file without extension' => array('/dir1/something', '/dir1'),
1800 'relative path with one part and file' => array('dir1/script.php', 'dir1'),
1801 'relative one-character path with one part and file' => array('d/script.php', 'd'),
1802 'absolute zero-part path with file' => array('/script.php', ''),
1803 'empty string' => array('', ''),
1804 );
1805 }
1806
1807 /**
1808 * @test
1809 *
1810 * @dataProvider dirnameDataProvider
1811 *
1812 * @param string $input the input for dirname
1813 * @param string $expectedValue the expected return value expected from dirname
1814 */
1815 public function dirnameWithDataProvider($input, $expectedValue) {
1816 $this->assertEquals(
1817 $expectedValue,
1818 t3lib_div::dirname($input)
1819 );
1820 }
1821
1822
1823 /////////////////////////////////////////////////////////////////////////////////////
1824 // Tests concerning makeInstance, setSingletonInstance, addInstance, purgeInstances
1825 /////////////////////////////////////////////////////////////////////////////////////
1826
1827 /**
1828 * @test
1829 *
1830 * @expectedException InvalidArgumentException
1831 */
1832 public function makeInstanceWithEmptyClassNameThrowsException() {
1833 t3lib_div::makeInstance('');
1834 }
1835
1836 /**
1837 * @test
1838 */
1839 public function makeInstanceReturnsClassInstance() {
1840 $className = get_class($this->getMock('foo'));
1841
1842 $this->assertTrue(
1843 t3lib_div::makeInstance($className) instanceof $className
1844 );
1845 }
1846
1847 /**
1848 * @test
1849 */
1850 public function makeInstancePassesParametersToConstructor() {
1851 $className = 'testingClass' . uniqid();
1852 if (!class_exists($className, FALSE)) {
1853 eval(
1854 'class ' . $className . ' {' .
1855 ' public $constructorParameter1;' .
1856 ' public $constructorParameter2;' .
1857 ' public function __construct($parameter1, $parameter2) {' .
1858 ' $this->constructorParameter1 = $parameter1;' .
1859 ' $this->constructorParameter2 = $parameter2;' .
1860 ' }' .
1861 '}'
1862 );
1863 }
1864
1865 $instance = t3lib_div::makeInstance($className, 'one parameter', 'another parameter');
1866
1867 $this->assertEquals(
1868 'one parameter',
1869 $instance->constructorParameter1,
1870 'The first constructor parameter has not been set.'
1871 );
1872 $this->assertEquals(
1873 'another parameter',
1874 $instance->constructorParameter2,
1875 'The second constructor parameter has not been set.'
1876 );
1877 }
1878
1879 /**
1880 * @test
1881 */
1882 public function makeInstanceCalledTwoTimesForNonSingletonClassReturnsDifferentInstances() {
1883 $className = get_class($this->getMock('foo'));
1884
1885 $this->assertNotSame(
1886 t3lib_div::makeInstance($className),
1887 t3lib_div::makeInstance($className)
1888 );
1889 }
1890
1891 /**
1892 * @test
1893 */
1894 public function makeInstanceCalledTwoTimesForSingletonClassReturnsSameInstance() {
1895 $className = get_class($this->getMock('t3lib_Singleton'));
1896
1897 $this->assertSame(
1898 t3lib_div::makeInstance($className),
1899 t3lib_div::makeInstance($className)
1900 );
1901 }
1902
1903 /**
1904 * @test
1905 */
1906 public function makeInstanceCalledTwoTimesForSingletonClassWithPurgeInstancesInbetweenReturnsDifferentInstances() {
1907 $className = get_class($this->getMock('t3lib_Singleton'));
1908
1909 $instance = t3lib_div::makeInstance($className);
1910 t3lib_div::purgeInstances();
1911
1912 $this->assertNotSame(
1913 $instance,
1914 t3lib_div::makeInstance($className)
1915 );
1916 }
1917
1918 /**
1919 * @test
1920 * @expectedException InvalidArgumentException
1921 */
1922 public function setSingletonInstanceForEmptyClassNameThrowsException() {
1923 $instance = $this->getMock('t3lib_Singleton');
1924
1925 t3lib_div::setSingletonInstance('', $instance);
1926 }
1927
1928 /**
1929 * @test
1930 * @expectedException InvalidArgumentException
1931 */
1932 public function setSingletonInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
1933 $instance = $this->getMock('t3lib_Singleton', array('foo'));
1934 $singletonClassName = get_class($this->getMock('t3lib_Singleton'));
1935
1936 t3lib_div::setSingletonInstance($singletonClassName, $instance);
1937 }
1938
1939 /**
1940 * @test
1941 */
1942 public function setSingletonInstanceMakesMakeInstanceReturnThatInstance() {
1943 $instance = $this->getMock('t3lib_Singleton');
1944 $singletonClassName = get_class($instance);
1945
1946 t3lib_div::setSingletonInstance($singletonClassName, $instance);
1947
1948 $this->assertSame(
1949 $instance,
1950 t3lib_div::makeInstance($singletonClassName)
1951 );
1952 }
1953
1954 /**
1955 * @test
1956 */
1957 public function setSingletonInstanceCalledTwoTimesMakesMakeInstanceReturnLastSetInstance() {
1958 $instance1 = $this->getMock('t3lib_Singleton');
1959 $singletonClassName = get_class($instance1);
1960 $instance2 = new $singletonClassName();
1961
1962 t3lib_div::setSingletonInstance($singletonClassName, $instance1);
1963 t3lib_div::setSingletonInstance($singletonClassName, $instance2);
1964
1965 $this->assertSame(
1966 $instance2,
1967 t3lib_div::makeInstance($singletonClassName)
1968 );
1969 }
1970
1971 /**
1972 * @test
1973 * @expectedException InvalidArgumentException
1974 */
1975 public function addInstanceForEmptyClassNameThrowsException() {
1976 $instance = $this->getMock('foo');
1977
1978 t3lib_div::addInstance('', $instance);
1979 }
1980
1981 /**
1982 * @test
1983 * @expectedException InvalidArgumentException
1984 */
1985 public function addInstanceForClassThatIsNoSubclassOfProvidedClassThrowsException() {
1986 $instance = $this->getMock('foo', array('bar'));
1987 $singletonClassName = get_class($this->getMock('foo'));
1988
1989 t3lib_div::addInstance($singletonClassName, $instance);
1990 }
1991
1992 /**
1993 * @test
1994 * @expectedException InvalidArgumentException
1995 */
1996 public function addInstanceWithSingletonInstanceThrowsException() {
1997 $instance = $this->getMock('t3lib_Singleton');
1998
1999 t3lib_div::addInstance(get_class($instance), $instance);
2000 }
2001
2002 /**
2003 * @test
2004 */
2005 public function addInstanceMakesMakeInstanceReturnThatInstance() {
2006 $instance = $this->getMock('foo');
2007 $className = get_class($instance);
2008
2009 t3lib_div::addInstance($className, $instance);
2010
2011 $this->assertSame(
2012 $instance,
2013 t3lib_div::makeInstance($className)
2014 );
2015 }
2016
2017 /**
2018 * @test
2019 */
2020 public function makeInstanceCalledTwoTimesAfterAddInstanceReturnTwoDifferentInstances() {
2021 $instance = $this->getMock('foo');
2022 $className = get_class($instance);
2023
2024 t3lib_div::addInstance($className, $instance);
2025
2026 $this->assertNotSame(
2027 t3lib_div::makeInstance($className),
2028 t3lib_div::makeInstance($className)
2029 );
2030 }
2031
2032 /**
2033 * @test
2034 */
2035 public function addInstanceCalledTwoTimesMakesMakeInstanceReturnBothInstancesInAddingOrder() {
2036 $instance1 = $this->getMock('foo');
2037 $className = get_class($instance1);
2038 t3lib_div::addInstance($className, $instance1);
2039
2040 $instance2 = new $className();
2041 t3lib_div::addInstance($className, $instance2);
2042
2043 $this->assertSame(
2044 $instance1,
2045 t3lib_div::makeInstance($className),
2046 'The first returned instance does not match the first added instance.'
2047 );
2048 $this->assertSame(
2049 $instance2,
2050 t3lib_div::makeInstance($className),
2051 'The second returned instance does not match the second added instance.'
2052 );
2053 }
2054
2055 /**
2056 * @test
2057 */
2058 public function purgeInstancesDropsAddedInstance() {
2059 $instance = $this->getMock('foo');
2060 $className = get_class($instance);
2061
2062 t3lib_div::addInstance($className, $instance);
2063 t3lib_div::purgeInstances();
2064
2065 $this->assertNotSame(
2066 $instance,
2067 t3lib_div::makeInstance($className)
2068 );
2069 }
2070 }
2071 ?>