Valinor/tests/Unit/Mapper/Tree/NodeTest.php

171 lines
5.8 KiB
PHP
Raw Normal View History

2021-11-28 17:43:02 +01:00
<?php
declare(strict_types=1);
namespace CuyZ\Valinor\Tests\Unit\Mapper\Tree;
use CuyZ\Valinor\Mapper\Tree\Exception\CannotGetInvalidNodeValue;
use CuyZ\Valinor\Mapper\Tree\Exception\DuplicatedNodeChild;
use CuyZ\Valinor\Mapper\Tree\Exception\InvalidNodeValue;
use CuyZ\Valinor\Tests\Fake\Definition\FakeAttributes;
use CuyZ\Valinor\Tests\Fake\Mapper\FakeNode;
2021-11-28 17:43:02 +01:00
use CuyZ\Valinor\Tests\Fake\Mapper\Tree\Message\FakeErrorMessage;
use CuyZ\Valinor\Tests\Fake\Mapper\Tree\Message\FakeMessage;
use CuyZ\Valinor\Tests\Fake\Type\FakeType;
use PHPUnit\Framework\TestCase;
final class NodeTest extends TestCase
{
public function test_node_leaf_values_can_be_retrieved(): void
{
$type = FakeType::permissive();
2021-11-28 17:43:02 +01:00
$value = 'some node value';
$node = FakeNode::leaf($type, $value);
2021-11-28 17:43:02 +01:00
self::assertSame($type, $node->type());
self::assertSame($value, $node->value());
self::assertTrue($node->isRoot());
self::assertTrue($node->isValid());
}
public function test_node_leaf_with_incorrect_value_throws_exception(): void
{
$type = new FakeType();
$this->expectException(InvalidNodeValue::class);
$this->expectExceptionCode(1630678334);
$this->expectExceptionMessage("Value of type `string` is not accepted by type `$type`.");
FakeNode::leaf($type, 'foo');
2021-11-28 17:43:02 +01:00
}
public function test_node_branch_values_can_be_retrieved(): void
{
$typeChildA = FakeType::permissive();
$typeChildB = FakeType::permissive();
2021-11-28 17:43:02 +01:00
$attributesChildA = new FakeAttributes();
$attributesChildB = new FakeAttributes();
$children = FakeNode::branch([
'foo' => ['type' => $typeChildA, 'value' => 'foo', 'attributes' => $attributesChildA],
'bar' => ['type' => $typeChildB, 'value' => 'bar', 'attributes' => $attributesChildB],
])->children();
2021-11-28 17:43:02 +01:00
self::assertSame('foo', $children['foo']->name());
self::assertSame('foo', $children['foo']->path());
self::assertFalse($children['foo']->isRoot());
self::assertSame($attributesChildA, $children['foo']->attributes());
self::assertSame('bar', $children['bar']->name());
self::assertSame('bar', $children['bar']->path());
self::assertFalse($children['bar']->isRoot());
self::assertSame($attributesChildB, $children['bar']->attributes());
}
public function test_node_branch_with_duplicated_child_name_throws_exception(): void
{
$this->expectException(DuplicatedNodeChild::class);
$this->expectExceptionCode(1634045114);
$this->expectExceptionMessage('The child `foo` is duplicated in the branch.');
FakeNode::branch([
['name' => 'foo'],
['name' => 'foo'],
]);
2021-11-28 17:43:02 +01:00
}
public function test_node_branch_with_incorrect_value_throws_exception(): void
{
$type = new FakeType();
$this->expectException(InvalidNodeValue::class);
$this->expectExceptionCode(1630678334);
$this->expectExceptionMessage("Value of type `string` is not accepted by type `$type`.");
FakeNode::branch([], $type, 'foo');
2021-11-28 17:43:02 +01:00
}
public function test_node_error_values_can_be_retrieved(): void
{
$message = new FakeErrorMessage();
$node = FakeNode::error($message);
2021-11-28 17:43:02 +01:00
self::assertFalse($node->isValid());
self::assertSame((string)$message, (string)$node->messages()[0]);
2021-11-28 17:43:02 +01:00
}
public function test_get_value_from_invalid_node_throws_exception(): void
{
$node = FakeNode::error();
2021-11-28 17:43:02 +01:00
$this->expectException(CannotGetInvalidNodeValue::class);
$this->expectExceptionCode(1630680246);
$this->expectExceptionMessage('Trying to get value of an invalid node at path ``.');
$node->value();
}
public function test_branch_node_with_invalid_child_is_invalid(): void
{
$node = FakeNode::branch([
'foo' => [],
'bar' => ['message' => new FakeErrorMessage()],
]);
2021-11-28 17:43:02 +01:00
self::assertFalse($node->isValid());
}
public function test_node_with_value_returns_node_with_value(): void
{
$nodeA = FakeNode::any();
2021-11-28 17:43:02 +01:00
$nodeB = $nodeA->withValue('bar');
self::assertNotSame($nodeA, $nodeB);
self::assertSame('bar', $nodeB->value());
self::assertTrue($nodeB->isValid());
}
public function test_node_with_invalid_value_returns_invalid_node(): void
{
$type = FakeType::accepting('foo');
2021-11-28 17:43:02 +01:00
$this->expectException(InvalidNodeValue::class);
$this->expectExceptionCode(1630678334);
$this->expectExceptionMessage("Value of type `int` is not accepted by type `$type`.");
FakeNode::leaf($type, 'foo')->withValue(1337);
2021-11-28 17:43:02 +01:00
}
public function test_node_with_messages_returns_node_with_messages(): void
{
$messageA = new FakeMessage('some message A');
$messageB = new FakeMessage('some message B');
2021-11-28 17:43:02 +01:00
$nodeA = FakeNode::any();
2021-11-28 17:43:02 +01:00
$nodeB = $nodeA->withMessage($messageA)->withMessage($messageB);
self::assertNotSame($nodeA, $nodeB);
self::assertTrue($nodeB->isValid());
self::assertSame(
['some message A', 'some message B'],
[(string)$nodeB->messages()[0], (string)$nodeB->messages()[1]]
);
2021-11-28 17:43:02 +01:00
}
public function test_node_with_error_message_returns_invalid_node(): void
{
$message = new FakeMessage();
$errorMessage = new FakeErrorMessage();
$nodeA = FakeNode::any();
2021-11-28 17:43:02 +01:00
$nodeB = $nodeA->withMessage($message)->withMessage($errorMessage);
self::assertNotSame($nodeA, $nodeB);
self::assertFalse($nodeB->isValid());
self::assertSame(
[(string)$message, (string)$errorMessage],
[(string)$nodeB->messages()[0], (string)$nodeB->messages()[1]]
);
2021-11-28 17:43:02 +01:00
}
}