Skip to content

Commit

Permalink
fix: allow interfaces as the target type of object mapper (#242)
Browse files Browse the repository at this point in the history
* fix: allow interfaces as the target type of object mapper

* test reverse mapping
  • Loading branch information
priyadi authored Oct 22, 2024
1 parent a9e4a19 commit f21b1ac
Show file tree
Hide file tree
Showing 8 changed files with 124 additions and 13 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# CHANGELOG

## 1.13.1

* fix: allow interfaces as the target type of object mapper

## 1.13.0

* feat: `Map(property: null)` ignores the mapping
Expand Down
7 changes: 5 additions & 2 deletions src/Transformer/Implementation/ObjectMapperTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,12 @@ public function transform(

if (
!\is_string($targetClass)
|| !class_exists($targetClass)
|| (
!class_exists($targetClass)
&& !interface_exists($targetClass)
)
) {
throw new InvalidArgumentException(\sprintf('Target class "%s" is not a valid class.', (string) $targetClass), context: $context);
throw new InvalidArgumentException(\sprintf('Target "%s" is not a valid class or interface.', (string) $targetClass), context: $context);
}

// get source class
Expand Down
32 changes: 22 additions & 10 deletions tests/config/rekalogika-mapper/generated-mappings.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,41 @@
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 47
// tests/src/IntegrationTest/ObjectMapperTest.php on line 49
source: \Brick\Money\Money::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDto::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 67
// tests/src/IntegrationTest/ObjectMapperTest.php on line 90
source: \Brick\Money\Money::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForProxy::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 109
// tests/src/IntegrationTest/ObjectMapperTest.php on line 132
source: \Brick\Money\Money::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetInvalidTypeHint::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 82
// tests/src/IntegrationTest/ObjectMapperTest.php on line 105
source: \Brick\Money\Money::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetModification::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 95
// tests/src/IntegrationTest/ObjectMapperTest.php on line 118
source: \Brick\Money\Money::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetReplacement::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 69
source: \Brick\Money\Money::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoInterface::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/AdderTest.php on lines 46, 55
source: \Rekalogika\Mapper\Tests\Fixtures\Adder\Comment::class,
Expand Down Expand Up @@ -694,31 +700,37 @@
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 155
// tests/src/IntegrationTest/ObjectMapperTest.php on line 178
source: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\Baz::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\Foo::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 145
// tests/src/IntegrationTest/ObjectMapperTest.php on line 168
source: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\Foo::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\Baz::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 57
// tests/src/IntegrationTest/ObjectMapperTest.php on line 59
source: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDto::class,
target: \Brick\Money\Money::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 139
// tests/src/IntegrationTest/ObjectMapperTest.php on line 80
source: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoToo::class,
target: \Brick\Money\Money::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 162
source: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\Person::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\FinalPersonDto::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ObjectMapperTest.php on line 115
// tests/src/IntegrationTest/ObjectMapperTest.php on line 138
source: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\Person::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\PersonDto::class
);
Expand Down
2 changes: 1 addition & 1 deletion tests/src/Fixtures/ObjectMapper/MoneyDto.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

namespace Rekalogika\Mapper\Tests\Fixtures\ObjectMapper;

final readonly class MoneyDto
final readonly class MoneyDto implements MoneyDtoInterface
{
public function __construct(
private string $amount,
Expand Down
21 changes: 21 additions & 0 deletions tests/src/Fixtures/ObjectMapper/MoneyDtoInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\Tests\Fixtures\ObjectMapper;

interface MoneyDtoInterface
{
public function getAmount(): string;

public function getCurrency(): string;
}
32 changes: 32 additions & 0 deletions tests/src/Fixtures/ObjectMapper/MoneyDtoToo.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

/*
* This file is part of rekalogika/mapper package.
*
* (c) Priyadi Iman Nurcahyo <https://rekalogika.dev>
*
* For the full copyright and license information, please view the LICENSE file
* that was distributed with this source code.
*/

namespace Rekalogika\Mapper\Tests\Fixtures\ObjectMapper;

final readonly class MoneyDtoToo implements MoneyDtoInterface
{
public function __construct(
private string $amount,
private string $currency,
) {}

public function getAmount(): string
{
return $this->amount;
}

public function getCurrency(): string
{
return $this->currency;
}
}
23 changes: 23 additions & 0 deletions tests/src/IntegrationTest/ObjectMapperTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetInvalidTypeHint;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetModification;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetReplacement;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoInterface;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoToo;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\Person;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\PersonDto;
use Rekalogika\Mapper\Tests\Services\ObjectMapper\MoneyObjectMapper;
Expand Down Expand Up @@ -61,6 +63,27 @@ public function testMoneyDtoToMoney(): void
$this->assertSame('USD', $result->getCurrency()->getCurrencyCode());
}

public function testMoneyToMoneyDtoInterface(): void
{
$money = Money::of('100.00', 'USD');
$result = $this->mapper->map($money, MoneyDtoInterface::class);

$this->assertInstanceOf(MoneyDtoInterface::class, $result);
$this->assertInstanceOf(MoneyDto::class, $result);
$this->assertSame('100.00', $result->getAmount());
$this->assertSame('USD', $result->getCurrency());
}

public function testMoneyDtoInterfaceToMoney(): void
{
$moneyDto = new MoneyDtoToo('100.00', 'USD');
$result = $this->mapper->map($moneyDto, Money::class);

$this->assertInstanceOf(Money::class, $result);
$this->assertSame('100.00', $result->getAmount()->__toString());
$this->assertSame('USD', $result->getCurrency()->getCurrencyCode());
}

public function testMoneyToMoneyDtoProxy(): void
{
$money = Money::of('100.00', 'USD');
Expand Down
16 changes: 16 additions & 0 deletions tests/src/Services/ObjectMapper/MoneyObjectMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetInvalidTypeHint;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetModification;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoForTargetReplacement;
use Rekalogika\Mapper\Tests\Fixtures\ObjectMapper\MoneyDtoInterface;

class MoneyObjectMapper
{
Expand All @@ -39,6 +40,21 @@ public function mapMoneyDtoToMoney(MoneyDto $moneyDto): Money
return Money::of($moneyDto->getAmount(), $moneyDto->getCurrency());
}

#[AsObjectMapper]
public function mapMoneyToMoneyDtoInterface(Money $money): MoneyDtoInterface
{
return new MoneyDto(
$money->getAmount()->__toString(),
$money->getCurrency()->getCurrencyCode(),
);
}

#[AsObjectMapper]
public function mapMoneyDtoInterfaceToMoney(MoneyDtoInterface $moneyDto): Money
{
return Money::of($moneyDto->getAmount(), $moneyDto->getCurrency());
}

#[AsObjectMapper]
public function mapMoneyToMoneyDtoForProxy(
Money $money,
Expand Down

0 comments on commit f21b1ac

Please sign in to comment.