Skip to content

Commit

Permalink
handle invalid extra target properties
Browse files Browse the repository at this point in the history
  • Loading branch information
priyadi committed Oct 13, 2024
1 parent 1158d2a commit 3b15b23
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 3 deletions.
40 changes: 40 additions & 0 deletions src/Transformer/Exception/ExtraTargetPropertyNotFoundException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?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\Transformer\Exception;

use Rekalogika\Mapper\Context\Context;
use Rekalogika\Mapper\Exception\LogicException;

/**
* @internal
*/
class ExtraTargetPropertyNotFoundException extends LogicException
{
/**
* @param class-string $class
*/
public function __construct(
string $class,
string $property,
Context $context,
) {
$message = \sprintf(
'Mapper is called with "ExtraTargetValues", but cannot find the target property "%s" in class "%s"',
$property,
$class,
);

parent::__construct($message, context: $context);
}
}
17 changes: 16 additions & 1 deletion src/Transformer/Implementation/ObjectToObjectTransformer.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use Rekalogika\Mapper\ServiceMethod\ServiceMethodSpecification;
use Rekalogika\Mapper\SubMapper\SubMapperFactoryInterface;
use Rekalogika\Mapper\Transformer\Exception\ClassNotInstantiableException;
use Rekalogika\Mapper\Transformer\Exception\ExtraTargetPropertyNotFoundException;
use Rekalogika\Mapper\Transformer\Exception\InstantiationFailureException;
use Rekalogika\Mapper\Transformer\Exception\NotAClassException;
use Rekalogika\Mapper\Transformer\Exception\UninitializedSourcePropertyException;
Expand Down Expand Up @@ -205,9 +206,23 @@ private function getExtraTargetValues(
ObjectToObjectMetadata $objectToObjectMetadata,
Context $context,
): array {
return $context(ExtraTargetValues::class)
$extraTargetValues = $context(ExtraTargetValues::class)
?->getArgumentsForClass($objectToObjectMetadata->getAllTargetClasses())
?? [];

$allPropertyMappings = $objectToObjectMetadata->getPropertyMappings();

foreach (array_keys($extraTargetValues) as $property) {
if (!isset($allPropertyMappings[$property])) {
throw new ExtraTargetPropertyNotFoundException(
class: $objectToObjectMetadata->getTargetClass(),
property: $property,
context: $context,
);
}
}

return $extraTargetValues;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions tests/config/rekalogika-mapper/generated-mappings.php
Original file line number Diff line number Diff line change
Expand Up @@ -388,13 +388,13 @@
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ExtraTargetValuesTest.php on line 27
// tests/src/IntegrationTest/ExtraTargetValuesTest.php on lines 28, 68
source: \Rekalogika\Mapper\Tests\Fixtures\ExtraTargetValues\SomeObject::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ExtraTargetValues\SomeObjectWithConstructorDto::class
);

$mappingCollection->addObjectMapping(
// tests/src/IntegrationTest/ExtraTargetValuesTest.php on line 46
// tests/src/IntegrationTest/ExtraTargetValuesTest.php on line 47
source: \Rekalogika\Mapper\Tests\Fixtures\ExtraTargetValues\SomeObject::class,
target: \Rekalogika\Mapper\Tests\Fixtures\ExtraTargetValues\SomeObjectWithPropertyDto::class
);
Expand Down
18 changes: 18 additions & 0 deletions tests/src/IntegrationTest/ExtraTargetValuesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use Rekalogika\Mapper\Tests\Fixtures\ExtraTargetValues\SomeObject;
use Rekalogika\Mapper\Tests\Fixtures\ExtraTargetValues\SomeObjectWithConstructorDto;
use Rekalogika\Mapper\Tests\Fixtures\ExtraTargetValues\SomeObjectWithPropertyDto;
use Rekalogika\Mapper\Transformer\Exception\ExtraTargetPropertyNotFoundException;

class ExtraTargetValuesTest extends FrameworkTestCase
{
Expand Down Expand Up @@ -59,4 +60,21 @@ public function testExtraTargetValuesOnProperty(): void
$this->assertInstanceOf(\DateTimeImmutable::class, $target->date);
$this->assertSame('2021-01-01', $target->date->format('Y-m-d'));
}

public function testInvalidExtraTargetValues(): void
{
$this->expectException(ExtraTargetPropertyNotFoundException::class);

$this->mapper->map(
source: new SomeObject(),
target: SomeObjectWithConstructorDto::class,
context: Context::create(
new ExtraTargetValues([
SomeObjectWithConstructorDto::class => [
'foo' => new \DateTimeImmutable('2021-01-01'),
],
]),
),
);
}
}

0 comments on commit 3b15b23

Please sign in to comment.