diff --git a/src/Mapper/Tree/Builder/InterfaceNodeBuilder.php b/src/Mapper/Tree/Builder/InterfaceNodeBuilder.php index 09597789..36afb2a5 100644 --- a/src/Mapper/Tree/Builder/InterfaceNodeBuilder.php +++ b/src/Mapper/Tree/Builder/InterfaceNodeBuilder.php @@ -74,7 +74,7 @@ public function build(Shell $shell, RootNodeBuilder $rootBuilder): TreeNode try { $classType = $this->implementations->implementation($className, $values); } catch (ObjectImplementationCallbackError $exception) { - throw UserlandError::from($exception->original()); + throw UserlandError::from($exception); } $class = $this->classDefinitionRepository->for($classType); diff --git a/src/Mapper/Tree/Builder/ObjectImplementations.php b/src/Mapper/Tree/Builder/ObjectImplementations.php index a1e9982c..bf92f657 100644 --- a/src/Mapper/Tree/Builder/ObjectImplementations.php +++ b/src/Mapper/Tree/Builder/ObjectImplementations.php @@ -6,14 +6,12 @@ use CuyZ\Valinor\Definition\FunctionDefinition; use CuyZ\Valinor\Definition\FunctionsContainer; -use CuyZ\Valinor\Mapper\Tree\Exception\InvalidAbstractObjectName; use CuyZ\Valinor\Mapper\Tree\Exception\InvalidResolvedImplementationValue; use CuyZ\Valinor\Mapper\Tree\Exception\MissingObjectImplementationRegistration; use CuyZ\Valinor\Mapper\Tree\Exception\ObjectImplementationCallbackError; use CuyZ\Valinor\Mapper\Tree\Exception\ObjectImplementationNotRegistered; use CuyZ\Valinor\Mapper\Tree\Exception\ResolvedImplementationIsNotAccepted; use CuyZ\Valinor\Type\ClassType; -use CuyZ\Valinor\Type\Parser\Exception\InvalidType; use CuyZ\Valinor\Type\Parser\TypeParser; use CuyZ\Valinor\Type\Type; use CuyZ\Valinor\Type\Types\ClassStringType; @@ -21,6 +19,8 @@ use CuyZ\Valinor\Type\Types\UnionType; use Exception; +use function assert; + /** @internal */ final class ObjectImplementations { @@ -30,12 +30,7 @@ final class ObjectImplementations public function __construct( private FunctionsContainer $functions, private TypeParser $typeParser - ) { - foreach ($functions as $name => $function) { - /** @var string $name */ - $this->implementations[$name] = $this->implementations($name); - } - } + ) {} public function has(string $name): bool { @@ -52,6 +47,9 @@ public function function(string $name): FunctionDefinition */ public function implementation(string $name, array $arguments): ClassType { + /** @infection-ignore-all / We cannot test the assignment */ + $this->implementations[$name] ??= $this->implementations($name); + $class = $this->call($name, $arguments); return $this->implementations[$name][$class] @@ -83,18 +81,14 @@ private function implementations(string $name): array { $function = $this->functions->get($name)->definition; - try { - $type = $this->typeParser->parse($name); - } catch (InvalidType) { - } + $type = $this->typeParser->parse($name); - if (! isset($type) || (! $type instanceof InterfaceType && ! $type instanceof ClassType)) { - throw new InvalidAbstractObjectName($name); - } + /** @infection-ignore-all */ + assert($type instanceof InterfaceType || $type instanceof ClassType); $classes = $this->implementationsByReturnSignature($name, $function); - if (empty($classes)) { + if ($classes === []) { throw new MissingObjectImplementationRegistration($name, $function); } diff --git a/tests/Integration/Cache/CacheInjectionTest.php b/tests/Integration/Cache/CacheInjectionTest.php index d55ed777..7f54e292 100644 --- a/tests/Integration/Cache/CacheInjectionTest.php +++ b/tests/Integration/Cache/CacheInjectionTest.php @@ -32,7 +32,7 @@ public function test_cache_entries_are_written_once_during_mapping(): void $files = $this->recursivelyFindPhpFiles($cacheDirectory); - self::assertCount(6, $files); + self::assertCount(4, $files); foreach ($files as $file) { $file->setContent($file->getContent() . "\n// generated value 1661895014"); diff --git a/tests/Integration/Cache/CacheWarmupTest.php b/tests/Integration/Cache/CacheWarmupTest.php index 17dc5a5c..3c4a8924 100644 --- a/tests/Integration/Cache/CacheWarmupTest.php +++ b/tests/Integration/Cache/CacheWarmupTest.php @@ -64,8 +64,8 @@ public function test_will_warmup_type_parser_cache_for_object_with_constructor() $mapper->warmup(ObjectToWarmupWithConstructors::class); $mapper->warmup(ObjectToWarmupWithConstructors::class, SomeObjectC::class); - self::assertSame(7, $this->cache->countEntries()); - self::assertSame(7, $this->cache->timeSetWasCalled()); + self::assertSame(6, $this->cache->countEntries()); + self::assertSame(6, $this->cache->timeSetWasCalled()); } public function test_will_warmup_type_parser_cache_for_interface(): void diff --git a/tests/Integration/Mapping/InterfaceInferringMappingTest.php b/tests/Integration/Mapping/InterfaceInferringMappingTest.php index 41358cfc..a4a8457d 100644 --- a/tests/Integration/Mapping/InterfaceInferringMappingTest.php +++ b/tests/Integration/Mapping/InterfaceInferringMappingTest.php @@ -6,13 +6,11 @@ use CuyZ\Valinor\Mapper\MappingError; use CuyZ\Valinor\Mapper\Tree\Exception\CannotResolveObjectType; -use CuyZ\Valinor\Mapper\Tree\Exception\InvalidAbstractObjectName; use CuyZ\Valinor\Mapper\Tree\Exception\InvalidResolvedImplementationValue; use CuyZ\Valinor\Mapper\Tree\Exception\MissingObjectImplementationRegistration; use CuyZ\Valinor\Mapper\Tree\Exception\ObjectImplementationCallbackError; use CuyZ\Valinor\Mapper\Tree\Exception\ObjectImplementationNotRegistered; use CuyZ\Valinor\Mapper\Tree\Exception\ResolvedImplementationIsNotAccepted; -use CuyZ\Valinor\Tests\Fake\Mapper\Tree\Message\FakeErrorMessage; use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\A\ClassThatInheritsInterfaceA; use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\B\ClassThatInheritsInterfaceB; use CuyZ\Valinor\Tests\Fixture\Object\InterfaceWithDifferentNamespaces\ClassWithBothInterfaces; @@ -279,30 +277,6 @@ public function test_object_implementation_callback_error_throws_exception(): vo ->map(DateTimeInterface::class, []); } - public function test_invalid_abstract_object_name_throws_exception(): void - { - $this->expectException(InvalidAbstractObjectName::class); - $this->expectExceptionCode(1653990369); - $this->expectExceptionMessage('Invalid interface or class name `invalid type`.'); - - $this->mapperBuilder() - ->infer('invalid type', fn () => stdClass::class) // @phpstan-ignore-line - ->mapper() - ->map(stdClass::class, []); - } - - public function test_invalid_abstract_object_type_throws_exception(): void - { - $this->expectException(InvalidAbstractObjectName::class); - $this->expectExceptionCode(1653990369); - $this->expectExceptionMessage('Invalid interface or class name `string`.'); - - $this->mapperBuilder() - ->infer('string', fn () => stdClass::class) // @phpstan-ignore-line - ->mapper() - ->map(stdClass::class, []); - } - public function test_missing_object_implementation_registration_throws_exception(): void { $this->expectException(MissingObjectImplementationRegistration::class); @@ -315,7 +289,7 @@ public function test_missing_object_implementation_registration_throws_exception fn (string $type) => SomeClassThatInheritsInterfaceA::class ) ->mapper() - ->map(SomeInterface::class, []); + ->map(SomeInterface::class, 'foo'); } public function test_invalid_union_object_implementation_registration_throws_exception(): void @@ -330,7 +304,7 @@ public function test_invalid_union_object_implementation_registration_throws_exc fn (string $value): string|int => $value === 'foo' ? 'foo' : 42 ) ->mapper() - ->map(SomeInterface::class, []); + ->map(SomeInterface::class, 'foo'); } public function test_invalid_class_string_object_implementation_registration_throws_exception(): void @@ -402,25 +376,6 @@ public function test_invalid_source_value_throws_exception(): void } } - public function test_exception_thrown_is_caught_and_throws_message_exception(): void - { - try { - $this->mapperBuilder() - ->infer( - DateTimeInterface::class, - /** @return class-string */ - fn (string $value) => throw new FakeErrorMessage('some error message', 1645303304) - ) - ->mapper() - ->map(DateTimeInterface::class, 'foo'); - } catch (MappingError $exception) { - $error = $exception->node()->messages()[0]; - - self::assertSame('1645303304', $error->code()); - self::assertSame('some error message', (string)$error); - } - } - public function test_superfluous_values_throws_exception(): void { try {