Skip to content

Commit dc8077d

Browse files
authored
Merge pull request #11 from pitchart/feature/optional-iterable
Allows reducing functions to directly handle iterables
2 parents 2d26999 + 19d24c1 commit dc8077d

20 files changed

+834
-94
lines changed

src/Transducer/transducers.php

Lines changed: 187 additions & 85 deletions
Large diffs are not rendered by default.

src/transform.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ function identity($value)
4040
}
4141

4242
/**
43+
* Transforms a function into a pure function
44+
*
4345
* @param callable $function
4446
* @param array ...$arguments
4547
*

tests/Reducer/CatTest.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,17 @@
33
namespace Pitchart\Transformer\Tests\Reducer;
44

55
use PHPUnit\Framework\TestCase;
6-
use Pitchart\Transformer\Reducer\Cat;
6+
use Pitchart\Transformer\Reducer;
77
use Pitchart\Transformer\Transformer;
8+
use Pitchart\Transformer\Transducer as t;
89

910
class CatTest extends TestCase
1011
{
12+
public function test_is_a_reducer()
13+
{
14+
self::assertInstanceOf(Reducer::class, t\cat()(t\to_array()));
15+
}
16+
1117
public function test_concatenates_items_from_nested_lists()
1218
{
1319
$concatenated = (new Transformer([0 ,1, [2, 3], [[4, 5], 6]]))
@@ -23,4 +29,16 @@ public function test_removes_empty_nested_lists()
2329

2430
self::assertEquals([0, 1, 2, 3, [4, 5], 6], $concatenated);
2531
}
32+
33+
public function test_applies_to_arrays()
34+
{
35+
$concatenated = t\cat([0 ,1, [], [2, 3], [[4, 5], 6]]);
36+
self::assertEquals([0, 1, 2, 3, [4, 5], 6], $concatenated);
37+
}
38+
39+
public function test_applies_to_iterators()
40+
{
41+
$concatenated = t\cat(new \ArrayIterator([0 ,1, [], [2, 3], [[4, 5], 6]]));
42+
self::assertEquals([0, 1, 2, 3, [4, 5], 6], $concatenated);
43+
}
2644
}

tests/Reducer/DedupeTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Pitchart\Transformer\Tests\Reducer;
4+
5+
use Pitchart\Transformer\Reducer;
6+
use Pitchart\Transformer\Reducer\Dedupe;
7+
use Pitchart\Transformer\Transducer as t;
8+
use PHPUnit\Framework\TestCase;
9+
use Pitchart\Transformer\Transformer;
10+
11+
class DedupeTest extends TestCase
12+
{
13+
public function test_is_a_reducer()
14+
{
15+
self::assertInstanceOf(Reducer::class, t\dedupe()(t\to_array()));
16+
}
17+
18+
public function test_removes_consecutive_equals_items()
19+
{
20+
$deduped = (new Transformer([1, 2, 3, 2, 2, 4, 6, 5, 1, 0, 0, 1]))
21+
->dedupe()->toArray();
22+
23+
self::assertEquals([1, 2, 3, 2, 4, 6, 5, 1, 0, 1], $deduped);
24+
}
25+
26+
public function test_applies_to_arrays()
27+
{
28+
$deduped = t\dedupe([1, 2, 3, 2, 2, 4, 6, 5, 1, 0, 0, 1]);
29+
self::assertEquals([1, 2, 3, 2, 4, 6, 5, 1, 0, 1], $deduped);
30+
}
31+
32+
public function test_applies_to_iterators()
33+
{
34+
$deduped = t\dedupe(new \ArrayIterator([1, 2, 3, 2, 2, 4, 6, 5, 1, 0, 0, 1]));
35+
self::assertEquals([1, 2, 3, 2, 4, 6, 5, 1, 0, 1], $deduped);
36+
}
37+
38+
}

tests/Reducer/DropTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Pitchart\Transformer\Tests\Reducer;
4+
5+
use Pitchart\Transformer\Reducer;
6+
use Pitchart\Transformer\Reducer\Drop;
7+
use PHPUnit\Framework\TestCase;
8+
use Pitchart\Transformer\Transformer;
9+
use Pitchart\Transformer\Transducer as t;
10+
11+
class DropTest extends TestCase
12+
{
13+
public function test_is_a_reducer()
14+
{
15+
self::assertInstanceOf(Reducer::class, t\drop(3)(t\to_array()));
16+
}
17+
18+
public function test_drops_a_number_of_values_from_a_collection()
19+
{
20+
$dropped = (new Transformer(range(1, 6)))
21+
->drop(4)->toArray();
22+
23+
self::assertEquals([5,6], $dropped);
24+
}
25+
26+
public function test_applies_to_arrays()
27+
{
28+
$dropped = t\drop(4, range(1, 6));
29+
self::assertEquals([5,6], $dropped);
30+
}
31+
32+
public function test_applies_to_iterators()
33+
{
34+
$dropped = t\drop(4, new \ArrayIterator(range(1, 6)));
35+
self::assertEquals([5, 6], $dropped);
36+
}
37+
38+
}

tests/Reducer/DropWhileTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace Pitchart\Transformer\Tests\Reducer;
4+
5+
use Pitchart\Transformer\Reducer;
6+
use Pitchart\Transformer\Reducer\DropWhile;
7+
use PHPUnit\Framework\TestCase;
8+
use function Pitchart\Transformer\Tests\is_lower_than_four;
9+
use Pitchart\Transformer\Transformer;
10+
use Pitchart\Transformer\Transducer as t;
11+
12+
class DropWhileTest extends TestCase
13+
{
14+
public function test_is_a_reducer()
15+
{
16+
self::assertInstanceOf(Reducer::class, t\drop_while(is_lower_than_four())(t\to_array()));
17+
}
18+
19+
public function test_drops_items_while_a_predicat_is_true()
20+
{
21+
$dropped = (new Transformer(range(1, 6)))
22+
->dropWhile(is_lower_than_four())->toArray();
23+
self::assertEquals([4, 5, 6], $dropped);
24+
}
25+
26+
public function test_applies_to_arrays()
27+
{
28+
$dropped = t\drop_while(is_lower_than_four(), range(1, 6));
29+
self::assertEquals([4, 5, 6], $dropped);
30+
}
31+
32+
public function test_applies_to_iterators()
33+
{
34+
$dropped = t\drop_while(is_lower_than_four(), new \ArrayIterator(range(1, 6)));
35+
self::assertEquals([4, 5, 6], $dropped);
36+
}
37+
38+
}

tests/Reducer/FilterTest.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace Pitchart\Transformer\Tests\Reducer;
44

5-
use Pitchart\Transformer\Reducer\Filter;
65
use PHPUnit\Framework\TestCase;
76
use Pitchart\Transformer\Reducer;
87
use Pitchart\Transformer\Transformer;
@@ -26,4 +25,16 @@ public function test_filters_items_with_a_callback()
2625

2726
$this->assertEquals([2, 4], $squared);
2827
}
28+
29+
public function test_applies_to_arrays()
30+
{
31+
$evens = t\filter(is_even(), [1, 2, 3, 4]);
32+
self::assertEquals([2, 4], $evens);
33+
}
34+
35+
public function test_applies_to_iterators()
36+
{
37+
$evens = t\filter(is_even(), new \ArrayIterator([1, 2, 3, 4]));
38+
self::assertEquals([2, 4], $evens);
39+
}
2940
}

tests/Reducer/FirstTest.php

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
namespace Pitchart\Transformer\Tests\Reducer;
4+
5+
use PHPUnit\Framework\TestCase;
6+
use function Pitchart\Transformer\Tests\is_greater_than_three;
7+
use Pitchart\Transformer\Transformer;
8+
use Pitchart\Transformer\Transducer as t;
9+
10+
class FirstTest extends TestCase
11+
{
12+
13+
public function test_gets_first_matching_item_of_iterable()
14+
{
15+
$first = (new Transformer(range(1,6)))
16+
->first(is_greater_than_three())->single();
17+
18+
self::assertEquals(4, $first);
19+
}
20+
21+
public function test_gets_first_matching_item_of_arrays()
22+
{
23+
$first = t\first(is_greater_than_three(), range(1, 6));
24+
self::assertEquals(4, $first);
25+
}
26+
27+
public function test_gets_first_matching_item_of_iterator()
28+
{
29+
$first = t\first(is_greater_than_three(), range(1, 6));
30+
self::assertEquals(4, $first);
31+
}
32+
}

tests/Reducer/FlattenTest.php

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,19 @@
22

33
namespace Pitchart\Transformer\Tests\Reducer;
44

5+
use Pitchart\Transformer\Reducer;
56
use Pitchart\Transformer\Reducer\Flatten;
67
use PHPUnit\Framework\TestCase;
78
use Pitchart\Transformer\Transformer;
9+
use Pitchart\Transformer\Transducer as t;
810

911
class FlattenTest extends TestCase
1012
{
13+
public function test_is_a_reducer()
14+
{
15+
self::assertInstanceOf(Reducer::class, t\flatten()(t\to_array()));
16+
}
17+
1118
public function test_converts_nested_sequences_to_a_single_flat_sequence()
1219
{
1320
$flat = (new Transformer([0 ,1, [2, 3], [[4, 5], 6]]))
@@ -16,12 +23,24 @@ public function test_converts_nested_sequences_to_a_single_flat_sequence()
1623
self::assertEquals([0, 1, 2, 3, 4, 5, 6], $flat);
1724
}
1825

19-
public function test_flatten_is_immutable()
26+
public function test_is_immutable()
2027
{
2128
$flatten = (new Transformer([0 ,1, [2, 3], [[4, 5], 6]]))
2229
->flatten();
2330

2431
self::assertEquals([0, 1, 2, 3, 4, 5, 6], $flatten->toArray());
2532
self::assertEquals([0, 1, 2, 3, 4, 5, 6], $flatten->toArray());
2633
}
34+
35+
public function test_applies_to_arrays()
36+
{
37+
$flat = t\flatten([0 ,1, [2, 3], [[4, 5], 6]]);
38+
self::assertEquals([0, 1, 2, 3, 4, 5, 6], $flat);
39+
}
40+
41+
public function test_applies_to_iterators()
42+
{
43+
$flat = t\flatten(new \ArrayIterator([0 ,1, [2, 3], [[4, 5], 6]]));
44+
self::assertEquals([0, 1, 2, 3, 4, 5, 6], $flat);
45+
}
2746
}

tests/Reducer/GroupByTest.php

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<?php
2+
3+
namespace Pitchart\Transformer\Tests\Reducer;
4+
5+
use Pitchart\Transformer\Reducer;
6+
use Pitchart\Transformer\Reducer\GroupBy;
7+
use PHPUnit\Framework\TestCase;
8+
use Pitchart\Transformer\Transducer as t;
9+
use Pitchart\Transformer\Transformer;
10+
11+
class GroupByTest extends TestCase
12+
{
13+
public function test_is_a_reducer()
14+
{
15+
self::assertInstanceOf(Reducer::class, t\group_by(function ($item) {return $item['group'];})(t\to_single()));
16+
}
17+
18+
/**
19+
* @param array $data
20+
* @param \Closure $callable
21+
* @param array $expected
22+
*
23+
* @dataProvider groupableDataProvider
24+
*/
25+
public function test_groups_items_by_a_callback($data, $callable, $expected)
26+
{
27+
$grouped = (new Transformer($data))
28+
->groupBy($callable)
29+
->single()
30+
;
31+
32+
self::assertEquals($expected, $grouped);
33+
}
34+
35+
/**
36+
* @param array $data
37+
* @param \Closure $callable
38+
* @param array $expected
39+
*
40+
* @dataProvider groupableDataProvider
41+
*/
42+
public function test_applies_to_arrays($data, $callable, $expected)
43+
{
44+
$grouped = t\group_by($callable, $data);
45+
self::assertEquals($expected, $grouped);
46+
}
47+
48+
/**
49+
* @param array $data
50+
* @param \Closure $callable
51+
* @param array $expected
52+
*
53+
* @dataProvider groupableDataProvider
54+
*/
55+
public function test_applies_to_iterators($data, $callable, $expected)
56+
{
57+
$grouped = t\group_by($callable, new \ArrayIterator($data));
58+
self::assertEquals($expected, $grouped);
59+
}
60+
61+
public function groupableDataProvider()
62+
{
63+
return [
64+
[
65+
[
66+
['group' => 'foo', 'value' => 'bar'],
67+
['group' => 'bar', 'value' => 'foo'],
68+
['group' => 'fizz', 'value' => 'bar'],
69+
['group' => 'foo', 'value' => 'test'],
70+
['group' => 'fizz', 'value' => 'foo'],
71+
['group' => 'bar', 'value' => 'foo'],
72+
],
73+
function ($item) {return $item['group'];},
74+
[
75+
'foo' => [['group' => 'foo', 'value' => 'bar'], ['group' => 'foo', 'value' => 'test'],],
76+
'bar' => [['group' => 'bar', 'value' => 'foo'], ['group' => 'bar', 'value' => 'foo'],],
77+
'fizz' => [['group' => 'fizz', 'value' => 'bar'], ['group' => 'fizz', 'value' => 'foo'],],
78+
]
79+
]
80+
];
81+
}
82+
}

0 commit comments

Comments
 (0)