From 17a46012ed5d2adea0356f67bfcb8934bbbaaecb Mon Sep 17 00:00:00 2001 From: Dominik Zogg Date: Fri, 30 Jan 2026 22:50:41 +0100 Subject: [PATCH] AbstractSchemaV2 --- src/Schema/AbstractObjectSchema.php | 78 ++++----- src/Schema/AbstractSchema.php | 3 + src/Schema/AbstractSchemaV2.php | 126 ++++++++++++++ src/Schema/ArraySchema.php | 78 ++++----- src/Schema/BackedEnumSchema.php | 76 ++++----- src/Schema/BoolSchema.php | 46 ++--- src/Schema/DateTimeSchema.php | 46 ++--- src/Schema/DiscriminatedUnionSchema.php | 75 ++++----- src/Schema/FloatSchema.php | 46 ++--- src/Schema/IntSchema.php | 46 ++--- src/Schema/LazySchema.php | 6 +- src/Schema/LiteralSchema.php | 58 +++---- src/Schema/RecordSchema.php | 75 ++++----- src/Schema/RespectValidationSchema.php | 26 +-- src/Schema/StringSchema.php | 46 ++--- src/Schema/TupleSchema.php | 90 +++++----- src/Schema/UnionSchema.php | 25 +-- tests/Unit/Schema/AbstractSchemaTest.php | 158 ++++++++++++++++++ tests/Unit/Schema/AbstractSchemaV2Test.php | 149 +++++++++++++++++ tests/Unit/Schema/ArraySchemaTest.php | 1 - tests/Unit/Schema/AssocSchemaTest.php | 1 - tests/Unit/Schema/BackedEnumSchemaTest.php | 1 - tests/Unit/Schema/BoolSchemaTest.php | 1 - tests/Unit/Schema/DateTimeSchemaTest.php | 1 - .../Schema/DiscriminatedUnionSchemaTest.php | 1 - tests/Unit/Schema/FloatSchemaTest.php | 1 - tests/Unit/Schema/IntSchemaTest.php | 1 - tests/Unit/Schema/LazySchemaTest.php | 1 - tests/Unit/Schema/LiteralSchemaTest.php | 1 - tests/Unit/Schema/ObjectSchemaTest.php | 1 - tests/Unit/Schema/RecordSchemaTest.php | 1 - .../Schema/RespectValidationSchemaTest.php | 1 - tests/Unit/Schema/StringSchemaTest.php | 1 - tests/Unit/Schema/TupleSchemaTest.php | 1 - tests/Unit/Schema/UnionSchemaTest.php | 1 - 35 files changed, 746 insertions(+), 523 deletions(-) create mode 100644 src/Schema/AbstractSchemaV2.php create mode 100644 tests/Unit/Schema/AbstractSchemaTest.php create mode 100644 tests/Unit/Schema/AbstractSchemaV2Test.php diff --git a/src/Schema/AbstractObjectSchema.php b/src/Schema/AbstractObjectSchema.php index 3b088a3..38a8802 100644 --- a/src/Schema/AbstractObjectSchema.php +++ b/src/Schema/AbstractObjectSchema.php @@ -8,7 +8,7 @@ use Chubbyphp\Parsing\Errors; use Chubbyphp\Parsing\ErrorsException; -abstract class AbstractObjectSchema extends AbstractSchema implements ObjectSchemaInterface +abstract class AbstractObjectSchema extends AbstractSchemaV2 implements ObjectSchemaInterface { public const string ERROR_TYPE_CODE = 'abstract_object.type'; public const string ERROR_TYPE_TEMPLATE = 'Type should be "array|\stdClass|\Traversable", {{given}} given'; @@ -64,54 +64,18 @@ public function __construct(array $fieldToSchema) } $this->fieldToSchema = $typeCheckedFieldToSchema; - } - - final public function parse(mixed $input): mixed - { - if ($input instanceof \stdClass || $input instanceof \Traversable) { - $input = (array) $input; - } - - if ($input instanceof \JsonSerializable) { - $input = $input->jsonSerialize(); - } - - try { - $input = $this->dispatchPreParses($input); - if (null === $input && $this->nullable) { - return null; + $this->preParses[] = static function (mixed $input) { + if ($input instanceof \stdClass || $input instanceof \Traversable) { + return (array) $input; } - if (!\is_array($input)) { - throw new ErrorsException( - new Error( - static::ERROR_TYPE_CODE, - static::ERROR_TYPE_TEMPLATE, - ['given' => $this->getDataType($input)] - ) - ); - } - - /** @var array $input */ - $childrenErrors = new Errors(); - - $this->unknownFields($input, $childrenErrors); - - $output = $this->parseFields($input, $childrenErrors); - - if ($childrenErrors->has()) { - throw new ErrorsException($childrenErrors); + if ($input instanceof \JsonSerializable) { + return $input->jsonSerialize(); } - return $this->dispatchPostParses($output); - } catch (ErrorsException $e) { - if ($this->catch) { - return ($this->catch)($input, $e); - } - - throw $e; - } + return $input; + }; } /** @@ -146,6 +110,32 @@ final public function optional(array $optional = []): static return $clone; } + protected function innerParse(mixed $input): mixed + { + if (!\is_array($input)) { + throw new ErrorsException( + new Error( + static::ERROR_TYPE_CODE, + static::ERROR_TYPE_TEMPLATE, + ['given' => $this->getDataType($input)] + ) + ); + } + + /** @var array $input */ + $childrenErrors = new Errors(); + + $this->unknownFields($input, $childrenErrors); + + $output = $this->parseFields($input, $childrenErrors); + + if ($childrenErrors->has()) { + throw new ErrorsException($childrenErrors); + } + + return $output; + } + /** * @param array $input */ diff --git a/src/Schema/AbstractSchema.php b/src/Schema/AbstractSchema.php index e0c1410..7a5b43f 100644 --- a/src/Schema/AbstractSchema.php +++ b/src/Schema/AbstractSchema.php @@ -7,6 +7,9 @@ use Chubbyphp\Parsing\ErrorsException; use Chubbyphp\Parsing\Result; +/** + * @deprecated use Chubbyphp\Parsing\Schem\AbstractSchemaV2 + */ abstract class AbstractSchema implements SchemaInterface { protected bool $nullable = false; diff --git a/src/Schema/AbstractSchemaV2.php b/src/Schema/AbstractSchemaV2.php new file mode 100644 index 0000000..54dc349 --- /dev/null +++ b/src/Schema/AbstractSchemaV2.php @@ -0,0 +1,126 @@ + + */ + protected array $preParses = []; + + /** + * @var array<\Closure> + */ + protected array $postParses = []; + + /** + * @var \Closure(mixed, ErrorsException): mixed + */ + protected ?\Closure $catch = null; + + final public function nullable(bool $nullable = true): static + { + $clone = clone $this; + $clone->nullable = $nullable; + + return $clone; + } + + final public function default(mixed $default): static + { + return $this->preParse(static fn (mixed $input) => $input ?? $default); + } + + /** + * @param \Closure(mixed $input): mixed $preParse + */ + final public function preParse(\Closure $preParse): static + { + $clone = clone $this; + $clone->preParses[] = $preParse; + + return $clone; + } + + final public function postParse(\Closure $postParse): static + { + $clone = clone $this; + $clone->postParses[] = $postParse; + + return $clone; + } + + final public function parse(mixed $input): mixed + { + try { + $input = $this->dispatchPreParses($input); + + if (null === $input && $this->nullable) { + return null; + } + + $output = $this->innerParse($input); + + return $this->dispatchPostParses($output); + } catch (ErrorsException $e) { + if ($this->catch) { + return ($this->catch)($input, $e); + } + + throw $e; + } + } + + final public function safeParse(mixed $input): Result + { + try { + return new Result($this->parse($input), null); + } catch (ErrorsException $e) { + return new Result(null, $e); + } + } + + /** + * @param \Closure(mixed $input, ErrorsException $e): mixed $catch + */ + final public function catch(\Closure $catch): static + { + $clone = clone $this; + $clone->catch = $catch; + + return $clone; + } + + abstract protected function innerParse(mixed $input): mixed; + + final protected function dispatchPreParses(mixed $data): mixed + { + return array_reduce( + $this->preParses, + static fn (mixed $currentData, \Closure $preParse) => $preParse($currentData), + $data + ); + } + + final protected function dispatchPostParses(mixed $data): mixed + { + return array_reduce( + $this->postParses, + static fn (mixed $currentData, \Closure $postParse) => $postParse($currentData), + $data + ); + } + + final protected function getDataType(mixed $input): string + { + return \is_object($input) ? $input::class : \gettype($input); + } +} diff --git a/src/Schema/ArraySchema.php b/src/Schema/ArraySchema.php index 7b15bbc..042526d 100644 --- a/src/Schema/ArraySchema.php +++ b/src/Schema/ArraySchema.php @@ -8,7 +8,7 @@ use Chubbyphp\Parsing\Errors; use Chubbyphp\Parsing\ErrorsException; -final class ArraySchema extends AbstractSchema implements SchemaInterface +final class ArraySchema extends AbstractSchemaV2 implements SchemaInterface { public const string ERROR_TYPE_CODE = 'array.type'; public const string ERROR_TYPE_TEMPLATE = 'Type should be "array", {{given}} given'; @@ -27,51 +27,6 @@ final class ArraySchema extends AbstractSchema implements SchemaInterface public function __construct(private SchemaInterface $itemSchema) {} - public function parse(mixed $input): mixed - { - try { - $input = $this->dispatchPreParses($input); - - if (null === $input && $this->nullable) { - return null; - } - - if (!\is_array($input)) { - throw new ErrorsException( - new Error( - self::ERROR_TYPE_CODE, - self::ERROR_TYPE_TEMPLATE, - ['given' => $this->getDataType($input)] - ) - ); - } - - $array = []; - - $childrenErrors = new Errors(); - - foreach ($input as $i => $item) { - try { - $array[$i] = $this->itemSchema->parse($item); - } catch (ErrorsException $e) { - $childrenErrors->add($e->errors, (string) $i); - } - } - - if ($childrenErrors->has()) { - throw new ErrorsException($childrenErrors); - } - - return $this->dispatchPostParses($array); - } catch (ErrorsException $e) { - if ($this->catch) { - return ($this->catch)($input, $e); - } - - throw $e; - } - } - public function length(int $length): static { return $this->postParse(static function (array $array) use ($length) { @@ -187,4 +142,35 @@ public function reduce(\Closure $reduce, mixed $initial = null): static { return $this->postParse(static fn (array $array) => array_reduce($array, $reduce, $initial)); } + + protected function innerParse(mixed $input): mixed + { + if (!\is_array($input)) { + throw new ErrorsException( + new Error( + self::ERROR_TYPE_CODE, + self::ERROR_TYPE_TEMPLATE, + ['given' => $this->getDataType($input)] + ) + ); + } + + $output = []; + + $childrenErrors = new Errors(); + + foreach ($input as $i => $item) { + try { + $output[$i] = $this->itemSchema->parse($item); + } catch (ErrorsException $e) { + $childrenErrors->add($e->errors, (string) $i); + } + } + + if ($childrenErrors->has()) { + throw new ErrorsException($childrenErrors); + } + + return $output; + } } diff --git a/src/Schema/BackedEnumSchema.php b/src/Schema/BackedEnumSchema.php index 0b5105d..871a7d0 100644 --- a/src/Schema/BackedEnumSchema.php +++ b/src/Schema/BackedEnumSchema.php @@ -7,7 +7,7 @@ use Chubbyphp\Parsing\Error; use Chubbyphp\Parsing\ErrorsException; -final class BackedEnumSchema extends AbstractSchema implements SchemaInterface +final class BackedEnumSchema extends AbstractSchemaV2 implements SchemaInterface { public const string ERROR_TYPE_CODE = 'backedEnum.type'; public const string ERROR_TYPE_TEMPLATE = 'Type should be "int|string", {{given}} given'; @@ -47,50 +47,6 @@ public function __construct(string $backedEnumClass) $this->backedEnum = $backedEnum; } - public function parse(mixed $input): mixed - { - try { - $input = $this->dispatchPreParses($input); - - if (null === $input && $this->nullable) { - return null; - } - - if (!\is_int($input) && !\is_string($input)) { - throw new ErrorsException( - new Error( - self::ERROR_TYPE_CODE, - self::ERROR_TYPE_TEMPLATE, - ['given' => $this->getDataType($input)] - ) - ); - } - - $output = ($this->backedEnum)::tryFrom($input); - - if (null === $output) { - throw new ErrorsException( - new Error( - self::ERROR_VALUE_CODE, - self::ERROR_VALUE_TEMPLATE, - [ - 'cases' => $this->casesToCasesValues($this->backedEnum), - 'given' => $input, - ] - ) - ); - } - - return $this->dispatchPostParses($output); - } catch (ErrorsException $e) { - if ($this->catch) { - return ($this->catch)($input, $e); - } - - throw $e; - } - } - public function toInt(): IntSchema { return (new IntSchema())->preParse(function ($input) { @@ -111,6 +67,36 @@ public function toString(): StringSchema })->nullable($this->nullable); } + protected function innerParse(mixed $input): mixed + { + if (!\is_int($input) && !\is_string($input)) { + throw new ErrorsException( + new Error( + self::ERROR_TYPE_CODE, + self::ERROR_TYPE_TEMPLATE, + ['given' => $this->getDataType($input)] + ) + ); + } + + $output = ($this->backedEnum)::tryFrom($input); + + if (null === $output) { + throw new ErrorsException( + new Error( + self::ERROR_VALUE_CODE, + self::ERROR_VALUE_TEMPLATE, + [ + 'cases' => $this->casesToCasesValues($this->backedEnum), + 'given' => $input, + ] + ) + ); + } + + return $output; + } + /** * @return array */ diff --git a/src/Schema/BoolSchema.php b/src/Schema/BoolSchema.php index fc61c18..feec64d 100644 --- a/src/Schema/BoolSchema.php +++ b/src/Schema/BoolSchema.php @@ -7,40 +7,11 @@ use Chubbyphp\Parsing\Error; use Chubbyphp\Parsing\ErrorsException; -final class BoolSchema extends AbstractSchema implements SchemaInterface +final class BoolSchema extends AbstractSchemaV2 implements SchemaInterface { public const string ERROR_TYPE_CODE = 'bool.type'; public const string ERROR_TYPE_TEMPLATE = 'Type should be "bool", {{given}} given'; - public function parse(mixed $input): mixed - { - try { - $input = $this->dispatchPreParses($input); - - if (null === $input && $this->nullable) { - return null; - } - - if (!\is_bool($input)) { - throw new ErrorsException( - new Error( - self::ERROR_TYPE_CODE, - self::ERROR_TYPE_TEMPLATE, - ['given' => $this->getDataType($input)] - ) - ); - } - - return $this->dispatchPostParses($input); - } catch (ErrorsException $e) { - if ($this->catch) { - return ($this->catch)($input, $e); - } - - throw $e; - } - } - public function toFloat(): FloatSchema { return (new FloatSchema())->preParse(function ($input): ?float { @@ -70,4 +41,19 @@ public function toString(): StringSchema return null !== $input ? (string) $input : null; })->nullable($this->nullable); } + + protected function innerParse(mixed $input): mixed + { + if (!\is_bool($input)) { + throw new ErrorsException( + new Error( + self::ERROR_TYPE_CODE, + self::ERROR_TYPE_TEMPLATE, + ['given' => $this->getDataType($input)] + ) + ); + } + + return $input; + } } diff --git a/src/Schema/DateTimeSchema.php b/src/Schema/DateTimeSchema.php index 8f375a2..0350c54 100644 --- a/src/Schema/DateTimeSchema.php +++ b/src/Schema/DateTimeSchema.php @@ -7,7 +7,7 @@ use Chubbyphp\Parsing\Error; use Chubbyphp\Parsing\ErrorsException; -final class DateTimeSchema extends AbstractSchema implements SchemaInterface +final class DateTimeSchema extends AbstractSchemaV2 implements SchemaInterface { public const string ERROR_TYPE_CODE = 'datetime.type'; public const string ERROR_TYPE_TEMPLATE = 'Type should be "\DateTimeInterface", {{given}} given'; @@ -18,35 +18,6 @@ final class DateTimeSchema extends AbstractSchema implements SchemaInterface public const string ERROR_TO_CODE = 'datetime.to'; public const string ERROR_TO_TEMPLATE = 'To datetime {{to}}, {{given}} given'; - public function parse(mixed $input): mixed - { - try { - $input = $this->dispatchPreParses($input); - - if (null === $input && $this->nullable) { - return null; - } - - if (!$input instanceof \DateTimeInterface) { - throw new ErrorsException( - new Error( - self::ERROR_TYPE_CODE, - self::ERROR_TYPE_TEMPLATE, - ['given' => $this->getDataType($input)] - ) - ); - } - - return $this->dispatchPostParses($input); - } catch (ErrorsException $e) { - if ($this->catch) { - return ($this->catch)($input, $e); - } - - throw $e; - } - } - public function from(\DateTimeImmutable $from): static { return $this->postParse(static function (\DateTimeImmutable $datetime) use ($from) { @@ -100,4 +71,19 @@ public function toString(): StringSchema return null !== $input ? $input->format('c') : null; })->nullable($this->nullable); } + + protected function innerParse(mixed $input): mixed + { + if (!$input instanceof \DateTimeInterface) { + throw new ErrorsException( + new Error( + self::ERROR_TYPE_CODE, + self::ERROR_TYPE_TEMPLATE, + ['given' => $this->getDataType($input)] + ) + ); + } + + return $input; + } } diff --git a/src/Schema/DiscriminatedUnionSchema.php b/src/Schema/DiscriminatedUnionSchema.php index daff5a8..782d234 100644 --- a/src/Schema/DiscriminatedUnionSchema.php +++ b/src/Schema/DiscriminatedUnionSchema.php @@ -8,7 +8,7 @@ use Chubbyphp\Parsing\Errors; use Chubbyphp\Parsing\ErrorsException; -final class DiscriminatedUnionSchema extends AbstractSchema implements SchemaInterface +final class DiscriminatedUnionSchema extends AbstractSchemaV2 implements SchemaInterface { public const string ERROR_TYPE_CODE = 'discriminatedUnion.type'; public const string ERROR_TYPE_TEMPLATE = 'Type should be "array|\stdClass|\Traversable", {{given}} given'; @@ -54,59 +54,42 @@ public function __construct(array $objectSchemas, private string $discriminatorF $this->objectSchemas[] = $objectSchema; } - } - - public function parse(mixed $input): mixed - { - if ($input instanceof \stdClass || $input instanceof \Traversable) { - $input = (array) $input; - } - - if ($input instanceof \JsonSerializable) { - $input = $input->jsonSerialize(); - } - - try { - $input = $this->dispatchPreParses($input); - if (null === $input && $this->nullable) { - return null; + $this->preParses[] = static function (mixed $input) { + if ($input instanceof \stdClass || $input instanceof \Traversable) { + return (array) $input; } - if (!\is_array($input)) { - throw new ErrorsException( - new Error( - self::ERROR_TYPE_CODE, - self::ERROR_TYPE_TEMPLATE, - ['given' => $this->getDataType($input)] - ) - ); + if ($input instanceof \JsonSerializable) { + return $input->jsonSerialize(); } - if (!isset($input[$this->discriminatorFieldName])) { - throw new ErrorsException( - new Error( - self::ERROR_DISCRIMINATOR_FIELD_CODE, - self::ERROR_DISCRIMINATOR_FIELD_TEMPLATE, - ['discriminatorFieldName' => $this->discriminatorFieldName] - ) - ); - } - - $output = $this->parseObjectSchemas($input, $input[$this->discriminatorFieldName]); + return $input; + }; + } - return $this->dispatchPostParses($output); - } catch (ErrorsException $e) { - if ($this->catch) { - return ($this->catch)($input, $e); - } + protected function innerParse(mixed $input): mixed + { + if (!\is_array($input)) { + throw new ErrorsException( + new Error( + self::ERROR_TYPE_CODE, + self::ERROR_TYPE_TEMPLATE, + ['given' => $this->getDataType($input)] + ) + ); + } - throw $e; + if (!isset($input[$this->discriminatorFieldName])) { + throw new ErrorsException( + new Error( + self::ERROR_DISCRIMINATOR_FIELD_CODE, + self::ERROR_DISCRIMINATOR_FIELD_TEMPLATE, + ['discriminatorFieldName' => $this->discriminatorFieldName] + ) + ); } - } - private function parseObjectSchemas(mixed $input, mixed $discriminator): mixed - { $errors = new Errors(); foreach ($this->objectSchemas as $objectSchema) { @@ -114,7 +97,7 @@ private function parseObjectSchemas(mixed $input, mixed $discriminator): mixed $discriminatorFieldSchema = $objectSchema->getFieldSchema($this->discriminatorFieldName); try { - $discriminatorFieldSchema->parse($discriminator); + $discriminatorFieldSchema->parse($input[$this->discriminatorFieldName]); } catch (ErrorsException $e) { $errors->add($e->errors); diff --git a/src/Schema/FloatSchema.php b/src/Schema/FloatSchema.php index 57eb48f..40df536 100644 --- a/src/Schema/FloatSchema.php +++ b/src/Schema/FloatSchema.php @@ -7,7 +7,7 @@ use Chubbyphp\Parsing\Error; use Chubbyphp\Parsing\ErrorsException; -final class FloatSchema extends AbstractSchema implements SchemaInterface +final class FloatSchema extends AbstractSchemaV2 implements SchemaInterface { public const string ERROR_TYPE_CODE = 'float.type'; public const string ERROR_TYPE_TEMPLATE = 'Type should be "float", {{given}} given'; @@ -27,35 +27,6 @@ final class FloatSchema extends AbstractSchema implements SchemaInterface public const string ERROR_INT_CODE = 'float.int'; public const string ERROR_INT_TEMPLATE = 'Cannot convert {{given}} to int'; - public function parse(mixed $input): mixed - { - try { - $input = $this->dispatchPreParses($input); - - if (null === $input && $this->nullable) { - return null; - } - - if (!\is_float($input)) { - throw new ErrorsException( - new Error( - self::ERROR_TYPE_CODE, - self::ERROR_TYPE_TEMPLATE, - ['given' => $this->getDataType($input)] - ) - ); - } - - return $this->dispatchPostParses($input); - } catch (ErrorsException $e) { - if ($this->catch) { - return ($this->catch)($input, $e); - } - - throw $e; - } - } - public function gt(float $gt): static { return $this->postParse(static function (float $float) use ($gt) { @@ -179,4 +150,19 @@ public function toString(): StringSchema return null !== $input ? (string) $input : null; })->nullable($this->nullable); } + + protected function innerParse(mixed $input): mixed + { + if (!\is_float($input)) { + throw new ErrorsException( + new Error( + self::ERROR_TYPE_CODE, + self::ERROR_TYPE_TEMPLATE, + ['given' => $this->getDataType($input)] + ) + ); + } + + return $input; + } } diff --git a/src/Schema/IntSchema.php b/src/Schema/IntSchema.php index 448e551..693f3c9 100644 --- a/src/Schema/IntSchema.php +++ b/src/Schema/IntSchema.php @@ -7,7 +7,7 @@ use Chubbyphp\Parsing\Error; use Chubbyphp\Parsing\ErrorsException; -final class IntSchema extends AbstractSchema implements SchemaInterface +final class IntSchema extends AbstractSchemaV2 implements SchemaInterface { public const string ERROR_TYPE_CODE = 'int.type'; public const string ERROR_TYPE_TEMPLATE = 'Type should be "int", {{given}} given'; @@ -24,35 +24,6 @@ final class IntSchema extends AbstractSchema implements SchemaInterface public const string ERROR_LTE_CODE = 'int.lte'; public const string ERROR_LTE_TEMPLATE = 'Value should be lesser than or equal {{lte}}, {{given}} given'; - public function parse(mixed $input): mixed - { - try { - $input = $this->dispatchPreParses($input); - - if (null === $input && $this->nullable) { - return null; - } - - if (!\is_int($input)) { - throw new ErrorsException( - new Error( - self::ERROR_TYPE_CODE, - self::ERROR_TYPE_TEMPLATE, - ['given' => $this->getDataType($input)] - ) - ); - } - - return $this->dispatchPostParses($input); - } catch (ErrorsException $e) { - if ($this->catch) { - return ($this->catch)($input, $e); - } - - throw $e; - } - } - public function gt(int $gt): static { return $this->postParse(static function (int $int) use ($gt) { @@ -171,4 +142,19 @@ public function toDateTime(): DateTimeSchema return null !== $input ? new \DateTimeImmutable('@'.$input) : null; })->nullable($this->nullable); } + + protected function innerParse(mixed $input): mixed + { + if (!\is_int($input)) { + throw new ErrorsException( + new Error( + self::ERROR_TYPE_CODE, + self::ERROR_TYPE_TEMPLATE, + ['given' => $this->getDataType($input)] + ) + ); + } + + return $input; + } } diff --git a/src/Schema/LazySchema.php b/src/Schema/LazySchema.php index 8bbc1ce..01964e2 100644 --- a/src/Schema/LazySchema.php +++ b/src/Schema/LazySchema.php @@ -11,9 +11,9 @@ final class LazySchema implements SchemaInterface private ?SchemaInterface $schema = null; /** - * @param \Closure(): SchemaInterface $lazy + * @param \Closure(): SchemaInterface $schemaFactory */ - public function __construct(private \Closure $lazy) {} + public function __construct(private \Closure $schemaFactory) {} /** * @internal @@ -80,7 +80,7 @@ public function catch(\Closure $catch): static private function resolveSchema(): SchemaInterface { if (!$this->schema) { - $this->schema = ($this->lazy)(); + $this->schema = ($this->schemaFactory)(); } return $this->schema; diff --git a/src/Schema/LiteralSchema.php b/src/Schema/LiteralSchema.php index ca0cd66..a298cc9 100644 --- a/src/Schema/LiteralSchema.php +++ b/src/Schema/LiteralSchema.php @@ -7,7 +7,7 @@ use Chubbyphp\Parsing\Error; use Chubbyphp\Parsing\ErrorsException; -final class LiteralSchema extends AbstractSchema +final class LiteralSchema extends AbstractSchemaV2 { public const string ERROR_TYPE_CODE = 'literal.type'; public const string ERROR_TYPE_TEMPLATE = 'Type should be "bool|float|int|string", {{given}} given'; @@ -17,42 +17,28 @@ final class LiteralSchema extends AbstractSchema public function __construct(private bool|float|int|string $literal) {} - public function parse(mixed $input): mixed + protected function innerParse(mixed $input): mixed { - try { - $input = $this->dispatchPreParses($input); - - if (null === $input && $this->nullable) { - return null; - } - - if (!\is_bool($input) && !\is_float($input) && !\is_int($input) && !\is_string($input)) { - throw new ErrorsException( - new Error( - self::ERROR_TYPE_CODE, - self::ERROR_TYPE_TEMPLATE, - ['given' => $this->getDataType($input)] - ) - ); - } - - if ($input !== $this->literal) { - throw new ErrorsException( - new Error( - self::ERROR_EQUALS_CODE, - self::ERROR_EQUALS_TEMPLATE, - ['expected' => $this->literal, 'given' => $input] - ) - ); - } - - return $this->dispatchPostParses($input); - } catch (ErrorsException $e) { - if ($this->catch) { - return ($this->catch)($input, $e); - } - - throw $e; + if (!\is_bool($input) && !\is_float($input) && !\is_int($input) && !\is_string($input)) { + throw new ErrorsException( + new Error( + self::ERROR_TYPE_CODE, + self::ERROR_TYPE_TEMPLATE, + ['given' => $this->getDataType($input)] + ) + ); } + + if ($input !== $this->literal) { + throw new ErrorsException( + new Error( + self::ERROR_EQUALS_CODE, + self::ERROR_EQUALS_TEMPLATE, + ['expected' => $this->literal, 'given' => $input] + ) + ); + } + + return $input; } } diff --git a/src/Schema/RecordSchema.php b/src/Schema/RecordSchema.php index dcb3961..78dafd9 100644 --- a/src/Schema/RecordSchema.php +++ b/src/Schema/RecordSchema.php @@ -8,63 +8,54 @@ use Chubbyphp\Parsing\Errors; use Chubbyphp\Parsing\ErrorsException; -final class RecordSchema extends AbstractSchema implements SchemaInterface +final class RecordSchema extends AbstractSchemaV2 implements SchemaInterface { public const string ERROR_TYPE_CODE = 'record.type'; public const string ERROR_TYPE_TEMPLATE = 'Type should be "array|\stdClass|\Traversable", {{given}} given'; - public function __construct(private SchemaInterface $fieldSchema) {} - - public function parse(mixed $input): mixed + public function __construct(private SchemaInterface $fieldSchema) { - if ($input instanceof \stdClass || $input instanceof \Traversable) { - $input = (array) $input; - } - - if ($input instanceof \JsonSerializable) { - $input = $input->jsonSerialize(); - } - - try { - $input = $this->dispatchPreParses($input); - - if (null === $input && $this->nullable) { - return null; + $this->preParses[] = static function (mixed $input) { + if ($input instanceof \stdClass || $input instanceof \Traversable) { + return (array) $input; } - if (!\is_array($input)) { - throw new ErrorsException( - new Error( - self::ERROR_TYPE_CODE, - self::ERROR_TYPE_TEMPLATE, - ['given' => $this->getDataType($input)] - ) - ); + if ($input instanceof \JsonSerializable) { + return $input->jsonSerialize(); } - $output = []; + return $input; + }; + } - $childrenErrors = new Errors(); + protected function innerParse(mixed $input): mixed + { + if (!\is_array($input)) { + throw new ErrorsException( + new Error( + self::ERROR_TYPE_CODE, + self::ERROR_TYPE_TEMPLATE, + ['given' => $this->getDataType($input)] + ) + ); + } - foreach ($input as $fieldName => $fieldValue) { - try { - $output[$fieldName] = $this->fieldSchema->parse($fieldValue); - } catch (ErrorsException $e) { - $childrenErrors->add($e->errors, $fieldName); - } - } + $output = []; - if ($childrenErrors->has()) { - throw new ErrorsException($childrenErrors); - } + $childrenErrors = new Errors(); - return $this->dispatchPostParses($output); - } catch (ErrorsException $e) { - if ($this->catch) { - return ($this->catch)($input, $e); + foreach ($input as $fieldName => $fieldValue) { + try { + $output[$fieldName] = $this->fieldSchema->parse($fieldValue); + } catch (ErrorsException $e) { + $childrenErrors->add($e->errors, $fieldName); } + } - throw $e; + if ($childrenErrors->has()) { + throw new ErrorsException($childrenErrors); } + + return $output; } } diff --git a/src/Schema/RespectValidationSchema.php b/src/Schema/RespectValidationSchema.php index 6cb4895..f904b6b 100644 --- a/src/Schema/RespectValidationSchema.php +++ b/src/Schema/RespectValidationSchema.php @@ -11,32 +11,18 @@ use Respect\Validation\Exceptions\ValidationException; use Respect\Validation\Validatable; -final class RespectValidationSchema extends AbstractSchema implements SchemaInterface +final class RespectValidationSchema extends AbstractSchemaV2 implements SchemaInterface { public function __construct(private Validatable $validatable) {} - public function parse(mixed $input): mixed + protected function innerParse(mixed $input): mixed { try { - $input = $this->dispatchPreParses($input); + $this->validatable->assert($input); - if (null === $input && $this->nullable) { - return null; - } - - try { - $this->validatable->assert($input); - - return $this->dispatchPostParses($input); - } catch (ValidationException $e) { - throw $this->convertException($e); - } - } catch (ErrorsException $e) { - if ($this->catch) { - return ($this->catch)($input, $e); - } - - throw $e; + return $input; + } catch (ValidationException $e) { + throw $this->convertException($e); } } diff --git a/src/Schema/StringSchema.php b/src/Schema/StringSchema.php index 5d83419..97dfc01 100644 --- a/src/Schema/StringSchema.php +++ b/src/Schema/StringSchema.php @@ -7,7 +7,7 @@ use Chubbyphp\Parsing\Error; use Chubbyphp\Parsing\ErrorsException; -final class StringSchema extends AbstractSchema implements SchemaInterface +final class StringSchema extends AbstractSchemaV2 implements SchemaInterface { public const string ERROR_TYPE_CODE = 'string.type'; public const string ERROR_TYPE_TEMPLATE = 'Type should be "string", {{given}} given'; @@ -69,35 +69,6 @@ final class StringSchema extends AbstractSchema implements SchemaInterface private const string UUID_V4_PATTERN = '/^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-(8|9|a|b)[0-9a-f]{3}-[0-9a-f]{12}$/i'; private const string UUID_V5_PATTERN = '/^[0-9a-f]{8}-[0-9a-f]{4}-5[0-9a-f]{3}-(8|9|a|b)[0-9a-f]{3}-[0-9a-f]{12}$/i'; - public function parse(mixed $input): mixed - { - try { - $input = $this->dispatchPreParses($input); - - if (null === $input && $this->nullable) { - return null; - } - - if (!\is_string($input)) { - throw new ErrorsException( - new Error( - self::ERROR_TYPE_CODE, - self::ERROR_TYPE_TEMPLATE, - ['given' => $this->getDataType($input)] - ) - ); - } - - return $this->dispatchPostParses($input); - } catch (ErrorsException $e) { - if ($this->catch) { - return ($this->catch)($input, $e); - } - - throw $e; - } - } - public function length(int $length): static { return $this->postParse(static function (string $string) use ($length) { @@ -527,4 +498,19 @@ public function toInt(): IntSchema return $intInput; })->nullable($this->nullable); } + + protected function innerParse(mixed $input): mixed + { + if (!\is_string($input)) { + throw new ErrorsException( + new Error( + self::ERROR_TYPE_CODE, + self::ERROR_TYPE_TEMPLATE, + ['given' => $this->getDataType($input)] + ) + ); + } + + return $input; + } } diff --git a/src/Schema/TupleSchema.php b/src/Schema/TupleSchema.php index 326cc4c..7db2df2 100644 --- a/src/Schema/TupleSchema.php +++ b/src/Schema/TupleSchema.php @@ -8,7 +8,7 @@ use Chubbyphp\Parsing\Errors; use Chubbyphp\Parsing\ErrorsException; -final class TupleSchema extends AbstractSchema implements SchemaInterface +final class TupleSchema extends AbstractSchemaV2 implements SchemaInterface { public const string ERROR_TYPE_CODE = 'tuple.type'; public const string ERROR_TYPE_TEMPLATE = 'Type should be "array", {{given}} given'; @@ -48,69 +48,55 @@ public function __construct(array $schemas) } } - public function parse(mixed $input): mixed + protected function innerParse(mixed $input): mixed { - try { - $input = $this->dispatchPreParses($input); - - if (null === $input && $this->nullable) { - return null; - } - - if (!\is_array($input)) { - throw new ErrorsException( - new Error( - self::ERROR_TYPE_CODE, - self::ERROR_TYPE_TEMPLATE, - ['given' => $this->getDataType($input)] - ) - ); - } - - $childrenErrors = new Errors(); - - $output = []; - - foreach ($this->schemas as $i => $schema) { - if (!isset($input[$i])) { - $childrenErrors->add(new Error( - self::ERROR_MISSING_INDEX_CODE, - self::ERROR_MISSING_INDEX_TEMPLATE, - ['index' => $i] - ), (string) $i); - - continue; - } + if (!\is_array($input)) { + throw new ErrorsException( + new Error( + self::ERROR_TYPE_CODE, + self::ERROR_TYPE_TEMPLATE, + ['given' => $this->getDataType($input)] + ) + ); + } - try { - $output[$i] = $schema->parse($input[$i]); - } catch (ErrorsException $e) { - $childrenErrors->add($e->errors, (string) $i); - } - } + $childrenErrors = new Errors(); - $inputCount = \count($input); - $schemaCount = \count($this->schemas); + $output = []; - for ($i = $schemaCount; $i < $inputCount; ++$i) { + foreach ($this->schemas as $i => $schema) { + if (!isset($input[$i])) { $childrenErrors->add(new Error( - self::ERROR_ADDITIONAL_INDEX_CODE, - self::ERROR_ADDITIONAL_INDEX_TEMPLATE, + self::ERROR_MISSING_INDEX_CODE, + self::ERROR_MISSING_INDEX_TEMPLATE, ['index' => $i] ), (string) $i); - } - if ($childrenErrors->has()) { - throw new ErrorsException($childrenErrors); + continue; } - return $this->dispatchPostParses($output); - } catch (ErrorsException $e) { - if ($this->catch) { - return ($this->catch)($input, $e); + try { + $output[$i] = $schema->parse($input[$i]); + } catch (ErrorsException $e) { + $childrenErrors->add($e->errors, (string) $i); } + } - throw $e; + $inputCount = \count($input); + $schemaCount = \count($this->schemas); + + for ($i = $schemaCount; $i < $inputCount; ++$i) { + $childrenErrors->add(new Error( + self::ERROR_ADDITIONAL_INDEX_CODE, + self::ERROR_ADDITIONAL_INDEX_TEMPLATE, + ['index' => $i] + ), (string) $i); + } + + if ($childrenErrors->has()) { + throw new ErrorsException($childrenErrors); } + + return $output; } } diff --git a/src/Schema/UnionSchema.php b/src/Schema/UnionSchema.php index b8cf03e..9f27ae9 100644 --- a/src/Schema/UnionSchema.php +++ b/src/Schema/UnionSchema.php @@ -7,7 +7,7 @@ use Chubbyphp\Parsing\Errors; use Chubbyphp\Parsing\ErrorsException; -final class UnionSchema extends AbstractSchema implements SchemaInterface +final class UnionSchema extends AbstractSchemaV2 implements SchemaInterface { /** * @var array @@ -35,28 +35,7 @@ public function __construct(array $schemas) } } - public function parse(mixed $input): mixed - { - try { - $input = $this->dispatchPreParses($input); - - if (null === $input && $this->nullable) { - return null; - } - - $output = $this->parseSchemas($input); - - return $this->dispatchPostParses($output); - } catch (ErrorsException $e) { - if ($this->catch) { - return ($this->catch)($input, $e); - } - - throw $e; - } - } - - private function parseSchemas(mixed $input): mixed + protected function innerParse(mixed $input): mixed { $errors = new Errors(); diff --git a/tests/Unit/Schema/AbstractSchemaTest.php b/tests/Unit/Schema/AbstractSchemaTest.php new file mode 100644 index 0000000..b08a8ed --- /dev/null +++ b/tests/Unit/Schema/AbstractSchemaTest.php @@ -0,0 +1,158 @@ +nullable) { + return null; + } + + if (null === $input) { + throw new ErrorsException(new Error('type', 'Type error', [])); + } + + return $input; + } + }; + + self::assertNotSame($schema, $schema->nullable()); + self::assertNull($schema->nullable()->parse(null)); + self::assertNull($schema->nullable(true)->parse(null)); + + try { + $schema->nullable(false)->parse(null); + + throw new \Exception('code should not be reached'); + } catch (ErrorsException) { + } + } + + public function testDefault(): void + { + $schema = new class extends AbstractSchema { + public function parse(mixed $input): mixed + { + return $this->dispatchPreParses($input); + } + }; + + self::assertNotSame($schema, $schema->default('default')); + self::assertSame('default', $schema->default('default')->parse(null)); + self::assertSame('value', $schema->default('default')->parse('value')); + } + + public function testPreParse(): void + { + $schema = new class extends AbstractSchema { + public function parse(mixed $input): mixed + { + return $this->dispatchPreParses($input); + } + }; + + self::assertNotSame($schema, $schema->preParse(static fn ($i) => $i)); + self::assertSame('a12', $schema + ->preParse(static fn ($i) => $i.'1') + ->preParse(static fn ($i) => $i.'2') + ->parse('a')); + } + + public function testPostParse(): void + { + $schema = new class extends AbstractSchema { + public function parse(mixed $input): mixed + { + return $this->dispatchPostParses($input); + } + }; + + self::assertNotSame($schema, $schema->postParse(static fn ($o) => $o)); + self::assertSame('a12', $schema + ->postParse(static fn ($o) => $o.'1') + ->postParse(static fn ($o) => $o.'2') + ->parse('a')); + } + + public function testSafeParse(): void + { + $successSchema = new class extends AbstractSchema { + public function parse(mixed $input): mixed + { + return $input; + } + }; + + $result = $successSchema->safeParse('value'); + self::assertTrue($result->success); + self::assertSame('value', $result->data); + + $failSchema = new class extends AbstractSchema { + public function parse(mixed $input): mixed + { + throw new ErrorsException(new Error('error', 'Error', [])); + } + }; + + $result = $failSchema->safeParse('value'); + self::assertFalse($result->success); + self::assertInstanceOf(ErrorsException::class, $result->exception); + } + + public function testCatch(): void + { + $schema = new class extends AbstractSchema { + public function parse(mixed $input): mixed + { + $e = new ErrorsException(new Error('error', 'Error', [])); + if (null !== $this->catch) { + return ($this->catch)($input, $e); + } + + throw $e; + } + }; + + self::assertNotSame($schema, $schema->catch(static fn ($i, $e) => $i)); + self::assertSame('caught', $schema->catch(static fn ($i, $e) => 'caught')->parse('value')); + } + + public function testGetDataType(): void + { + $schema = new class extends AbstractSchema { + public function parse(mixed $input): mixed + { + throw new ErrorsException(new Error('type', '{{given}}', ['given' => $this->getDataType($input)])); + } + }; + + try { + $schema->parse('string'); + } catch (ErrorsException $e) { + self::assertSame('string', $e->errors->jsonSerialize()[0]['error']['variables']['given']); + } + + try { + $schema->parse(new \stdClass()); + } catch (ErrorsException $e) { + self::assertSame(\stdClass::class, $e->errors->jsonSerialize()[0]['error']['variables']['given']); + } + } +} diff --git a/tests/Unit/Schema/AbstractSchemaV2Test.php b/tests/Unit/Schema/AbstractSchemaV2Test.php new file mode 100644 index 0000000..e3d2ea3 --- /dev/null +++ b/tests/Unit/Schema/AbstractSchemaV2Test.php @@ -0,0 +1,149 @@ +nullable()); + self::assertNull($schema->nullable()->parse(null)); + self::assertNull($schema->nullable(true)->parse(null)); + + try { + $schema->nullable(false)->parse(null); + + throw new \Exception('code should not be reached'); + } catch (ErrorsException) { + } + } + + public function testDefault(): void + { + $schema = new class extends AbstractSchemaV2 { + protected function innerParse(mixed $input): mixed + { + return $input; + } + }; + + self::assertNotSame($schema, $schema->default('default')); + self::assertSame('default', $schema->default('default')->parse(null)); + self::assertSame('value', $schema->default('default')->parse('value')); + } + + public function testPreParse(): void + { + $schema = new class extends AbstractSchemaV2 { + protected function innerParse(mixed $input): mixed + { + return $input; + } + }; + + self::assertNotSame($schema, $schema->preParse(static fn ($i) => $i)); + self::assertSame('a12', $schema + ->preParse(static fn ($i) => $i.'1') + ->preParse(static fn ($i) => $i.'2') + ->parse('a')); + } + + public function testPostParse(): void + { + $schema = new class extends AbstractSchemaV2 { + protected function innerParse(mixed $input): mixed + { + return $input; + } + }; + + self::assertNotSame($schema, $schema->postParse(static fn ($o) => $o)); + self::assertSame('a12', $schema + ->postParse(static fn ($o) => $o.'1') + ->postParse(static fn ($o) => $o.'2') + ->parse('a')); + } + + public function testSafeParse(): void + { + $successSchema = new class extends AbstractSchemaV2 { + protected function innerParse(mixed $input): mixed + { + return $input; + } + }; + + $result = $successSchema->safeParse('value'); + self::assertTrue($result->success); + self::assertSame('value', $result->data); + + $failSchema = new class extends AbstractSchemaV2 { + protected function innerParse(mixed $input): mixed + { + throw new ErrorsException(new Error('error', 'Error', [])); + } + }; + + $result = $failSchema->safeParse('value'); + self::assertFalse($result->success); + self::assertInstanceOf(ErrorsException::class, $result->exception); + } + + public function testCatch(): void + { + $schema = new class extends AbstractSchemaV2 { + protected function innerParse(mixed $input): mixed + { + throw new ErrorsException(new Error('error', 'Error', [])); + } + }; + + self::assertNotSame($schema, $schema->catch(static fn ($i, $e) => $i)); + self::assertSame('caught', $schema->catch(static fn ($i, $e) => 'caught')->parse('value')); + } + + public function testGetDataType(): void + { + $schema = new class extends AbstractSchemaV2 { + protected function innerParse(mixed $input): mixed + { + throw new ErrorsException(new Error('type', '{{given}}', ['given' => $this->getDataType($input)])); + } + }; + + try { + $schema->parse('string'); + } catch (ErrorsException $e) { + self::assertSame('string', $e->errors->jsonSerialize()[0]['error']['variables']['given']); + } + + try { + $schema->parse(new \stdClass()); + } catch (ErrorsException $e) { + self::assertSame(\stdClass::class, $e->errors->jsonSerialize()[0]['error']['variables']['given']); + } + } +} diff --git a/tests/Unit/Schema/ArraySchemaTest.php b/tests/Unit/Schema/ArraySchemaTest.php index 7794fb5..a2a6903 100644 --- a/tests/Unit/Schema/ArraySchemaTest.php +++ b/tests/Unit/Schema/ArraySchemaTest.php @@ -12,7 +12,6 @@ use PHPUnit\Framework\TestCase; /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\ArraySchema * * @internal diff --git a/tests/Unit/Schema/AssocSchemaTest.php b/tests/Unit/Schema/AssocSchemaTest.php index bb1fd8a..e271045 100644 --- a/tests/Unit/Schema/AssocSchemaTest.php +++ b/tests/Unit/Schema/AssocSchemaTest.php @@ -27,7 +27,6 @@ public function jsonSerialize(): array } /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\AssocSchema * * @internal diff --git a/tests/Unit/Schema/BackedEnumSchemaTest.php b/tests/Unit/Schema/BackedEnumSchemaTest.php index c9d4e86..8ef7abe 100644 --- a/tests/Unit/Schema/BackedEnumSchemaTest.php +++ b/tests/Unit/Schema/BackedEnumSchemaTest.php @@ -35,7 +35,6 @@ enum BackedSuitInt: int enum BackedEmpty: string {} /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\BackedEnumSchema * * @internal diff --git a/tests/Unit/Schema/BoolSchemaTest.php b/tests/Unit/Schema/BoolSchemaTest.php index 415d523..3d001df 100644 --- a/tests/Unit/Schema/BoolSchemaTest.php +++ b/tests/Unit/Schema/BoolSchemaTest.php @@ -9,7 +9,6 @@ use PHPUnit\Framework\TestCase; /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\BoolSchema * * @internal diff --git a/tests/Unit/Schema/DateTimeSchemaTest.php b/tests/Unit/Schema/DateTimeSchemaTest.php index d4e2a5f..b834cc1 100644 --- a/tests/Unit/Schema/DateTimeSchemaTest.php +++ b/tests/Unit/Schema/DateTimeSchemaTest.php @@ -9,7 +9,6 @@ use PHPUnit\Framework\TestCase; /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\DateTimeSchema * * @internal diff --git a/tests/Unit/Schema/DiscriminatedUnionSchemaTest.php b/tests/Unit/Schema/DiscriminatedUnionSchemaTest.php index e4d1e35..7849da0 100644 --- a/tests/Unit/Schema/DiscriminatedUnionSchemaTest.php +++ b/tests/Unit/Schema/DiscriminatedUnionSchemaTest.php @@ -28,7 +28,6 @@ public function jsonSerialize(): array } /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\DiscriminatedUnionSchema * * @internal diff --git a/tests/Unit/Schema/FloatSchemaTest.php b/tests/Unit/Schema/FloatSchemaTest.php index ac98046..c4888d7 100644 --- a/tests/Unit/Schema/FloatSchemaTest.php +++ b/tests/Unit/Schema/FloatSchemaTest.php @@ -9,7 +9,6 @@ use PHPUnit\Framework\TestCase; /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\FloatSchema * * @internal diff --git a/tests/Unit/Schema/IntSchemaTest.php b/tests/Unit/Schema/IntSchemaTest.php index 31feaa6..594b998 100644 --- a/tests/Unit/Schema/IntSchemaTest.php +++ b/tests/Unit/Schema/IntSchemaTest.php @@ -9,7 +9,6 @@ use PHPUnit\Framework\TestCase; /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\IntSchema * * @internal diff --git a/tests/Unit/Schema/LazySchemaTest.php b/tests/Unit/Schema/LazySchemaTest.php index e7fcb71..f326a13 100644 --- a/tests/Unit/Schema/LazySchemaTest.php +++ b/tests/Unit/Schema/LazySchemaTest.php @@ -10,7 +10,6 @@ use PHPUnit\Framework\TestCase; /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\LazySchema * * @internal diff --git a/tests/Unit/Schema/LiteralSchemaTest.php b/tests/Unit/Schema/LiteralSchemaTest.php index 618ecd0..d7aff44 100644 --- a/tests/Unit/Schema/LiteralSchemaTest.php +++ b/tests/Unit/Schema/LiteralSchemaTest.php @@ -9,7 +9,6 @@ use PHPUnit\Framework\TestCase; /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\LiteralSchema * * @internal diff --git a/tests/Unit/Schema/ObjectSchemaTest.php b/tests/Unit/Schema/ObjectSchemaTest.php index 486eef8..f0ccfd2 100644 --- a/tests/Unit/Schema/ObjectSchemaTest.php +++ b/tests/Unit/Schema/ObjectSchemaTest.php @@ -27,7 +27,6 @@ public function jsonSerialize(): array } /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\ObjectSchema * * @internal diff --git a/tests/Unit/Schema/RecordSchemaTest.php b/tests/Unit/Schema/RecordSchemaTest.php index 969e8ce..663308e 100644 --- a/tests/Unit/Schema/RecordSchemaTest.php +++ b/tests/Unit/Schema/RecordSchemaTest.php @@ -24,7 +24,6 @@ public function jsonSerialize(): array } /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\RecordSchema * * @internal diff --git a/tests/Unit/Schema/RespectValidationSchemaTest.php b/tests/Unit/Schema/RespectValidationSchemaTest.php index 2565ad0..3d81f50 100644 --- a/tests/Unit/Schema/RespectValidationSchemaTest.php +++ b/tests/Unit/Schema/RespectValidationSchemaTest.php @@ -10,7 +10,6 @@ use Respect\Validation\Validator as v; /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\RespectValidationSchema * * @internal diff --git a/tests/Unit/Schema/StringSchemaTest.php b/tests/Unit/Schema/StringSchemaTest.php index c5d394f..696ab41 100644 --- a/tests/Unit/Schema/StringSchemaTest.php +++ b/tests/Unit/Schema/StringSchemaTest.php @@ -9,7 +9,6 @@ use PHPUnit\Framework\TestCase; /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\StringSchema * * @internal diff --git a/tests/Unit/Schema/TupleSchemaTest.php b/tests/Unit/Schema/TupleSchemaTest.php index 7bd3eae..e0dbb30 100644 --- a/tests/Unit/Schema/TupleSchemaTest.php +++ b/tests/Unit/Schema/TupleSchemaTest.php @@ -10,7 +10,6 @@ use PHPUnit\Framework\TestCase; /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\TupleSchema * * @internal diff --git a/tests/Unit/Schema/UnionSchemaTest.php b/tests/Unit/Schema/UnionSchemaTest.php index 9caaaf5..90273ab 100644 --- a/tests/Unit/Schema/UnionSchemaTest.php +++ b/tests/Unit/Schema/UnionSchemaTest.php @@ -11,7 +11,6 @@ use PHPUnit\Framework\TestCase; /** - * @covers \Chubbyphp\Parsing\Schema\AbstractSchema * @covers \Chubbyphp\Parsing\Schema\UnionSchema * * @internal