Skip to content

Commit

Permalink
Fix nested missing values
Browse files Browse the repository at this point in the history
  • Loading branch information
zerkms committed Nov 6, 2024
1 parent 6b02ca3 commit 8915096
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 4 deletions.
21 changes: 18 additions & 3 deletions src/Psl/Type/Exception/CoercionException.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ final class CoercionException extends Exception
{
private string $target;

private bool $withValue;

/**
* @param list<string> $paths
*/
private function __construct(?string $actual, string $target, string $message, array $paths = [], ?Throwable $previous = null)
private function __construct(?string $actual, string $target, string $message, bool $withValue, array $paths = [], ?Throwable $previous = null)
{
parent::__construct(
$message,
Expand All @@ -27,6 +29,7 @@ private function __construct(?string $actual, string $target, string $message, a
);

$this->target = $target;
$this->withValue = $withValue;
}

public function getTargetType(): string
Expand All @@ -52,7 +55,7 @@ public static function withValue(
$previous && !$previous instanceof self ? ': ' . $previous->getMessage() : '',
);

return new self($actual, $target, $message, $paths, $previous);
return new self($actual, $target, $message, true, $paths, $previous);
}

public static function withoutValue(
Expand All @@ -69,6 +72,18 @@ public static function withoutValue(
$previous && !$previous instanceof self ? ': ' . $previous->getMessage() : '',
);

return new self(null, $target, $message, $paths, $previous);
return new self(null, $target, $message, false, $paths, $previous);
}

public function wrap(
mixed $value,
string $target,
?string $path = null
): self {
if ($this->withValue) {
return self::withValue($value, $target, $path, $this);
}

return self::withoutValue($target, $path, $this);
}
}
2 changes: 1 addition & 1 deletion src/Psl/Type/Internal/ShapeType.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ private function coerceIterable(mixed $value): array
}
} catch (CoercionException $e) {
throw match (true) {
$element_value_found => CoercionException::withValue($array[$element] ?? null, $this->toString(), PathExpression::path($element), $e),
$element_value_found => $e->wrap($array[$element] ?? null, $this->toString(), PathExpression::path($element)),
default => $e
};
}
Expand Down
11 changes: 11 additions & 0 deletions tests/unit/Type/ShapeTypeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,17 @@ public static function provideCoerceExceptionExpectations(): iterable
[],
'Could not coerce to type "array{\'name\': string}" at path "name" as the value was not passed.'
];
yield 'missing nested key' => [
Type\shape([
'a' => Type\shape([
'b' => Type\shape([
'c' => Type\mixed(),
]),
]),
]),
['a' => ['b' => []]],
'Could not coerce to type "array{\'a\': array{\'b\': array{\'c\': mixed}}}" at path "a.b.c" as the value was not passed.',
];
yield 'invalid key' => [
Type\shape([
'name' => Type\string(),
Expand Down

0 comments on commit 8915096

Please sign in to comment.