diff --git a/README.md b/README.md index 7e58ce37..23f79767 100644 --- a/README.md +++ b/README.md @@ -226,7 +226,7 @@ try { // All messages bound to the node can be accessed foreach ($node->messages() as $message) { // Errors can be retrieved by filtering like below: - if ($message instanceof Throwable) { + if ($message->isError()) { // Do something… } } diff --git a/src/Mapper/Object/Exception/ObjectConstructionError.php b/src/Mapper/Object/Exception/ObjectConstructionError.php deleted file mode 100644 index 3f97b68c..00000000 --- a/src/Mapper/Object/Exception/ObjectConstructionError.php +++ /dev/null @@ -1,21 +0,0 @@ -getMessage(), - 1630142421, - $exception - ); - } -} diff --git a/src/Mapper/Object/MethodObjectBuilder.php b/src/Mapper/Object/MethodObjectBuilder.php index f684e7b1..1d774978 100644 --- a/src/Mapper/Object/MethodObjectBuilder.php +++ b/src/Mapper/Object/MethodObjectBuilder.php @@ -13,7 +13,7 @@ use CuyZ\Valinor\Mapper\Object\Exception\InvalidSourceForObject; use CuyZ\Valinor\Mapper\Object\Exception\MethodNotFound; use CuyZ\Valinor\Mapper\Object\Exception\MissingMethodArgument; -use CuyZ\Valinor\Mapper\Object\Exception\ObjectConstructionError; +use CuyZ\Valinor\Mapper\Tree\Message\ThrowableMessage; use CuyZ\Valinor\Type\Types\ClassType; use Exception; @@ -102,7 +102,7 @@ public function build(array $arguments): object /** @infection-ignore-all */ return $className::$methodName(...array_values($arguments)); // @phpstan-ignore-line } catch (Exception $exception) { - throw new ObjectConstructionError($exception); + throw ThrowableMessage::from($exception); } } diff --git a/src/Mapper/Tree/Message/NodeMessage.php b/src/Mapper/Tree/Message/NodeMessage.php new file mode 100644 index 00000000..657c0b29 --- /dev/null +++ b/src/Mapper/Tree/Message/NodeMessage.php @@ -0,0 +1,124 @@ +node = $node; + $this->message = $message; + } + + /** + * Performs a placeholders replace operation on the given content. + * + * The values to be replaced will be the ones given as second argument; if + * none is given these values will be used instead, in order: + * + * 1. The original code of this message + * 2. The original content of this message + * 3. A string representation of the node type + * 4. The name of the node + * 5. The path of the node + * + * See usage examples below: + * + * ``` + * $content = $message->format('the previous code was: %1$s'); + * + * $content = $message->format( + * '%1$s / new message content (type: %2$s)', + * 'some parameter', + * $message->type(), + * ); + * ``` + */ + public function format(string $content, string ...$values): string + { + return sprintf($content, ...$values ?: [ + $this->code(), + (string)$this, + (string)$this->type(), + $this->name(), + $this->path(), + ]); + } + + public function name(): string + { + return $this->node->name(); + } + + public function path(): string + { + return $this->node->path(); + } + + public function type(): Type + { + return $this->node->type(); + } + + public function attributes(): Attributes + { + return $this->node->attributes(); + } + + /** + * @return mixed + */ + public function value() + { + if (! $this->node->isValid()) { + return null; + } + + return $this->node->value(); + } + + public function originalMessage(): Message + { + return $this->message; + } + + public function isError(): bool + { + return $this->message instanceof Throwable; + } + + public function code(): string + { + if ($this->message instanceof HasCode) { + return $this->message->code(); + } + + if ($this->message instanceof Throwable) { + return (string)$this->message->getCode(); + } + + return 'unknown'; + } + + public function __toString(): string + { + if ($this->message instanceof Throwable) { + return $this->message->getMessage(); + } + + return (string)$this->message; + } +} diff --git a/src/Mapper/Tree/Message/ThrowableMessage.php b/src/Mapper/Tree/Message/ThrowableMessage.php index 886bc780..86396d13 100644 --- a/src/Mapper/Tree/Message/ThrowableMessage.php +++ b/src/Mapper/Tree/Message/ThrowableMessage.php @@ -5,19 +5,37 @@ namespace CuyZ\Valinor\Mapper\Tree\Message; use RuntimeException; +use Throwable; final class ThrowableMessage extends RuntimeException implements Message, HasCode { - public function __construct(string $message, string $code) + public static function new(string $message, string $code): self { - parent::__construct($message); + $instance = new self($message); + $instance->code = $code; - $this->code = $code; + return $instance; + } + + /** + * @return Message&Throwable + */ + public static function from(Throwable $message): Message + { + if ($message instanceof Message) { + return $message; + } + + /** @infection-ignore-all */ + $instance = new self($message->getMessage(), 0, $message); + $instance->code = (string)$message->getCode(); + + return $instance; } public function code(): string { - return $this->code; + return (string)$this->code; } public function __toString(): string diff --git a/src/Mapper/Tree/Node.php b/src/Mapper/Tree/Node.php index e58a4399..faaced6e 100644 --- a/src/Mapper/Tree/Node.php +++ b/src/Mapper/Tree/Node.php @@ -9,6 +9,7 @@ use CuyZ\Valinor\Mapper\Tree\Exception\DuplicatedNodeChild; use CuyZ\Valinor\Mapper\Tree\Exception\InvalidNodeValue; use CuyZ\Valinor\Mapper\Tree\Message\Message; +use CuyZ\Valinor\Mapper\Tree\Message\NodeMessage; use CuyZ\Valinor\Type\Type; use Throwable; @@ -22,7 +23,7 @@ final class Node /** @var array */ private array $children = []; - /** @var array */ + /** @var array */ private array $messages = []; private bool $valid = true; @@ -137,18 +138,17 @@ public function children(): array public function withMessage(Message $message): self { + $message = new NodeMessage($this, $message); + $clone = clone $this; $clone->messages = [...$this->messages, $message]; - - if ($message instanceof Throwable) { - $clone->valid = false; - } + $clone->valid = $clone->valid && ! $message->isError(); return $clone; } /** - * @return array + * @return array */ public function messages(): array { diff --git a/tests/Fake/Mapper/Tree/Message/FakeErrorMessage.php b/tests/Fake/Mapper/Tree/Message/FakeErrorMessage.php index 9a240183..77eca50c 100644 --- a/tests/Fake/Mapper/Tree/Message/FakeErrorMessage.php +++ b/tests/Fake/Mapper/Tree/Message/FakeErrorMessage.php @@ -9,8 +9,13 @@ final class FakeErrorMessage extends Exception implements Message { + public function __construct(string $message = 'some error message') + { + parent::__construct($message); + } + public function __toString(): string { - return 'some error message'; + return $this->message; } } diff --git a/tests/Fake/Mapper/Tree/Message/FakeMessage.php b/tests/Fake/Mapper/Tree/Message/FakeMessage.php index 52b1d39d..846c5580 100644 --- a/tests/Fake/Mapper/Tree/Message/FakeMessage.php +++ b/tests/Fake/Mapper/Tree/Message/FakeMessage.php @@ -4,12 +4,25 @@ namespace CuyZ\Valinor\Tests\Fake\Mapper\Tree\Message; +use CuyZ\Valinor\Mapper\Tree\Message\HasCode; use CuyZ\Valinor\Mapper\Tree\Message\Message; -final class FakeMessage implements Message +final class FakeMessage implements Message, HasCode { + private string $message; + + public function __construct(string $message = 'some message') + { + $this->message = $message; + } + public function __toString(): string { - return 'some message'; + return $this->message; + } + + public function code(): string + { + return 'some_code'; } } diff --git a/tests/Integration/IntegrationTest.php b/tests/Integration/IntegrationTest.php index 1380ac2d..1e0529f4 100644 --- a/tests/Integration/IntegrationTest.php +++ b/tests/Integration/IntegrationTest.php @@ -9,7 +9,6 @@ use CuyZ\Valinor\MapperBuilder; use FilesystemIterator; use PHPUnit\Framework\TestCase; -use Throwable; use function implode; use function is_dir; @@ -61,8 +60,8 @@ protected function mappingFail(MappingError $error) $errors = []; foreach ($node->messages() as $message) { - if ($message instanceof Throwable) { - $errors[] = $message->getMessage(); + if ($message->isError()) { + $errors[] = (string)$message; } } diff --git a/tests/Integration/Mapping/Object/ArrayValuesMappingTest.php b/tests/Integration/Mapping/Object/ArrayValuesMappingTest.php index 26f834f2..949254cb 100644 --- a/tests/Integration/Mapping/Object/ArrayValuesMappingTest.php +++ b/tests/Integration/Mapping/Object/ArrayValuesMappingTest.php @@ -5,12 +5,9 @@ namespace CuyZ\Valinor\Tests\Integration\Mapping\Object; use CuyZ\Valinor\Mapper\MappingError; -use CuyZ\Valinor\Mapper\Tree\Exception\CannotCastToScalarValue; -use CuyZ\Valinor\Mapper\Tree\Exception\InvalidNodeValue; use CuyZ\Valinor\Tests\Integration\IntegrationTest; use CuyZ\Valinor\Tests\Integration\Mapping\Fixture\SimpleObject; use CuyZ\Valinor\Tests\Integration\Mapping\Fixture\SimpleObject as SimpleObjectAlias; -use Throwable; final class ArrayValuesMappingTest extends IntegrationTest { @@ -78,11 +75,8 @@ public function test_empty_array_in_non_empty_array_throws_exception(): void } catch (MappingError $exception) { $error = $exception->node()->children()['nonEmptyArraysOfStrings']->messages()[0]; - assert($error instanceof Throwable); - - self::assertInstanceOf(InvalidNodeValue::class, $error); - self::assertSame(1630678334, $error->getCode()); - self::assertSame('Empty array is not accepted by `non-empty-array`.', $error->getMessage()); + self::assertSame('1630678334', $error->code()); + self::assertSame('Empty array is not accepted by `non-empty-array`.', (string)$error); } } @@ -95,11 +89,8 @@ public function test_value_that_cannot_be_casted_throws_exception(): void } catch (MappingError $exception) { $error = $exception->node()->children()['integers']->children()[0]->messages()[0]; - assert($error instanceof Throwable); - - self::assertInstanceOf(CannotCastToScalarValue::class, $error); - self::assertSame(1618736242, $error->getCode()); - self::assertSame('Cannot cast value of type `string` to `int`.', $error->getMessage()); + self::assertSame('1618736242', $error->code()); + self::assertSame('Cannot cast value of type `string` to `int`.', (string)$error); } } } diff --git a/tests/Integration/Mapping/Object/DateTimeMappingTest.php b/tests/Integration/Mapping/Object/DateTimeMappingTest.php index bcee1b29..8ae0419a 100644 --- a/tests/Integration/Mapping/Object/DateTimeMappingTest.php +++ b/tests/Integration/Mapping/Object/DateTimeMappingTest.php @@ -6,13 +6,10 @@ use CuyZ\Valinor\Mapper\MappingError; use CuyZ\Valinor\Mapper\Object\DateTimeObjectBuilder; -use CuyZ\Valinor\Mapper\Object\Exception\CannotParseToDateTime; use CuyZ\Valinor\Tests\Integration\IntegrationTest; -use CuyZ\Valinor\Type\Resolver\Exception\UnionTypeDoesNotAllowNull; use DateTime; use DateTimeImmutable; use DateTimeInterface; -use Throwable; final class DateTimeMappingTest extends IntegrationTest { @@ -71,11 +68,8 @@ public function test_invalid_datetime_throws_exception(): void } catch (MappingError $exception) { $error = $exception->node()->children()['dateTime']->messages()[0]; - assert($error instanceof Throwable); - - self::assertInstanceOf(CannotParseToDateTime::class, $error); - self::assertSame(1630686564, $error->getCode()); - self::assertSame('Impossible to convert `invalid datetime` to `DateTime`.', $error->getMessage()); + self::assertSame('1630686564', $error->code()); + self::assertSame('Impossible to convert `invalid datetime` to `DateTime`.', (string)$error); } } @@ -93,11 +87,8 @@ public function test_invalid_datetime_from_array_throws_exception(): void } catch (MappingError $exception) { $error = $exception->node()->children()['dateTime']->messages()[0]; - assert($error instanceof Throwable); - - self::assertInstanceOf(CannotParseToDateTime::class, $error); - self::assertSame(1630686564, $error->getCode()); - self::assertSame('Impossible to convert `1337` to `DateTime`.', $error->getMessage()); + self::assertSame('1630686564', $error->code()); + self::assertSame('Impossible to convert `1337` to `DateTime`.', (string)$error); } } @@ -114,7 +105,8 @@ public function test_invalid_array_source_throws_exception(): void } catch (MappingError $exception) { $error = $exception->node()->children()['dateTime']->children()['datetime']->messages()[0]; - self::assertInstanceOf(UnionTypeDoesNotAllowNull::class, $error); + self::assertSame('1618742357', $error->code()); + self::assertSame('Cannot assign an empty value to union type `positive-int|non-empty-string`.', (string)$error); } } } diff --git a/tests/Integration/Mapping/Object/ListValuesMappingTest.php b/tests/Integration/Mapping/Object/ListValuesMappingTest.php index 9731d545..a59ded2b 100644 --- a/tests/Integration/Mapping/Object/ListValuesMappingTest.php +++ b/tests/Integration/Mapping/Object/ListValuesMappingTest.php @@ -5,12 +5,9 @@ namespace CuyZ\Valinor\Tests\Integration\Mapping\Object; use CuyZ\Valinor\Mapper\MappingError; -use CuyZ\Valinor\Mapper\Tree\Exception\CannotCastToScalarValue; -use CuyZ\Valinor\Mapper\Tree\Exception\InvalidNodeValue; use CuyZ\Valinor\Tests\Integration\IntegrationTest; use CuyZ\Valinor\Tests\Integration\Mapping\Fixture\SimpleObject; use CuyZ\Valinor\Tests\Integration\Mapping\Fixture\SimpleObject as SimpleObjectAlias; -use Throwable; use function array_values; @@ -78,11 +75,8 @@ public function test_empty_list_in_non_empty_list_throws_exception(): void } catch (MappingError $exception) { $error = $exception->node()->children()['nonEmptyListOfStrings']->messages()[0]; - assert($error instanceof Throwable); - - self::assertInstanceOf(InvalidNodeValue::class, $error); - self::assertSame(1630678334, $error->getCode()); - self::assertSame('Empty array is not accepted by `non-empty-list`.', $error->getMessage()); + self::assertSame('1630678334', $error->code()); + self::assertSame('Empty array is not accepted by `non-empty-list`.', (string)$error); } } @@ -95,11 +89,8 @@ public function test_value_that_cannot_be_casted_throws_exception(): void } catch (MappingError $exception) { $error = $exception->node()->children()['integers']->children()['0']->messages()[0]; - assert($error instanceof Throwable); - - self::assertInstanceOf(CannotCastToScalarValue::class, $error); - self::assertSame(1618736242, $error->getCode()); - self::assertSame('Cannot cast value of type `string` to `int`.', $error->getMessage()); + self::assertSame('1618736242', $error->code()); + self::assertSame('Cannot cast value of type `string` to `int`.', (string)$error); } } } diff --git a/tests/Integration/Mapping/Object/ScalarValuesMappingTest.php b/tests/Integration/Mapping/Object/ScalarValuesMappingTest.php index 6174e386..55f36f75 100644 --- a/tests/Integration/Mapping/Object/ScalarValuesMappingTest.php +++ b/tests/Integration/Mapping/Object/ScalarValuesMappingTest.php @@ -5,7 +5,6 @@ namespace CuyZ\Valinor\Tests\Integration\Mapping\Object; use CuyZ\Valinor\Mapper\MappingError; -use CuyZ\Valinor\Mapper\Tree\Exception\CannotCastToScalarValue; use CuyZ\Valinor\Tests\Integration\IntegrationTest; use CuyZ\Valinor\Tests\Integration\Mapping\Fixture\SimpleObject; use DateTime; @@ -13,7 +12,6 @@ use DateTimeInterface; use stdClass; use stdClass as ObjectAlias; -use Throwable; final class ScalarValuesMappingTest extends IntegrationTest { @@ -73,11 +71,8 @@ public function test_value_that_cannot_be_casted_throws_exception(): void } catch (MappingError $exception) { $error = $exception->node()->children()['value']->messages()[0]; - assert($error instanceof Throwable); - - self::assertInstanceOf(CannotCastToScalarValue::class, $error); - self::assertSame(1618736242, $error->getCode()); - self::assertSame('Cannot cast value of type `stdClass` to `string`.', $error->getMessage()); + self::assertSame('1618736242', $error->code()); + self::assertSame('Cannot cast value of type `stdClass` to `string`.', (string)$error); } } @@ -90,11 +85,8 @@ public function test_empty_mandatory_value_throws_exception(): void } catch (MappingError $exception) { $error = $exception->node()->children()['value']->messages()[0]; - assert($error instanceof Throwable); - - self::assertInstanceOf(CannotCastToScalarValue::class, $error); - self::assertSame(1618736242, $error->getCode()); - self::assertSame('Cannot be empty and must be filled with a value of type `string`.', $error->getMessage()); + self::assertSame('1618736242', $error->code()); + self::assertSame('Cannot be empty and must be filled with a value of type `string`.', (string)$error); } } } diff --git a/tests/Integration/Mapping/Object/ShapedArrayValuesMappingTest.php b/tests/Integration/Mapping/Object/ShapedArrayValuesMappingTest.php index 3603a08e..429da50b 100644 --- a/tests/Integration/Mapping/Object/ShapedArrayValuesMappingTest.php +++ b/tests/Integration/Mapping/Object/ShapedArrayValuesMappingTest.php @@ -5,11 +5,9 @@ namespace CuyZ\Valinor\Tests\Integration\Mapping\Object; use CuyZ\Valinor\Mapper\MappingError; -use CuyZ\Valinor\Mapper\Tree\Exception\CannotCastToScalarValue; use CuyZ\Valinor\Tests\Integration\IntegrationTest; use CuyZ\Valinor\Tests\Integration\Mapping\Fixture\SimpleObject; use stdClass; -use Throwable; final class ShapedArrayValuesMappingTest extends IntegrationTest { @@ -76,11 +74,8 @@ public function test_value_that_cannot_be_casted_throws_exception(): void } catch (MappingError $exception) { $error = $exception->node()->children()['basicShapedArrayWithStringKeys']->children()['foo']->messages()[0]; - assert($error instanceof Throwable); - - self::assertInstanceOf(CannotCastToScalarValue::class, $error); - self::assertSame(1618736242, $error->getCode()); - self::assertSame('Cannot cast value of type `stdClass` to `string`.', $error->getMessage()); + self::assertSame('1618736242', $error->code()); + self::assertSame('Cannot cast value of type `stdClass` to `string`.', (string)$error); } } } diff --git a/tests/Integration/Mapping/VisitorMappingTest.php b/tests/Integration/Mapping/VisitorMappingTest.php index b75c28cd..912286b0 100644 --- a/tests/Integration/Mapping/VisitorMappingTest.php +++ b/tests/Integration/Mapping/VisitorMappingTest.php @@ -35,7 +35,7 @@ public function test_visitors_are_called_during_mapping(): void ->mapper() ->map(SimpleObject::class, ['value' => 'foo']); } catch (MappingError $exception) { - self::assertSame($error, $exception->node()->messages()[0]); + self::assertSame((string)$error, (string)$exception->node()->messages()[0]); } self::assertSame(['#1', '#2'], $visits); diff --git a/tests/Unit/Mapper/Object/MethodObjectBuilderTest.php b/tests/Unit/Mapper/Object/MethodObjectBuilderTest.php index 556b77a1..a50631d4 100644 --- a/tests/Unit/Mapper/Object/MethodObjectBuilderTest.php +++ b/tests/Unit/Mapper/Object/MethodObjectBuilderTest.php @@ -12,8 +12,8 @@ use CuyZ\Valinor\Mapper\Object\Exception\InvalidSourceForObject; use CuyZ\Valinor\Mapper\Object\Exception\MethodNotFound; use CuyZ\Valinor\Mapper\Object\Exception\MissingMethodArgument; -use CuyZ\Valinor\Mapper\Object\Exception\ObjectConstructionError; use CuyZ\Valinor\Mapper\Object\MethodObjectBuilder; +use CuyZ\Valinor\Mapper\Tree\Message\ThrowableMessage; use CuyZ\Valinor\Tests\Fake\Definition\FakeClassDefinition; use Generator; use PHPUnit\Framework\TestCase; @@ -164,8 +164,8 @@ public function test_exception_thrown_by_constructor_is_caught_and_wrapped(): vo $class = FakeClassDefinition::fromReflection(new ReflectionClass(ObjectWithConstructorThatThrowsException::class)); $objectBuilder = new MethodObjectBuilder($class, '__construct'); - $this->expectException(ObjectConstructionError::class); - $this->expectExceptionCode(1630142421); + $this->expectException(ThrowableMessage::class); + $this->expectExceptionCode(1337); $this->expectExceptionMessage('some exception'); $objectBuilder->build([]); @@ -194,6 +194,6 @@ final class ObjectWithConstructorThatThrowsException { public function __construct() { - throw new RuntimeException('some exception'); + throw new RuntimeException('some exception', 1337); } } diff --git a/tests/Unit/Mapper/Tree/Message/NodeMessageTest.php b/tests/Unit/Mapper/Tree/Message/NodeMessageTest.php new file mode 100644 index 00000000..904210c7 --- /dev/null +++ b/tests/Unit/Mapper/Tree/Message/NodeMessageTest.php @@ -0,0 +1,79 @@ + 'foo', + 'type' => $type, + 'value' => 'some value', + 'attributes' => $attributes, + 'message' => $originalMessage + ]])->children()['foo']; + + $message = new NodeMessage($node, $originalMessage); + + self::assertSame('foo', $message->name()); + self::assertSame('foo', $message->path()); + self::assertSame('some value', $message->value()); + self::assertSame($type, $message->type()); + self::assertSame($attributes, $message->attributes()); + self::assertSame($originalMessage, $message->originalMessage()); + } + + public function test_value_from_invalid_node_returns_null(): void + { + $originalMessage = new FakeErrorMessage(); + $node = FakeNode::leaf(FakeType::permissive(), 'foo')->withMessage($originalMessage); + + $message = new NodeMessage($node, $originalMessage); + + self::assertNull($message->value()); + } + + public function test_format_message_replaces_placeholders_with_default_values(): void + { + $originalMessage = new FakeMessage(); + $type = FakeType::permissive(); + + $node = FakeNode::branch([[ + 'name' => 'foo', + 'type' => $type, + 'value' => 'some value', + 'message' => $originalMessage + ]])->children()['foo']; + + $message = new NodeMessage($node, $originalMessage); + $text = $message->format('%1$s / %2$s / %3$s / %4$s / %5$s'); + + self::assertSame("some_code / some message / $type / foo / foo", $text); + } + + public function test_format_message_replaces_placeholders_with_given_values(): void + { + $originalMessage = new FakeMessage(); + $node = FakeNode::any(); + + $message = new NodeMessage($node, $originalMessage); + $text = $message->format('%1$s / %2$s', 'foo', 'bar'); + + self::assertSame('foo / bar', $text); + } +} diff --git a/tests/Unit/Mapper/Tree/Message/ThrowableMessageTest.php b/tests/Unit/Mapper/Tree/Message/ThrowableMessageTest.php index f3e837ba..82512b5a 100644 --- a/tests/Unit/Mapper/Tree/Message/ThrowableMessageTest.php +++ b/tests/Unit/Mapper/Tree/Message/ThrowableMessageTest.php @@ -4,8 +4,10 @@ namespace CuyZ\Valinor\Tests\Unit\Mapper\Tree\Message; +use CuyZ\Valinor\Mapper\Tree\Message\Message; use CuyZ\Valinor\Mapper\Tree\Message\ThrowableMessage; use PHPUnit\Framework\TestCase; +use RuntimeException; final class ThrowableMessageTest extends TestCase { @@ -14,9 +16,25 @@ public function test_properties_can_be_accessed(): void $message = 'some message'; $code = 'some code'; - $codedError = new ThrowableMessage($message, $code); + $codedError = ThrowableMessage::new($message, $code); self::assertSame($message, (string)$codedError); self::assertSame($code, $codedError->code()); } + + public function test_from_message_returns_message(): void + { + $message = new class ('some message') extends RuntimeException implements Message { }; + + self::assertSame($message, ThrowableMessage::from($message)); + } + + public function test_from_throwable_returns_message(): void + { + $message = new RuntimeException('some message', 1337); + $throwableMessage = ThrowableMessage::from($message); + + self::assertSame('some message', (string)$throwableMessage); + self::assertSame('1337', $throwableMessage->code()); // @phpstan-ignore-line + } } diff --git a/tests/Unit/Mapper/Tree/NodeTest.php b/tests/Unit/Mapper/Tree/NodeTest.php index ce7852cb..c08b5b79 100644 --- a/tests/Unit/Mapper/Tree/NodeTest.php +++ b/tests/Unit/Mapper/Tree/NodeTest.php @@ -145,8 +145,11 @@ public function test_node_with_messages_returns_node_with_messages(): void $nodeB = $nodeA->withMessage($messageA)->withMessage($messageB); self::assertNotSame($nodeA, $nodeB); - self::assertSame([$messageA, $messageB], $nodeB->messages()); self::assertTrue($nodeB->isValid()); + self::assertSame( + ['some message A', 'some message B'], + [(string)$nodeB->messages()[0], (string)$nodeB->messages()[1]] + ); } public function test_node_with_error_message_returns_invalid_node(): void @@ -158,7 +161,10 @@ public function test_node_with_error_message_returns_invalid_node(): void $nodeB = $nodeA->withMessage($message)->withMessage($errorMessage); self::assertNotSame($nodeA, $nodeB); - self::assertSame([$message, $errorMessage], $nodeB->messages()); self::assertFalse($nodeB->isValid()); + self::assertSame( + [(string)$message, (string)$errorMessage], + [(string)$nodeB->messages()[0], (string)$nodeB->messages()[1]] + ); } }