diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f6f2ab0..efa44717 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ handle the current target value in all cases * test: test lazy constructor * fix: double mapping if a property is in the constructor and also has a setter +* fix: issue [#232](https://github.com/rekalogika/mapper/issues/232)232 ## 1.11.0 diff --git a/tests/config/rekalogika-mapper/generated-mappings.php b/tests/config/rekalogika-mapper/generated-mappings.php index 795be04b..0992080b 100644 --- a/tests/config/rekalogika-mapper/generated-mappings.php +++ b/tests/config/rekalogika-mapper/generated-mappings.php @@ -471,6 +471,18 @@ target: \Rekalogika\Mapper\Tests\Fixtures\InternalClass\ObjectWithInternalClassDto::class ); + $mappingCollection->addObjectMapping( + // tests/src/IntegrationTest/Issue232Test.php on line 27 + source: \Rekalogika\Mapper\Tests\Fixtures\Issue232\BigDecimalSource::class, + target: \Rekalogika\Mapper\Tests\Fixtures\Issue232\BigDecimalTarget::class + ); + + $mappingCollection->addObjectMapping( + // tests/src/IntegrationTest/Issue232Test.php on line 35 + source: \Rekalogika\Mapper\Tests\Fixtures\Issue232\CurrencySource::class, + target: \Rekalogika\Mapper\Tests\Fixtures\Issue232\CurrencyTarget::class + ); + $mappingCollection->addObjectMapping( // tests/src/IntegrationTest/LazyObjectTest.php on lines 99, 109 source: \Rekalogika\Mapper\Tests\Fixtures\LazyObject\ObjectWithId::class, diff --git a/tests/src/Fixtures/Issue232/BigDecimalSource.php b/tests/src/Fixtures/Issue232/BigDecimalSource.php new file mode 100644 index 00000000..dd29b84f --- /dev/null +++ b/tests/src/Fixtures/Issue232/BigDecimalSource.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +namespace Rekalogika\Mapper\Tests\Fixtures\Issue232; + +final readonly class BigDecimalSource +{ + public function __construct( + public string $amount, + ) {} +} diff --git a/tests/src/Fixtures/Issue232/BigDecimalTarget.php b/tests/src/Fixtures/Issue232/BigDecimalTarget.php new file mode 100644 index 00000000..fcc0d379 --- /dev/null +++ b/tests/src/Fixtures/Issue232/BigDecimalTarget.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +namespace Rekalogika\Mapper\Tests\Fixtures\Issue232; + +use Brick\Math\BigDecimal; + +final readonly class BigDecimalTarget +{ + public function __construct( + public BigDecimal $amount, + ) {} +} diff --git a/tests/src/Fixtures/Issue232/CurrencySource.php b/tests/src/Fixtures/Issue232/CurrencySource.php new file mode 100644 index 00000000..ead4eb0b --- /dev/null +++ b/tests/src/Fixtures/Issue232/CurrencySource.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +namespace Rekalogika\Mapper\Tests\Fixtures\Issue232; + +final readonly class CurrencySource +{ + public function __construct( + public string $currency, + ) {} +} diff --git a/tests/src/Fixtures/Issue232/CurrencyTarget.php b/tests/src/Fixtures/Issue232/CurrencyTarget.php new file mode 100644 index 00000000..a944c664 --- /dev/null +++ b/tests/src/Fixtures/Issue232/CurrencyTarget.php @@ -0,0 +1,23 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +namespace Rekalogika\Mapper\Tests\Fixtures\Issue232; + +use Brick\Money\Currency; + +final readonly class CurrencyTarget +{ + public function __construct( + public Currency $currency, + ) {} +} diff --git a/tests/src/IntegrationTest/Issue232Test.php b/tests/src/IntegrationTest/Issue232Test.php new file mode 100644 index 00000000..d79aad43 --- /dev/null +++ b/tests/src/IntegrationTest/Issue232Test.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +namespace Rekalogika\Mapper\Tests\IntegrationTest; + +use Rekalogika\Mapper\Tests\Common\FrameworkTestCase; +use Rekalogika\Mapper\Tests\Fixtures\Issue232\BigDecimalSource; +use Rekalogika\Mapper\Tests\Fixtures\Issue232\BigDecimalTarget; +use Rekalogika\Mapper\Tests\Fixtures\Issue232\CurrencySource; +use Rekalogika\Mapper\Tests\Fixtures\Issue232\CurrencyTarget; + +class Issue232Test extends FrameworkTestCase +{ + public function testBigDecimal(): void + { + $source = new BigDecimalSource('100'); + $target = $this->mapper->map($source, BigDecimalTarget::class); + + $this->assertEquals('100', $target->amount->toScale(0)->jsonSerialize()); + } + + public function testCurrency(): void + { + $source = new CurrencySource('USD'); + $target = $this->mapper->map($source, CurrencyTarget::class); + + $this->assertEquals('USD', $target->currency->getCurrencyCode()); + } +} diff --git a/tests/src/Services/Issue232/BigDecimalTransformer.php b/tests/src/Services/Issue232/BigDecimalTransformer.php new file mode 100644 index 00000000..262d6ad9 --- /dev/null +++ b/tests/src/Services/Issue232/BigDecimalTransformer.php @@ -0,0 +1,65 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +namespace Rekalogika\Mapper\Tests\Services\Issue232; + +use Brick\Math\BigDecimal; +use Rekalogika\Mapper\Context\Context; +use Rekalogika\Mapper\Transformer\TransformerInterface; +use Rekalogika\Mapper\Transformer\TypeMapping; +use Rekalogika\Mapper\Util\TypeFactory; +use Symfony\Component\PropertyInfo\Type; + +final readonly class BigDecimalTransformer implements TransformerInterface +{ + public function transform( + mixed $source, + mixed $target, + ?Type $sourceType, + ?Type $targetType, + Context $context, + ): BigDecimal|string { + if ($source instanceof BigDecimal) { + return (string) $source; + } + + /** + * @psalm-suppress MixedArgument + * @phpstan-ignore argument.type + */ + return BigDecimal::of($source)->toBigDecimal(); + } + + public function getSupportedTransformation(): iterable + { + yield new TypeMapping( + TypeFactory::string(), + TypeFactory::objectOfClass(BigDecimal::class), + ); + + yield new TypeMapping( + TypeFactory::int(), + TypeFactory::objectOfClass(BigDecimal::class), + ); + + yield new TypeMapping( + TypeFactory::float(), + TypeFactory::objectOfClass(BigDecimal::class), + ); + + yield new TypeMapping( + TypeFactory::objectOfClass(BigDecimal::class), + TypeFactory::string(), + ); + } +} diff --git a/tests/src/Services/Issue232/CurrencyTransformer.php b/tests/src/Services/Issue232/CurrencyTransformer.php new file mode 100644 index 00000000..f9689c62 --- /dev/null +++ b/tests/src/Services/Issue232/CurrencyTransformer.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +namespace Rekalogika\Mapper\Tests\Services\Issue232; + +use Brick\Money\Currency; +use Rekalogika\Mapper\Context\Context; +use Rekalogika\Mapper\Transformer\TransformerInterface; +use Rekalogika\Mapper\Transformer\TypeMapping; +use Rekalogika\Mapper\Util\TypeFactory; +use Symfony\Component\PropertyInfo\Type; + +final readonly class CurrencyTransformer implements TransformerInterface +{ + public function transform( + mixed $source, + mixed $target, + ?Type $sourceType, + ?Type $targetType, + Context $context, + ): mixed { + /** + * @psalm-suppress MixedArgument + * @phpstan-ignore argument.type + */ + return Currency::of($source); + } + + public function getSupportedTransformation(): iterable + { + yield new TypeMapping( + TypeFactory::string(), + TypeFactory::objectOfClass(Currency::class), + ); + } +}