[TASK] Merge submodule fluid into core
[Packages/TYPO3.CMS.git] / typo3 / sysext / extbase / Tests / Unit / Utility / ArrayUtilityTest.php
1 <?php
2 namespace TYPO3\CMS\Extbase\Tests\Unit\Utility;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) Extbase Team
8 * All rights reserved
9 *
10 * This class is a backport of the corresponding class of TYPO3 Flow.
11 * All credits go to the TYPO3 Flow team.
12 *
13 * This script is part of the TYPO3 project. The TYPO3 project is
14 * free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * The GNU General Public License can be found at
20 * http://www.gnu.org/copyleft/gpl.html.
21 *
22 * This script is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 *
27 * This copyright notice MUST APPEAR in all copies of the script!
28 ***************************************************************/
29 /**
30 * Testcase for the \TYPO3\CMS\Extbase\Utility\ArrayUtility class.
31 *
32 * @author Tymoteusz Motylewski <t.motylewski@gmail.com>
33 */
34 class ArrayUtilityTest extends \TYPO3\CMS\Extbase\Tests\Unit\BaseTestCase {
35
36 /**
37 * @test
38 */
39 public function containsMultipleTypesReturnsFalseOnEmptyArray() {
40 $this->assertFalse(\TYPO3\CMS\Extbase\Utility\ArrayUtility::containsMultipleTypes(array()));
41 }
42
43 /**
44 * @test
45 */
46 public function containsMultipleTypesReturnsFalseOnArrayWithIntegers() {
47 $this->assertFalse(\TYPO3\CMS\Extbase\Utility\ArrayUtility::containsMultipleTypes(array(1, 2, 3)));
48 }
49
50 /**
51 * @test
52 */
53 public function containsMultipleTypesReturnsFalseOnArrayWithObjects() {
54 $this->assertFalse(\TYPO3\CMS\Extbase\Utility\ArrayUtility::containsMultipleTypes(array(new \stdClass(), new \stdClass(), new \stdClass())));
55 }
56
57 /**
58 * @test
59 */
60 public function containsMultipleTypesReturnsTrueOnMixedArray() {
61 $this->assertTrue(\TYPO3\CMS\Extbase\Utility\ArrayUtility::containsMultipleTypes(array(1, 'string', 1.25, new \stdClass())));
62 }
63
64 /**
65 * @test
66 */
67 public function getValueByPathReturnsTheValueOfANestedArrayByFollowingTheGivenSimplePath() {
68 $array = array('Foo' => 'the value');
69 $this->assertSame('the value', \TYPO3\CMS\Extbase\Utility\ArrayUtility::getValueByPath($array, array('Foo')));
70 }
71
72 /**
73 * @test
74 */
75 public function getValueByPathReturnsTheValueOfANestedArrayByFollowingTheGivenPath() {
76 $array = array('Foo' => array('Bar' => array('Baz' => array(2 => 'the value'))));
77 $this->assertSame('the value', \TYPO3\CMS\Extbase\Utility\ArrayUtility::getValueByPath($array, array('Foo', 'Bar', 'Baz', 2)));
78 }
79
80 /**
81 * @test
82 */
83 public function getValueByPathReturnsTheValueOfANestedArrayByFollowingTheGivenPathIfPathIsString() {
84 $path = 'Foo.Bar.Baz.2';
85 $array = array('Foo' => array('Bar' => array('Baz' => array(2 => 'the value'))));
86 $expectedResult = 'the value';
87 $actualResult = \TYPO3\CMS\Extbase\Utility\ArrayUtility::getValueByPath($array, $path);
88 $this->assertSame($expectedResult, $actualResult);
89 }
90
91 /**
92 * @test
93 * @expectedException \InvalidArgumentException
94 */
95 public function getValueByPathThrowsExceptionIfPathIsNoArrayOrString() {
96 $array = array('Foo' => array('Bar' => array('Baz' => array(2 => 'the value'))));
97 \TYPO3\CMS\Extbase\Utility\ArrayUtility::getValueByPath($array, NULL);
98 }
99
100 /**
101 * @test
102 */
103 public function getValueByPathReturnsNullIfTheSegementsOfThePathDontExist() {
104 $array = array('Foo' => array('Bar' => array('Baz' => array(2 => 'the value'))));
105 $this->assertNull(\TYPO3\CMS\Extbase\Utility\ArrayUtility::getValueByPath($array, array('Foo', 'Bar', 'Bax', 2)));
106 }
107
108 /**
109 * @test
110 */
111 public function getValueByPathReturnsNullIfThePathHasMoreSegmentsThanTheGivenArray() {
112 $array = array('Foo' => array('Bar' => array('Baz' => 'the value')));
113 $this->assertNull(\TYPO3\CMS\Extbase\Utility\ArrayUtility::getValueByPath($array, array('Foo', 'Bar', 'Baz', 'Bux')));
114 }
115
116 /**
117 * @test
118 */
119 public function convertObjectToArrayConvertsNestedObjectsToArray() {
120 $object = new \stdClass();
121 $object->a = 'v';
122 $object->b = new \stdClass();
123 $object->b->c = 'w';
124 $object->d = array('i' => 'foo', 'j' => 12, 'k' => TRUE, 'l' => new \stdClass());
125 $array = \TYPO3\CMS\Extbase\Utility\ArrayUtility::convertObjectToArray($object);
126 $expected = array(
127 'a' => 'v',
128 'b' => array(
129 'c' => 'w'
130 ),
131 'd' => array(
132 'i' => 'foo',
133 'j' => 12,
134 'k' => TRUE,
135 'l' => array()
136 )
137 );
138 $this->assertSame($expected, $array);
139 }
140
141 /**
142 * @test
143 */
144 public function setValueByPathSetsValueRecursivelyIfPathIsArray() {
145 $array = array();
146 $path = array('foo', 'bar', 'baz');
147 $expectedValue = array('foo' => array('bar' => array('baz' => 'The Value')));
148 $actualValue = \TYPO3\CMS\Extbase\Utility\ArrayUtility::setValueByPath($array, $path, 'The Value');
149 $this->assertSame($expectedValue, $actualValue);
150 }
151
152 /**
153 * @test
154 */
155 public function setValueByPathSetsValueRecursivelyIfPathIsString() {
156 $array = array();
157 $path = 'foo.bar.baz';
158 $expectedValue = array('foo' => array('bar' => array('baz' => 'The Value')));
159 $actualValue = \TYPO3\CMS\Extbase\Utility\ArrayUtility::setValueByPath($array, $path, 'The Value');
160 $this->assertSame($expectedValue, $actualValue);
161 }
162
163 /**
164 * @test
165 */
166 public function setValueByPathRecursivelyMergesAnArray() {
167 $array = array('foo' => array('bar' => 'should be overriden'), 'bar' => 'Baz');
168 $path = array('foo', 'bar', 'baz');
169 $expectedValue = array('foo' => array('bar' => array('baz' => 'The Value')), 'bar' => 'Baz');
170 $actualValue = \TYPO3\CMS\Extbase\Utility\ArrayUtility::setValueByPath($array, $path, 'The Value');
171 $this->assertSame($expectedValue, $actualValue);
172 }
173
174 /**
175 * @test
176 * @expectedException \InvalidArgumentException
177 */
178 public function setValueByPathThrowsExceptionIfPathIsNoArrayOrString() {
179 $array = array('Foo' => array('Bar' => array('Baz' => array(2 => 'the value'))));
180 \TYPO3\CMS\Extbase\Utility\ArrayUtility::setValueByPath($array, NULL, 'Some Value');
181 }
182
183 /**
184 * @test
185 * @expectedException \InvalidArgumentException
186 */
187 public function setValueByPathThrowsExceptionIfSubjectIsNoArray() {
188 $subject = 'foobar';
189 \TYPO3\CMS\Extbase\Utility\ArrayUtility::setValueByPath($subject, 'foo', 'bar');
190 }
191
192 /**
193 * @test
194 * @expectedException \InvalidArgumentException
195 */
196 public function setValueByPathThrowsExceptionIfSubjectIsNoArrayAccess() {
197 $subject = new \stdClass();
198 \TYPO3\CMS\Extbase\Utility\ArrayUtility::setValueByPath($subject, 'foo', 'bar');
199 }
200
201 /**
202 * @test
203 */
204 public function setValueByLeavesInputArrayUnchanged() {
205 $subject = ($subjectBackup = array('foo' => 'bar'));
206 \TYPO3\CMS\Extbase\Utility\ArrayUtility::setValueByPath($subject, 'foo', 'baz');
207 $this->assertSame($subject, $subjectBackup);
208 }
209
210 /**
211 * @test
212 */
213 public function unsetValueByPathDoesNotModifyAnArrayIfThePathWasNotFound() {
214 $array = array('foo' => array('bar' => array('baz' => 'Some Value')), 'bar' => 'Baz');
215 $path = array('foo', 'bar', 'nonExistingKey');
216 $expectedValue = $array;
217 $actualValue = \TYPO3\CMS\Extbase\Utility\ArrayUtility::unsetValueByPath($array, $path);
218 $this->assertSame($expectedValue, $actualValue);
219 }
220
221 /**
222 * @test
223 */
224 public function unsetValueByPathRemovesSpecifiedKey() {
225 $array = array('foo' => array('bar' => array('baz' => 'Some Value')), 'bar' => 'Baz');
226 $path = array('foo', 'bar', 'baz');
227 $expectedValue = array('foo' => array('bar' => array()), 'bar' => 'Baz');
228 $actualValue = \TYPO3\CMS\Extbase\Utility\ArrayUtility::unsetValueByPath($array, $path);
229 $this->assertSame($expectedValue, $actualValue);
230 }
231
232 /**
233 * @test
234 */
235 public function unsetValueByPathRemovesSpecifiedKeyIfPathIsString() {
236 $array = array('foo' => array('bar' => array('baz' => 'Some Value')), 'bar' => 'Baz');
237 $path = 'foo.bar.baz';
238 $expectedValue = array('foo' => array('bar' => array()), 'bar' => 'Baz');
239 $actualValue = \TYPO3\CMS\Extbase\Utility\ArrayUtility::unsetValueByPath($array, $path);
240 $this->assertSame($expectedValue, $actualValue);
241 }
242
243 /**
244 * @test
245 */
246 public function unsetValueByPathRemovesSpecifiedBranch() {
247 $array = array('foo' => array('bar' => array('baz' => 'Some Value')), 'bar' => 'Baz');
248 $path = array('foo');
249 $expectedValue = array('bar' => 'Baz');
250 $actualValue = \TYPO3\CMS\Extbase\Utility\ArrayUtility::unsetValueByPath($array, $path);
251 $this->assertSame($expectedValue, $actualValue);
252 }
253
254 /**
255 * @test
256 * @expectedException \InvalidArgumentException
257 */
258 public function unsetValueByPathThrowsExceptionIfPathIsNoArrayOrString() {
259 $array = array('Foo' => array('Bar' => array('Baz' => array(2 => 'the value'))));
260 \TYPO3\CMS\Extbase\Utility\ArrayUtility::unsetValueByPath($array, NULL);
261 }
262
263 /**
264 * @test
265 */
266 public function removeEmptyElementsRecursivelyRemovesNullValues() {
267 $array = array('EmptyElement' => NULL, 'Foo' => array('Bar' => array('Baz' => array('NotNull' => '', 'AnotherEmptyElement' => NULL))));
268 $expectedResult = array('Foo' => array('Bar' => array('Baz' => array('NotNull' => ''))));
269 $actualResult = \TYPO3\CMS\Extbase\Utility\ArrayUtility::removeEmptyElementsRecursively($array);
270 $this->assertSame($expectedResult, $actualResult);
271 }
272
273 /**
274 * @test
275 */
276 public function removeEmptyElementsRecursivelyRemovesEmptySubArrays() {
277 $array = array('EmptyElement' => array(), 'Foo' => array('Bar' => array('Baz' => array('AnotherEmptyElement' => NULL))), 'NotNull' => 123);
278 $expectedResult = array('NotNull' => 123);
279 $actualResult = \TYPO3\CMS\Extbase\Utility\ArrayUtility::removeEmptyElementsRecursively($array);
280 $this->assertSame($expectedResult, $actualResult);
281 }
282
283 public function arrayMergeRecursiveOverruleData() {
284 return array(
285 'simple usage' => array(
286 'inputArray1' => array(
287 'k1' => 'v1',
288 'k2' => 'v2'
289 ),
290 'inputArray2' => array(
291 'k2' => 'v2a',
292 'k3' => 'v3'
293 ),
294 'dontAddNewKeys' => FALSE,
295 // default
296 'emptyValuesOverride' => TRUE,
297 // default
298 'expected' => array(
299 'k1' => 'v1',
300 'k2' => 'v2a',
301 'k3' => 'v3'
302 )
303 ),
304 'simple usage with recursion' => array(
305 'inputArray1' => array(
306 'k1' => 'v1',
307 'k2' => array(
308 'k2.1' => 'v2.1',
309 'k2.2' => 'v2.2'
310 )
311 ),
312 'inputArray2' => array(
313 'k2' => array(
314 'k2.2' => 'v2.2a',
315 'k2.3' => 'v2.3'
316 ),
317 'k3' => 'v3'
318 ),
319 'dontAddNewKeys' => FALSE,
320 // default
321 'emptyValuesOverride' => TRUE,
322 // default
323 'expected' => array(
324 'k1' => 'v1',
325 'k2' => array(
326 'k2.1' => 'v2.1',
327 'k2.2' => 'v2.2a',
328 'k2.3' => 'v2.3'
329 ),
330 'k3' => 'v3'
331 )
332 ),
333 'simple type should override array (k2)' => array(
334 'inputArray1' => array(
335 'k1' => 'v1',
336 'k2' => array(
337 'k2.1' => 'v2.1'
338 )
339 ),
340 'inputArray2' => array(
341 'k2' => 'v2a',
342 'k3' => 'v3'
343 ),
344 'dontAddNewKeys' => FALSE,
345 // default
346 'emptyValuesOverride' => TRUE,
347 // default
348 'expected' => array(
349 'k1' => 'v1',
350 'k2' => 'v2a',
351 'k3' => 'v3'
352 )
353 ),
354 'null should override array (k2)' => array(
355 'inputArray1' => array(
356 'k1' => 'v1',
357 'k2' => array(
358 'k2.1' => 'v2.1'
359 )
360 ),
361 'inputArray2' => array(
362 'k2' => NULL,
363 'k3' => 'v3'
364 ),
365 'dontAddNewKeys' => FALSE,
366 // default
367 'emptyValuesOverride' => TRUE,
368 // default
369 'expected' => array(
370 'k1' => 'v1',
371 'k2' => NULL,
372 'k3' => 'v3'
373 )
374 )
375 );
376 }
377
378 /**
379 * @test
380 * @param array $inputArray1
381 * @param array $inputArray2
382 * @param boolean $dontAddNewKeys
383 * @param boolean $emptyValuesOverride
384 * @param array $expected
385 * @dataProvider arrayMergeRecursiveOverruleData
386 */
387 public function arrayMergeRecursiveOverruleMergesSimpleArrays(array $inputArray1, array $inputArray2, $dontAddNewKeys, $emptyValuesOverride, array $expected) {
388 $this->assertSame($expected, \TYPO3\CMS\Extbase\Utility\ArrayUtility::arrayMergeRecursiveOverrule($inputArray1, $inputArray2, $dontAddNewKeys, $emptyValuesOverride));
389 }
390
391 /**
392 * @test
393 */
394 public function integerExplodeReturnsArrayOfIntegers() {
395 $inputString = '1,2,3,4,5,6';
396 $expected = array(1, 2, 3, 4, 5, 6);
397 $this->assertSame($expected, \TYPO3\CMS\Extbase\Utility\ArrayUtility::integerExplode(',', $inputString));
398 }
399
400 /**
401 * @test
402 */
403 public function integerExplodeReturnsZeroForStringValues() {
404 $inputString = '1,abc,3,,5';
405 $expected = array(1, 0, 3, 0, 5);
406 $this->assertSame($expected, \TYPO3\CMS\Extbase\Utility\ArrayUtility::integerExplode(',', $inputString));
407 }
408 }
409
410 ?>