Passed
Pull Request — develop (#27)
by Glynn
03:01
created

ArrayFunctionTests   A

Complexity

Total Complexity 27

Size/Duplication

Total Lines 424
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 240
dl 0
loc 424
rs 10
c 1
b 0
f 0
wmc 27
1
<?php
2
3
declare(strict_types=1);
4
5
require_once dirname(__FILE__, 2) . '/FunctionsLoader.php';
6
7
/**
8
 * Tests for the Array functions class.
9
 *
10
 * @since 0.1.0
11
 * @author Glynn Quelch <[email protected]>
12
 */
13
14
use PHPUnit\Framework\TestCase;
15
use PinkCrab\FunctionConstructors\Arrays as Arr;
16
use PinkCrab\FunctionConstructors\Numbers as Num;
17
use PinkCrab\FunctionConstructors\Strings as Str;
18
use PinkCrab\FunctionConstructors\FunctionsLoader;
19
use PinkCrab\FunctionConstructors\GeneralFunctions as Func;
20
21
use function PHPUnit\Framework\throwException;
22
23
/**
24
 * ArrayFunction class.
25
 */
26
class ArrayFunctionTests extends TestCase
27
{
28
    /**
29
     * Random pollyfills
30
     */
31
    public function __call($method, $params)
32
    {
33
        switch ($method) {
34
            case 'assertIsArray':
35
                $this->assertTrue(is_array($params));
36
                break;
37
        }
38
    }
39
40
    public function setup(): void
41
    {
42
        FunctionsLoader::include();
43
    }
44
45
    public function testCanPushToHead(): void
46
    {
47
        $pushToHead = Arr\pushHead(array(3, 4, 5, 6));
48
        $added2     = $pushToHead(2);
49
        $this->assertEquals(2, $added2[0]);
50
51
        $pushToHead = Arr\pushHead($added2);
52
        $added1     = $pushToHead(1);
53
        $this->assertEquals(1, $added1[0]);
54
55
        // As curried.
56
        $curried = Arr\pushHead(array(3, 4, 5, 6))(2);
57
        $this->assertEquals(2, $curried[0]);
58
    }
59
60
    public function testCanPushToTail(): void
61
    {
62
        $pushToTail = Arr\pushTail(array(1, 2, 3, 4));
63
        $added2     = $pushToTail(5);
64
        $this->assertEquals(5, $added2[4]);
65
66
        $pushToTail = Arr\pushTail($added2);
67
        $added1     = $pushToTail(6);
68
        $this->assertEquals(6, $added1[5]);
69
70
        // As curried.
71
        $curried = Arr\pushTail(array(1, 2, 3, 4))(5);
72
        $this->assertEquals(5, $curried[4]);
73
    }
74
75
    public function testCanUseTail()
76
    {
77
        $names = array('Sam Smith', 'Barry Smith', 'Sam Power', 'Rebecca Smith');
78
        $this->assertEquals('Rebecca Smith', Arr\tail($names));
79
        // Check returns null if empty.
80
        $this->assertNull(Arr\tail(array()));
81
    }
82
83
    public function testCanUseHead()
84
    {
85
        $names = array('Sam Smith', 'Barry Smith', 'Sam Power', 'Rebecca Smith');
86
        $this->assertEquals('Sam Smith', Arr\head($names));
87
        // Check returns null if empty.
88
        $this->assertNull(Arr\head(array()));
89
    }
90
91
    public function testCanCompileArray(): void
92
    {
93
        $arrayCompiler = Arr\arrayCompiler();
94
        $arrayCompiler = $arrayCompiler('Hello');
95
        $arrayCompiler = $arrayCompiler('ERROR');
96
        $this->assertEquals('Hello', $arrayCompiler()[0]);
97
        $this->assertEquals('ERROR', $arrayCompiler()[1]);
98
99
        // As curried
100
        $arrayCompiler = $arrayCompiler('NO PLEASE GOD NO')('what')('more');
101
        $this->assertEquals('NO PLEASE GOD NO', $arrayCompiler()[2]);
102
        $this->assertEquals('what', $arrayCompiler()[3]);
103
        $this->assertEquals('more', $arrayCompiler()[4]);
104
105
        // Test can output on invoke.
106
        $this->assertTrue(is_array($arrayCompiler()));
107
    }
108
109
    public function testCanCompileArrayTyped()
110
    {
111
        $arrayCompiler = Arr\arrayCompilerTyped('is_string');
112
        $arrayCompiler = $arrayCompiler('Hello');
113
        $arrayCompiler = $arrayCompiler('ERROR');
114
        $arrayCompiler = $arrayCompiler(array('ERROR'));
115
        $this->assertCount(2, $arrayCompiler());
116
117
        $arrayCompiler = $arrayCompiler('Hello')(1)(NAN)('so 4?');
118
        $this->assertCount(4, $arrayCompiler());
119
    }
120
121
    public function testCanGroupByArray(): void
122
    {
123
        $groupByPerfectNumbers = Arr\groupBy(
124
            function ($e) {
125
                return in_array($e, array(1, 2, 3, 6, 12)) ? 'Perfect' : 'Not Perfect';
126
            }
127
        );
128
129
        $grouped = $groupByPerfectNumbers(range(1, 12));
130
131
        $this->assertArrayHasKey('Perfect', $grouped);
132
        $this->assertArrayHasKey('Not Perfect', $grouped);
133
        $this->assertContains(1, $grouped['Perfect']);
134
        $this->assertContains(2, $grouped['Perfect']);
135
        $this->assertContains(3, $grouped['Perfect']);
136
        $this->assertContains(5, $grouped['Not Perfect']);
137
        $this->assertContains(7, $grouped['Not Perfect']);
138
        $this->assertContains(9, $grouped['Not Perfect']);
139
    }
140
141
    public function testCanChunk(): void
142
    {
143
        $chunkIn5     = Arr\chunk(5);
144
        $chunkedRange = $chunkIn5(range(1, 500));
145
        $this->assertCount(100, $chunkedRange);
146
        $this->assertCount(5, $chunkedRange[5]);
147
        $this->assertCount(5, $chunkedRange[78]);
148
149
        // Check that keys are retained.
150
        $chunkInPairs = Arr\chunk(2, true);
151
        $chunkedNames = $chunkInPairs(array('Jim', 'Bob', 'Gem', 'Fay'));
152
        $this->assertCount(2, $chunkedNames);
153
        $this->assertEquals('Bob', $chunkedNames[0][1]);
154
        $this->assertEquals('Fay', $chunkedNames[1][3]);
155
    }
156
157
    public function testCanUseZip()
158
    {
159
        $array = ['a', 'b', 'c'];
160
161
        // Missing Key.
162
        $arrayMissing = ['A', 'B'];
163
        $expectedMissing = [['a', 'A'], ['b', 'B'], ['c', 'FALLBACK']];
164
        $resultMissing = Arr\zip($arrayMissing, 'FALLBACK')($array);
165
        $this->assertSame($resultMissing, $expectedMissing);
166
167
        // Matching length.
168
        $arrayFull = ['A', 'B', 'C'];
169
        $expectedFull = [['a', 'A'], ['b', 'B'], ['c', 'C']];
170
        $resultFull = Arr\zip($arrayFull, 'FALLBACK')($array);
171
        $this->assertSame($resultFull, $expectedFull);
172
    }
173
174
    public function testCanUseColumn(): void
175
    {
176
        $data = array(
177
            array(
178
                'id'   => 41,
179
                'name' => 'Bob',
180
                'foo'  => rand(1, 7),
181
            ),
182
            array(
183
                'id'   => 26,
184
                'name' => 'Jane',
185
                'foo'  => rand(1, 7),
186
            ),
187
            array(
188
                'id'   => 53,
189
                'name' => 'Sam',
190
                'foo'  => rand(1, 7),
191
            ),
192
            array(
193
                'id'   => 64,
194
                'name' => 'Bev',
195
                'foo'  => rand(1, 7),
196
            ),
197
            array(
198
                'id'   => 55,
199
                'name' => 'Joan',
200
                'foo'  => rand(1, 7),
201
            ),
202
            array(
203
                'id'   => 644,
204
                'name' => 'Bazza',
205
                'foo'  => rand(1, 7),
206
            ),
207
            array(
208
                'id'   => 66667,
209
                'name' => 'Duke',
210
                'foo'  => rand(1, 7),
211
            ),
212
            array(
213
                'id'   => 666668,
214
                'name' => 'Guybrush',
215
                'foo'  => rand(1, 7),
216
            ),
217
        );
218
219
        $getUsersNames = Arr\column('name', 'id');
220
        $this->assertCount(8, $getUsersNames($data));
221
        $this->assertEquals('Bob', $getUsersNames($data)[41]);
222
        $this->assertEquals('Bev', $getUsersNames($data)[64]);
223
        $this->assertEquals('Guybrush', $getUsersNames($data)[666668]);
224
225
        $getUsersRandoms = Arr\column('foo', 'name');
226
        $this->assertCount(8, $getUsersRandoms($data));
227
        $this->assertArrayHasKey('Bev', $getUsersRandoms($data));
228
        $this->assertArrayHasKey('Duke', $getUsersRandoms($data));
229
        $this->assertArrayNotHasKey(2, $getUsersRandoms($data));
230
        $this->assertArrayHasKey('Bazza', $getUsersRandoms($data));
231
    }
232
233
    public function testCanFlattenArray(): void
234
    {
235
        $array = array(
236
            1,
237
            2,
238
            array(3, 4),
239
            array(
240
                5,
241
                6,
242
                7,
243
                8,
244
                array(
245
                    9,
246
                    10,
247
                    array(11, 12, 13),
248
                ),
249
            ),
250
        );
251
        $this->assertArrayHasKey(2, Arr\flattenByN(2)($array));
252
        $this->assertIsArray(Arr\flattenByN(1)($array)[8]);
253
254
        $this->assertArrayHasKey(9, Arr\flattenByN(2)($array));
255
        $this->assertIsArray(Arr\flattenByN(2)($array)[10]);
256
257
        $this->assertArrayHasKey(12, Arr\flattenByN(3)($array));
258
        $this->assertEquals(13, Arr\flattenByN(3)($array)[12]);
259
260
        // Check will fully flatten if no depth defined.
261
        $this->assertArrayHasKey(12, Arr\flattenByN()($array));
262
        $this->assertEquals(13, Arr\flattenByN()($array)[12]);
263
    }
264
265
    public function testCanUseReplace()
266
    {
267
        $base          = array('orange', 'banana', 'apple', 'raspberry');
268
        $replacements  = array(
269
            0 => 'pineapple',
270
            4 => 'cherry',
271
        );
272
        $replacements2 = array(0 => 'grape');
273
274
        $replaceItems = Arr\replace($replacements, $replacements2);
275
276
        $this->assertIsArray($replaceItems($base));
277
        $this->assertEquals('grape', $replaceItems($base)[0]);
278
        $this->assertEquals('banana', $replaceItems($base)[1]);
279
        $this->assertEquals('apple', $replaceItems($base)[2]);
280
        $this->assertEquals('raspberry', $replaceItems($base)[3]);
281
        $this->assertEquals('cherry', $replaceItems($base)[4]);
282
    }
283
    public function testCanUseReplaceRecursive(): void
284
    {
285
        $base = array(
286
            'citrus'  => array('orange'),
287
            'berries' => array('apple', 'raspberry'),
288
        );
289
290
        $replacements = array(
291
            'citrus'  => array('pineapple'),
292
            'berries' => array('blueberry'),
293
        );
294
295
        $replaceItems = Arr\replaceRecursive($replacements);
296
297
        $this->assertIsArray($replaceItems($base));
298
        $this->assertArrayHasKey('citrus', $replaceItems($base));
299
        $this->assertArrayHasKey('berries', $replaceItems($base));
300
        $this->assertEquals('pineapple', $replaceItems($base)['citrus'][0]);
301
        $this->assertEquals('raspberry', $replaceItems($base)['berries'][1]);
302
    }
303
304
    public function testCanUseSumWhere()
305
    {
306
        $data = array(
307
            (object) array(
308
                'id'   => 1,
309
                'cost' => 12.55,
310
            ),
311
            (object) array(
312
                'id'   => 3,
313
                'cost' => 2.45,
314
            ),
315
            (object) array(
316
                'id'   => 34,
317
                'cost' => 99.99,
318
            ),
319
            (object) array(
320
                'id'   => 12,
321
                'cost' => 100.01,
322
            ),
323
        );
324
325
        $costSum = Arr\sumWhere(
326
            function ($e) {
327
                return $e->cost;
328
            }
329
        );
330
331
        $this->assertEquals(215.00, $costSum($data));
332
    }
333
334
335
336
    public function testCanSortArray(): void
337
    {
338
        $array         = array('b', 'c', 'a', 'f', 'd', 'z', 'g');
339
        $sortAsStrings = Arr\sort(SORT_STRING);
340
341
        $sortedArray = $sortAsStrings($array);
342
        $this->assertEquals('a', $sortedArray[0]);
343
        $this->assertEquals('b', $sortedArray[1]);
344
        $this->assertEquals('c', $sortedArray[2]);
345
        $this->assertEquals('z', $sortedArray[6]);
346
347
        // Check hasnt changed inital array.
348
        $this->assertEquals('c', $array[1]);
349
        $this->assertEquals('a', $array[2]);
350
    }
351
352
    public function testCanDoUasortOnArray(): void
353
    {
354
        $array = array(
355
            'a' => 4,
356
            'b' => 8,
357
            'c' => -1,
358
            'd' => -9,
359
            'e' => 2,
360
            'f' => 5,
361
            'g' => 3,
362
            'h' => -4,
363
        );
364
365
        $lowestFirstCallback = function ($a, $b) {
366
            if ($a == $b) {
367
                return 0;
368
            }
369
            return ($a < $b) ? -1 : 1;
370
        };
371
372
        $sortByLowest = Arr\uasort($lowestFirstCallback);
373
374
        // Still retains the key.
375
        $sortedArray = $sortByLowest($array);
376
377
        $this->assertEquals(-9, $sortedArray['d']);
378
        $this->assertEquals(-9, array_values($sortedArray)[0]);
379
380
        $this->assertEquals(2, $sortedArray['e']);
381
        $this->assertEquals(2, array_values($sortedArray)[3]);
382
383
        $this->assertEquals(8, $sortedArray['b']);
384
        $this->assertEquals(8, array_values($sortedArray)[7]);
385
    }
386
387
388
    public function testCanDoUsortOnArray(): void
389
    {
390
        $array = array(3, 2, 5, 6, 1);
391
392
        $lowestFirstCallback = function ($a, $b) {
393
            if ($a == $b) {
394
                return 0;
395
            }
396
            return ($a < $b) ? -1 : 1;
397
        };
398
399
        $sortByLowest = Arr\usort($lowestFirstCallback);
400
401
        // Still retains the key.
402
        $sortedArray = $sortByLowest($array);
403
404
        $this->assertEquals(1, $sortedArray[0]);
405
        $this->assertEquals(2, $sortedArray[1]);
406
        $this->assertEquals(5, $sortedArray[3]);
407
        $this->assertEquals(6, $sortedArray[4]);
408
    }
409
410
    public function testCanPartitionTable()
411
    {
412
        $isEven = function ($e) {
413
            return $e % 2 === 0;
414
        };
415
416
        $sortByOddEven = Arr\partition($isEven);
417
418
        $data = array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
419
420
        $sorted = $sortByOddEven($data);
421
        $this->assertCount(5, $sorted[0]);
422
        $this->assertCount(5, $sorted[1]);
423
424
        $this->assertContains(2, $sorted[1]);
425
        $this->assertContains(4, $sorted[1]);
426
        $this->assertContains(8, $sorted[1]);
427
        $this->assertContains(3, $sorted[0]);
428
        $this->assertContains(7, $sorted[0]);
429
    }
430
431
    public function testCanDoToString(): void
432
    {
433
        $source = array(
434
            'hi',
435
            'there',
436
            'how',
437
            'are',
438
            'you',
439
            3,
440
            12.7,
441
            true,
442
            null,
443
        );
444
445
        $noSpacing   = Arr\toString();
446
        $withSpacing = Arr\toString(' ');
447
448
        $this->assertEquals('hitherehowareyou312.71', $noSpacing($source));
449
        $this->assertEquals('hi there how are you 3 12.7 1 ', $withSpacing($source));
450
    }
451
}
452