Skip to content

Commit 03184f3

Browse files
authored
Release/2.0.1 (#23)
1 parent 27df0f6 commit 03184f3

File tree

5 files changed

+103
-0
lines changed

5 files changed

+103
-0
lines changed

src/Internal/Extractors/IterableExtractor.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ public function __construct(private ReflectionExtractor $extractor)
1414

1515
public function extract(object $object): array
1616
{
17+
if ($object instanceof Traversable) {
18+
return iterator_to_array($object);
19+
}
20+
1721
$properties = $this->extractor->extractProperties(object: $object);
1822

1923
$candidates = array_filter(

tests/CollectionMappingTest.php

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
use Test\TinyBlocks\Mapper\Models\Description;
1818
use Test\TinyBlocks\Mapper\Models\Employee;
1919
use Test\TinyBlocks\Mapper\Models\Employees;
20+
use Test\TinyBlocks\Mapper\Models\Invoice;
21+
use Test\TinyBlocks\Mapper\Models\Invoices;
22+
use Test\TinyBlocks\Mapper\Models\InvoiceSummaries;
2023
use Test\TinyBlocks\Mapper\Models\Member;
2124
use Test\TinyBlocks\Mapper\Models\MemberId;
2225
use Test\TinyBlocks\Mapper\Models\Members;
@@ -89,6 +92,30 @@ public function testCollectionOfScalars(): void
8992
self::assertSame('mixed', $attributes->getType());
9093
}
9194

95+
public function testCollectionOfTraversable(): void
96+
{
97+
/** @Given an InvoiceSummaries collection with traversable invoices */
98+
$invoiceSummaries = InvoiceSummaries::createFrom(
99+
invoices: Invoices::createFrom(elements: [
100+
new Invoice(id: 'INV001', amount: 100.0, customer: 'Customer A'),
101+
new Invoice(id: 'INV002', amount: 150.5, customer: 'Customer B'),
102+
new Invoice(id: 'INV003', amount: 200.75, customer: 'Customer C')
103+
])
104+
);
105+
106+
/** @When mapping the InvoiceSummaries collection to an array */
107+
$actual = $invoiceSummaries->toArray();
108+
109+
/** @Then the mapped array should have expected values */
110+
$expected = [
111+
'INV001' => ['id' => 'INV001', 'amount' => 100.0, 'customer' => 'Customer A'],
112+
'INV002' => ['id' => 'INV002', 'amount' => 150.5, 'customer' => 'Customer B'],
113+
'INV003' => ['id' => 'INV003', 'amount' => 200.75, 'customer' => 'Customer C']
114+
];
115+
116+
self::assertSame($expected, $actual);
117+
}
118+
92119
#[DataProvider('collectionDiscardKeysProvider')]
93120
public function testCollectionDiscardKeys(IterableMapper $collection, array $expected): void
94121
{

tests/Models/Invoice.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Test\TinyBlocks\Mapper\Models;
6+
7+
final readonly class Invoice
8+
{
9+
public function __construct(public string $id, public float $amount, public string $customer)
10+
{
11+
}
12+
}

tests/Models/InvoiceSummaries.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Test\TinyBlocks\Mapper\Models;
6+
7+
use IteratorAggregate;
8+
use TinyBlocks\Mapper\IterableMappability;
9+
use TinyBlocks\Mapper\IterableMapper;
10+
use Traversable;
11+
12+
final class InvoiceSummaries implements IterableMapper, IteratorAggregate
13+
{
14+
use IterableMappability;
15+
16+
private function __construct(private readonly Invoices $invoices)
17+
{
18+
}
19+
20+
public static function createFrom(Invoices $invoices): InvoiceSummaries
21+
{
22+
return new InvoiceSummaries(invoices: $invoices);
23+
}
24+
25+
public function getIterator(): Traversable
26+
{
27+
foreach ($this->invoices as $invoice) {
28+
yield $invoice->id => $invoice;
29+
}
30+
}
31+
}

tests/Models/Invoices.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Test\TinyBlocks\Mapper\Models;
6+
7+
use IteratorAggregate;
8+
use TinyBlocks\Mapper\IterableMappability;
9+
use TinyBlocks\Mapper\IterableMapper;
10+
use Traversable;
11+
12+
final class Invoices implements IterableMapper, IteratorAggregate
13+
{
14+
use IterableMappability;
15+
16+
public function __construct(public array $elements)
17+
{
18+
}
19+
20+
public static function createFrom(array $elements): Invoices
21+
{
22+
return new Invoices(elements: $elements);
23+
}
24+
25+
public function getIterator(): Traversable
26+
{
27+
return yield from $this->elements;
28+
}
29+
}

0 commit comments

Comments
 (0)