Skip to content

Commit 3ca9db5

Browse files
committed
refactor!: Make Collection an instantiable class.
1 parent c1a00b4 commit 3ca9db5

File tree

4 files changed

+28
-61
lines changed

4 files changed

+28
-61
lines changed

src/Domain/Collection.php

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,22 @@
1010
use IteratorAggregate;
1111
use Traversable;
1212

13-
abstract class Collection implements Countable, IteratorAggregate
13+
class Collection implements Countable, IteratorAggregate
1414
{
1515
/**
1616
* @template T of object
1717
* @extends IteratorAggregate<T>
1818
*
1919
* @param T[] $items
20+
* @param class-string<T> $itemType
2021
*/
2122
final public function __construct(
2223
private readonly array $items = [],
24+
?string $itemType = null,
2325
) {
24-
Assert\Assertion::allIsInstanceOf($items, $this->itemType());
26+
if ($itemType !== null) {
27+
Assert\Assertion::allIsInstanceOf($items, $itemType);
28+
}
2529
}
2630

2731
/**
@@ -39,16 +43,4 @@ public function count(): int
3943
{
4044
return count($this->items);
4145
}
42-
43-
/**
44-
* @inheritDoc
45-
*/
46-
47-
/**
48-
* Return the type of the items in the collection.
49-
* This is a poor man's workaround for missing generics in PHP.
50-
*
51-
* @return string
52-
*/
53-
abstract protected function itemType(): string;
5446
}

src/Infrastructure/InMemory/Repository.php

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,23 +23,19 @@ abstract class Repository implements RepositoryInterface
2323
* @extends IteratorAggregate<T>
2424
*
2525
* @param class-string<T> $itemType
26-
* @param class-string<Collection<T>> $collectionType
2726
*/
2827
public function __construct(
2928
private string $itemType,
30-
private string $collectionType,
3129
) {
3230
Assert::that($this->itemType)->classExists();
33-
Assert::that($this->collectionType)->classExists();
3431
}
3532

3633
/**
3734
* @inheritDoc
3835
*/
3936
public function collect(): Collection
4037
{
41-
$collectionClass = $this->collectionType;
42-
return new $collectionClass($this->items);
38+
return new Collection($this->items, $this->itemType);
4339
}
4440

4541
/**

tests/Domain/CollectionTest.php

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,33 +17,20 @@ class Foo
1717
{
1818
}
1919

20-
/**
21-
* Test subject.
22-
*
23-
* @package GeekCell\Ddd\Tests\Domain
24-
*/
25-
class TestCollection extends Collection
26-
{
27-
protected function itemType(): string
28-
{
29-
return Foo::class;
30-
}
31-
}
32-
3320
class CollectionTest extends TestCase
3421
{
35-
public function testConstructor(): void
22+
public function testTypedConstructor(): void
3623
{
3724
// Given
3825
$items = [new Foo(), new Foo(), new Foo()];
3926

4027
// When
41-
$collection = new TestCollection($items);
28+
$collection = new Collection($items, Foo::class);
4229

43-
$this->assertInstanceOf(TestCollection::class, $collection);
30+
$this->assertInstanceOf(Collection::class, $collection);
4431
}
4532

46-
public function testConstructorWithInvalidType(): void
33+
public function testTypedConstructorWithInvalidType(): void
4734
{
4835
// Given
4936
$items = [new Foo(), new Foo(), new \stdClass()];
@@ -52,7 +39,18 @@ public function testConstructorWithInvalidType(): void
5239
$this->expectException(Assert\InvalidArgumentException::class);
5340

5441
// When
55-
$collection = new TestCollection($items);
42+
$collection = new Collection($items, Foo::class);
43+
}
44+
45+
public function testUntypedConstructor(): void
46+
{
47+
// Given
48+
$items = [new Foo(), new \stdClass(), 42, 'foo'];
49+
50+
// When
51+
$collection = new Collection($items);
52+
53+
$this->assertInstanceOf(Collection::class, $collection);
5654
}
5755

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

6361
// When
64-
$collection = new TestCollection($items);
62+
$collection = new Collection($items, Foo::class);
6563

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

7573
// When
76-
$collection = new TestCollection($items);
74+
$collection = new Collection($items, Foo::class);
7775

7876
// Then
7977
$this->assertEquals($items, iterator_to_array($collection));

tests/Infrastructure/InMemory/RepositoryTest.php

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,6 @@
1111
use GeekCell\Ddd\Tests\Fixtures\Counter;
1212
use PHPUnit\Framework\TestCase;
1313

14-
/**
15-
* Test fixture for InMemoryRepository.
16-
*
17-
* @package GeekCell\Ddd\Tests\Infrastructure
18-
*/
19-
class CounterCollection extends Collection
20-
{
21-
protected function itemType(): string
22-
{
23-
return Counter::class;
24-
}
25-
}
26-
2714
/**
2815
* Test subject.
2916
*
@@ -33,10 +20,7 @@ class InMemoryTestRepository extends InMemoryRepository
3320
{
3421
public function __construct()
3522
{
36-
parent::__construct(
37-
Counter::class,
38-
CounterCollection::class
39-
);
23+
parent::__construct(Counter::class);
4024
}
4125

4226
public function setItems(array $items): void
@@ -74,10 +58,7 @@ public function testConstructWithInvalidTypes(): void
7458
$instance = new class () extends InMemoryRepository {
7559
public function __construct()
7660
{
77-
parent::__construct(
78-
'Foo\Bar\Baz',
79-
'Foo\Bar\BazCollection'
80-
);
61+
parent::__construct('Foo\Bar\Baz');
8162
}
8263
};
8364
}
@@ -96,7 +77,7 @@ public function testCollectAndCount(): void
9677
$result = $repository->collect();
9778

9879
// Then
99-
$this->assertInstanceOf(CounterCollection::class, $result);
80+
$this->assertInstanceOf(Collection::class, $result);
10081
$this->assertEquals(count($this->items), count($result));
10182
}
10283

0 commit comments

Comments
 (0)