Skip to content

Commit

Permalink
Refactoring.
Browse files Browse the repository at this point in the history
  • Loading branch information
drupol committed Aug 27, 2019
1 parent a543106 commit 5b2a0cf
Show file tree
Hide file tree
Showing 70 changed files with 409 additions and 428 deletions.
21 changes: 10 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
A Collection is an object that can hold a list of items and do things with it.

This Collection class:
* is immutable,
* is [immutable](https://en.wikipedia.org/wiki/Immutable_object),
* extendable,
* leverage the power of PHP generators and iterators,
* doesn't depends or require any other library or framework.
* leverage the power of PHP [generators](https://www.php.net/manual/en/class.generator.php) and [iterators](https://www.php.net/manual/en/class.iterator.php),
* use [S.O.L.I.D principles](https://en.wikipedia.org/wiki/SOLID),
* doesn't depends or require any other library or framework.

Except a few methods, most of methods are pure and returning a new Collection object.

Expand Down Expand Up @@ -152,21 +153,20 @@ $square = new class() extends Operation {
/**
* {@inheritdoc}
*/
public function run(CollectionInterface $collection): CollectionInterface
public function on(\Traversable $collection): \Closure
{
return Collection::with(
static function () use ($collection) {
return static function () use ($collection) {
foreach ($collection as $item) {
yield $item ** 2;
}
}
);
};
}
};

Collection::range(5, 15)
Collection::with(
Collection::range(5, 15)
->run($square)
->all(); // [25, 36, 49, 64, 81, 100, 121, 144, 169, 196]
)->all();
```

## API
Expand Down Expand Up @@ -203,7 +203,6 @@ the methods always return the same values for the same inputs.
| `pad` | new Collection object | [Pad.php](./src/Operation/Pad.php)
| `pluck` | new Collection object | [Pluck.php](./src/Operation/Pluck.php)
| `prepend` | new Collection object | [Prepend.php](./src/Operation/Prepend.php)
| `proxy` | new Collection object | [Proxy.php](./src/Operation/Proxy.php)
| `rebase` | new Collection object | [Rebase.php](./src/Operation/Rebase.php)
| `reduce` | mixed | [Reduce.php](./src/Operation/Reduce.php)
| `run` | mixed | [Run.php](./src/Operation/Run.php)
Expand Down
44 changes: 10 additions & 34 deletions spec/drupol/collection/CollectionSpec.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use drupol\collection\BaseCollection;
use drupol\collection\Collection;
use drupol\collection\Contract\BaseCollection as CollectionInterface;
use drupol\collection\Contract\Operation;
use PhpSpec\ObjectBehavior;

Expand All @@ -15,7 +14,7 @@ class CollectionSpec extends ObjectBehavior
public function it_can_append_items(): void
{
$this
->beConstructedThrough('with', [new \ArrayObject(['1', '2', '3'])]);
->beConstructedThrough('with', [['1', '2', '3']]);

$this
->append('4')
Expand Down Expand Up @@ -63,7 +62,7 @@ public function it_can_apply(): void
->apply(static function ($item) {
return false;
})
->shouldReturn($this);
->shouldReturnAnInstanceOf(\drupol\collection\Contract\BaseCollection::class);

$callback = static function (): void {
throw new \Exception('foo');
Expand Down Expand Up @@ -225,17 +224,17 @@ public function it_can_chunk(): void
$this
->beConstructedThrough('with', [\range('A', 'F')]);

$this
$this::with(\range('A', 'F'))
->chunk(2)
->all()
->shouldReturn([[0 => 'A', 1 => 'B'], [2 => 'C', 3 => 'D'], [4 => 'E', 5 => 'F']]);

$this
$this::with(\range('A', 'F'))
->chunk(0)
->all()
->shouldReturn([]);

$this
$this::with(\range('A', 'F'))
->chunk(1)
->all()
->shouldReturn([[0 => 'A'], [1 => 'B'], [2 => 'C'], [3 => 'D'], [4 => 'E'], [5 => 'F']]);
Expand Down Expand Up @@ -728,29 +727,6 @@ public function it_can_prepend(): void
->shouldReturn(['A', 'B', 'C', 'D', 'E', 'F']);
}

public function it_can_proxy(): void
{
$input1 = new \ArrayObject(\range('A', 'E'));
$input2 = new \ArrayObject(\range(1, 5));

$this
->beConstructedThrough('with', [[$input1, $input2]]);

$this
->proxy('map', 'count')
->all()
->shouldReturn([5, 5]);

$this
->proxy('map', 'foo')
->shouldThrow(\Exception::class)
->during('all');

$this
->shouldThrow(\Exception::class)
->during('proxy', ['foo', 'foo']);
}

public function it_can_rebase(): void
{
$this
Expand Down Expand Up @@ -780,7 +756,7 @@ static function ($carry, $item) {
public function it_can_run_an_operation(Operation $operation): void
{
$square = new class() extends \drupol\collection\Operation\Operation {
public function run(CollectionInterface $collection)
public function on(\Traversable $collection)
{
return Collection::with(
static function () use ($collection) {
Expand All @@ -793,7 +769,7 @@ static function () use ($collection) {
};

$sqrt = new class() extends \drupol\collection\Operation\Operation {
public function run(CollectionInterface $collection)
public function on(\Traversable $collection)
{
return Collection::with(
static function () use ($collection) {
Expand All @@ -806,7 +782,7 @@ static function () use ($collection) {
};

$map = new class() extends \drupol\collection\Operation\Operation {
public function run(CollectionInterface $collection)
public function on(\Traversable $collection)
{
return Collection::with(
static function () use ($collection) {
Expand Down Expand Up @@ -974,12 +950,12 @@ public function it_can_zip(): void
$this
->zip(['D', 'E', 'F'])
->all()
->shouldIterateAs([['A', 'D'], ['B', 'E'], ['C', 'F']]);
->shouldReturn([['A', 'D'], ['B', 'E'], ['C', 'F']]);

$this::with(['A', 'C', 'E'])
->zip(['B', 'D', 'F', 'H'])
->all()
->shouldIterateAs([['A', 'B'], ['C', 'D'], ['E', 'F'], [null, 'H']]);
->shouldReturn([['A', 'B'], ['C', 'D'], ['E', 'F'], [null, 'H']]);

$collection = Collection::with(\range(1, 5));

Expand Down
28 changes: 11 additions & 17 deletions src/BaseCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace drupol\collection;

use drupol\collection\Contract\BaseCollection as BaseCollectionInterface;
use drupol\collection\Iterator\ClosureIterator;

/**
* Class BaseCollection.
Expand All @@ -28,38 +29,31 @@ public function __construct($data = [])
$this->source = $data;

break;
case $data instanceof \IteratorAggregate:
case $data instanceof \Traversable:
$this->source = static function () use ($data) {
yield from \iterator_to_array(
(static function () use ($data) {
yield from $data;
})()
);
foreach ($data as $k => $v) {
yield $k => $v;
}
};

break;

default:
$this->source = static function () use ($data) {
yield from (array) $data;
foreach ((array) $data as $k => $v) {
yield $k => $v;
}
};
}
}

/**
* {@inheritdoc}
*
* @throws \ReflectionException
*/
public function getIterator()
{
return ($this->source)();
}

/**
* {@inheritdoc}
*/
public static function with($data = []): BaseCollectionInterface
public function getIterator(): ClosureIterator
{
return new static($data);
return new ClosureIterator($this->source);
}
}

0 comments on commit 5b2a0cf

Please sign in to comment.