Skip to content

Commit

Permalink
fix detection of primitive types on union type
Browse files Browse the repository at this point in the history
detect int before boolean and exclude int(1) from boolean detection
fixes #1573
  • Loading branch information
fabianerni committed Dec 2, 2024
1 parent 9bbc691 commit 0b1b137
Show file tree
Hide file tree
Showing 4 changed files with 18 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/Handler/UnionHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ private function testPrimitive(mixed $data, string $type, string $format): bool

case 'bool':
case 'boolean':
return (string) (bool) $data === (string) $data;
return (string) (bool) $data === (string) $data && 1 !== $data; // prevent false positive for 1/true

case 'string':
return (string) $data === (string) $data;
Expand Down
4 changes: 2 additions & 2 deletions src/Metadata/Driver/TypedPropertiesDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ public function __construct(DriverInterface $delegate, ?ParserInterface $typePar
private function reorderTypes(array $types): array
{
uasort($types, static function ($a, $b) {
$order = ['null' => 0, 'true' => 1, 'false' => 2, 'bool' => 3, 'int' => 4, 'float' => 5, 'string' => 6];
$order = ['null' => 0, 'true' => 1, 'false' => 2, 'int' => 3, 'float' => 4, 'bool' => 5, 'string' => 6];

return ($order[$a['name']] ?? 7) <=> ($order[$b['name']] ?? 7);
});

return $types;
return \array_values($types);
}

private function getDefaultWhiteList(): array
Expand Down
16 changes: 8 additions & 8 deletions tests/Metadata/Driver/UnionTypedPropertiesDriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,12 @@ public function testInferUnionTypesShouldResultInManyTypes()
{
$m = $this->resolve(UnionTypedProperties::class);

self::assertEquals(
self::assertSame(
[
'name' => 'union',
'params' =>
[
[
[
'name' => 'string',
'params' => [],
],
[
'name' => 'int',
'params' => [],
Expand All @@ -50,6 +46,10 @@ public function testInferUnionTypesShouldResultInManyTypes()
'name' => 'bool',
'params' => [],
],
[
'name' => 'string',
'params' => [],
],
],
],
],
Expand All @@ -61,18 +61,18 @@ public function testInferUnionTypesShouldIncludeValueTypes()
{
$m = $this->resolve(UnionTypedProperties::class);

self::assertEquals(
self::assertSame(
[
'name' => 'union',
'params' =>
[
[
[
'name' => 'string',
'name' => 'false',
'params' => [],
],
[
'name' => 'false',
'name' => 'string',
'params' => [],
],
],
Expand Down
7 changes: 7 additions & 0 deletions tests/Serializer/JsonSerializationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ protected static function getContent($key)
$outputs['uninitialized_typed_props'] = '{"virtual_role":{},"id":1,"role":{},"tags":[]}';
$outputs['custom_datetimeinterface'] = '{"custom":"2021-09-07"}';
$outputs['data_integer'] = '{"data":10000}';
$outputs['data_integer_one'] = '{"data":1}';
$outputs['data_float'] = '{"data":1.236}';
$outputs['data_bool'] = '{"data":false}';
$outputs['data_string'] = '{"data":"foo"}';
Expand Down Expand Up @@ -454,6 +455,9 @@ public function testDeserializingUnionProperties()
$object = new UnionTypedProperties(10000);
self::assertEquals($object, $this->deserialize(static::getContent('data_integer'), UnionTypedProperties::class));

$object = new UnionTypedProperties(1);
self::assertEquals($object, $this->deserialize(static::getContent('data_integer_one'), UnionTypedProperties::class));

$object = new UnionTypedProperties(1.236);
self::assertEquals($object, $this->deserialize(static::getContent('data_float'), UnionTypedProperties::class));

Expand All @@ -475,6 +479,9 @@ public function testSerializingUnionProperties()
$serialized = $this->serialize(new UnionTypedProperties(10000));
self::assertEquals(static::getContent('data_integer'), $serialized);

$serialized = $this->serialize(new UnionTypedProperties(1));
self::assertEquals(static::getContent('data_integer_one'), $serialized);

$serialized = $this->serialize(new UnionTypedProperties(1.236));
self::assertEquals(static::getContent('data_float'), $serialized);

Expand Down

0 comments on commit 0b1b137

Please sign in to comment.