Skip to content

Commit

Permalink
Merge branch 'master' into union-properties-array
Browse files Browse the repository at this point in the history
  • Loading branch information
scyzoryck authored Dec 1, 2024
2 parents 7a8b0e9 + f8adbc4 commit 18f462f
Show file tree
Hide file tree
Showing 14 changed files with 143 additions and 12 deletions.
7 changes: 4 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"doctrine/instantiator": "^1.3.1 || ^2.0",
"doctrine/lexer": "^2.0 || ^3.0",
"jms/metadata": "^2.6",
"phpstan/phpdoc-parser": "^1.20"
"phpstan/phpdoc-parser": "^1.20 || ^2.0"
},
"suggest": {
"doctrine/collections": "Required if you like to use doctrine collection types as ArrayCollection.",
Expand All @@ -37,17 +37,18 @@
"require-dev": {
"ext-pdo_sqlite": "*",
"doctrine/annotations": "^1.14 || ^2.0",
"slevomat/coding-standard": "dev-master#f2cc4c553eae68772624ffd7dd99022343b69c31 as 8.11.9999",
"doctrine/coding-standard": "^12.0",
"doctrine/orm": "^2.14 || ^3.0",
"doctrine/persistence": "^2.5.2 || ^3.0",
"doctrine/phpcr-odm": "^1.5.2 || ^2.0",
"jackalope/jackalope-doctrine-dbal": "^1.3",
"ocramius/proxy-manager": "^1.0 || ^2.0",
"phpbench/phpbench": "^1.0",
"phpstan/phpstan": "^1.10.57",
"phpstan/phpstan": "^2.0",
"phpunit/phpunit": "^9.0 || ^10.0 || ^11.0",
"psr/container": "^1.0 || ^2.0",
"rector/rector": "^1.0.0",
"rector/rector": "^1.0.0 || ^2.0@dev",
"symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0",
"symfony/expression-language": "^5.4 || ^6.0 || ^7.0",
"symfony/filesystem": "^5.4 || ^6.0 || ^7.0",
Expand Down
8 changes: 5 additions & 3 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ parameters:
- '#^Property JMS\\Serializer\\Handler\\FormErrorHandler\:\:\$translator has unknown class Symfony\\Component\\Translation\\TranslatorInterface as its type\.$#'
- '#^Cannot call method appendChild\(\) on null\.$#'
- '#^Call to an undefined method JMS\\Serializer\\VisitorInterface\:\:setData\(\)\.$#'
- '#^Property JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\CollectionOfNotExistingClasses\:\:\$productIds has unknown class JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\NotExistingClass as its type\.$#'
- '#^Call to method expects\(\) on an unknown class Symfony\\Component\\Translation\\TranslatorInterface\.$#'
- '#^Call to an undefined method JMS\\Serializer\\VisitorInterface\:\:hasData\(\)\.$#'
- '#^Property JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\CollectionOfClassesWithFullNamespacePath\:\:\$productIds has unknown class JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\Product as its type\.$#'
- '#^Property JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\CollectionOfInterfacesWithFullNamespacePath\:\:\$productColors has unknown class JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\JMS\\Serializer\\Tests\\Fixtures\\DocBlockType\\Collection\\Details\\ProductColor as its type\.$#'
- '#^Method JMS\\Serializer\\GraphNavigator\\DeserializationGraphNavigator\:\:resolveMetadata\(\) should return JMS\\Serializer\\Metadata\\ClassMetadata\|null#'
- '#^ArrayObject<\*NEVER\*, \*NEVER\*> does not accept list<string\|null>\.#'
- '#^ArrayObject<\*NEVER\*, \*NEVER\*> does not accept array<string, ArrayObject>\.#'
paths:
- %currentWorkingDirectory%/src
- %currentWorkingDirectory%/tests
excludePaths:
- tests/Fixtures/*
reportUnmatchedIgnoredErrors: false
1 change: 0 additions & 1 deletion phpstan/no-typed-prop.neon
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@ parameters:
- %currentWorkingDirectory%/tests/Fixtures/DocBlockType/Collection/ConstructorPropertyPromotion.php
- %currentWorkingDirectory%/tests/Fixtures/DocBlockType/Collection/ConstructorPropertyPromotionWithoutDocblock.php
- %currentWorkingDirectory%/tests/Fixtures/DocBlockType/Collection/ConstructorPropertyPromotionWithScalar.php
- %currentWorkingDirectory%/tests/Serializer/BaseSerializationTest.php
1 change: 1 addition & 0 deletions phpstan/no-unions.neon
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
parameters:
excludePaths:
- %currentWorkingDirectory%/src/Handler/UnionHandler.php
- %currentWorkingDirectory%/tests/Fixtures/TypedProperties/ComplexDiscriminatedUnion.php
2 changes: 2 additions & 0 deletions src/GraphNavigator/DeserializationGraphNavigator.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,8 @@ public function accept($data, ?array $type = null)

case 'bool':
case 'boolean':
case 'false':
case 'true':
return $this->visitor->visitBoolean($data, $type);

case 'double':
Expand Down
2 changes: 2 additions & 0 deletions src/GraphNavigator/SerializationGraphNavigator.php
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ public function accept($data, ?array $type = null)

case 'bool':
case 'boolean':
case 'true':
case 'false':
return $this->visitor->visitBoolean((bool) $data, $type);

case 'double':
Expand Down
1 change: 0 additions & 1 deletion src/Handler/FormErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ private function getErrorMessage(FormError $error): ?string

private function convertFormToArray(SerializationVisitorInterface $visitor, FormInterface $data): \ArrayObject
{
/** @var \ArrayObject{errors?:array<string>,children?:array<string,\ArrayObject>} $form */
$form = new \ArrayObject();
$errors = [];
foreach ($data->getErrors() as $error) {
Expand Down
23 changes: 19 additions & 4 deletions src/Metadata/Driver/DocBlockDriver/DocBlockTypeResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
use PHPStan\PhpDocParser\Parser\PhpDocParser;
use PHPStan\PhpDocParser\Parser\TokenIterator;
use PHPStan\PhpDocParser\Parser\TypeParser;
use PHPStan\PhpDocParser\ParserConfig;

/**
* @internal
Expand Down Expand Up @@ -47,11 +48,25 @@ final class DocBlockTypeResolver

public function __construct()
{
$constExprParser = new ConstExprParser();
$typeParser = new TypeParser($constExprParser);
// PHPStan PHPDoc Parser 2
if (class_exists(ParserConfig::class)) {
$config = new ParserConfig(['lines' => true, 'indexes' => true]);

$this->phpDocParser = new PhpDocParser($typeParser, $constExprParser);
$this->lexer = new Lexer();
$constExprParser = new ConstExprParser($config);
$typeParser = new TypeParser($config, $constExprParser);

$this->phpDocParser = new PhpDocParser($config, $typeParser, $constExprParser);
$this->lexer = new Lexer($config);
} else {
// @phpstan-ignore arguments.count
$constExprParser = new ConstExprParser();
// @phpstan-ignore arguments.count
$typeParser = new TypeParser($constExprParser);
// @phpstan-ignore arguments.count
$this->phpDocParser = new PhpDocParser($typeParser, $constExprParser);
// @phpstan-ignore arguments.count
$this->lexer = new Lexer();
}
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/Metadata/Driver/TypedPropertiesDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ private function getDefaultWhiteList(): array
'float',
'bool',
'boolean',
'true',
'false',
'string',
'double',
'iterable',
Expand Down
16 changes: 16 additions & 0 deletions tests/Fixtures/DataFalse.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace JMS\Serializer\Tests\Fixtures;

class DataFalse
{
public false $data;

public function __construct(
false $data
) {
$this->data = $data;
}
}
16 changes: 16 additions & 0 deletions tests/Fixtures/DataTrue.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?php

declare(strict_types=1);

namespace JMS\Serializer\Tests\Fixtures;

class DataTrue
{
public true $data;

public function __construct(
true $data
) {
$this->data = $data;
}
}
2 changes: 2 additions & 0 deletions tests/Fixtures/TypedProperties/UnionTypedProperties.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ class UnionTypedProperties

private int|bool|float|string|null $nullableData;

private string|false $valueTypedUnion;

public function __construct($data)
{
$this->data = $data;
Expand Down
25 changes: 25 additions & 0 deletions tests/Metadata/Driver/UnionTypedPropertiesDriverTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,31 @@ public function testInferUnionTypesShouldResultInManyTypes()
);
}

public function testInferUnionTypesShouldIncludeValueTypes()
{
$m = $this->resolve(UnionTypedProperties::class);

self::assertEquals(
[
'name' => 'union',
'params' =>
[
[
[
'name' => 'string',
'params' => [],
],
[
'name' => 'false',
'params' => [],
],
],
],
],
$m->propertyMetadata['valueTypedUnion']->type,
);
}

private function resolve(string $classToResolve): ClassMetadata
{
$namingStrategy = new IdenticalPropertyNamingStrategy();
Expand Down
49 changes: 49 additions & 0 deletions tests/Serializer/JsonSerializationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@
use JMS\Serializer\SerializationContext;
use JMS\Serializer\Tests\Fixtures\Author;
use JMS\Serializer\Tests\Fixtures\AuthorList;
use JMS\Serializer\Tests\Fixtures\DataFalse;
use JMS\Serializer\Tests\Fixtures\DataTrue;
use JMS\Serializer\Tests\Fixtures\DiscriminatedAuthor;
use JMS\Serializer\Tests\Fixtures\DiscriminatedComment;
use JMS\Serializer\Tests\Fixtures\FirstClassMapCollection;
Expand All @@ -27,6 +29,7 @@
use JMS\Serializer\Visitor\Factory\JsonSerializationVisitorFactory;
use JMS\Serializer\Visitor\SerializationVisitorInterface;
use PHPUnit\Framework\Attributes\DataProvider;
use TypeError;

class JsonSerializationTest extends BaseSerializationTestCase
{
Expand Down Expand Up @@ -152,6 +155,8 @@ protected static function getContent($key)
$outputs['data_bool'] = '{"data":false}';
$outputs['data_string'] = '{"data":"foo"}';
$outputs['data_array'] = '{"data":[1,2,3]}';
$outputs['data_true'] = '{"data":true}';
$outputs['data_false'] = '{"data":false}';
$outputs['data_author'] = '{"data":{"full_name":"foo"}}';
$outputs['data_comment'] = '{"data":{"author":{"full_name":"foo"},"text":"bar"}}';
$outputs['data_discriminated_author'] = '{"data":{"full_name":"foo","objectType":"author"}}';
Expand Down Expand Up @@ -465,6 +470,50 @@ public function testUnionProperties($data, string $expected): void
self::assertEquals($this->serialize($object), static::getContent($expected));
}

public function testTrueDataType()
{
if (PHP_VERSION_ID < 80200) {
$this->markTestSkipped('True type requires PHP 8.2');

return;
}

self::assertEquals(
static::getContent('data_true'),
$this->serialize(new DataTrue(true)),
);

self::assertEquals(
new DataTrue(true),
$this->deserialize(static::getContent('data_true'), DataTrue::class),
);

$this->expectException(TypeError::class);
$this->deserialize(static::getContent('data_false'), DataTrue::class);
}

public function testFalseDataType()
{
if (PHP_VERSION_ID < 80200) {
$this->markTestSkipped('False type requires PHP 8.2');

return;
}

self::assertEquals(
static::getContent('data_false'),
$this->serialize(new DataFalse(false)),
);

self::assertEquals(
new DataFalse(false),
$this->deserialize(static::getContent('data_false'), DataFalse::class),
);

$this->expectException(TypeError::class);
$this->deserialize(static::getContent('data_true'), DataFalse::class);
}

public function testDeserializingComplexDiscriminatedUnionProperties()
{
if (PHP_VERSION_ID < 80000) {
Expand Down

0 comments on commit 18f462f

Please sign in to comment.