fix: allow missing and null value for array node in flexible mode

This commit is contained in:
Romain Canon 2022-11-03 21:23:26 +01:00
parent 08fb0e17ba
commit 034f1c51e1
2 changed files with 78 additions and 15 deletions

View File

@ -23,16 +23,24 @@ final class StrictNodeBuilder implements NodeBuilder
public function build(Shell $shell, RootNodeBuilder $rootBuilder): TreeNode
{
$type = $shell->type();
if (! $this->flexible) {
TypeHelper::checkPermissiveType($shell->type());
TypeHelper::checkPermissiveType($type);
}
if (! $shell->hasValue()) {
if ($this->flexible && $shell->type()->accepts(null)) {
return TreeNode::leaf($shell, null);
if ($this->flexible) {
if ($type->accepts(null)) {
return TreeNode::leaf($shell, null);
}
if ($type->accepts([])) {
return TreeNode::leaf($shell, []);
}
}
throw new MissingNodeValue($shell->type());
throw new MissingNodeValue($type);
}
return $this->delegate->build($shell, $rootBuilder);

View File

@ -94,17 +94,6 @@ final class FlexibleMappingTest extends IntegrationTest
}
}
public function test_object_with_no_argument_build_with_non_array_source_in_flexible_mode_works_as_expected(): void
{
try {
$result = (new MapperBuilder())->flexible()->mapper()->map(stdClass::class, 'foo');
} catch (MappingError $error) {
$this->mappingFail($error);
}
self::assertFalse(isset($result->foo));
}
public function test_source_matching_two_unions_maps_the_one_with_most_arguments(): void
{
try {
@ -149,6 +138,72 @@ final class FlexibleMappingTest extends IntegrationTest
self::assertSame($source, $result);
}
public function test_missing_value_for_array_fills_it_with_empty_array(): void
{
try {
$result = (new MapperBuilder())->flexible()->mapper()->map(
'array{foo: string, bar: array<string>}',
['foo' => 'foo']
);
} catch (MappingError $error) {
$this->mappingFail($error);
}
self::assertSame('foo', $result['foo']);
self::assertSame([], $result['bar']);
}
public function test_null_value_for_array_fills_it_with_empty_array(): void
{
try {
$result = (new MapperBuilder())->flexible()->mapper()->map(
'array{foo: string, bar: array<string>}',
[
'foo' => 'foo',
'bar' => null
]
);
} catch (MappingError $error) {
$this->mappingFail($error);
}
self::assertSame('foo', $result['foo']);
self::assertSame([], $result['bar']);
}
public function test_missing_value_for_list_fills_it_with_empty_array(): void
{
try {
$result = (new MapperBuilder())->flexible()->mapper()->map(
'array{foo: string, bar: list<string>}',
['foo' => 'foo']
);
} catch (MappingError $error) {
$this->mappingFail($error);
}
self::assertSame('foo', $result['foo']);
self::assertSame([], $result['bar']);
}
public function test_null_value_for_list_fills_it_with_empty_array(): void
{
try {
$result = (new MapperBuilder())->flexible()->mapper()->map(
'array{foo: string, bar: list<string>}',
[
'foo' => 'foo',
'bar' => null
]
);
} catch (MappingError $error) {
$this->mappingFail($error);
}
self::assertSame('foo', $result['foo']);
self::assertSame([], $result['bar']);
}
public function test_missing_value_for_nullable_property_fills_it_with_null(): void
{
$class = new class () {