Skip to content

Commit

Permalink
Merge pull request #39 from rekalogika:feat/null-array-source
Browse files Browse the repository at this point in the history
feat: null to `Traversable` or `ArrayAccess` is now handled & returns empty.
  • Loading branch information
priyadi committed Feb 21, 2024
2 parents b74e2ad + f43f5e1 commit 3023390
Show file tree
Hide file tree
Showing 9 changed files with 115 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* feat(`PresetMappingFactory`): Add `fromObjectCache()` and `fromObjectCacheReversed()`.
* chore: Simplify remembering mapper.
* refactor: Deprecate serializer context.
* feat: null to `Traversable` or `ArrayAccess` is now handled & returns empty.

## 1.0.0

Expand Down
2 changes: 2 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
<file name="tests/Fixtures/UninitializedProperty/ObjectWithUninitializedProperty.php" />
<file name="tests/Fixtures/UninitializedPropertyDto/FinalObjectWithUninitializedPropertyDto.php" />
<file name="tests/Fixtures/UninitializedPropertyDto/ObjectWithUninitializedPropertyDto.php" />
<file name="tests/Fixtures/ArrayLikeDto/ObjectWithNotNullArrayAccessPropertyDto.php" />
<file name="tests/Fixtures/ArrayLikeDto/ObjectWithNotNullTraversablePropertyDto.php" />
</errorLevel>
</MissingConstructor>
<ArgumentTypeCoercion>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ public function transform(
?Type $targetType,
Context $context
): mixed {
if ($source === null) {
$source = [];
}

if ($targetType === null) {
throw new InvalidArgumentException('Target type must not be null.', context: $context);
}
Expand Down Expand Up @@ -221,6 +225,7 @@ public function getSupportedTransformation(): iterable
$sourceTypes = [
TypeFactory::objectOfClass(\Traversable::class),
TypeFactory::array(),
TypeFactory::null(),
];

$targetTypes = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ public function transform(
?Type $targetType,
Context $context
): mixed {
if ($source === null) {
$source = [];
}

if ($targetType === null) {
throw new InvalidArgumentException('Target type must not be null.', context: $context);
}
Expand Down Expand Up @@ -103,6 +107,7 @@ public function getSupportedTransformation(): iterable
$sourceTypes = [
TypeFactory::objectOfClass(\Traversable::class),
TypeFactory::array(),
TypeFactory::null(),
];

$targetTypes = [
Expand Down
25 changes: 25 additions & 0 deletions tests/Fixtures/ArrayLike/ObjectWithNullCollectionProperty.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?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\ArrayLike;

use Doctrine\Common\Collections\Collection;
use Rekalogika\Mapper\Tests\Fixtures\Scalar\ObjectWithScalarProperties;

class ObjectWithNullCollectionProperty
{
/**
* @var null|Collection<int,ObjectWithScalarProperties>
*/
public ?Collection $property = null;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?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\ArrayLikeDto;

use Rekalogika\Mapper\Tests\Fixtures\ScalarDto\ObjectWithScalarPropertiesDto;

class ObjectWithNotNullArrayAccessPropertyDto
{
/**
* @var \ArrayAccess<int,ObjectWithScalarPropertiesDto>
*/
public \ArrayAccess $property;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?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\ArrayLikeDto;

use Rekalogika\Mapper\Tests\Fixtures\ScalarDto\ObjectWithScalarPropertiesDto;

class ObjectWithNotNullTraversablePropertyDto
{
/**
* @var \Traversable<int,ObjectWithScalarPropertiesDto>
*/
public \Traversable $property;
}
16 changes: 16 additions & 0 deletions tests/IntegrationTest/TraversableToArrayAccessMappingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use Rekalogika\Mapper\Tests\Fixtures\ArrayLike\ObjectWithArrayProperty;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLike\ObjectWithArrayPropertyWithStringKey;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLike\ObjectWithCollectionProperty;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLike\ObjectWithNullCollectionProperty;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLike\ObjectWithSplObjectStorageProperty;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLike\ObjectWithTraversableProperties;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLikeDto\ObjectWithArrayAccessPropertyDto;
Expand All @@ -30,6 +31,7 @@
use Rekalogika\Mapper\Tests\Fixtures\ArrayLikeDto\ObjectWithArrayPropertyWithCompatibleHintDto;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLikeDto\ObjectWithArrayPropertyWithoutTypeHintDto;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLikeDto\ObjectWithCollectionPropertyDto;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLikeDto\ObjectWithNotNullArrayAccessPropertyDto;
use Rekalogika\Mapper\Tests\Fixtures\Scalar\ObjectWithScalarProperties;
use Rekalogika\Mapper\Tests\Fixtures\ScalarDto\ObjectWithScalarPropertiesDto;
use Rekalogika\Mapper\Transformer\Model\HashTable;
Expand Down Expand Up @@ -177,6 +179,20 @@ public function testCollectionToArrayAccessDto(): void
$this->assertEquals(1.1, $result->property[1]?->d);
}

public function testNullToNotNullArrayAccessDto(): void
{
$source = new ObjectWithNullCollectionProperty();

$result = $this->mapper->map($source, ObjectWithNotNullArrayAccessPropertyDto::class);

$this->assertInstanceOf(ObjectWithNotNullArrayAccessPropertyDto::class, $result);

$property = $result->property;
$this->assertInstanceOf(LazyArray::class, $property);
// @phpstan-ignore-next-line
$this->assertInstanceOf(\ArrayAccess::class, $property);
}

public function testArrayToArrayInterfaceDto(): void
{
$source = new ObjectWithArrayProperty();
Expand Down
13 changes: 13 additions & 0 deletions tests/IntegrationTest/TraversableToTraversableMappingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
use Rekalogika\Mapper\Tests\Fixtures\ArrayLike\ObjectWithArrayProperty;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLike\ObjectWithLazyDoctrineCollectionProperty;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLike\ObjectWithLazyDoctrineCollectionWithPresetCountableProperty;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLike\ObjectWithNullCollectionProperty;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLike\ObjectWithTraversableProperties;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLikeDto\ObjectWithNotNullTraversablePropertyDto;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLikeDto\ObjectWithTraversablePropertyDto;
use Rekalogika\Mapper\Tests\Fixtures\ArrayLikeDto\ObjectWithTraversablePropertyWithoutTypeHintDto;
use Rekalogika\Mapper\Tests\Fixtures\Scalar\ObjectWithScalarProperties;
Expand Down Expand Up @@ -121,4 +123,15 @@ public function testArrayToTraversableWithoutTypehint(): void
$this->assertEquals(1.1, $item->d);
}
}

public function testNullToNotNullTraversableDto(): void
{
$source = new ObjectWithNullCollectionProperty();
$result = $this->mapper->map($source, ObjectWithNotNullTraversablePropertyDto::class);

$this->assertInstanceOf(\Traversable::class, $result->property);

$arrayResult = iterator_to_array($result->property);
$this->assertEmpty($arrayResult);
}
}

0 comments on commit 3023390

Please sign in to comment.