Merge pull request #16584 from eileenmcnaughton/role
[civicrm-core.git] / tests / phpunit / CRM / Utils / ArrayTest.php
CommitLineData
6a488035 1<?php
aba1cd8b
EM
2
3/**
4 * Class CRM_Utils_ArrayTest
acb109b7 5 * @group headless
aba1cd8b 6 */
6a488035 7class CRM_Utils_ArrayTest extends CiviUnitTestCase {
6a488035 8
00be9182 9 public function testIndexArray() {
9099cab3
CW
10 $inputs = [];
11 $inputs[] = [
6a488035
TO
12 'lang' => 'en',
13 'msgid' => 'greeting',
17deafad 14 'familiar' => FALSE,
21dfd5f5 15 'value' => 'Hello',
9099cab3
CW
16 ];
17 $inputs[] = [
6a488035
TO
18 'lang' => 'en',
19 'msgid' => 'parting',
21dfd5f5 20 'value' => 'Goodbye',
9099cab3
CW
21 ];
22 $inputs[] = [
6a488035
TO
23 'lang' => 'fr',
24 'msgid' => 'greeting',
21dfd5f5 25 'value' => 'Bon jour',
9099cab3
CW
26 ];
27 $inputs[] = [
6a488035
TO
28 'lang' => 'fr',
29 'msgid' => 'parting',
21dfd5f5 30 'value' => 'Au revoir',
9099cab3
CW
31 ];
32 $inputs[] = [
6a488035
TO
33 'lang' => 'en',
34 'msgid' => 'greeting',
17deafad 35 'familiar' => TRUE,
21dfd5f5 36 'value' => 'Hey',
9099cab3
CW
37 ];
38 $inputs[] = [
928c5201
TO
39 'msgid' => 'greeting',
40 'familiar' => TRUE,
21dfd5f5 41 'value' => 'Universal greeting',
9099cab3 42 ];
6a488035 43
9099cab3 44 $byLangMsgid = CRM_Utils_Array::index(['lang', 'msgid'], $inputs);
6a488035
TO
45 $this->assertEquals($inputs[4], $byLangMsgid['en']['greeting']);
46 $this->assertEquals($inputs[1], $byLangMsgid['en']['parting']);
47 $this->assertEquals($inputs[2], $byLangMsgid['fr']['greeting']);
48 $this->assertEquals($inputs[3], $byLangMsgid['fr']['parting']);
928c5201 49 $this->assertEquals($inputs[5], $byLangMsgid[NULL]['greeting']);
6a488035
TO
50 }
51
00be9182 52 public function testCollect() {
9099cab3
CW
53 $arr = [
54 ['catWord' => 'cat', 'dogWord' => 'dog'],
55 ['catWord' => 'chat', 'dogWord' => 'chien'],
56 ['catWord' => 'gato'],
57 ];
58 $expected = ['cat', 'chat', 'gato'];
6a488035
TO
59 $this->assertEquals($expected, CRM_Utils_Array::collect('catWord', $arr));
60
9099cab3
CW
61 $arr = [];
62 $arr['en'] = (object) ['catWord' => 'cat', 'dogWord' => 'dog'];
63 $arr['fr'] = (object) ['catWord' => 'chat', 'dogWord' => 'chien'];
64 $arr['es'] = (object) ['catWord' => 'gato'];
65 $expected = ['en' => 'cat', 'fr' => 'chat', 'es' => 'gato'];
6a488035
TO
66 $this->assertEquals($expected, CRM_Utils_Array::collect('catWord', $arr));
67 }
68
00be9182 69 public function testProduct0() {
17deafad 70 $actual = CRM_Utils_Array::product(
9099cab3
CW
71 [],
72 ['base data' => 1]
17deafad 73 );
9099cab3
CW
74 $this->assertEquals([
75 ['base data' => 1],
76 ], $actual);
17deafad
TO
77 }
78
00be9182 79 public function testProduct1() {
17deafad 80 $actual = CRM_Utils_Array::product(
9099cab3
CW
81 ['dim1' => ['a', 'b']],
82 ['base data' => 1]
17deafad 83 );
9099cab3
CW
84 $this->assertEquals([
85 ['base data' => 1, 'dim1' => 'a'],
86 ['base data' => 1, 'dim1' => 'b'],
87 ], $actual);
17deafad
TO
88 }
89
00be9182 90 public function testProduct3() {
17deafad 91 $actual = CRM_Utils_Array::product(
9099cab3
CW
92 ['dim1' => ['a', 'b'], 'dim2' => ['alpha', 'beta'], 'dim3' => ['one', 'two']],
93 ['base data' => 1]
17deafad 94 );
9099cab3
CW
95 $this->assertEquals([
96 ['base data' => 1, 'dim1' => 'a', 'dim2' => 'alpha', 'dim3' => 'one'],
97 ['base data' => 1, 'dim1' => 'a', 'dim2' => 'alpha', 'dim3' => 'two'],
98 ['base data' => 1, 'dim1' => 'a', 'dim2' => 'beta', 'dim3' => 'one'],
99 ['base data' => 1, 'dim1' => 'a', 'dim2' => 'beta', 'dim3' => 'two'],
100 ['base data' => 1, 'dim1' => 'b', 'dim2' => 'alpha', 'dim3' => 'one'],
101 ['base data' => 1, 'dim1' => 'b', 'dim2' => 'alpha', 'dim3' => 'two'],
102 ['base data' => 1, 'dim1' => 'b', 'dim2' => 'beta', 'dim3' => 'one'],
103 ['base data' => 1, 'dim1' => 'b', 'dim2' => 'beta', 'dim3' => 'two'],
104 ], $actual);
17deafad 105 }
82376c19 106
00be9182 107 public function testIsSubset() {
9099cab3
CW
108 $this->assertTrue(CRM_Utils_Array::isSubset([], []));
109 $this->assertTrue(CRM_Utils_Array::isSubset(['a'], ['a']));
110 $this->assertTrue(CRM_Utils_Array::isSubset(['a'], ['b', 'a', 'c']));
111 $this->assertTrue(CRM_Utils_Array::isSubset(['b', 'd'], ['a', 'b', 'c', 'd']));
112 $this->assertFalse(CRM_Utils_Array::isSubset(['a'], []));
113 $this->assertFalse(CRM_Utils_Array::isSubset(['a'], ['b']));
114 $this->assertFalse(CRM_Utils_Array::isSubset(['a'], ['b', 'c', 'd']));
82376c19 115 }
f63d0d11 116
00be9182 117 public function testRemove() {
9099cab3 118 $data = [
f63d0d11
CW
119 'one' => 1,
120 'two' => 2,
121 'three' => 3,
122 'four' => 4,
123 'five' => 5,
124 'six' => 6,
9099cab3
CW
125 ];
126 CRM_Utils_Array::remove($data, 'one', 'two', ['three', 'four'], 'five');
127 $this->assertEquals($data, ['six' => 6]);
f63d0d11 128 }
96025800 129
393f41dd 130 public function testGetSetPathParts() {
9099cab3 131 $arr = [
393f41dd 132 'one' => '1',
9099cab3 133 'two' => [
393f41dd 134 'half' => 2,
9099cab3
CW
135 ],
136 ];
137 $this->assertEquals('1', CRM_Utils_Array::pathGet($arr, ['one']));
138 $this->assertEquals('2', CRM_Utils_Array::pathGet($arr, ['two', 'half']));
139 $this->assertEquals(NULL, CRM_Utils_Array::pathGet($arr, ['zoo', 'half']));
140 CRM_Utils_Array::pathSet($arr, ['zoo', 'half'], '3');
141 $this->assertEquals(3, CRM_Utils_Array::pathGet($arr, ['zoo', 'half']));
393f41dd
TO
142 $this->assertEquals(3, $arr['zoo']['half']);
143 }
144
6db70618 145 public function getSortExamples() {
9099cab3
CW
146 $red = ['label' => 'Red', 'id' => 1, 'weight' => '90'];
147 $orange = ['label' => 'Orange', 'id' => 2, 'weight' => '70'];
148 $yellow = ['label' => 'Yellow', 'id' => 3, 'weight' => '10'];
149 $green = ['label' => 'Green', 'id' => 4, 'weight' => '70'];
150 $blue = ['label' => 'Blue', 'id' => 5, 'weight' => '70'];
151
152 $examples = [];
153 $examples[] = [
154 [
6db70618
TO
155 'r' => $red,
156 'y' => $yellow,
157 'g' => $green,
158 'o' => $orange,
159 'b' => $blue,
9099cab3 160 ],
6db70618 161 'id',
9099cab3 162 [
6db70618
TO
163 'r' => $red,
164 'o' => $orange,
165 'y' => $yellow,
166 'g' => $green,
167 'b' => $blue,
9099cab3
CW
168 ],
169 ];
170 $examples[] = [
171 [
6db70618
TO
172 'r' => $red,
173 'y' => $yellow,
174 'g' => $green,
175 'o' => $orange,
176 'b' => $blue,
9099cab3 177 ],
6db70618 178 'label',
9099cab3 179 [
6db70618
TO
180 'b' => $blue,
181 'g' => $green,
182 'o' => $orange,
183 'r' => $red,
184 'y' => $yellow,
9099cab3
CW
185 ],
186 ];
187 $examples[] = [
188 [
6db70618
TO
189 'r' => $red,
190 'g' => $green,
191 'y' => $yellow,
192 'o' => $orange,
193 'b' => $blue,
9099cab3
CW
194 ],
195 ['weight', 'id'],
196 [
6db70618
TO
197 'y' => $yellow,
198 'o' => $orange,
199 'g' => $green,
200 'b' => $blue,
201 'r' => $red,
9099cab3
CW
202 ],
203 ];
6db70618
TO
204
205 return $examples;
206 }
207
208 /**
209 * @param array $array
210 * @param string|array $field
211 * @param $expected
212 * @dataProvider getSortExamples
213 */
214 public function testCrmArraySortByField($array, $field, $expected) {
215 $actual = CRM_Utils_Array::crmArraySortByField($array, $field);
216
217 // assertEquals() has nicer error output, but it's not precise about order.
218 $this->assertEquals($expected, $actual);
219
220 $aIter = new ArrayIterator($actual);
221 $eIter = new ArrayIterator($expected);
222 $this->assertEquals($eIter->count(), $aIter->count());
223 $pos = 0;
224 while ($aIter->valid()) {
225 $this->assertEquals($eIter->key(), $aIter->key(), "Keys at offset $pos do not match");
226 $this->assertEquals($eIter->current(), $aIter->current(), "Values at offset $pos do not match");
227 $aIter->next();
228 $eIter->next();
229 $pos++;
230 }
231 }
232
7d812442
CW
233 public function getRecursiveIssetExamples() {
234 return [
235 [
236 [[[], [0, 1, 2], []]], [0, 1, 2], TRUE,
237 ],
238 [
239 [[[], [0, 1, 2], []]], [0, 1, 3], FALSE,
240 ],
241 [
242 [], ['foo'], FALSE,
243 ],
244 [
245 [NULL, ['wrong' => NULL, 'right' => ['foo' => 1, 'bar' => 2]]], [1, 'wrong'], FALSE,
246 ],
247 [
248 [NULL, ['wrong' => NULL, 'right' => ['foo' => 1, 'bar' => 2]]], [1, 'right'], TRUE,
249 ],
250 [
251 [NULL, ['wrong' => NULL, 'right' => ['foo' => 1, 'bar' => 2]]], [1, 'right', 'foo'], TRUE,
252 ],
253 ];
254 }
255
256 /**
257 * @param $array
258 * @param $path
259 * @param $expected
260 * @dataProvider getRecursiveIssetExamples
261 */
262 public function testRecursiveIsset($array, $path, $expected) {
e4118a7e 263 $result = CRM_Utils_Array::pathIsset($array, $path);
7d812442
CW
264 $this->assertEquals($expected, $result);
265 }
266
267 public function getRecursiveValueExamples() {
268 return [
269 [
270 [[[], [0, 1, 2], []]], [0, 1, 2], NULL, 2,
271 ],
272 [
273 [[[], [0, 1, 2], []]], [0, 1, 3], NULL, NULL,
274 ],
275 [
276 [], ['foo'], FALSE, FALSE,
277 ],
278 [
279 [NULL, ['wrong' => NULL, 'right' => ['foo' => 1, 'bar' => 2]]], [1, 'wrong'], 'nada', 'nada',
280 ],
281 [
39b959db 282 [NULL, ['wrong' => NULL, 'right' => ['foo' => 1, 'bar' => 2]]], [1, 'right'], NULL, ['foo' => 1, 'bar' => 2],
7d812442
CW
283 ],
284 [
285 [NULL, ['wrong' => NULL, 'right' => ['foo' => 1, 'bar' => 2]]], [1, 'right', 'foo'], NULL, 1,
286 ],
287 ];
288 }
289
290 /**
291 * @param $array
292 * @param $path
39b959db 293 * @param $default
7d812442
CW
294 * @param $expected
295 * @dataProvider getRecursiveValueExamples
296 */
297 public function testRecursiveValue($array, $path, $default, $expected) {
e4118a7e 298 $result = CRM_Utils_Array::pathGet($array, $path, $default);
7d812442
CW
299 $this->assertEquals($expected, $result);
300 }
301
f18ccb71 302 /**
303 * Get values for build test.
304 */
305 public function getBuildValueExamples() {
306 return [
307 [
c17dff4c
CW
308 [], [0, 'email', 2, 'location'], [0 => ['email' => [2 => ['location' => 'llama']]]],
309 ],
310 [
311 ['foo', 'bar', [['donkey']]], [2, 0, 1], ['foo', 'bar', [['donkey', 'llama']]],
312 ],
313 [
314 ['a' => [1, 2, 3], 'b' => ['x' => [], 'y' => ['a' => 'donkey', 'b' => 'bear'], 'z' => [4, 5, 6]]], ['b', 'y', 'b'], ['a' => [1, 2, 3], 'b' => ['x' => [], 'y' => ['a' => 'donkey', 'b' => 'llama'], 'z' => [4, 5, 6]]],
315 ],
f18ccb71 316 ];
317 }
318
319 /**
320 * Test the build recursive function.
321 *
39b959db 322 * @param $source
f18ccb71 323 * @param $path
324 * @param $expected
325 *
326 * @dataProvider getBuildValueExamples
327 */
c17dff4c 328 public function testBuildRecursiveValue($source, $path, $expected) {
e4118a7e
CW
329 CRM_Utils_Array::pathSet($source, $path, 'llama');
330 $this->assertEquals($expected, $source);
f18ccb71 331 }
332
127d8f6b
AS
333 /**
334 * Test the flatten function
335 */
336 public function testFlatten() {
337 $data = [
338 'my_array' => [
339 '0' => 'bar',
340 '1' => 'baz',
341 '2' => 'boz',
342 ],
343 'my_complex' => [
39b959db
SL
344 'dog' => 'woof',
345 'asdf' => [
346 'my_zero' => 0,
347 'my_int' => 1,
348 'my_null' => NULL,
349 'my_empty' => '',
350 ],
127d8f6b
AS
351 ],
352 'my_simple' => 999,
353 ];
354
355 $expected = [
356 'my_array.0' => 'bar',
357 'my_array.1' => 'baz',
358 'my_array.2' => 'boz',
359 'my_complex.dog' => 'woof',
360 'my_complex.asdf.my_zero' => 0,
361 'my_complex.asdf.my_int' => 1,
362 'my_complex.asdf.my_null' => NULL,
363 'my_complex.asdf.my_empty' => '',
364 'my_simple' => 999,
365 ];
366
367 $flat = [];
368 CRM_Utils_Array::flatten($data, $flat);
369 $this->assertEquals($flat, $expected);
370 }
371
6a488035 372}