From 54fdd74b81680a78b16aec5d25351c5c7e3c0cce Mon Sep 17 00:00:00 2001 From: Rico Sonntag Date: Fri, 14 Nov 2025 11:43:35 +0100 Subject: [PATCH] fix(ci): satisfy composer ci:test --- src/JsonMapper.php | 30 ++++++------ src/JsonMapper/Attribute/ReplaceProperty.php | 2 +- .../CollectionDocBlockTypeResolver.php | 6 +-- .../Collection/CollectionFactory.php | 12 ++--- .../Collection/CollectionFactoryInterface.php | 12 ++--- .../Configuration/JsonMapperConfiguration.php | 14 +++--- src/JsonMapper/Context/MappingContext.php | 4 +- src/JsonMapper/Context/MappingError.php | 6 +-- src/JsonMapper/Exception/MappingException.php | 6 +-- .../Exception/MissingPropertyException.php | 6 +-- .../Exception/UnknownPropertyException.php | 6 +-- src/JsonMapper/Report/MappingResult.php | 2 +- src/JsonMapper/Resolver/ClassResolver.php | 14 +++--- src/JsonMapper/Type/TypeResolver.php | 8 ++-- src/JsonMapper/Value/ClosureTypeHandler.php | 2 +- src/JsonMapper/Value/CustomTypeRegistry.php | 8 ++-- .../BuiltinValueConversionStrategy.php | 20 ++++---- .../CollectionValueConversionStrategy.php | 8 ++-- .../CustomTypeValueConversionStrategy.php | 8 ++-- .../DateTimeValueConversionStrategy.php | 8 ++-- .../Strategy/EnumValueConversionStrategy.php | 8 ++-- .../Strategy/NullValueConversionStrategy.php | 8 ++-- .../ObjectTypeConversionGuardTrait.php | 12 ++--- .../ObjectValueConversionStrategy.php | 12 ++--- .../PassthroughValueConversionStrategy.php | 8 ++-- .../ValueConversionStrategyInterface.php | 8 ++-- src/JsonMapper/Value/ValueConverter.php | 4 +- tests/Fixtures/Cache/InMemoryCachePool.php | 15 ++++-- .../DocsCustomNameConverterTest.php | 2 +- .../JsonMapper/DocsNestedCollectionsTest.php | 29 ++++++++---- tests/JsonMapper/DocsQuickStartTest.php | 47 ++++++++++++++----- tests/JsonMapper/JsonMapperTypeCacheTest.php | 4 +- 32 files changed, 191 insertions(+), 148 deletions(-) diff --git a/src/JsonMapper.php b/src/JsonMapper.php index 2f89413..6110d2e 100644 --- a/src/JsonMapper.php +++ b/src/JsonMapper.php @@ -110,12 +110,12 @@ /** * Creates a mapper that converts JSON data into PHP objects using the configured Symfony services. * - * @param PropertyInfoExtractorInterface $extractor Extractor that provides type information for mapped properties. - * @param PropertyAccessorInterface $accessor Property accessor used to write values onto target objects. + * @param PropertyInfoExtractorInterface $extractor Extractor that provides type information for mapped properties. + * @param PropertyAccessorInterface $accessor Property accessor used to write values onto target objects. * @param PropertyNameConverterInterface|null $nameConverter Optional converter to normalise incoming property names. - * @param array $classMap Map of base classes to resolvers that determine the concrete class to instantiate. - * @param CacheItemPoolInterface|null $typeCache Optional cache for resolved type information. - * @param JsonMapperConfiguration $config Default mapper configuration cloned for new mapping contexts. + * @param array $classMap Map of base classes to resolvers that determine the concrete class to instantiate. + * @param CacheItemPoolInterface|null $typeCache Optional cache for resolved type information. + * @param JsonMapperConfiguration $config Default mapper configuration cloned for new mapping contexts. */ public function __construct( private PropertyInfoExtractorInterface $extractor, @@ -179,7 +179,7 @@ public function addTypeHandler(TypeHandlerInterface $handler): JsonMapper * Registers a custom type using a closure-based handler. * * @param non-empty-string $type Name of the custom type alias handled by the closure. - * @param Closure $closure Closure that converts the incoming value to the target type. + * @param Closure $closure Closure that converts the incoming value to the target type. * * @deprecated Use addTypeHandler() with a TypeHandlerInterface implementation instead. * @@ -213,11 +213,11 @@ public function addCustomClassMapEntry(string $className, Closure $closure): Jso /** * Maps the JSON to the specified class entity. * - * @param mixed $json Source data to map into PHP objects. - * @param class-string|null $className Fully qualified class name that should be instantiated for mapped objects. - * @param class-string|null $collectionClassName Collection class that should wrap the mapped objects when required. - * @param MappingContext|null $context Optional mapping context reused across nested mappings. - * @param JsonMapperConfiguration|null $configuration Optional configuration that overrides the default mapper settings. + * @param mixed $json Source data to map into PHP objects. + * @param class-string|null $className Fully qualified class name that should be instantiated for mapped objects. + * @param class-string|null $collectionClassName Collection class that should wrap the mapped objects when required. + * @param MappingContext|null $context Optional mapping context reused across nested mappings. + * @param JsonMapperConfiguration|null $configuration Optional configuration that overrides the default mapper settings. * * @return mixed The mapped PHP value or collection produced from the given JSON. */ @@ -540,9 +540,9 @@ private function convertValue(mixed $json, Type $type, MappingContext $context): /** * Converts the value according to the provided union type. * - * @param mixed $json Value being converted so it matches one of the union candidates. - * @param UnionType $type Union definition listing acceptable target types. - * @param MappingContext $context Context used to track conversion errors while testing candidates. + * @param mixed $json Value being converted so it matches one of the union candidates. + * @param UnionType $type Union definition listing acceptable target types. + * @param MappingContext $context Context used to track conversion errors while testing candidates. * * @return mixed Value converted to a type accepted by the union. */ @@ -683,7 +683,7 @@ private function isNullType(Type $type): bool /** * Creates an instance of the given class name. * - * @param string $className Fully qualified class name to instantiate. + * @param string $className Fully qualified class name to instantiate. * @param mixed ...$constructorArguments Arguments forwarded to the constructor of the class. * * @return object Newly created instance of the requested class. diff --git a/src/JsonMapper/Attribute/ReplaceProperty.php b/src/JsonMapper/Attribute/ReplaceProperty.php index 8263b28..0625434 100644 --- a/src/JsonMapper/Attribute/ReplaceProperty.php +++ b/src/JsonMapper/Attribute/ReplaceProperty.php @@ -20,7 +20,7 @@ final readonly class ReplaceProperty { /** - * @param string $value Name of the incoming JSON field that should be renamed. + * @param string $value Name of the incoming JSON field that should be renamed. * @param string $replaces Target property name that receives the value. */ public function __construct( diff --git a/src/JsonMapper/Collection/CollectionDocBlockTypeResolver.php b/src/JsonMapper/Collection/CollectionDocBlockTypeResolver.php index 3afd078..dfb66d3 100644 --- a/src/JsonMapper/Collection/CollectionDocBlockTypeResolver.php +++ b/src/JsonMapper/Collection/CollectionDocBlockTypeResolver.php @@ -37,9 +37,9 @@ final class CollectionDocBlockTypeResolver private DocBlockFactoryInterface $docBlockFactory; /** - * @param DocBlockFactoryInterface|null $docBlockFactory Optional docblock factory used to parse collection annotations. - * @param ContextFactory $contextFactory Factory for building type resolution contexts for reflected classes. - * @param PhpDocTypeHelper $phpDocTypeHelper Helper translating DocBlock types into Symfony TypeInfo representations. + * @param DocBlockFactoryInterface|null $docBlockFactory Optional docblock factory used to parse collection annotations. + * @param ContextFactory $contextFactory Factory for building type resolution contexts for reflected classes. + * @param PhpDocTypeHelper $phpDocTypeHelper Helper translating DocBlock types into Symfony TypeInfo representations. */ public function __construct( ?DocBlockFactoryInterface $docBlockFactory = null, diff --git a/src/JsonMapper/Collection/CollectionFactory.php b/src/JsonMapper/Collection/CollectionFactory.php index e0b8496..47c78a8 100644 --- a/src/JsonMapper/Collection/CollectionFactory.php +++ b/src/JsonMapper/Collection/CollectionFactory.php @@ -54,9 +54,9 @@ public function __construct( /** * Converts the provided iterable JSON structure to a PHP array. * - * @param mixed $json Raw JSON data representing the collection to hydrate. - * @param Type $valueType Type descriptor for individual collection entries. - * @param MappingContext $context Active mapping context providing path and strictness information. + * @param mixed $json Raw JSON data representing the collection to hydrate. + * @param Type $valueType Type descriptor for individual collection entries. + * @param MappingContext $context Active mapping context providing path and strictness information. * * @return array|null Normalised collection data or null when conversion fails. */ @@ -100,9 +100,9 @@ public function mapIterable(mixed $json, Type $valueType, MappingContext $contex /** * Builds a collection based on the specified collection type description. * - * @param CollectionType> $type Resolved collection metadata from docblocks or attributes. - * @param mixed $json Raw JSON payload containing the collection values. - * @param MappingContext $context Mapping context controlling strict mode and error tracking. + * @param CollectionType> $type Resolved collection metadata from docblocks or attributes. + * @param mixed $json Raw JSON payload containing the collection values. + * @param MappingContext $context Mapping context controlling strict mode and error tracking. * * @return object|array|null Instantiated collection wrapper or the normalised array values. */ diff --git a/src/JsonMapper/Collection/CollectionFactoryInterface.php b/src/JsonMapper/Collection/CollectionFactoryInterface.php index 1ca8fbf..7bcb51d 100644 --- a/src/JsonMapper/Collection/CollectionFactoryInterface.php +++ b/src/JsonMapper/Collection/CollectionFactoryInterface.php @@ -32,9 +32,9 @@ interface CollectionFactoryInterface /** * Converts the provided iterable JSON structure to a PHP array. * - * @param mixed $json Raw JSON data representing the iterable input to normalise. - * @param Type $valueType Type description for the collection values. - * @param MappingContext $context Active mapping context carrying strictness and error reporting configuration. + * @param mixed $json Raw JSON data representing the iterable input to normalise. + * @param Type $valueType Type description for the collection values. + * @param MappingContext $context Active mapping context carrying strictness and error reporting configuration. * * @return array|null Normalised array representation or null when conversion fails. */ @@ -43,9 +43,9 @@ public function mapIterable(mixed $json, Type $valueType, MappingContext $contex /** * Builds a collection based on the specified collection type description. * - * @param CollectionType> $type Resolved collection metadata from PHPDoc or attributes. - * @param mixed $json Raw JSON payload containing the collection values. - * @param MappingContext $context Mapping context controlling strict mode and error recording. + * @param CollectionType> $type Resolved collection metadata from PHPDoc or attributes. + * @param mixed $json Raw JSON payload containing the collection values. + * @param MappingContext $context Mapping context controlling strict mode and error recording. * * @return array|object|null Instantiated collection wrapper or the normalised array values. */ diff --git a/src/JsonMapper/Configuration/JsonMapperConfiguration.php b/src/JsonMapper/Configuration/JsonMapperConfiguration.php index a240670..c29da28 100644 --- a/src/JsonMapper/Configuration/JsonMapperConfiguration.php +++ b/src/JsonMapper/Configuration/JsonMapperConfiguration.php @@ -24,13 +24,13 @@ final class JsonMapperConfiguration /** * Creates a new configuration instance with optional overrides. * - * @param bool $strictMode Whether unknown/missing properties should trigger errors - * @param bool $collectErrors Whether encountered mapping errors should be collected - * @param bool $emptyStringIsNull Whether empty strings are converted to null - * @param bool $ignoreUnknownProperties Whether properties missing in the destination type are ignored - * @param bool $treatNullAsEmptyCollection Whether null collections are replaced with empty collections - * @param string $defaultDateFormat Default `DateTimeInterface` format used for serialization/deserialization - * @param bool $allowScalarToObjectCasting Whether scalars can be coerced into objects when supported + * @param bool $strictMode Whether unknown/missing properties should trigger errors + * @param bool $collectErrors Whether encountered mapping errors should be collected + * @param bool $emptyStringIsNull Whether empty strings are converted to null + * @param bool $ignoreUnknownProperties Whether properties missing in the destination type are ignored + * @param bool $treatNullAsEmptyCollection Whether null collections are replaced with empty collections + * @param string $defaultDateFormat Default `DateTimeInterface` format used for serialization/deserialization + * @param bool $allowScalarToObjectCasting Whether scalars can be coerced into objects when supported */ public function __construct( private bool $strictMode = false, diff --git a/src/JsonMapper/Context/MappingContext.php b/src/JsonMapper/Context/MappingContext.php index e163424..fc7f7c0 100644 --- a/src/JsonMapper/Context/MappingContext.php +++ b/src/JsonMapper/Context/MappingContext.php @@ -108,8 +108,8 @@ public function withPathSegment(string|int $segment, callable $callback): mixed /** * Stores the error message for later consumption. * - * @param string $message Human-readable description of the failure - * @param MappingException|null $exception Optional exception associated with the failure + * @param string $message Human-readable description of the failure + * @param MappingException|null $exception Optional exception associated with the failure * * @return void */ diff --git a/src/JsonMapper/Context/MappingError.php b/src/JsonMapper/Context/MappingError.php index 6aa9065..24b9e49 100644 --- a/src/JsonMapper/Context/MappingError.php +++ b/src/JsonMapper/Context/MappingError.php @@ -19,9 +19,9 @@ final readonly class MappingError { /** - * @param string $path JSON path pointing to the failing property - * @param string $message Human-readable description of the failure - * @param MappingException|null $exception Exception that triggered the error, when available + * @param string $path JSON path pointing to the failing property + * @param string $message Human-readable description of the failure + * @param MappingException|null $exception Exception that triggered the error, when available */ public function __construct( private string $path, diff --git a/src/JsonMapper/Exception/MappingException.php b/src/JsonMapper/Exception/MappingException.php index 4931852..f79be6b 100644 --- a/src/JsonMapper/Exception/MappingException.php +++ b/src/JsonMapper/Exception/MappingException.php @@ -20,9 +20,9 @@ abstract class MappingException extends RuntimeException { /** - * @param string $message Human readable description of the failure scenario. - * @param string $path JSON pointer or dotted path identifying the failing value. - * @param int $code Optional error code to bubble up to the caller. + * @param string $message Human readable description of the failure scenario. + * @param string $path JSON pointer or dotted path identifying the failing value. + * @param int $code Optional error code to bubble up to the caller. * @param Throwable|null $previous Underlying cause, if the exception wraps another failure. */ public function __construct( diff --git a/src/JsonMapper/Exception/MissingPropertyException.php b/src/JsonMapper/Exception/MissingPropertyException.php index 8e3a72e..d6d1b99 100644 --- a/src/JsonMapper/Exception/MissingPropertyException.php +++ b/src/JsonMapper/Exception/MissingPropertyException.php @@ -19,9 +19,9 @@ final class MissingPropertyException extends MappingException { /** - * @param string $path Path indicating where the missing property should have been present. - * @param string $propertyName Name of the required property defined on the PHP target. - * @param class-string $className Fully qualified name of the DTO or object declaring the property. + * @param string $path Path indicating where the missing property should have been present. + * @param string $propertyName Name of the required property defined on the PHP target. + * @param class-string $className Fully qualified name of the DTO or object declaring the property. */ public function __construct( string $path, diff --git a/src/JsonMapper/Exception/UnknownPropertyException.php b/src/JsonMapper/Exception/UnknownPropertyException.php index 6661abd..0564f1d 100644 --- a/src/JsonMapper/Exception/UnknownPropertyException.php +++ b/src/JsonMapper/Exception/UnknownPropertyException.php @@ -19,9 +19,9 @@ final class UnknownPropertyException extends MappingException { /** - * @param string $path Path to the JSON value that references the unknown property. - * @param string $propertyName Name of the property that does not exist on the PHP target. - * @param class-string $className Fully qualified name of the object that lacks the property. + * @param string $path Path to the JSON value that references the unknown property. + * @param string $propertyName Name of the property that does not exist on the PHP target. + * @param class-string $className Fully qualified name of the object that lacks the property. */ public function __construct( string $path, diff --git a/src/JsonMapper/Report/MappingResult.php b/src/JsonMapper/Report/MappingResult.php index 1b62d67..b0e760d 100644 --- a/src/JsonMapper/Report/MappingResult.php +++ b/src/JsonMapper/Report/MappingResult.php @@ -17,7 +17,7 @@ final readonly class MappingResult { /** - * @param mixed $value The mapped value returned by the mapper. + * @param mixed $value The mapped value returned by the mapper. * @param MappingReport $report Report containing diagnostics for the mapping operation. */ public function __construct( diff --git a/src/JsonMapper/Resolver/ClassResolver.php b/src/JsonMapper/Resolver/ClassResolver.php index e39dbd4..465279d 100644 --- a/src/JsonMapper/Resolver/ClassResolver.php +++ b/src/JsonMapper/Resolver/ClassResolver.php @@ -48,8 +48,8 @@ public function __construct(array $classMap = []) /** * Adds a custom resolution rule. * - * @param class-string $className Base class or interface the resolver handles. - * @param Closure(mixed):class-string|Closure(mixed, MappingContext):class-string $resolver Callback returning a concrete class based on the JSON payload and optional mapping context. + * @param class-string $className Base class or interface the resolver handles. + * @param Closure(mixed):class-string|Closure(mixed, MappingContext):class-string $resolver Callback returning a concrete class based on the JSON payload and optional mapping context. * * @phpstan-param class-string $className * @phpstan-param Closure(mixed):class-string|Closure(mixed, MappingContext):class-string $resolver @@ -63,9 +63,9 @@ public function add(string $className, Closure $resolver): void /** * Resolves the class name for the provided JSON payload. * - * @param class-string $className Base class name configured in the resolver map. - * @param mixed $json Raw JSON fragment inspected to determine the target class. - * @param MappingContext $context Mapping context passed to resolution callbacks when required. + * @param class-string $className Base class name configured in the resolver map. + * @param mixed $json Raw JSON fragment inspected to determine the target class. + * @param MappingContext $context Mapping context passed to resolution callbacks when required. * * @return class-string Fully-qualified class name that should be instantiated for the payload. */ @@ -100,8 +100,8 @@ public function resolve(string $className, mixed $json, MappingContext $context) * Executes a resolver callback while adapting the invocation to its declared arity. * * @param Closure(mixed):class-string|Closure(mixed, MappingContext):class-string $resolver User-provided resolver that determines the concrete class; the parameter list defines whether the mapping context can be injected. - * @param mixed $json JSON fragment forwarded to the resolver so it can inspect discriminator values. - * @param MappingContext $context Context object passed when supported to supply additional mapping metadata. + * @param mixed $json JSON fragment forwarded to the resolver so it can inspect discriminator values. + * @param MappingContext $context Context object passed when supported to supply additional mapping metadata. * * @return mixed Raw resolver result that will subsequently be validated as a class-string. */ diff --git a/src/JsonMapper/Type/TypeResolver.php b/src/JsonMapper/Type/TypeResolver.php index 87e7a47..3866a11 100644 --- a/src/JsonMapper/Type/TypeResolver.php +++ b/src/JsonMapper/Type/TypeResolver.php @@ -156,8 +156,8 @@ private function buildCacheKey(string $className, string $propertyName): string /** * Falls back to native reflection when PropertyInfo does not expose metadata for a property. * - * @param class-string $className Declaring class inspected via reflection; invalid classes yield null. - * @param string $propertyName Name of the property to inspect; missing properties short-circuit to null. + * @param class-string $className Declaring class inspected via reflection; invalid classes yield null. + * @param string $propertyName Name of the property to inspect; missing properties short-circuit to null. * * @return Type|null Type derived from the reflected signature, including nullability, or null when no type hint exists. */ @@ -216,8 +216,8 @@ private function resolveFromReflection(string $className, string $propertyName): /** * Translates a reflected named type into the internal Type representation while preserving nullability. * - * @param ReflectionNamedType $type Native type declaration; builtin names map to builtin identifiers, class names to object types. - * @param bool|null $nullable Overrides the reflection nullability flag when provided; null defers to the reflection metadata. + * @param ReflectionNamedType $type Native type declaration; builtin names map to builtin identifiers, class names to object types. + * @param bool|null $nullable Overrides the reflection nullability flag when provided; null defers to the reflection metadata. * * @return Type|null Resolved Type instance or null when the builtin name is unsupported. */ diff --git a/src/JsonMapper/Value/ClosureTypeHandler.php b/src/JsonMapper/Value/ClosureTypeHandler.php index fa03096..e47ff76 100644 --- a/src/JsonMapper/Value/ClosureTypeHandler.php +++ b/src/JsonMapper/Value/ClosureTypeHandler.php @@ -28,7 +28,7 @@ final class ClosureTypeHandler implements TypeHandlerInterface private Closure $converter; /** - * @param non-empty-string $className Type alias handled by the converter. + * @param non-empty-string $className Type alias handled by the converter. * @param callable(mixed):mixed|callable(mixed, MappingContext):mixed $converter Callable receiving the mapped value and * optionally the mapping context. */ diff --git a/src/JsonMapper/Value/CustomTypeRegistry.php b/src/JsonMapper/Value/CustomTypeRegistry.php index 91c24d6..8abbf4e 100644 --- a/src/JsonMapper/Value/CustomTypeRegistry.php +++ b/src/JsonMapper/Value/CustomTypeRegistry.php @@ -30,7 +30,7 @@ final class CustomTypeRegistry /** * Registers the converter for the provided class name. * - * @param non-empty-string $className Fully-qualified type alias handled by the converter. + * @param non-empty-string $className Fully-qualified type alias handled by the converter. * @param callable(mixed):mixed|callable(mixed, MappingContext):mixed $converter Callback responsible for creating the destination value. * * @return void @@ -55,7 +55,7 @@ public function registerHandler(TypeHandlerInterface $handler): void /** * Returns TRUE if a handler for the type exists. * - * @param Type $type Type information describing the target property. + * @param Type $type Type information describing the target property. * @param mixed $value JSON value that should be converted. * * @return bool TRUE when at least one registered handler supports the value. @@ -74,8 +74,8 @@ public function supports(Type $type, mixed $value): bool /** * Executes the converter for the class. * - * @param Type $type Type information describing the target property. - * @param mixed $value JSON value that should be converted. + * @param Type $type Type information describing the target property. + * @param mixed $value JSON value that should be converted. * @param MappingContext $context Mapping context providing runtime configuration and state. * * @return mixed Converted value returned by the first supporting handler. diff --git a/src/JsonMapper/Value/Strategy/BuiltinValueConversionStrategy.php b/src/JsonMapper/Value/Strategy/BuiltinValueConversionStrategy.php index 2556fcb..4071d39 100644 --- a/src/JsonMapper/Value/Strategy/BuiltinValueConversionStrategy.php +++ b/src/JsonMapper/Value/Strategy/BuiltinValueConversionStrategy.php @@ -43,8 +43,8 @@ final class BuiltinValueConversionStrategy implements ValueConversionStrategyInt /** * Determines whether the provided type represents a builtin PHP value. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return bool TRUE when the target type is a builtin PHP type. @@ -57,8 +57,8 @@ public function supports(mixed $value, Type $type, MappingContext $context): boo /** * Converts the provided value to the builtin type defined by the metadata. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return mixed Value cast to the requested builtin type when possible. @@ -84,8 +84,8 @@ public function convert(mixed $value, Type $type, MappingContext $context): mixe /** * Normalizes common scalar representations before the conversion happens. * - * @param mixed $value Raw value coming from the input payload. - * @param BuiltinType $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param BuiltinType $type Type metadata describing the target property. * * @return mixed Normalized value that is compatible with the builtin type conversion. */ @@ -151,9 +151,9 @@ private function normalizeValue(mixed $value, BuiltinType $type): mixed /** * Validates that the value matches the builtin type or records a mismatch. * - * @param mixed $value Normalized value used during conversion. - * @param BuiltinType $type Type metadata describing the target property. - * @param MappingContext $context Mapping context providing configuration such as strict mode. + * @param mixed $value Normalized value used during conversion. + * @param BuiltinType $type Type metadata describing the target property. + * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return void */ @@ -203,7 +203,7 @@ private function allowsNull(BuiltinType $type): bool /** * Checks whether the value matches the builtin type identifier. * - * @param mixed $value Normalized value used during conversion. + * @param mixed $value Normalized value used during conversion. * @param TypeIdentifier $identifier Identifier of the builtin type to check against. * * @return bool TRUE when the value matches the identifier requirements. diff --git a/src/JsonMapper/Value/Strategy/CollectionValueConversionStrategy.php b/src/JsonMapper/Value/Strategy/CollectionValueConversionStrategy.php index f3f7e05..789b954 100644 --- a/src/JsonMapper/Value/Strategy/CollectionValueConversionStrategy.php +++ b/src/JsonMapper/Value/Strategy/CollectionValueConversionStrategy.php @@ -36,8 +36,8 @@ public function __construct( /** * Determines whether the supplied type represents a collection. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return bool TRUE when the target type is a collection type. @@ -50,8 +50,8 @@ public function supports(mixed $value, Type $type, MappingContext $context): boo /** * Converts the JSON value into a collection instance. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return mixed Collection created by the factory based on the type metadata. diff --git a/src/JsonMapper/Value/Strategy/CustomTypeValueConversionStrategy.php b/src/JsonMapper/Value/Strategy/CustomTypeValueConversionStrategy.php index 5093d59..9ab0bc7 100644 --- a/src/JsonMapper/Value/Strategy/CustomTypeValueConversionStrategy.php +++ b/src/JsonMapper/Value/Strategy/CustomTypeValueConversionStrategy.php @@ -33,8 +33,8 @@ public function __construct( /** * Determines whether the registry can handle the provided type. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return bool TRUE when the registry has a matching custom handler. @@ -47,8 +47,8 @@ public function supports(mixed $value, Type $type, MappingContext $context): boo /** * Converts the value using the registered handler. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return mixed Value produced by the registered custom handler. diff --git a/src/JsonMapper/Value/Strategy/DateTimeValueConversionStrategy.php b/src/JsonMapper/Value/Strategy/DateTimeValueConversionStrategy.php index 8c54049..dc771a5 100644 --- a/src/JsonMapper/Value/Strategy/DateTimeValueConversionStrategy.php +++ b/src/JsonMapper/Value/Strategy/DateTimeValueConversionStrategy.php @@ -35,8 +35,8 @@ final class DateTimeValueConversionStrategy implements ValueConversionStrategyIn /** * Determines whether the requested type is a supported date or interval class. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return bool TRUE when the type represents a supported date/time object. @@ -57,8 +57,8 @@ public function supports(mixed $value, Type $type, MappingContext $context): boo /** * Converts ISO-8601 strings and timestamps into the desired date/time object. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return mixed Instance of the configured date/time class. diff --git a/src/JsonMapper/Value/Strategy/EnumValueConversionStrategy.php b/src/JsonMapper/Value/Strategy/EnumValueConversionStrategy.php index db4b1c6..03dc169 100644 --- a/src/JsonMapper/Value/Strategy/EnumValueConversionStrategy.php +++ b/src/JsonMapper/Value/Strategy/EnumValueConversionStrategy.php @@ -34,8 +34,8 @@ final class EnumValueConversionStrategy implements ValueConversionStrategyInterf /** * Determines whether the provided type is a backed enum. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return bool TRUE when the target type resolves to a backed enum. @@ -60,8 +60,8 @@ public function supports(mixed $value, Type $type, MappingContext $context): boo /** * Converts the JSON scalar into the matching enum case. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return mixed Backed enum instance returned by the case factory method. diff --git a/src/JsonMapper/Value/Strategy/NullValueConversionStrategy.php b/src/JsonMapper/Value/Strategy/NullValueConversionStrategy.php index 535a4d0..0e98065 100644 --- a/src/JsonMapper/Value/Strategy/NullValueConversionStrategy.php +++ b/src/JsonMapper/Value/Strategy/NullValueConversionStrategy.php @@ -22,8 +22,8 @@ final class NullValueConversionStrategy implements ValueConversionStrategyInterf /** * Determines whether the incoming value represents a null assignment. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return bool TRUE when the value is exactly null. @@ -36,8 +36,8 @@ public function supports(mixed $value, Type $type, MappingContext $context): boo /** * Returns null to preserve the absence of a value. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return null Always returns null for supported values. diff --git a/src/JsonMapper/Value/Strategy/ObjectTypeConversionGuardTrait.php b/src/JsonMapper/Value/Strategy/ObjectTypeConversionGuardTrait.php index 4633f0b..82a3860 100644 --- a/src/JsonMapper/Value/Strategy/ObjectTypeConversionGuardTrait.php +++ b/src/JsonMapper/Value/Strategy/ObjectTypeConversionGuardTrait.php @@ -44,9 +44,9 @@ private function extractObjectType(Type $type): ?ObjectType /** * Ensures null values comply with the target object's nullability. * - * @param mixed $value Raw value coming from the input payload. - * @param ObjectType $type Object type metadata describing the target property. - * @param MappingContext $context Mapping context providing configuration such as strict mode. + * @param mixed $value Raw value coming from the input payload. + * @param ObjectType $type Object type metadata describing the target property. + * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return void */ @@ -66,9 +66,9 @@ private function guardNullableValue(mixed $value, ObjectType $type, MappingConte /** * Executes the provided converter when a valid object type is available. * - * @param Type $type Type metadata describing the target property. - * @param MappingContext $context Mapping context providing configuration such as strict mode. - * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. + * @param MappingContext $context Mapping context providing configuration such as strict mode. + * @param mixed $value Raw value coming from the input payload. * @param callable(string, mixed): mixed $converter Callback that performs the actual conversion when a class-string is available. * * @return mixed Result from the converter or the original value when no object type was detected. diff --git a/src/JsonMapper/Value/Strategy/ObjectValueConversionStrategy.php b/src/JsonMapper/Value/Strategy/ObjectValueConversionStrategy.php index 414e1cd..de32da8 100644 --- a/src/JsonMapper/Value/Strategy/ObjectValueConversionStrategy.php +++ b/src/JsonMapper/Value/Strategy/ObjectValueConversionStrategy.php @@ -31,8 +31,8 @@ /** * Creates the strategy with the class resolver and mapper callback. * - * @param ClassResolver $classResolver Resolver used to select the concrete class to instantiate. - * @param Closure(mixed, class-string, MappingContext):mixed $mapper Callback responsible for mapping values into objects. + * @param ClassResolver $classResolver Resolver used to select the concrete class to instantiate. + * @param Closure(mixed, class-string, MappingContext):mixed $mapper Callback responsible for mapping values into objects. */ public function __construct( private ClassResolver $classResolver, @@ -43,8 +43,8 @@ public function __construct( /** * Determines whether the metadata describes an object type. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return bool TRUE when the target type represents an object. @@ -57,8 +57,8 @@ public function supports(mixed $value, Type $type, MappingContext $context): boo /** * Delegates conversion to the mapper for the resolved class. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return mixed Value returned by the mapper callback. diff --git a/src/JsonMapper/Value/Strategy/PassthroughValueConversionStrategy.php b/src/JsonMapper/Value/Strategy/PassthroughValueConversionStrategy.php index f5ddf06..c6801d6 100644 --- a/src/JsonMapper/Value/Strategy/PassthroughValueConversionStrategy.php +++ b/src/JsonMapper/Value/Strategy/PassthroughValueConversionStrategy.php @@ -22,8 +22,8 @@ final class PassthroughValueConversionStrategy implements ValueConversionStrateg /** * Always supports conversion and acts as the terminal strategy. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return bool Always TRUE so the strategy can act as the final fallback. @@ -36,8 +36,8 @@ public function supports(mixed $value, Type $type, MappingContext $context): boo /** * Returns the original value without modification. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return mixed Unmodified value passed through from the input. diff --git a/src/JsonMapper/Value/Strategy/ValueConversionStrategyInterface.php b/src/JsonMapper/Value/Strategy/ValueConversionStrategyInterface.php index f37020d..63aeddc 100644 --- a/src/JsonMapper/Value/Strategy/ValueConversionStrategyInterface.php +++ b/src/JsonMapper/Value/Strategy/ValueConversionStrategyInterface.php @@ -22,8 +22,8 @@ interface ValueConversionStrategyInterface /** * Determines whether the strategy can convert the provided value for the requested type. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return bool TRUE when the strategy should perform the conversion. @@ -33,8 +33,8 @@ public function supports(mixed $value, Type $type, MappingContext $context): boo /** * Converts the value into a representation compatible with the requested type. * - * @param mixed $value Raw value coming from the input payload. - * @param Type $type Type metadata describing the target property. + * @param mixed $value Raw value coming from the input payload. + * @param Type $type Type metadata describing the target property. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return mixed Result of the conversion when the strategy supports the value. diff --git a/src/JsonMapper/Value/ValueConverter.php b/src/JsonMapper/Value/ValueConverter.php index 0f68da6..58a429d 100644 --- a/src/JsonMapper/Value/ValueConverter.php +++ b/src/JsonMapper/Value/ValueConverter.php @@ -43,8 +43,8 @@ public function addStrategy(ValueConversionStrategyInterface $strategy): void /** * Converts the value using the first matching strategy. * - * @param mixed $value Raw JSON value that needs to be converted. - * @param Type $type Target type metadata that should be satisfied by the conversion result. + * @param mixed $value Raw JSON value that needs to be converted. + * @param Type $type Target type metadata that should be satisfied by the conversion result. * @param MappingContext $context Mapping context providing configuration such as strict mode. * * @return mixed Result from the first strategy that declares support for the value. diff --git a/tests/Fixtures/Cache/InMemoryCachePool.php b/tests/Fixtures/Cache/InMemoryCachePool.php index 5f38b19..51b0901 100644 --- a/tests/Fixtures/Cache/InMemoryCachePool.php +++ b/tests/Fixtures/Cache/InMemoryCachePool.php @@ -25,30 +25,39 @@ final class InMemoryCachePool implements CacheItemPoolInterface private int $hitCount = 0; + /** + * @return InMemoryCacheItem + */ public function getItem(string $key): CacheItemInterface { if (isset($this->items[$key])) { $item = $this->items[$key]; if ($item->isHit()) { - $this->hitCount++; + ++$this->hitCount; } return $item; } - $item = new InMemoryCacheItem($key); + $item = new InMemoryCacheItem($key); $this->items[$key] = $item; return $item; } + /** + * @param array $keys + * + * @return iterable + */ public function getItems(array $keys = []): iterable { if ($keys === []) { return $this->items; } + /** @var array $result */ $result = []; foreach ($keys as $key) { @@ -98,7 +107,7 @@ public function save(CacheItemInterface $item): bool ? $item : new InMemoryCacheItem($item->getKey(), $item->get(), $item->isHit()); - $this->saveCalls++; + ++$this->saveCalls; return true; } diff --git a/tests/JsonMapper/DocsCustomNameConverterTest.php b/tests/JsonMapper/DocsCustomNameConverterTest.php index c5e4c70..91f0d25 100644 --- a/tests/JsonMapper/DocsCustomNameConverterTest.php +++ b/tests/JsonMapper/DocsCustomNameConverterTest.php @@ -28,7 +28,7 @@ public function itMapsUsingTheCustomNameConverterRecipe(): void { $converter = new UpperSnakeCaseConverter(); $extractor = new PropertyInfoExtractor([new ReflectionExtractor()], [new PhpDocExtractor()]); - $mapper = new JsonMapper( + $mapper = new JsonMapper( $extractor, PropertyAccess::createPropertyAccessor(), $converter, diff --git a/tests/JsonMapper/DocsNestedCollectionsTest.php b/tests/JsonMapper/DocsNestedCollectionsTest.php index 396153d..5af7091 100644 --- a/tests/JsonMapper/DocsNestedCollectionsTest.php +++ b/tests/JsonMapper/DocsNestedCollectionsTest.php @@ -39,23 +39,36 @@ public function itMapsTheNestedCollectionsRecipe(): void self::assertInstanceOf(ArticleCollection::class, $articles); self::assertCount(1, $articles); - self::assertContainsOnlyInstancesOf(Article::class, $articles); + self::assertTrue($articles->offsetExists(0)); $article = $articles[0]; - self::assertInstanceOf(NestedTagCollection::class, $article->tags); - self::assertCount(2, $article->tags); - self::assertContainsOnlyInstancesOf(TagCollection::class, $article->tags); + self::assertInstanceOf(Article::class, $article); - $firstRow = $article->tags[0]; + /** @var NestedTagCollection> $tags */ + $tags = $article->tags; + self::assertCount(2, $tags); + self::assertContainsOnlyInstancesOf(TagCollection::class, $tags); + + self::assertTrue($tags->offsetExists(0)); + $firstRow = $tags[0]; self::assertInstanceOf(TagCollection::class, $firstRow); self::assertCount(1, $firstRow); self::assertContainsOnlyInstancesOf(Tag::class, $firstRow); - self::assertSame('php', $firstRow[0]->name); + self::assertTrue($firstRow->offsetExists(0)); + + $firstTag = $firstRow[0]; + self::assertInstanceOf(Tag::class, $firstTag); + self::assertSame('php', $firstTag->name); - $secondRow = $article->tags[1]; + self::assertTrue($tags->offsetExists(1)); + $secondRow = $tags[1]; self::assertInstanceOf(TagCollection::class, $secondRow); self::assertCount(1, $secondRow); self::assertContainsOnlyInstancesOf(Tag::class, $secondRow); - self::assertSame('json', $secondRow[0]->name); + self::assertTrue($secondRow->offsetExists(0)); + + $secondTag = $secondRow[0]; + self::assertInstanceOf(Tag::class, $secondTag); + self::assertSame('json', $secondTag->name); } } diff --git a/tests/JsonMapper/DocsQuickStartTest.php b/tests/JsonMapper/DocsQuickStartTest.php index 519f6f0..bd89f99 100644 --- a/tests/JsonMapper/DocsQuickStartTest.php +++ b/tests/JsonMapper/DocsQuickStartTest.php @@ -25,27 +25,48 @@ public function itMapsTheReadmeQuickStartExample(): void { $mapper = $this->getJsonMapper(); - $single = $this->getJsonAsObject('{"title":"Hello world","comments":[{"message":"First!"}]}'); + $single = $this->getJsonAsObject('{"title":"Hello world","comments":[{"message":"First!"}]}'); $article = $mapper->map($single, Article::class); self::assertInstanceOf(Article::class, $article); self::assertSame('Hello world', $article->title); - self::assertInstanceOf(CommentCollection::class, $article->comments); - self::assertCount(1, $article->comments); - self::assertContainsOnlyInstancesOf(Comment::class, $article->comments); - self::assertSame('First!', $article->comments[0]->message); - $list = $this->getJsonAsObject('[{"title":"Hello world","comments":[{"message":"First!"}]},{"title":"Second","comments":[]}]'); + /** @var CommentCollection $comments */ + $comments = $article->comments; + self::assertCount(1, $comments); + self::assertTrue($comments->offsetExists(0)); + + $firstComment = $comments[0]; + self::assertInstanceOf(Comment::class, $firstComment); + self::assertSame('First!', $firstComment->message); + + $list = $this->getJsonAsObject('[{"title":"Hello world","comments":[{"message":"First!"}]},{"title":"Second","comments":[]}]'); $articles = $mapper->map($list, Article::class, ArticleCollection::class); self::assertInstanceOf(ArticleCollection::class, $articles); self::assertCount(2, $articles); - self::assertContainsOnlyInstancesOf(Article::class, $articles); - self::assertSame('Hello world', $articles[0]->title); - self::assertSame('Second', $articles[1]->title); - self::assertInstanceOf(CommentCollection::class, $articles[0]->comments); - self::assertCount(1, $articles[0]->comments); - self::assertInstanceOf(CommentCollection::class, $articles[1]->comments); - self::assertCount(0, $articles[1]->comments); + self::assertTrue($articles->offsetExists(0)); + self::assertTrue($articles->offsetExists(1)); + + $firstArticle = $articles[0]; + self::assertInstanceOf(Article::class, $firstArticle); + self::assertSame('Hello world', $firstArticle->title); + + /** @var CommentCollection $firstArticleComments */ + $firstArticleComments = $firstArticle->comments; + self::assertCount(1, $firstArticleComments); + self::assertTrue($firstArticleComments->offsetExists(0)); + + $firstArticleComment = $firstArticleComments[0]; + self::assertInstanceOf(Comment::class, $firstArticleComment); + self::assertSame('First!', $firstArticleComment->message); + + $secondArticle = $articles[1]; + self::assertInstanceOf(Article::class, $secondArticle); + self::assertSame('Second', $secondArticle->title); + + /** @var CommentCollection $secondArticleComments */ + $secondArticleComments = $secondArticle->comments; + self::assertCount(0, $secondArticleComments); } } diff --git a/tests/JsonMapper/JsonMapperTypeCacheTest.php b/tests/JsonMapper/JsonMapperTypeCacheTest.php index 6400e62..7768893 100644 --- a/tests/JsonMapper/JsonMapperTypeCacheTest.php +++ b/tests/JsonMapper/JsonMapperTypeCacheTest.php @@ -27,9 +27,9 @@ final class JsonMapperTypeCacheTest extends TestCase #[Test] public function itCachesResolvedTypesWhenConfigured(): void { - $cache = new InMemoryCachePool(); + $cache = new InMemoryCachePool(); $extractor = new PropertyInfoExtractor([new ReflectionExtractor()], [new PhpDocExtractor()]); - $mapper = new JsonMapper( + $mapper = new JsonMapper( $extractor, PropertyAccess::createPropertyAccessor(), new CamelCasePropertyNameConverter(),