Skip to content

Commit

Permalink
Merge pull request #29 from veewee/bastien-phi-decode_falsy_values
Browse files Browse the repository at this point in the history
Improve decoding and encoding falsy values
  • Loading branch information
veewee authored Feb 14, 2022
2 parents 9c4e8c1 + be818b9 commit 75ec9f9
Show file tree
Hide file tree
Showing 4 changed files with 138 additions and 23 deletions.
3 changes: 2 additions & 1 deletion src/Xml/Encoding/Internal/Decoder/Builder/element.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,8 @@ function element(DOMElement $element): array
$namespaces,
$attributes,
$children ?: ['@value' => $element->textContent]
)
),
static fn (mixed $data): bool => $data !== []
)
];
}
39 changes: 18 additions & 21 deletions src/Xml/Encoding/Internal/Decoder/Builder/grouped_children.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
namespace VeeWee\Xml\Encoding\Internal\Decoder\Builder;

use DOMElement;
use function Psl\Dict\filter;
use function Psl\Dict\map;
use function Psl\Dict\merge;
use function Psl\Iter\reduce_with_keys;
Expand All @@ -16,25 +15,23 @@
*/
function grouped_children(DOMElement $element): array
{
return filter(
reduce_with_keys(
group_child_elements($element),
/**
* @param array $children
* @param DOMElement|list<DOMElement> $child
* @return array
*/
static fn (array $children, string $name, DOMElement|array $child): array
=> merge(
$children,
[
$name => is_array($child)
? [...map($child, static fn (DOMElement $child): array|string
=> unwrap_element(element($child)))]
: unwrap_element(element($child))
]
),
[],
)
return reduce_with_keys(
group_child_elements($element),
/**
* @param array $children
* @param DOMElement|list<DOMElement> $child
* @return array
*/
static fn (array $children, string $name, DOMElement|array $child): array
=> merge(
$children,
[
$name => is_array($child)
? [...map($child, static fn (DOMElement $child): array|string
=> unwrap_element(element($child)))]
: unwrap_element(element($child))
]
),
[],
);
}
2 changes: 1 addition & 1 deletion src/Xml/Encoding/Internal/Encoder/Builder/element.php
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ function element(string $name, array $data): callable
$children = filter_nulls([
$attributes ? attributes($attributes) : null,
$namedNamespaces ? xmlns_attributes($namedNamespaces) : null,
$value ? escaped_value($value) : null,
$value !== null ? escaped_value($value) : null,
...values(map_with_key(
$element,
/**
Expand Down
117 changes: 117 additions & 0 deletions tests/Xml/Encoding/EncodingTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ public function test_it_encodes_to_document(string $xml, array $data)
* @dataProvider provideBidirectionalCases
* @dataProvider provideRiskyBidirectionalCases
* @dataProvider provideDecodingOnly
* @dataProvider provideRiskyDecodingOnly
*/
public function test_it_decodes(string $xml, array $data)
{
Expand Down Expand Up @@ -108,6 +109,7 @@ public function provideBidirectionalCases()
'default' => 'world',
'value' => 'Toon',
],
'@value' => ''
]]
];
yield 'nested-single-child' => [
Expand Down Expand Up @@ -172,6 +174,45 @@ public function provideBidirectionalCases()
]
]
];
yield 'falsy values' => [
'xml' => <<<EOXML
<root>
<zero>0</zero>
<one>1</one>
<empty-string />
<string>string</string>
<attributes attr1="val1">0</attributes>
<empty-attributes attr1="val1" />
<falsy-attributes attr1="0" />
</root>
EOXML,
'data' => [
'root' => [
'zero' => '0',
'one' => '1',
'empty-string' => '',
'string' => 'string',
'attributes' => [
'@attributes' => [
'attr1' => 'val1',
],
'@value' => '0',
],
'empty-attributes' => [
'@attributes' => [
'attr1' => 'val1',
],
'@value' => '',
],
'falsy-attributes' => [
'@attributes' => [
'attr1' => '0',
],
'@value' => '',
],
]
]
];
}

public function provideRiskyBidirectionalCases()
Expand Down Expand Up @@ -268,6 +309,82 @@ public function provideDecodingOnly()
];
}

public function provideRiskyDecodingOnly()
{
yield 'falsy namespaced' => [
'xml' => <<<EOXML
<root>
<a xmlns="http://a" attr1="val1" />
<b xmlns="http://b" attr1="val1">0</b>
<x:c xmlns:x="http://x" attr1="val1" />
<x:d xmlns:x="http://x" attr1="val1">0</x:d>
<c xmlns="http://c" attr1="val1" />
<c xmlns="http://c" attr1="val1">0</c>
</root>
EOXML,
'data' => [
'root' => [
'a' => [
'@namespaces' => [
'' => 'http://a',
],
'@attributes' => [
'attr1' => 'val1',
],
'@value' => '',
],
'b' => [
'@namespaces' => [
'' => 'http://b',
],
'@attributes' => [
'attr1' => 'val1',
],
'@value' => '0',
],
'x:c' => [
'@namespaces' => [
'x' => 'http://x',
],
'@attributes' => [
'attr1' => 'val1',
],
'@value' => '',
],
'x:d' => [
'@namespaces' => [
'x' => 'http://x',
],
'@attributes' => [
'attr1' => 'val1',
],
'@value' => '0',
],
'c' => [
[
'@namespaces' => [
'' => 'http://c',
],
'@attributes' => [
'attr1' => 'val1',
],
'@value' => '',
],
[
'@namespaces' => [
'' => 'http://c',
],
'@attributes' => [
'attr1' => 'val1',
],
'@value' => '0',
],
]
]
],
];
}

public function provideInvalidXml()
{
yield 'items-in-root' => [
Expand Down

0 comments on commit 75ec9f9

Please sign in to comment.