Skip to content

Commit

Permalink
refactor!: Make Collection an instantiable class.
Browse files Browse the repository at this point in the history
  • Loading branch information
b00gizm committed Jan 16, 2023
1 parent c1a00b4 commit 3ca9db5
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 61 deletions.
20 changes: 6 additions & 14 deletions src/Domain/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,22 @@
use IteratorAggregate;
use Traversable;

abstract class Collection implements Countable, IteratorAggregate
class Collection implements Countable, IteratorAggregate
{
/**
* @template T of object
* @extends IteratorAggregate<T>
*
* @param T[] $items
* @param class-string<T> $itemType
*/
final public function __construct(
private readonly array $items = [],
?string $itemType = null,
) {
Assert\Assertion::allIsInstanceOf($items, $this->itemType());
if ($itemType !== null) {
Assert\Assertion::allIsInstanceOf($items, $itemType);
}
}

/**
Expand All @@ -39,16 +43,4 @@ public function count(): int
{
return count($this->items);
}

/**
* @inheritDoc
*/

/**
* Return the type of the items in the collection.
* This is a poor man's workaround for missing generics in PHP.
*
* @return string
*/
abstract protected function itemType(): string;
}
6 changes: 1 addition & 5 deletions src/Infrastructure/InMemory/Repository.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,23 +23,19 @@ abstract class Repository implements RepositoryInterface
* @extends IteratorAggregate<T>
*
* @param class-string<T> $itemType
* @param class-string<Collection<T>> $collectionType
*/
public function __construct(
private string $itemType,
private string $collectionType,
) {
Assert::that($this->itemType)->classExists();
Assert::that($this->collectionType)->classExists();
}

/**
* @inheritDoc
*/
public function collect(): Collection
{
$collectionClass = $this->collectionType;
return new $collectionClass($this->items);
return new Collection($this->items, $this->itemType);
}

/**
Expand Down
38 changes: 18 additions & 20 deletions tests/Domain/CollectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,20 @@ class Foo
{
}

/**
* Test subject.
*
* @package GeekCell\Ddd\Tests\Domain
*/
class TestCollection extends Collection
{
protected function itemType(): string
{
return Foo::class;
}
}

class CollectionTest extends TestCase
{
public function testConstructor(): void
public function testTypedConstructor(): void
{
// Given
$items = [new Foo(), new Foo(), new Foo()];

// When
$collection = new TestCollection($items);
$collection = new Collection($items, Foo::class);

$this->assertInstanceOf(TestCollection::class, $collection);
$this->assertInstanceOf(Collection::class, $collection);
}

public function testConstructorWithInvalidType(): void
public function testTypedConstructorWithInvalidType(): void
{
// Given
$items = [new Foo(), new Foo(), new \stdClass()];
Expand All @@ -52,7 +39,18 @@ public function testConstructorWithInvalidType(): void
$this->expectException(Assert\InvalidArgumentException::class);

// When
$collection = new TestCollection($items);
$collection = new Collection($items, Foo::class);
}

public function testUntypedConstructor(): void
{
// Given
$items = [new Foo(), new \stdClass(), 42, 'foo'];

// When
$collection = new Collection($items);

$this->assertInstanceOf(Collection::class, $collection);
}

public function testCount(): void
Expand All @@ -61,7 +59,7 @@ public function testCount(): void
$items = [new Foo(), new Foo(), new Foo()];

// When
$collection = new TestCollection($items);
$collection = new Collection($items, Foo::class);

// Then
$this->assertCount(3, $collection);
Expand All @@ -73,7 +71,7 @@ public function testIterater(): void
$items = [new Foo(), new Foo(), new Foo()];

// When
$collection = new TestCollection($items);
$collection = new Collection($items, Foo::class);

// Then
$this->assertEquals($items, iterator_to_array($collection));
Expand Down
25 changes: 3 additions & 22 deletions tests/Infrastructure/InMemory/RepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,6 @@
use GeekCell\Ddd\Tests\Fixtures\Counter;
use PHPUnit\Framework\TestCase;

/**
* Test fixture for InMemoryRepository.
*
* @package GeekCell\Ddd\Tests\Infrastructure
*/
class CounterCollection extends Collection
{
protected function itemType(): string
{
return Counter::class;
}
}

/**
* Test subject.
*
Expand All @@ -33,10 +20,7 @@ class InMemoryTestRepository extends InMemoryRepository
{
public function __construct()
{
parent::__construct(
Counter::class,
CounterCollection::class
);
parent::__construct(Counter::class);
}

public function setItems(array $items): void
Expand Down Expand Up @@ -74,10 +58,7 @@ public function testConstructWithInvalidTypes(): void
$instance = new class () extends InMemoryRepository {
public function __construct()
{
parent::__construct(
'Foo\Bar\Baz',
'Foo\Bar\BazCollection'
);
parent::__construct('Foo\Bar\Baz');
}
};
}
Expand All @@ -96,7 +77,7 @@ public function testCollectAndCount(): void
$result = $repository->collect();

// Then
$this->assertInstanceOf(CounterCollection::class, $result);
$this->assertInstanceOf(Collection::class, $result);
$this->assertEquals(count($this->items), count($result));
}

Expand Down

0 comments on commit 3ca9db5

Please sign in to comment.