Skip to content

Commit 4a6d854

Browse files
committed
Handling case when a class docblok typed property receives a null value
1 parent 64efc83 commit 4a6d854

File tree

4 files changed

+46
-10
lines changed

4 files changed

+46
-10
lines changed

.phpunit.result.cache

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
C:37:"PHPUnit\Runner\DefaultTestResultCache":1847:{a:2:{s:7:"defects";a:1:{s:117:"Emul\ArrayToClassMapper\Test\Unit\MapperTest::testMapWhenClassDocBlockTypedPropertyGivenWithNullValue_shouldSetToNull";i:4;}s:5:"times";a:13:{s:117:"Emul\ArrayToClassMapper\Test\Unit\MapperTest::testMapWhenClassDocBlockTypedPropertyGivenWithNullValue_shouldSetToNull";d:0.006;s:76:"Emul\ArrayToClassMapper\Test\Unit\MapperTest::testMapWhenNullGiven_shouldSet";d:0.028;s:93:"Emul\ArrayToClassMapper\Test\Unit\MapperTest::testMapWhenBuiltInTypedPropertyGiven_shouldCast";d:0.005;s:114:"Emul\ArrayToClassMapper\Test\Unit\MapperTest::testMapWhenArrayTypedPropertyGivenWithoutDocBlock_shouldCastElements";d:0.006;s:123:"Emul\ArrayToClassMapper\Test\Unit\MapperTest::testMapWhenArrayTypedPropertyGivenWithBuiltInDockBlockType_shouldCastElements";d:0.006;s:133:"Emul\ArrayToClassMapper\Test\Unit\MapperTest::testMapWhenArrayTypedPropertyGivenWithCustomDockBlockType_shouldMapElementsToCustomType";d:0.01;s:109:"Emul\ArrayToClassMapper\Test\Unit\MapperTest::testMapWhenClassTypedPropertyGivenWithNullValue_shouldSetToNull";d:0.006;s:90:"Emul\ArrayToClassMapper\Test\Unit\MapperTest::testMapWhenClassTypedPropertyGiven_shouldMap";d:0.006;s:159:"Emul\ArrayToClassMapper\Test\Unit\MapperTest::testMapWhenArrayTypedPropertyGivenWithCustomDockBlockTypeAndCustomMapperProvided_shouldMapElementsWithGivenMapper";d:0.022;s:94:"Emul\ArrayToClassMapper\Test\Unit\MapperTest::testMapWhenTypelessPropertyGiven_shouldJustStore";d:0.005;s:115:"Emul\ArrayToClassMapper\Test\Unit\MapperTest::testMapWhenScalarDocBlockTypePropertyGiven_shouldCastToDocumentedType";d:0.005;s:114:"Emul\ArrayToClassMapper\Test\Unit\MapperTest::testMapWhenCustomDocBlockTypedPropertyGiven_shouldMapWithGivenMapper";d:0.006;s:119:"Emul\ArrayToClassMapper\Test\Unit\MapperTest::testMapWhenCustomDocBlockTypedArrayPropertyGiven_shouldMapWithGivenMapper";d:0.008;}}}

src/Mapper.php

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -66,15 +66,7 @@ public function map(array $input, string $className)
6666
$property->setValue($object, $value);
6767
}
6868
} else {
69-
if (
70-
$value === null
71-
&& empty($this->getCustomMapper($type->getName()))
72-
) {
73-
$property->setValue($object, null);
74-
}
75-
else {
76-
$property->setValue($object, $this->castCustom($value, $type->getName()));
77-
}
69+
$this->setCustomValue($object, $property, $type->getName(), $value);
7870
}
7971
} else {
8072
if (empty($docBlockType)) {
@@ -88,7 +80,7 @@ public function map(array $input, string $className)
8880
$property->setValue($object, $value);
8981
}
9082
} else {
91-
$property->setValue($object, $this->castCustom($value, $docBlockType->getName()));
83+
$this->setCustomValue($object, $property, $docBlockType->getName(), $value);
9284
}
9385
}
9486
}
@@ -98,6 +90,19 @@ public function map(array $input, string $className)
9890
return $object;
9991
}
10092

93+
private function setCustomValue($object, \ReflectionProperty $property, string $typeName, $value): void
94+
{
95+
if (
96+
$value === null
97+
&& empty($this->getCustomMapper($typeName))
98+
) {
99+
$property->setValue($object, null);
100+
}
101+
else {
102+
$property->setValue($object, $this->castCustom($value, $typeName));
103+
}
104+
}
105+
101106
private function castArray(array $array, DocBlockType $docblockType): array
102107
{
103108
$castedArray = [];

test/Unit/MapperTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Emul\ArrayToClassMapper\DocBlock\DocBlockParser;
99
use Emul\ArrayToClassMapper\DocBlock\Entity\DocBlockType;
1010
use Emul\ArrayToClassMapper\Test\Unit\Stub\ClassDocBlockTypedArrayStub;
11+
use Emul\ArrayToClassMapper\Test\Unit\Stub\ClassDocBlockTypedStub;
1112
use Emul\ArrayToClassMapper\Test\Unit\Stub\ClassTypedStub;
1213
use Emul\ArrayToClassMapper\Test\Unit\Stub\CustomDocBlockTypedArrayStub;
1314
use Emul\ArrayToClassMapper\Test\Unit\Stub\CustomDocBlockTypedStub;
@@ -130,6 +131,20 @@ public function testMapWhenClassTypedPropertyGivenWithNullValue_shouldSetToNull(
130131
$this->assertNull($result->getObject());
131132
}
132133

134+
public function testMapWhenClassDocBlockTypedPropertyGivenWithNullValue_shouldSetToNull()
135+
{
136+
$mapper = $this->getMapper();
137+
138+
$this->expectTypeRetrievedFromDocBlock('/** @var ScalarTypedStub|null */', new DocBlockType('ScalarTypedStub', true, false, true));
139+
140+
$input = ['object' => null];
141+
142+
/** @var ClassDocBlockTypedStub $result */
143+
$result = $mapper->map($input, ClassDocBlockTypedStub::class);
144+
145+
$this->assertNull($result->getObject());
146+
}
147+
133148
public function testMapWhenClassTypedPropertyGiven_shouldMap()
134149
{
135150
$mapper = $this->getMapper();
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Emul\ArrayToClassMapper\Test\Unit\Stub;
5+
6+
class ClassDocBlockTypedStub
7+
{
8+
/** @var ScalarTypedStub|null */
9+
private $object;
10+
11+
public function getObject(): ?ScalarTypedStub
12+
{
13+
return $this->object;
14+
}
15+
}

0 commit comments

Comments
 (0)