From e9b4c922a8c2ba23a13035e8f7b4babedc8f9cb0 Mon Sep 17 00:00:00 2001 From: Priyadi Iman Nurcahyo <1102197+priyadi@users.noreply.github.com> Date: Tue, 20 Feb 2024 21:02:15 +0700 Subject: [PATCH] Deprecate `ArrayToObjectTransformer` & `ObjectToArrayTransformer`, replace with `ArrayObjectTransformer`. --- CHANGELOG.md | 2 + config/services.php | 46 +++++----- src/MapperFactory.php | 79 +++++++++++++++-- .../Implementation/ArrayObjectTransformer.php | 87 ++++++++++++++++++ .../ArrayToObjectTransformer.php | 2 + .../ObjectToArrayTransformer.php | 2 + tests/Common/TestKernel.php | 2 - .../AnotherContainsArray.php} | 4 +- .../Fixtures/ArrayAndObject/ContainsArray.php | 22 +++++ ...ontainingObject.php => ContainsObject.php} | 2 +- .../ArrayAndObjectMappingTest.php | 88 +++++++++++++------ tests/IntegrationTest/DataCollectorTest.php | 12 +-- 12 files changed, 279 insertions(+), 69 deletions(-) create mode 100644 src/Transformer/Implementation/ArrayObjectTransformer.php rename tests/Fixtures/{ArrayAndObjectDto/ContainingObjectDto.php => ArrayAndObject/AnotherContainsArray.php} (80%) create mode 100644 tests/Fixtures/ArrayAndObject/ContainsArray.php rename tests/Fixtures/ArrayAndObject/{ContainingObject.php => ContainsObject.php} (97%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 77e03b5..f94cb53 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ * fix(`PresetMapping`): Support proxied classes, add tests. * fix: Disallow proxy for objects with dynamic properties, including `stdClass`. * feat: Dynamic properties (`stdClass` & co) on the target side. +* feat: Deprecate `ArrayToObjectTransformer` & `ObjectToArrayTransformer`, + replace with `ArrayObjectTransformer`. ## 1.0.0 diff --git a/config/services.php b/config/services.php index 000ef65..80c418e 100644 --- a/config/services.php +++ b/config/services.php @@ -40,14 +40,13 @@ use Rekalogika\Mapper\Transformer\EagerPropertiesResolver\Implementation\ChainEagerPropertiesResolver; use Rekalogika\Mapper\Transformer\EagerPropertiesResolver\Implementation\DoctrineEagerPropertiesResolver; use Rekalogika\Mapper\Transformer\EagerPropertiesResolver\Implementation\HeuristicsEagerPropertiesResolver; -use Rekalogika\Mapper\Transformer\Implementation\ArrayToObjectTransformer; +use Rekalogika\Mapper\Transformer\Implementation\ArrayObjectTransformer; use Rekalogika\Mapper\Transformer\Implementation\ClassMethodTransformer; use Rekalogika\Mapper\Transformer\Implementation\CopyTransformer; use Rekalogika\Mapper\Transformer\Implementation\DateTimeTransformer; use Rekalogika\Mapper\Transformer\Implementation\NullToNullTransformer; use Rekalogika\Mapper\Transformer\Implementation\NullTransformer; use Rekalogika\Mapper\Transformer\Implementation\ObjectMapperTransformer; -use Rekalogika\Mapper\Transformer\Implementation\ObjectToArrayTransformer; use Rekalogika\Mapper\Transformer\Implementation\ObjectToObjectTransformer; use Rekalogika\Mapper\Transformer\Implementation\ObjectToStringTransformer; use Rekalogika\Mapper\Transformer\Implementation\PresetTransformer; @@ -69,8 +68,6 @@ use Symfony\Component\PropertyInfo\PropertyInfoExtractor; use Symfony\Component\PropertyInfo\PropertyReadInfoExtractorInterface; use Symfony\Component\PropertyInfo\PropertyWriteInfoExtractorInterface; -use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; -use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use function Symfony\Component\DependencyInjection\Loader\Configurator\param; use function Symfony\Component\DependencyInjection\Loader\Configurator\service; @@ -122,7 +119,7 @@ $services ->set(ScalarToScalarTransformer::class) - ->tag('rekalogika.mapper.transformer', ['priority' => -300]); + ->tag('rekalogika.mapper.transformer', ['priority' => -350]); $services ->set(ObjectMapperTransformer::class) @@ -132,57 +129,52 @@ service('rekalogika.mapper.object_mapper.table_factory'), service('rekalogika.mapper.object_mapper.resolver'), ]) - ->tag('rekalogika.mapper.transformer', ['priority' => -350]); + ->tag('rekalogika.mapper.transformer', ['priority' => -400]); $services ->set(DateTimeTransformer::class) - ->tag('rekalogika.mapper.transformer', ['priority' => -400]); + ->tag('rekalogika.mapper.transformer', ['priority' => -450]); $services ->set(StringToBackedEnumTransformer::class) - ->tag('rekalogika.mapper.transformer', ['priority' => -450]); + ->tag('rekalogika.mapper.transformer', ['priority' => -500]); $services ->set(SymfonyUidTransformer::class) - ->tag('rekalogika.mapper.transformer', ['priority' => -500]); + ->tag('rekalogika.mapper.transformer', ['priority' => -550]); $services ->set(ObjectToStringTransformer::class) - ->tag('rekalogika.mapper.transformer', ['priority' => -550]); + ->tag('rekalogika.mapper.transformer', ['priority' => -600]); $services ->set(PresetTransformer::class) - ->tag('rekalogika.mapper.transformer', ['priority' => -600]); + ->tag('rekalogika.mapper.transformer', ['priority' => -650]); $services ->set(ClassMethodTransformer::class) ->args([ service('rekalogika.mapper.sub_mapper.factory'), ]) - ->tag('rekalogika.mapper.transformer', ['priority' => -650]); + ->tag('rekalogika.mapper.transformer', ['priority' => -700]); $services ->set(TraversableToArrayAccessTransformer::class) ->args([ service('rekalogika.mapper.array_like_metadata_factory') ]) - ->tag('rekalogika.mapper.transformer', ['priority' => -700]); + ->tag('rekalogika.mapper.transformer', ['priority' => -750]); $services ->set(TraversableToTraversableTransformer::class) ->args([ service('rekalogika.mapper.array_like_metadata_factory') ]) - ->tag('rekalogika.mapper.transformer', ['priority' => -750]); - - $services - ->set(ObjectToArrayTransformer::class) - ->args([service(NormalizerInterface::class)]) ->tag('rekalogika.mapper.transformer', ['priority' => -800]); $services - ->set(ArrayToObjectTransformer::class) - ->args([service(DenormalizerInterface::class)]) + ->set(ArrayObjectTransformer::class) + ->args([service('rekalogika.mapper.transformer.array_object.object_to_object_transformer')]) ->tag('rekalogika.mapper.transformer', ['priority' => -850]); $services @@ -224,6 +216,20 @@ service('kernel') ]); + # special instance of object to object transformer for ArrayObjectTransformer + + $services + ->set( + 'rekalogika.mapper.transformer.array_object.object_to_object_transformer', + ObjectToObjectTransformer::class + ) + ->args([ + '$objectToObjectMetadataFactory' => service('rekalogika.mapper.object_to_object_metadata_factory'), + '$propertyMapperLocator' => tagged_locator('rekalogika.mapper.property_mapper'), + '$subMapperFactory' => service('rekalogika.mapper.sub_mapper.factory'), + '$proxyFactory' => service('rekalogika.mapper.proxy.factory'), + ]); + # mapping cache warmer $services diff --git a/src/MapperFactory.php b/src/MapperFactory.php index cd126bf..dac4f91 100644 --- a/src/MapperFactory.php +++ b/src/MapperFactory.php @@ -45,15 +45,18 @@ use Rekalogika\Mapper\Transformer\ArrayLikeMetadata\Implementation\ArrayLikeMetadataFactory; use Rekalogika\Mapper\Transformer\EagerPropertiesResolver\EagerPropertiesResolverInterface; use Rekalogika\Mapper\Transformer\EagerPropertiesResolver\Implementation\HeuristicsEagerPropertiesResolver; +use Rekalogika\Mapper\Transformer\Implementation\ArrayObjectTransformer; use Rekalogika\Mapper\Transformer\Implementation\ArrayToObjectTransformer; use Rekalogika\Mapper\Transformer\Implementation\ClassMethodTransformer; use Rekalogika\Mapper\Transformer\Implementation\CopyTransformer; use Rekalogika\Mapper\Transformer\Implementation\DateTimeTransformer; +use Rekalogika\Mapper\Transformer\Implementation\NullToNullTransformer; use Rekalogika\Mapper\Transformer\Implementation\NullTransformer; use Rekalogika\Mapper\Transformer\Implementation\ObjectMapperTransformer; use Rekalogika\Mapper\Transformer\Implementation\ObjectToArrayTransformer; use Rekalogika\Mapper\Transformer\Implementation\ObjectToObjectTransformer; use Rekalogika\Mapper\Transformer\Implementation\ObjectToStringTransformer; +use Rekalogika\Mapper\Transformer\Implementation\PresetTransformer; use Rekalogika\Mapper\Transformer\Implementation\ScalarToScalarTransformer; use Rekalogika\Mapper\Transformer\Implementation\StringToBackedEnumTransformer; use Rekalogika\Mapper\Transformer\Implementation\SymfonyUidTransformer; @@ -111,6 +114,7 @@ class MapperFactory private ?Serializer $serializer = null; + private ?NullToNullTransformer $nullToNullTransformer = null; private ?NullTransformer $nullTransformer = null; private ?ObjectToObjectTransformer $objectToObjectTransformer = null; private ?ObjectToStringTransformer $objectToStringTransformer = null; @@ -119,12 +123,14 @@ class MapperFactory private ?StringToBackedEnumTransformer $stringToBackedEnumTransformer = null; private ?ArrayToObjectTransformer $arrayToObjectTransformer = null; private ?ObjectToArrayTransformer $objectToArrayTransformer = null; + private ?ArrayObjectTransformer $arrayObjectTransformer = null; private ?DateTimeTransformer $dateTimeTransformer = null; private ?TraversableToArrayAccessTransformer $traversableToArrayAccessTransformer = null; private ?TraversableToTraversableTransformer $traversableToTraversableTransformer = null; private ?CopyTransformer $copyTransformer = null; private ?ClassMethodTransformer $classMethodTransformer = null; private ?SymfonyUidTransformer $symfonyUidTransformer = null; + private ?PresetTransformer $presetTransformer = null; private CacheItemPoolInterface $propertyInfoExtractorCache; private null|(PropertyInfoExtractorInterface&PropertyInitializableExtractorInterface) $propertyInfoExtractor = null; @@ -321,6 +327,15 @@ private function getDenormalizer(): DenormalizerInterface // transformers // + protected function getNullToNullTransformer(): TransformerInterface + { + if (null === $this->nullToNullTransformer) { + $this->nullToNullTransformer = new NullToNullTransformer(); + } + + return $this->nullToNullTransformer; + } + protected function getNullTransformer(): TransformerInterface { if (null === $this->nullTransformer) { @@ -385,6 +400,9 @@ protected function getStringToBackedEnumTransformer(): TransformerInterface return $this->stringToBackedEnumTransformer; } + /** + * @deprecated + */ protected function getArrayToObjectTransformer(): TransformerInterface { if (null === $this->arrayToObjectTransformer) { @@ -396,6 +414,9 @@ protected function getArrayToObjectTransformer(): TransformerInterface return $this->arrayToObjectTransformer; } + /** + * @deprecated + */ protected function getObjectToArrayTransformer(): TransformerInterface { if (null === $this->objectToArrayTransformer) { @@ -407,6 +428,20 @@ protected function getObjectToArrayTransformer(): TransformerInterface return $this->objectToArrayTransformer; } + protected function getArrayObjectTransformer(): TransformerInterface + { + $objectToObjectTransformer = $this->getObjectToObjectTransformer(); + assert($objectToObjectTransformer instanceof ObjectToObjectTransformer); + + if (null === $this->arrayObjectTransformer) { + $this->arrayObjectTransformer = new ArrayObjectTransformer( + $objectToObjectTransformer + ); + } + + return $this->arrayObjectTransformer; + } + protected function getDateTimeTransformer(): TransformerInterface { if (null === $this->dateTimeTransformer) { @@ -473,6 +508,15 @@ protected function getSymfonyUidTransformer(): SymfonyUidTransformer return $this->symfonyUidTransformer; } + protected function getPresetTransformer(): PresetTransformer + { + if (null === $this->presetTransformer) { + $this->presetTransformer = new PresetTransformer(); + } + + return $this->presetTransformer; + } + // // other services // @@ -525,7 +569,10 @@ protected function getArrayLikeMetadataFactory(): ArrayLikeMetadataFactoryInterf */ protected function getTransformersIterator(): iterable { + yield 'NullToNullTransformer' => $this->getNullToNullTransformer(); + yield from $this->additionalTransformers; + yield 'ScalarToScalarTransformer' => $this->getScalarToScalarTransformer(); yield 'ObjectMapperTransformer' @@ -534,11 +581,6 @@ protected function getTransformersIterator(): iterable => $this->getDateTimeTransformer(); yield 'StringToBackedEnumTransformer' => $this->getStringToBackedEnumTransformer(); - /** - * @psalm-suppress DeprecatedMethod - * @phpstan-ignore-next-line - */ - yield 'ClassMethodTransformer' => $this->getClassMethodTransformer(); if (class_exists(UuidFactory::class)) { yield 'SymfonyUidTransformer' @@ -547,14 +589,33 @@ protected function getTransformersIterator(): iterable yield 'ObjectToStringTransformer' => $this->getObjectToStringTransformer(); + + yield 'PresetTransformer' + => $this->getPresetTransformer(); + + /** + * @psalm-suppress DeprecatedMethod + * @phpstan-ignore-next-line + */ + yield 'ClassMethodTransformer' => $this->getClassMethodTransformer(); + yield 'TraversableToArrayAccessTransformer' => $this->getTraversableToArrayAccessTransformer(); yield 'TraversableToTraversableTransformer' => $this->getTraversableToTraversableTransformer(); - yield 'ObjectToArrayTransformer' - => $this->getObjectToArrayTransformer(); - yield 'ArrayToObjectTransformer' - => $this->getArrayToObjectTransformer(); + + /** + * @psalm-suppress DeprecatedMethod + * @phpstan-ignore-next-line + */ + yield 'ObjectToArrayTransformer' => $this->getObjectToArrayTransformer(); + + /** + * @psalm-suppress DeprecatedMethod + * @phpstan-ignore-next-line + */ + yield 'ArrayToObjectTransformer' => $this->getArrayToObjectTransformer(); + yield 'ObjectToObjectTransformer' => $this->getObjectToObjectTransformer(); yield 'NullTransformer' diff --git a/src/Transformer/Implementation/ArrayObjectTransformer.php b/src/Transformer/Implementation/ArrayObjectTransformer.php new file mode 100644 index 0000000..45ab85e --- /dev/null +++ b/src/Transformer/Implementation/ArrayObjectTransformer.php @@ -0,0 +1,87 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +namespace Rekalogika\Mapper\Transformer\Implementation; + +use Rekalogika\Mapper\Context\Context; +use Rekalogika\Mapper\MainTransformer\MainTransformerInterface; +use Rekalogika\Mapper\Transformer\MainTransformerAwareInterface; +use Rekalogika\Mapper\Transformer\TransformerInterface; +use Rekalogika\Mapper\Transformer\TypeMapping; +use Rekalogika\Mapper\Util\TypeCheck; +use Rekalogika\Mapper\Util\TypeFactory; +use Symfony\Component\PropertyInfo\Type; + +/** + * Do object to array, array to object, and array to array transformation by + * converting array to stdClass & passing the task to ObjectToObjectTransformer. + */ +final readonly class ArrayObjectTransformer implements + TransformerInterface, + MainTransformerAwareInterface +{ + public function __construct( + private ObjectToObjectTransformer $objectToObjectTransformer, + ) { + } + + public function withMainTransformer(MainTransformerInterface $mainTransformer): static + { + $objectToObjectTransformer = $this->objectToObjectTransformer + ->withMainTransformer($mainTransformer); + + return new self($objectToObjectTransformer); + } + + public function transform( + mixed $source, + mixed $target, + ?Type $sourceType, + ?Type $targetType, + Context $context + ): mixed { + $originalTargetType = $targetType; + + if (TypeCheck::isArray($sourceType)) { + $source = (object) $source; + $sourceType = TypeFactory::objectOfClass(\stdClass::class); + } + + if (TypeCheck::isArray($targetType)) { + $target = (object) $target; + $targetType = TypeFactory::objectOfClass(\stdClass::class); + } + + /** @var mixed */ + $result = $this->objectToObjectTransformer->transform( + source: $source, + target: $target, + sourceType: $sourceType, + targetType: $targetType, + context: $context + ); + + if (TypeCheck::isArray($originalTargetType)) { + return (array) $result; + } + + return $result; + } + + public function getSupportedTransformation(): iterable + { + yield new TypeMapping(TypeFactory::array(), TypeFactory::object(), true); + yield new TypeMapping(TypeFactory::object(), TypeFactory::array()); + yield new TypeMapping(TypeFactory::array(), TypeFactory::array()); + } +} diff --git a/src/Transformer/Implementation/ArrayToObjectTransformer.php b/src/Transformer/Implementation/ArrayToObjectTransformer.php index ba42d23..079f64e 100644 --- a/src/Transformer/Implementation/ArrayToObjectTransformer.php +++ b/src/Transformer/Implementation/ArrayToObjectTransformer.php @@ -28,6 +28,8 @@ /** * Map an array to an object. Uses the Symfony Serializer component as the * backend. + * + * @deprecated Use ArrayObjectTransformer instead */ final readonly class ArrayToObjectTransformer implements TransformerInterface { diff --git a/src/Transformer/Implementation/ObjectToArrayTransformer.php b/src/Transformer/Implementation/ObjectToArrayTransformer.php index 5f9bc24..deae92f 100644 --- a/src/Transformer/Implementation/ObjectToArrayTransformer.php +++ b/src/Transformer/Implementation/ObjectToArrayTransformer.php @@ -25,6 +25,8 @@ /** * Map an object to an array. Uses the Symfony Serializer component as the * backend. + * + * @deprecated Use ArrayObjectTransformer instead */ final readonly class ObjectToArrayTransformer implements TransformerInterface { diff --git a/tests/Common/TestKernel.php b/tests/Common/TestKernel.php index b5e1acb..810dc62 100644 --- a/tests/Common/TestKernel.php +++ b/tests/Common/TestKernel.php @@ -81,8 +81,6 @@ public static function getServiceIds(): iterable yield ObjectToStringTransformer::class; yield TraversableToArrayAccessTransformer::class; yield TraversableToTraversableTransformer::class; - yield ObjectToArrayTransformer::class; - yield ArrayToObjectTransformer::class; yield ObjectToObjectTransformer::class; yield NullTransformer::class; yield CopyTransformer::class; diff --git a/tests/Fixtures/ArrayAndObjectDto/ContainingObjectDto.php b/tests/Fixtures/ArrayAndObject/AnotherContainsArray.php similarity index 80% rename from tests/Fixtures/ArrayAndObjectDto/ContainingObjectDto.php rename to tests/Fixtures/ArrayAndObject/AnotherContainsArray.php index 56ab619..d2ceaf2 100644 --- a/tests/Fixtures/ArrayAndObjectDto/ContainingObjectDto.php +++ b/tests/Fixtures/ArrayAndObject/AnotherContainsArray.php @@ -11,9 +11,9 @@ * that was distributed with this source code. */ -namespace Rekalogika\Mapper\Tests\Fixtures\ArrayAndObjectDto; +namespace Rekalogika\Mapper\Tests\Fixtures\ArrayAndObject; -class ContainingObjectDto +class AnotherContainsArray { /** * @var null|array diff --git a/tests/Fixtures/ArrayAndObject/ContainsArray.php b/tests/Fixtures/ArrayAndObject/ContainsArray.php new file mode 100644 index 0000000..e40ce68 --- /dev/null +++ b/tests/Fixtures/ArrayAndObject/ContainsArray.php @@ -0,0 +1,22 @@ + + * + * For the full copyright and license information, please view the LICENSE file + * that was distributed with this source code. + */ + +namespace Rekalogika\Mapper\Tests\Fixtures\ArrayAndObject; + +class ContainsArray +{ + /** + * @var null|array + */ + public ?array $data = null; +} diff --git a/tests/Fixtures/ArrayAndObject/ContainingObject.php b/tests/Fixtures/ArrayAndObject/ContainsObject.php similarity index 97% rename from tests/Fixtures/ArrayAndObject/ContainingObject.php rename to tests/Fixtures/ArrayAndObject/ContainsObject.php index 2133ec4..e3ffdb3 100644 --- a/tests/Fixtures/ArrayAndObject/ContainingObject.php +++ b/tests/Fixtures/ArrayAndObject/ContainsObject.php @@ -13,7 +13,7 @@ namespace Rekalogika\Mapper\Tests\Fixtures\ArrayAndObject; -class ContainingObject +class ContainsObject { private ?ObjectWithProperties $data = null; diff --git a/tests/IntegrationTest/ArrayAndObjectMappingTest.php b/tests/IntegrationTest/ArrayAndObjectMappingTest.php index ce20cee..2eb3e5f 100644 --- a/tests/IntegrationTest/ArrayAndObjectMappingTest.php +++ b/tests/IntegrationTest/ArrayAndObjectMappingTest.php @@ -13,26 +13,24 @@ namespace Rekalogika\Mapper\Tests\IntegrationTest; -use Rekalogika\Mapper\Context\Context; -use Rekalogika\Mapper\Serializer\DenormalizerContext; -use Rekalogika\Mapper\Serializer\NormalizerContext; use Rekalogika\Mapper\Tests\Common\FrameworkTestCase; -use Rekalogika\Mapper\Tests\Fixtures\ArrayAndObject\ContainingObject; -use Rekalogika\Mapper\Tests\Fixtures\ArrayAndObjectDto\ContainingObjectDto; +use Rekalogika\Mapper\Tests\Fixtures\ArrayAndObject\AnotherContainsArray; +use Rekalogika\Mapper\Tests\Fixtures\ArrayAndObject\ContainsArray; +use Rekalogika\Mapper\Tests\Fixtures\ArrayAndObject\ContainsObject; class ArrayAndObjectMappingTest extends FrameworkTestCase { public function testObjectToArrayAndBack(): void { - $object = ContainingObject::create(); - $dto = $this->mapper->map($object, ContainingObjectDto::class); + $object = ContainsObject::create(); + $dto = $this->mapper->map($object, ContainsArray::class); $this->assertEquals(1, $dto->data['a'] ?? null); $this->assertEquals('string', $dto->data['b'] ?? null); $this->assertEquals(true, $dto->data['c'] ?? null); $this->assertEquals(1.1, $dto->data['d'] ?? null); - $object = $this->mapper->map($dto, ContainingObject::class); + $object = $this->mapper->map($dto, ContainsObject::class); $this->assertEquals(1, $object->getData()?->a); $this->assertEquals('string', $object->getData()?->b); @@ -40,42 +38,74 @@ public function testObjectToArrayAndBack(): void $this->assertEquals(1.1, $object->getData()?->d); } - public function testObjectToArrayWithSerializerGroups(): void + public function testArrayToObject(): void { - $normalizationContext = new NormalizerContext([ - 'groups' => ['groupa', 'groupc'], - ]); - $context = Context::create($normalizationContext); + $objectWithArray = new ContainsArray(); + $objectWithArray->data = [ + 'a' => 1, + 'b' => 'string', + 'c' => true, + 'd' => 1.1, + ]; - $object = ContainingObject::create(); - $dto = $this->mapper->map($object, ContainingObjectDto::class, $context); + $object = $this->mapper->map($objectWithArray, ContainsObject::class); - $this->assertEquals(1, $dto->data['a'] ?? null); - $this->assertNull($dto->data['b'] ?? null); - $this->assertEquals(true, $dto->data['c'] ?? null); - $this->assertNull($dto->data['d'] ?? null); + $this->assertEquals(1, $object->getData()?->a); + $this->assertEquals('string', $object->getData()?->b); + $this->assertEquals(true, $object->getData()?->c); + $this->assertEquals(1.1, $object->getData()?->d); } - public function testArrayToObjectWithSerializerGroups(): void + public function testArrayWithIncompletePropertiesToObject(): void { - $denormalizationContext = new DenormalizerContext([ - 'groups' => ['groupa', 'groupc'], - ]); - $context = Context::create($denormalizationContext); + $objectWithArray = new ContainsArray(); + $objectWithArray->data = [ + 'a' => 1, + 'b' => 'string', + ]; + + $object = $this->mapper->map($objectWithArray, ContainsObject::class); + + $this->assertEquals(1, $object->getData()?->a); + $this->assertEquals('string', $object->getData()?->b); + $this->assertNull($object->getData()?->c); + $this->assertNull($object->getData()?->d); + } - $dto = new ContainingObjectDto(); - $dto->data = [ + public function testArrayWithExtraPropertiesToObject(): void + { + $objectWithArray = new ContainsArray(); + $objectWithArray->data = [ 'a' => 1, 'b' => 'string', 'c' => true, 'd' => 1.1, + 'e' => 'extra', ]; - $object = $this->mapper->map($dto, ContainingObject::class, $context); + $object = $this->mapper->map($objectWithArray, ContainsObject::class); $this->assertEquals(1, $object->getData()?->a); - $this->assertNull($object->getData()?->b); + $this->assertEquals('string', $object->getData()?->b); $this->assertEquals(true, $object->getData()?->c); - $this->assertNull($object->getData()?->d); + $this->assertEquals(1.1, $object->getData()?->d); + } + + public function testArrayToArray(): void + { + $objectWithArray = new ContainsArray(); + $objectWithArray->data = [ + 'a' => 1, + 'b' => 'string', + 'c' => true, + 'd' => 1.1, + ]; + + $result = $this->mapper->map($objectWithArray, AnotherContainsArray::class); + + $this->assertEquals(1, $result->data['a'] ?? null); + $this->assertEquals('string', $result->data['b'] ?? null); + $this->assertEquals(true, $result->data['c'] ?? null); + $this->assertEquals(1.1, $result->data['d'] ?? null); } } diff --git a/tests/IntegrationTest/DataCollectorTest.php b/tests/IntegrationTest/DataCollectorTest.php index adc119a..b189858 100644 --- a/tests/IntegrationTest/DataCollectorTest.php +++ b/tests/IntegrationTest/DataCollectorTest.php @@ -15,17 +15,17 @@ use Rekalogika\Mapper\Debug\MapperDataCollector; use Rekalogika\Mapper\Tests\Common\FrameworkTestCase; -use Rekalogika\Mapper\Tests\Fixtures\ArrayAndObject\ContainingObject; -use Rekalogika\Mapper\Tests\Fixtures\ArrayAndObjectDto\ContainingObjectDto; -use Rekalogika\Mapper\Transformer\Implementation\ObjectToArrayTransformer; +use Rekalogika\Mapper\Tests\Fixtures\ArrayAndObject\ContainsArray; +use Rekalogika\Mapper\Tests\Fixtures\ArrayAndObject\ContainsObject; +use Rekalogika\Mapper\Transformer\Implementation\ArrayObjectTransformer; use Rekalogika\Mapper\Transformer\Implementation\ObjectToObjectTransformer; class DataCollectorTest extends FrameworkTestCase { public function testDataCollector(): void { - $object = ContainingObject::create(); - $result = $this->mapper->map($object, ContainingObjectDto::class); + $object = ContainsObject::create(); + $result = $this->mapper->map($object, ContainsArray::class); $this->initialize($result); $dataCollector = $this->get('test.rekalogika.mapper.data_collector'); @@ -46,6 +46,6 @@ public function testDataCollector(): void $this->assertNotNull($subFirstMapping); $this->assertEquals('data', $subFirstMapping->getPath()); - $this->assertEquals(ObjectToArrayTransformer::class, $subFirstMapping->getTransformerClass()); + $this->assertEquals(ArrayObjectTransformer::class, $subFirstMapping->getTransformerClass()); } }