diff --git a/annotated-container-definition.xsd b/annotated-container-definition.xsd index 77c06fa1..ed251b09 100644 --- a/annotated-container-definition.xsd +++ b/annotated-container-definition.xsd @@ -43,12 +43,9 @@ - - - - + @@ -104,32 +101,33 @@ - - - - + - + + + + + + + + + - + - - - - - - - - - - - - + + + + + + + + diff --git a/composer.json b/composer.json index d56cdd53..a1972d6c 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ } ], "require": { - "php": "^8.1", + "php": "^8.2", "ext-dom": "*", "ext-libxml": "*", "composer-runtime-api": "^2.2", @@ -21,8 +21,7 @@ "cspray/annotated-target": "^v2.0.0.alpha", "cspray/architectural-decision": "^3.0.0.alpha", "cspray/precision-stopwatch": "^0.2.0", - "cspray/typiphy": "^0.4", - "nikic/php-parser": "^4.19", + "nikic/php-parser": "^5.3", "psr/container": "^2.0" }, "require-dev": { @@ -40,7 +39,8 @@ }, "files": [ "src/Function/auto-wired-parameters.php", - "src/Function/definitions.php" + "src/Function/definitions.php", + "src/Function/types.php" ] }, "autoload-dev": { diff --git a/docs/how-to/01-add-third-party-services.md b/docs/how-to/01-add-third-party-services.md index cfaf337b..ac65328b 100644 --- a/docs/how-to/01-add-third-party-services.md +++ b/docs/how-to/01-add-third-party-services.md @@ -49,7 +49,7 @@ class ThirdPartyServicesProvider implements DefinitionProvider { public function consume(DefinitionProviderContext $context) : void { $context->addServiceDefinition(service($loggerType = objectType(LoggerInterface::class))); $context->addServiceDelegateDefinition( - serviceDelegate($loggerType, objectType(MonologLoggerFactory::class), 'createLogger') + serviceDelegate(objectType(MonologLoggerFactory::class), 'createLogger') ); $context->addServicePrepareDefinition( servicePrepare( diff --git a/docs/references/02-functional-api.md b/docs/references/02-functional-api.md index b3d16db7..e615c138 100644 --- a/docs/references/02-functional-api.md +++ b/docs/references/02-functional-api.md @@ -23,7 +23,6 @@ This document lists the functions for each purpose. ) : \Cspray\AnnotatedContainer\Definition\AliasDefinition; \Cspray\AnnotatedContainer\serviceDelegate( - \Cspray\Typiphy\ObjectType $service, \Cspray\Typiphy\ObjectType $factoryClass, string $factoryMethod ) : \Cspray\AnnotatedContainer\Definition\ServiceDelegateDefinition; diff --git a/known-issues.xml b/known-issues.xml index 742aea98..119a3900 100644 --- a/known-issues.xml +++ b/known-issues.xml @@ -1,26 +1,95 @@ + + + + + + + + + ]]> + service; + } + + public function definition() : ServiceDefinition { + return $this->definition; + } + }]]> + + + + + + + + + + + + + + + + + + + valueType->name()]]> + + + + + + + + + abstractService()->name()]]> + class()->name()]]> + concreteService()->name()]]> + delegateType()->name()]]> + delegateType()->name()]]> + delegateType()->name()]]> + service()->name()]]> + serviceType()->name()]]> + serviceType()->name()]]> + type()->name()]]> + type()->name()]]> + type()->name()]]> + valueType->name()]]> + + + name()]]> + name()]]]> + @@ -31,16 +100,298 @@ + + + + + + + + class($this->type)]]> + + + + + + abstractService()->name()]]> + class()->name()]]> + service()->name()]]> + + + + + name()]]> + name()]]]> + + + + + + + + + + valueType->name()]]> + + + + + name()]]> + + name()]]> + + + + + + + + + + + typeFactory->class($reflection->getDeclaringClass()->getName())]]> + + + delegateMethod]]> + method]]> + parameter]]> + + + + + + + + + + + + + + + + + + + + + + + + nodeValue]]> + types()->class($domElement->nodeValue)]]> + types()->fromName($domElement->nodeValue)]]> + + + types()->class($domElement->nodeValue), + iterator_to_array($xpath->query('cd:valueType/cd:typeIntersect/*', $injectDefinition)) + )]]> + types()->class($domElement->nodeValue), + iterator_to_array($xpath->query('cd:valueType/cd:typeIntersect/*', $injectDefinition)) + )]]> + types()->class($domElement->nodeValue), + iterator_to_array($xpath->query('cd:valueType/cd:typeIntersect/*', $injectDefinition)) + )]]> + class($abstract)]]> + class($concrete)]]> + class($delegateType)]]> + class($service)]]> + class($serviceType)]]> + + + + + + + + + + + + + + + + nodeValue]]> + nodeValue]]> + query('cd:attribute/text()', $delegateDefinition)[0]?->nodeValue]]> + query('cd:attribute/text()', $prepareDefinition)[0]?->nodeValue]]> + query('cd:attribute/text()', $serviceDefinition)[0]?->nodeValue]]> + + + + + + + + + + + + + + + + + + + + + + + + name]]> + profiles]]> + + + + + + + + + ($attribute instanceof ServicePrepareFromFunctionalApi ? 'Call to servicePrepare() in DefinitionProvider' : 'Attributed with ' . $attribute::class) . PHP_EOL]]> + + + + + type()->name()]]> + + + + + + + + $this->array(), + 'bool' => $this->bool(), + 'float' => $this->float(), + 'int' => $this->int(), + 'mixed' => $this->mixed(), + 'never' => $this->never(), + 'null' => $this->null(), + 'object' => $this->object(), + 'self' => $this->self(), + 'static' => $this->static(), + 'string' => $this->string(), + 'void' => $this->void(), + default => $this->class($name), + }]]> + + + + + + name]]> + name]]> + types]]> + types]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + createType('array')]]> + createType('array')]]> + createType('bool')]]> + createType('bool')]]> + createType('float')]]> + createType('float')]]> + createType('int')]]> + createType('int')]]> + createType('mixed')]]> + createType('mixed')]]> + createType('never')]]> + createType('never')]]> + createType('null')]]> + createType('null')]]> + createType('object')]]> + createType('object')]]> + createType('self')]]> + createType('self')]]> + createType('static')]]> + createType('static')]]> + createType('string')]]> + createType('string')]]> + createType('void')]]> + createType('void')]]> + + + + ]]> + + + + + + + + + + + + + + + + getName()]]> + + + + + + + + + + + $attributeType->value, AttributeType::cases())]]> + diff --git a/phpunit.xml b/phpunit.xml index 247fc4d7..493e4762 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -20,8 +20,8 @@ - diff --git a/psalm.xml b/psalm.xml index fb781091..e83fceb2 100644 --- a/psalm.xml +++ b/psalm.xml @@ -29,13 +29,7 @@ - - - - - - diff --git a/src/Bootstrap/Bootstrap.php b/src/Bootstrap/Bootstrap.php index dc542414..beffab3b 100644 --- a/src/Bootstrap/Bootstrap.php +++ b/src/Bootstrap/Bootstrap.php @@ -11,7 +11,6 @@ use Cspray\AnnotatedContainer\Filesystem\PhpFunctionsFilesystem; use Cspray\AnnotatedContainer\Profiles; use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalyzer; -use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetDefinitionConverter; use Cspray\AnnotatedContainer\StaticAnalysis\CacheAwareContainerDefinitionAnalyzer; use Cspray\AnnotatedContainer\StaticAnalysis\ContainerDefinitionAnalysisOptions; use Cspray\AnnotatedTarget\PhpParserAnnotatedTargetParser; @@ -118,7 +117,6 @@ private function runStaticAnalysis( ) : ContainerDefinition { $analyzer = new AnnotatedTargetContainerDefinitionAnalyzer( new PhpParserAnnotatedTargetParser(), - new AnnotatedTargetDefinitionConverter(), $this->emitter ); $cache = $configuration->cache(); diff --git a/src/Bootstrap/ServiceWiringListener.php b/src/Bootstrap/ServiceWiringListener.php index 21bc6e59..d9986b11 100644 --- a/src/Bootstrap/ServiceWiringListener.php +++ b/src/Bootstrap/ServiceWiringListener.php @@ -75,12 +75,10 @@ public function servicesWithAttribute(string $attributeType) : array { * @return ServiceFromServiceDefinition */ private function createServiceFromServiceDefinition(object $service, ServiceDefinition $serviceDefinition) : ServiceFromServiceDefinition { - $serviceFromDefinition = - /** * @implements ServiceFromServiceDefinition */ - new class($service, $serviceDefinition) implements ServiceFromServiceDefinition { + return new class($service, $serviceDefinition) implements ServiceFromServiceDefinition { public function __construct( private readonly object $service, private readonly ServiceDefinition $definition @@ -95,9 +93,6 @@ public function definition() : ServiceDefinition { return $this->definition; } }; - - /** @var ServiceFromServiceDefinition $serviceFromDefinition */ - return $serviceFromDefinition; } }; $this->wireServices($container, $serviceGatherer); diff --git a/src/Cli/Command/BuildCommand.php b/src/Cli/Command/BuildCommand.php index 0c4967a5..cac95d1b 100644 --- a/src/Cli/Command/BuildCommand.php +++ b/src/Cli/Command/BuildCommand.php @@ -8,7 +8,6 @@ use Cspray\AnnotatedContainer\Definition\Cache\ContainerDefinitionCache; use Cspray\AnnotatedContainer\Event\Emitter; use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalyzer; -use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetDefinitionConverter; use Cspray\AnnotatedContainer\StaticAnalysis\CacheAwareContainerDefinitionAnalyzer; use Cspray\AnnotatedContainer\StaticAnalysis\ContainerDefinitionAnalysisOptions; use Cspray\AnnotatedContainer\StaticAnalysis\ContainerDefinitionAnalyzer; @@ -75,7 +74,6 @@ private function analyzer() : ContainerDefinitionAnalyzer { return new CacheAwareContainerDefinitionAnalyzer( new AnnotatedTargetContainerDefinitionAnalyzer( new PhpParserAnnotatedTargetParser(), - new AnnotatedTargetDefinitionConverter(), new Emitter() ), $this->cache, diff --git a/src/Cli/Command/ValidateCommand.php b/src/Cli/Command/ValidateCommand.php index dca95bc7..5f79b27b 100644 --- a/src/Cli/Command/ValidateCommand.php +++ b/src/Cli/Command/ValidateCommand.php @@ -22,7 +22,6 @@ use Cspray\AnnotatedContainer\LogicalConstraint\LogicalConstraintViolationType; use Cspray\AnnotatedContainer\Profiles; use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalyzer; -use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetDefinitionConverter; use Cspray\AnnotatedTarget\PhpParserAnnotatedTargetParser; final class ValidateCommand implements Command { @@ -122,7 +121,6 @@ public function handle(Input $input, TerminalOutput $output) : int { $analyzer = new AnnotatedTargetContainerDefinitionAnalyzer( new PhpParserAnnotatedTargetParser(), - new AnnotatedTargetDefinitionConverter(), new Emitter() ); $containerDefinition = $analyzer->analyze( diff --git a/src/ContainerFactory/AbstractContainerFactory.php b/src/ContainerFactory/AbstractContainerFactory.php index d870a9f6..4092761b 100644 --- a/src/ContainerFactory/AbstractContainerFactory.php +++ b/src/ContainerFactory/AbstractContainerFactory.php @@ -117,7 +117,7 @@ final protected function injectDefinitionValue(InjectDefinition $definition) : m $value->type(), $type ); - } elseif ($type instanceof ObjectType && !is_a($definition->type()->name(), UnitEnum::class, true)) { + } elseif ((class_exists($definition->type()->name()) || interface_exists($definition->type()->name())) && !is_a($definition->type()->name(), UnitEnum::class, true)) { assert(is_string($value) && $value !== ''); $value = new ContainerReference($value, $type); } diff --git a/src/ContainerFactory/AliasResolution/AliasDefinitionResolver.php b/src/ContainerFactory/AliasResolution/AliasDefinitionResolver.php index f8fcfa1d..5596231a 100644 --- a/src/ContainerFactory/AliasResolution/AliasDefinitionResolver.php +++ b/src/ContainerFactory/AliasResolution/AliasDefinitionResolver.php @@ -3,12 +3,12 @@ namespace Cspray\AnnotatedContainer\ContainerFactory\AliasResolution; use Cspray\AnnotatedContainer\Definition\ContainerDefinition; -use Cspray\Typiphy\ObjectType; +use Cspray\AnnotatedContainer\Reflection\Type; interface AliasDefinitionResolver { public function resolveAlias( ContainerDefinition $containerDefinition, - ObjectType $abstractService + Type $abstractService ) : AliasDefinitionResolution; } diff --git a/src/ContainerFactory/AliasResolution/StandardAliasDefinitionResolver.php b/src/ContainerFactory/AliasResolution/StandardAliasDefinitionResolver.php index d3b1a626..b7fc400e 100644 --- a/src/ContainerFactory/AliasResolution/StandardAliasDefinitionResolver.php +++ b/src/ContainerFactory/AliasResolution/StandardAliasDefinitionResolver.php @@ -4,14 +4,13 @@ use Cspray\AnnotatedContainer\Definition\AliasDefinition; use Cspray\AnnotatedContainer\Definition\ContainerDefinition; -use Cspray\AnnotatedContainer\Definition\ServiceDefinition; -use Cspray\Typiphy\ObjectType; +use Cspray\AnnotatedContainer\Reflection\Type; final class StandardAliasDefinitionResolver implements AliasDefinitionResolver { public function resolveAlias( ContainerDefinition $containerDefinition, - ObjectType $abstractService + Type $abstractService ) : AliasDefinitionResolution { if ($this->isServiceDelegate($containerDefinition, $abstractService)) { $definition = null; @@ -69,7 +68,7 @@ public function aliasDefinition() : ?AliasDefinition { }; } - private function isServiceDelegate(ContainerDefinition $containerDefinition, ObjectType $service) : bool { + private function isServiceDelegate(ContainerDefinition $containerDefinition, Type $service) : bool { foreach ($containerDefinition->serviceDelegateDefinitions() as $serviceDelegateDefinition) { if ($serviceDelegateDefinition->serviceType()->name() === $service->name()) { return true; @@ -80,7 +79,7 @@ private function isServiceDelegate(ContainerDefinition $containerDefinition, Obj } /** - * @return list + * @return list */ private function primaryServiceNames(ContainerDefinition $containerDefinition) : array { $names = []; diff --git a/src/ContainerFactory/AurynContainerFactory.php b/src/ContainerFactory/AurynContainerFactory.php index 0e5f15e8..4e9957d9 100644 --- a/src/ContainerFactory/AurynContainerFactory.php +++ b/src/ContainerFactory/AurynContainerFactory.php @@ -195,7 +195,6 @@ private function convertAutowireableParameterSet(AutowireableParameterSet $param foreach ($parameters as $parameter) { if ($parameter->isServiceIdentifier()) { $parameterValue = $parameter->value(); - assert($parameterValue instanceof ObjectType); /** @var non-empty-string $value */ $value = $parameterValue->name(); diff --git a/src/ContainerFactory/AurynContainerFactoryState.php b/src/ContainerFactory/AurynContainerFactoryState.php index f7b0d40c..a4c8f8b0 100644 --- a/src/ContainerFactory/AurynContainerFactoryState.php +++ b/src/ContainerFactory/AurynContainerFactoryState.php @@ -4,7 +4,7 @@ use Auryn\Injector; use Cspray\AnnotatedContainer\Definition\ContainerDefinition; -use Cspray\Typiphy\ObjectType; +use Cspray\AnnotatedContainer\Reflection\Type; final class AurynContainerFactoryState implements ContainerFactoryState { @@ -15,7 +15,7 @@ final class AurynContainerFactoryState implements ContainerFactoryState { public readonly Injector $injector; /** - * @var array + * @var array */ private array $nameTypeMap = []; @@ -67,18 +67,18 @@ public function addMethodInject(string $class, string $method, string $param, mi /** * @param non-empty-string $name - * @param ObjectType $type + * @param Type $type * @return void */ - public function addNameType(string $name, ObjectType $type) : void { + public function addNameType(string $name, Type $type) : void { $this->nameTypeMap[$name] = $type; } /** * @param non-empty-string $name - * @return ObjectType|null + * @return Type|null */ - public function typeForName(string $name) : ?ObjectType { + public function typeForName(string $name) : ?Type { return $this->nameTypeMap[$name] ?? null; } } diff --git a/src/ContainerFactory/ContainerReference.php b/src/ContainerFactory/ContainerReference.php index 0f9030ba..0bc96896 100644 --- a/src/ContainerFactory/ContainerReference.php +++ b/src/ContainerFactory/ContainerReference.php @@ -2,7 +2,7 @@ namespace Cspray\AnnotatedContainer\ContainerFactory; -use Cspray\Typiphy\ObjectType; +use Cspray\AnnotatedContainer\Reflection\Type; /** * @internal @@ -11,11 +11,11 @@ final class ContainerReference { /** * @param non-empty-string $name - * @param ObjectType $type + * @param Type $type */ public function __construct( public readonly string $name, - public readonly ObjectType $type + public readonly Type $type ) { } } diff --git a/src/ContainerFactory/EnvironmentParameterStore.php b/src/ContainerFactory/EnvironmentParameterStore.php index ab57f9ea..c1d3beed 100644 --- a/src/ContainerFactory/EnvironmentParameterStore.php +++ b/src/ContainerFactory/EnvironmentParameterStore.php @@ -3,10 +3,9 @@ namespace Cspray\AnnotatedContainer\ContainerFactory; use Cspray\AnnotatedContainer\Exception\EnvironmentVarNotFound; -use Cspray\AnnotatedContainer\Exception\InvalidParameterException; -use Cspray\Typiphy\Type; -use Cspray\Typiphy\TypeIntersect; -use Cspray\Typiphy\TypeUnion; +use Cspray\AnnotatedContainer\Reflection\Type; +use Cspray\AnnotatedContainer\Reflection\TypeUnion; +use Cspray\AnnotatedContainer\Reflection\TypeIntersect; final class EnvironmentParameterStore implements ParameterStore { diff --git a/src/ContainerFactory/IlluminateContainerFactory.php b/src/ContainerFactory/IlluminateContainerFactory.php index 89414992..ae2ae903 100644 --- a/src/ContainerFactory/IlluminateContainerFactory.php +++ b/src/ContainerFactory/IlluminateContainerFactory.php @@ -20,6 +20,7 @@ use Cspray\AnnotatedContainer\Profiles; use Cspray\Typiphy\ObjectType; use Illuminate\Contracts\Container\Container; +use function Cspray\AnnotatedContainer\Reflection\types; use function Cspray\Typiphy\arrayType; use function Cspray\Typiphy\objectType; @@ -163,7 +164,7 @@ static function(Container $container) use($target, $delegateInfo) : object { ->needs($value->type->name()) ->give($value->name); } elseif ($value instanceof ServiceCollectorReference) { - if ($value->collectionType === arrayType()) { + if ($value->collectionType === types()->array()) { $paramIdentifier = sprintf('$%s', $param); } else { $paramIdentifier = $value->collectionType->name(); diff --git a/src/ContainerFactory/ListOf.php b/src/ContainerFactory/ListOf.php index ce4f12ea..1422ee34 100644 --- a/src/ContainerFactory/ListOf.php +++ b/src/ContainerFactory/ListOf.php @@ -2,7 +2,7 @@ namespace Cspray\AnnotatedContainer\ContainerFactory; -use Cspray\Typiphy\ObjectType; +use Cspray\AnnotatedContainer\Reflection\Type; /** * @template ServiceType of object @@ -10,7 +10,7 @@ */ interface ListOf { - public function type() : ObjectType; + public function type() : Type; /**' * @psalm-param list $servicesOfType diff --git a/src/ContainerFactory/ListOfAsArray.php b/src/ContainerFactory/ListOfAsArray.php index ee25dac3..69356436 100644 --- a/src/ContainerFactory/ListOfAsArray.php +++ b/src/ContainerFactory/ListOfAsArray.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\ContainerFactory; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; /** * @template ItemType of object @@ -19,8 +19,8 @@ public function __construct( ) { } - public function type() : ObjectType { - return objectType($this->type); + public function type() : Type { + return types()->class($this->type); } public function toCollection(array $servicesOfType) : array { diff --git a/src/ContainerFactory/ParameterStore.php b/src/ContainerFactory/ParameterStore.php index 82a8a15d..833bde61 100644 --- a/src/ContainerFactory/ParameterStore.php +++ b/src/ContainerFactory/ParameterStore.php @@ -2,9 +2,9 @@ namespace Cspray\AnnotatedContainer\ContainerFactory; -use Cspray\Typiphy\Type; -use Cspray\Typiphy\TypeIntersect; -use Cspray\Typiphy\TypeUnion; +use Cspray\AnnotatedContainer\Reflection\Type; +use Cspray\AnnotatedContainer\Reflection\TypeIntersect; +use Cspray\AnnotatedContainer\Reflection\TypeUnion; /** * Defines an implementation that can programmatically determine values that should be used with Inject definitions. diff --git a/src/ContainerFactory/PhpDiContainerFactory.php b/src/ContainerFactory/PhpDiContainerFactory.php index bda0180a..4fa1c576 100644 --- a/src/ContainerFactory/PhpDiContainerFactory.php +++ b/src/ContainerFactory/PhpDiContainerFactory.php @@ -194,7 +194,6 @@ private function convertAutowireableParameterSet(AutowireableParameterSet $param /** @var Reference|mixed $value */ $value = $parameter->value(); if ($parameter->isServiceIdentifier()) { - assert($value instanceof ObjectType); $value = get($value->name()); } diff --git a/src/ContainerFactory/ServiceCollectorReference.php b/src/ContainerFactory/ServiceCollectorReference.php index c88929d3..83e6b7e6 100644 --- a/src/ContainerFactory/ServiceCollectorReference.php +++ b/src/ContainerFactory/ServiceCollectorReference.php @@ -2,10 +2,9 @@ namespace Cspray\AnnotatedContainer\ContainerFactory; -use Cspray\Typiphy\ObjectType; -use Cspray\Typiphy\Type; -use Cspray\Typiphy\TypeIntersect; -use Cspray\Typiphy\TypeUnion; +use Cspray\AnnotatedContainer\Reflection\Type; +use Cspray\AnnotatedContainer\Reflection\TypeIntersect; +use Cspray\AnnotatedContainer\Reflection\TypeUnion; /** * @internal @@ -14,7 +13,7 @@ final class ServiceCollectorReference { public function __construct( public readonly ListOf $listOf, - public readonly ObjectType $valueType, + public readonly Type $valueType, public readonly Type|TypeUnion|TypeIntersect $collectionType ) { } diff --git a/src/Definition/AliasDefinition.php b/src/Definition/AliasDefinition.php index d58260aa..56842f2e 100644 --- a/src/Definition/AliasDefinition.php +++ b/src/Definition/AliasDefinition.php @@ -2,26 +2,20 @@ namespace Cspray\AnnotatedContainer\Definition; -use Cspray\Typiphy\ObjectType; +use Cspray\AnnotatedContainer\Reflection\Type; /** * Define the concrete Service that should be used when constructing an abstract Service. - * - * @see AliasDefinitionBuilder */ interface AliasDefinition { /** * An abstract Service used by your application but cannot be constructed directly. - * - * @return ObjectType */ - public function abstractService() : ObjectType; + public function abstractService() : Type; /** * The concrete Service that should be used where your applications requires the corresponding abstract Service. - * - * @return ObjectType */ - public function concreteService() : ObjectType; + public function concreteService() : Type; } diff --git a/src/Definition/AliasDefinitionBuilder.php b/src/Definition/AliasDefinitionBuilder.php deleted file mode 100644 index 05c29a79..00000000 --- a/src/Definition/AliasDefinitionBuilder.php +++ /dev/null @@ -1,66 +0,0 @@ -abstractType = $serviceDefinition; - return $instance; - } - - /** - * Define the concrete Service that acts as an alias for the given abstract Service. - * - * This method is immutable and a new AliasDefinitionBuilder will be returned. - * - * @param ObjectType $serviceDefinition - * @return $this - */ - public function withConcrete(ObjectType $serviceDefinition) : self { - $instance = clone $this; - $instance->concreteType = $serviceDefinition; - return $instance; - } - - /** - * Returns an AliasDefinition with the provided abstract and concrete Services. - * - * @return AliasDefinition - */ - public function build() : AliasDefinition { - return new class($this->abstractType, $this->concreteType) implements AliasDefinition { - public function __construct( - private readonly ObjectType $abstractService, - private readonly ObjectType $concreteService - ) { - } - - public function abstractService() : ObjectType { - return $this->abstractService; - } - - public function concreteService() : ObjectType { - return $this->concreteService; - } - }; - } -} diff --git a/src/Definition/DefinitionFactory.php b/src/Definition/DefinitionFactory.php new file mode 100644 index 00000000..353493dc --- /dev/null +++ b/src/Definition/DefinitionFactory.php @@ -0,0 +1,379 @@ +typeFactory = types(); + } + + public function serviceDefinitionFromAnnotatedTarget(AnnotatedTarget $annotatedTarget) : ServiceDefinition { + $attribute = $annotatedTarget->attributeInstance(); + if (!$attribute instanceof ServiceAttribute) { + throw ServiceAttributeRequired::fromNotServiceAttributeProvidedInAnnotatedTarget( + $attribute::class + ); + } + + $reflection = $annotatedTarget->targetReflection(); + if (!$reflection instanceof ReflectionClass) { + throw WrongTargetForServiceAttribute::fromServiceAttributeNotTargetingClass($reflection); + } + + return $this->serviceDefinitionFromReflectionClassAndAttribute($reflection, $attribute); + } + + public function serviceDefinitionFromObjectTypeAndAttribute( + Type $objectType, + ServiceAttribute $serviceAttribute + ) : ServiceDefinition { + $reflection = new ReflectionClass($objectType->name()); + + return $this->serviceDefinitionFromReflectionClassAndAttribute($reflection, $serviceAttribute); + } + + private function serviceDefinitionFromReflectionClassAndAttribute( + ReflectionClass $reflection, + ServiceAttribute $attribute, + ) : ServiceDefinition { + $objectType = $this->typeFactory->class($reflection->getName()); + $isAbstract = $reflection->isInterface() || $reflection->isAbstract(); + + return $this->serviceDefinitionFromManualSetup( + $objectType, + $attribute, + !$isAbstract + ); + } + + public function serviceDefinitionFromManualSetup( + Type $type, + ServiceAttribute $attribute, + bool $isConcrete + ) : ServiceDefinition { + return new class($type, $attribute, $isConcrete) implements ServiceDefinition { + + public function __construct( + private readonly Type $type, + private readonly ServiceAttribute $attribute, + private readonly bool $isConcrete, + ) { + } + + public function type() : Type { + return $this->type; + } + + public function name() : ?string { + return $this->attribute->name(); + } + + public function profiles() : array { + $profiles = $this->attribute->profiles(); + if ($profiles === []) { + $profiles = ['default']; + } + + return $profiles; + } + + public function isPrimary() : bool { + return $this->attribute->isPrimary(); + } + + public function isConcrete() : bool { + return $this->isConcrete; + } + + public function isAbstract() : bool { + return $this->isConcrete() === false; + } + + public function attribute() : ServiceAttribute { + return $this->attribute; + } + }; + } + + public function servicePrepareDefinitionFromAnnotatedTarget(AnnotatedTarget $annotatedTarget) : ServicePrepareDefinition { + $attribute = $annotatedTarget->attributeInstance(); + if (!$attribute instanceof ServicePrepareAttribute) { + throw ServicePrepareAttributeRequired::fromNotServicePrepareAttributeInAnnotatedTarget($attribute::class); + } + + $reflection = $annotatedTarget->targetReflection(); + if (!$reflection instanceof ReflectionMethod) { + throw WrongTargetForServicePrepareAttribute::fromServicePrepareAttributeNotTargetingMethod($reflection); + } + + return $this->servicePrepareDefinitionFromReflectionMethodAndAttribute($reflection, $attribute); + } + + public function servicePrepareDefinitionFromClassMethodAndAttribute( + Type $objectType, + string $method, + ServicePrepareAttribute $attribute, + ) : ServicePrepareDefinition { + return new class($objectType, $method, $attribute) implements ServicePrepareDefinition { + /** + * @param Type $service + * @param non-empty-string $method + * @param ServicePrepareAttribute $attribute + */ + public function __construct( + private readonly Type $service, + private readonly string $method, + private readonly ServicePrepareAttribute $attribute, + ) { + } + + public function service() : Type { + return $this->service; + } + + /** + * @return non-empty-string + */ + public function methodName() : string { + return $this->method; + } + + public function attribute() : ServicePrepareAttribute { + return $this->attribute; + } + }; + } + + private function servicePrepareDefinitionFromReflectionMethodAndAttribute( + ReflectionMethod $reflection, + ServicePrepareAttribute $attribute + ) : ServicePrepareDefinition { + return $this->servicePrepareDefinitionFromClassMethodAndAttribute( + $this->typeFactory->class($reflection->getDeclaringClass()->getName()), + $reflection->getName(), + $attribute, + ); + } + + public function serviceDelegateDefinitionFromAnnotatedTarget(AnnotatedTarget $target) : ServiceDelegateDefinition { + $attribute = $target->attributeInstance(); + if (!$attribute instanceof ServiceDelegateAttribute) { + throw ServiceDelegateAttributeRequired::fromNotServiceDelegateAttributeInAnnotatedTarget($attribute::class); + } + + $reflection = $target->targetReflection(); + if (!$reflection instanceof ReflectionMethod) { + throw WrongTargetForServiceDelegateAttribute::fromServiceDelegateAttributeNotTargetingMethod($reflection); + } + + return $this->serviceDelegateDefinitionFromReflectionMethodAndAttribute($reflection, $attribute); + } + + public function serviceDelegateDefinitionFromClassMethodAndAttribute( + Type $delegateType, + string $delegateMethod, + ServiceDelegateAttribute $attribute, + ) : ServiceDelegateDefinition { + $reflection = new ReflectionMethod($delegateType->name(), $delegateMethod); + + return $this->serviceDelegateDefinitionFromReflectionMethodAndAttribute($reflection, $attribute); + } + + private function serviceDelegateDefinitionFromReflectionMethodAndAttribute( + ReflectionMethod $reflection, + ServiceDelegateAttribute $attribute + ) : ServiceDelegateDefinition { + $delegateType = $this->typeFactory->class($reflection->getDeclaringClass()->getName()); + $delegateMethod = $reflection->getName(); + $returnType = $reflection->getReturnType(); + + if ($returnType === null) { + throw ServiceDelegateReturnsUnknownType::fromServiceDelegateHasNoReturnType($delegateType, $delegateMethod); + } + + if ($returnType instanceof ReflectionIntersectionType) { + throw ServiceDelegateReturnsIntersectionType::fromServiceDelegateCreatesIntersectionType($delegateType, $delegateMethod); + } + + if ($returnType instanceof ReflectionUnionType) { + throw ServiceDelegateReturnsUnionType::fromServiceDelegateReturnsUnionType($delegateType, $delegateMethod); + } + + $returnTypeName = $returnType->getName(); + if ($returnTypeName === 'self') { + $returnTypeName = $delegateType->name(); + } + + if (!interface_exists($returnTypeName) && !class_exists($returnTypeName)) { + throw ServiceDelegateReturnsScalarType::fromServiceDelegateCreatesScalarType($delegateType, $delegateMethod); + } + + $serviceType = $this->typeFactory->class($returnTypeName); + + return new class( + $delegateType, + $delegateMethod, + $serviceType, + $attribute + ) implements ServiceDelegateDefinition { + + public function __construct( + private readonly Type $delegateType, + private readonly string $delegateMethod, + private readonly Type $serviceType, + private readonly ServiceDelegateAttribute $attribute, + ) { + } + + public function delegateType() : Type { + return $this->delegateType; + } + + public function delegateMethod() : string { + return $this->delegateMethod; + } + + public function serviceType() : Type { + return $this->serviceType; + } + + public function attribute() : ServiceDelegateAttribute { + return $this->attribute; + } + }; + } + + public function injectDefinitionFromAnnotatedTarget(AnnotatedTarget $target) : InjectDefinition { + $attribute = $target->attributeInstance(); + if (!$attribute instanceof InjectAttribute) { + throw InjectAttributeRequired::fromNotInjectAttributeProvidedInAnnotatedTarget($attribute::class); + } + + $reflection = $target->targetReflection(); + if (!$reflection instanceof ReflectionParameter) { + throw WrongTargetForInjectAttribute::fromInjectAttributeNotTargetMethodParameter($reflection); + } + + return $this->injectDefinitionFromReflectionParameterAndAttribute($reflection, $attribute); + } + + public function injectDefinitionFromReflectionParameterAndAttribute( + ReflectionParameter $reflection, + InjectAttribute $attribute, + ) : InjectDefinition { + $class = $this->typeFactory->class($reflection->getDeclaringClass()->getName()); + $method = $reflection->getDeclaringFunction()->getName(); + $type = $this->typeFactory->fromReflection($reflection->getType()); + $parameter = $reflection->getName(); + + return $this->injectDefinitionFromManualSetup($class, $method, $type, $parameter, $attribute); + } + + public function injectDefinitionFromManualSetup( + Type $service, + string $method, + Type|TypeUnion|TypeIntersect $type, + string $parameterName, + InjectAttribute $injectAttribute + ) : InjectDefinition { + return new class( + $service, + $method, + $type, + $parameterName, + $injectAttribute, + ) implements InjectDefinition { + + public function __construct( + private readonly Type $class, + private readonly string $method, + private readonly Type|TypeUnion|TypeIntersect $type, + private readonly string $parameter, + private readonly InjectAttribute $attribute, + ) { + } + + public function class() : Type { + return $this->class; + } + + public function methodName() : string { + return $this->method; + } + + public function type() : Type|TypeUnion|TypeIntersect { + return $this->type; + } + + public function parameterName() : string { + return $this->parameter; + } + + public function value() : mixed { + return $this->attribute->value(); + } + + public function profiles() : array { + $profiles = $this->attribute->profiles(); + return $profiles === [] ? ['default'] : $profiles; + } + + public function storeName() : ?string { + return $this->attribute->from(); + } + + public function attribute() : InjectAttribute { + return $this->attribute; + } + }; + } + + public function aliasDefinition(Type $abstract, Type $concrete) : AliasDefinition { + return new class($abstract, $concrete) implements AliasDefinition { + public function __construct( + private readonly Type $abstract, + private readonly Type $concrete, + ) { + } + + public function abstractService() : Type { + return $this->abstract; + } + + public function concreteService() : Type { + return $this->concrete; + } + }; + } +} diff --git a/src/Definition/InjectDefinition.php b/src/Definition/InjectDefinition.php index b414a2ab..e0688a77 100644 --- a/src/Definition/InjectDefinition.php +++ b/src/Definition/InjectDefinition.php @@ -3,16 +3,13 @@ namespace Cspray\AnnotatedContainer\Definition; use Cspray\AnnotatedContainer\Attribute\InjectAttribute; -use Cspray\Typiphy\ObjectType; -use Cspray\Typiphy\Type; -use Cspray\Typiphy\TypeIntersect; -use Cspray\Typiphy\TypeUnion; +use Cspray\AnnotatedContainer\Reflection\Type; +use Cspray\AnnotatedContainer\Reflection\TypeIntersect; +use Cspray\AnnotatedContainer\Reflection\TypeUnion; /** * A definition that provides details on values that should be injected into method parameters or Configuration properties * that can't be implicitly derived through static analysis. - * - * @see InjectDefinitionBuilder */ interface InjectDefinition { @@ -45,14 +42,12 @@ public function profiles() : array; */ public function storeName() : ?string; - public function attribute() : ?InjectAttribute; + public function attribute() : InjectAttribute; /** * The class that has the method being injected into. - * - * @return ObjectType */ - public function class() : ObjectType; + public function class() : Type; /** * @return non-empty-string diff --git a/src/Definition/InjectDefinitionBuilder.php b/src/Definition/InjectDefinitionBuilder.php deleted file mode 100644 index 9687849d..00000000 --- a/src/Definition/InjectDefinitionBuilder.php +++ /dev/null @@ -1,163 +0,0 @@ - - */ - private array $profiles = []; - - /** - * @var non-empty-string|null - */ - private ?string $store = null; - - private function __construct() { - } - - public static function forService(ObjectType $type) : self { - $instance = new self(); - $instance->service = $type; - return $instance; - } - - /** - * @param non-empty-string $method - * @param Type|TypeUnion|TypeIntersect $type - * @param non-empty-string $paramName - * @return $this - */ - public function withMethod(string $method, Type|TypeUnion|TypeIntersect $type, string $paramName) : self { - $instance = clone $this; - $instance->method = $method; - $instance->paramName = $paramName; - $instance->type = $type; - return $instance; - } - - public function withValue(mixed $value) : self { - $instance = clone $this; - $instance->value = $value; - $instance->isValueCalled = true; - return $instance; - } - - /** - * @param non-empty-string $profile - * @param non-empty-string ...$additionalProfiles - */ - public function withProfiles(string $profile, string...$additionalProfiles) : self { - $instance = clone $this; - $instance->profiles[] = $profile; - foreach ($additionalProfiles as $additionalProfile) { - $instance->profiles[] = $additionalProfile; - } - return $instance; - } - - /** - * @param non-empty-string $storeName - * @return $this - */ - public function withStore(string $storeName) : self { - $instance = clone $this; - $instance->store = $storeName; - return $instance; - } - - public function withAttribute(InjectAttribute $injectAttribute) : self { - $instance = clone $this; - $instance->attribute = $injectAttribute; - return $instance; - } - - public function build() : InjectDefinition { - if (!isset($this->method) || !isset($this->paramName)) { - throw InvalidInjectDefinition::fromMissingMethod(); - } elseif (!$this->isValueCalled) { - throw InvalidInjectDefinition::fromMissingValue(); - } - - $profiles = $this->profiles; - if (empty($profiles)) { - $profiles[] = 'default'; - } - - return new class($this->service, $this->method, $this->paramName, $this->type, $this->value, $this->store, $profiles, $this->attribute) implements InjectDefinition { - - /** - * @param Type|TypeUnion|TypeIntersect $type - * @param non-empty-string $methodName - * @param non-empty-string $paramName - * @param non-empty-string|null $store - * @param list $profiles - */ - public function __construct( - private readonly ObjectType $class, - private readonly string $methodName, - private readonly string $paramName, - private readonly Type|TypeUnion|TypeIntersect $type, - private readonly mixed $annotationValue, - private readonly ?string $store, - private readonly array $profiles, - private readonly ?InjectAttribute $attribute - ) { - } - - public function type() : Type|TypeUnion|TypeIntersect { - return $this->type; - } - - public function value() : mixed { - return $this->annotationValue; - } - - public function profiles() : array { - return $this->profiles; - } - - public function storeName() : ?string { - return $this->store; - } - - public function attribute() : ?InjectAttribute { - return $this->attribute; - } - - public function class() : ObjectType { - return $this->class; - } - - public function methodName() : string { - return $this->methodName; - } - - public function parameterName() : string { - return $this->paramName; - } - }; - } -} diff --git a/src/Definition/ProfilesAwareContainerDefinition.php b/src/Definition/ProfilesAwareContainerDefinition.php index 52c1f366..22546f3e 100644 --- a/src/Definition/ProfilesAwareContainerDefinition.php +++ b/src/Definition/ProfilesAwareContainerDefinition.php @@ -4,7 +4,7 @@ use Cspray\AnnotatedContainer\Exception\InvalidAlias; use Cspray\AnnotatedContainer\Profiles; -use Cspray\Typiphy\ObjectType; +use Cspray\AnnotatedContainer\Reflection\Type; final class ProfilesAwareContainerDefinition implements ContainerDefinition { @@ -63,7 +63,7 @@ public function injectDefinitions() : array { return $filtered; } - private function getServiceDefinition(ObjectType $objectType) : ?ServiceDefinition { + private function getServiceDefinition(Type $objectType) : ?ServiceDefinition { foreach ($this->containerDefinition->serviceDefinitions() as $serviceDefinition) { if ($serviceDefinition->type() === $objectType) { return $serviceDefinition; diff --git a/src/Definition/Serializer/XmlContainerDefinitionSerializer.php b/src/Definition/Serializer/XmlContainerDefinitionSerializer.php index 64ed47f1..9baa015f 100644 --- a/src/Definition/Serializer/XmlContainerDefinitionSerializer.php +++ b/src/Definition/Serializer/XmlContainerDefinitionSerializer.php @@ -4,29 +4,22 @@ use Cspray\AnnotatedContainer\AnnotatedContainerVersion; use Cspray\AnnotatedContainer\Attribute\InjectAttribute; -use Cspray\AnnotatedContainer\Attribute\ServiceAttribute; -use Cspray\AnnotatedContainer\Attribute\ServiceDelegateAttribute; -use Cspray\AnnotatedContainer\Attribute\ServicePrepareAttribute; -use Cspray\AnnotatedContainer\Definition\AliasDefinitionBuilder; use Cspray\AnnotatedContainer\Definition\ContainerDefinition; use Cspray\AnnotatedContainer\Definition\ContainerDefinitionBuilder; use Cspray\AnnotatedContainer\Definition\InjectDefinition; -use Cspray\AnnotatedContainer\Definition\InjectDefinitionBuilder; -use Cspray\AnnotatedContainer\Definition\ServiceDefinitionBuilder; -use Cspray\AnnotatedContainer\Definition\ServiceDelegateDefinitionBuilder; -use Cspray\AnnotatedContainer\Definition\ServicePrepareDefinition; -use Cspray\AnnotatedContainer\Definition\ServicePrepareDefinitionBuilder; use Cspray\AnnotatedContainer\Exception\InvalidSerializedContainerDefinition; use Cspray\AnnotatedContainer\Exception\InvalidInjectDefinition; use Cspray\AnnotatedContainer\Exception\MismatchedContainerDefinitionSerializerVersions; -use Cspray\AnnotatedContainer\Internal\SerializerInjectValueParser; +use Cspray\AnnotatedContainer\Reflection\Type; +use Cspray\AnnotatedContainer\Reflection\TypeIntersect; +use Cspray\AnnotatedContainer\Reflection\TypeUnion; use DOMDocument; use DOMElement; use DOMNodeList; use DOMXPath; use Exception as PhpException; -use function Cspray\Typiphy\objectType; -use function PHPUnit\Framework\assertSame; +use function Cspray\AnnotatedContainer\Definition\definitionFactory; +use function Cspray\AnnotatedContainer\Reflection\types; /** * @internal @@ -37,31 +30,33 @@ final class XmlContainerDefinitionSerializer implements ContainerDefinitionSeria private const ROOT_ELEMENT = 'annotatedContainerDefinition'; - private readonly SerializerInjectValueParser $injectValueParser; - - public function __construct() { - $this->injectValueParser = new SerializerInjectValueParser(); - } - public function serialize(ContainerDefinition $containerDefinition) : SerializedContainerDefinition { - $dom = new DOMDocument(encoding: 'UTF-8'); - $dom->formatOutput = true; - $root = $dom->createElementNS(self::XML_SCHEMA, self::ROOT_ELEMENT); - $root->setAttribute('version', AnnotatedContainerVersion::version()); + try { + libxml_use_internal_errors(true); + $dom = new DOMDocument(encoding: 'UTF-8'); + $dom->formatOutput = true; + $root = $dom->createElementNS(self::XML_SCHEMA, self::ROOT_ELEMENT); + $root->setAttribute('version', AnnotatedContainerVersion::version()); - $dom->appendChild($root); + $dom->appendChild($root); - $this->addServiceDefinitionsToDom($root, $containerDefinition); - $this->addAliasDefinitionsToDom($root, $containerDefinition); - $this->addServicePrepareDefinitionsToDom($root, $containerDefinition); - $this->addServiceDelegateDefinitionsToDom($root, $containerDefinition); - $this->addInjectDefinitionsToDom($root, $containerDefinition); + $this->addServiceDefinitionsToDom($root, $containerDefinition); + $this->addAliasDefinitionsToDom($root, $containerDefinition); + $this->addServicePrepareDefinitionsToDom($root, $containerDefinition); + $this->addServiceDelegateDefinitionsToDom($root, $containerDefinition); + $this->addInjectDefinitionsToDom($root, $containerDefinition); - // if we get to this point then we know the XML document will contain _something_ - $xml = $dom->saveXML(); - assert($xml !== false && $xml !== ''); + $this->validateDom($dom); - return SerializedContainerDefinition::fromString($xml); + // if we get to this point then we know the XML document will contain _something_ + $xml = $dom->saveXML(); + assert($xml !== false && $xml !== ''); + + return SerializedContainerDefinition::fromString($xml); + } finally { + libxml_clear_errors(); + libxml_use_internal_errors(false); + } } private function addServiceDefinitionsToDom(DOMElement $root, ContainerDefinition $containerDefinition) : void { @@ -76,44 +71,17 @@ private function addServiceDefinitionsToDom(DOMElement $root, ContainerDefinitio $serviceDefinitionNode = $dom->createElementNS(self::XML_SCHEMA, 'serviceDefinition') ); - if ($serviceDefinition->isPrimary()) { - $serviceDefinitionNode->setAttribute('isPrimary', 'true'); - } + $serviceDefinitionNode->setAttribute('isConcrete', $serviceDefinition->isConcrete() ? 'true' : 'false'); $serviceDefinitionNode->appendChild( $dom->createElementNS(self::XML_SCHEMA, 'type', $serviceDefinition->type()->name()) ); - $serviceDefinitionNode->appendChild( - $nameNode = $dom->createElementNS(self::XML_SCHEMA, 'name') - ); - - $name = $serviceDefinition->name(); - if ($name !== null) { - $nameNode->nodeValue = $name; - } - - $serviceDefinitionNode->appendChild( - $profilesNode = $dom->createElementNS(self::XML_SCHEMA, 'profiles') - ); - - foreach ($serviceDefinition->profiles() as $profile) { - $profilesNode->appendChild( - $dom->createElementNS(self::XML_SCHEMA, 'profile', $profile) - ); - } - - $serviceDefinitionNode->appendChild( - $dom->createElementNS(self::XML_SCHEMA, 'concreteOrAbstract', $serviceDefinition->isConcrete() ? 'Concrete' : 'Abstract') - ); $serviceDefinitionNode->appendChild( $attrNode = $dom->createElementNS(self::XML_SCHEMA, 'attribute') ); - $attr = $serviceDefinition->attribute(); - if ($attr !== null) { - $attrNode->nodeValue = base64_encode(serialize($attr)); - } + $attrNode->nodeValue = base64_encode(serialize($serviceDefinition->attribute())); } } @@ -153,19 +121,13 @@ private function addServicePrepareDefinitionsToDom(DOMElement $root, ContainerDe $servicePrepareDefinitionNode->appendChild( $dom->createElementNS(self::XML_SCHEMA, 'type', $servicePrepareDefinition->service()->name()) ); - $servicePrepareDefinitionNode->appendChild( $dom->createElementNS(self::XML_SCHEMA, 'method', $servicePrepareDefinition->methodName()) ); $servicePrepareDefinitionNode->appendChild( - $attrNode = $dom->createElementNS(self::XML_SCHEMA, 'attribute') + $dom->createElementNS(self::XML_SCHEMA, 'attribute', base64_encode(serialize($servicePrepareDefinition->attribute()))) ); - - $attr = $servicePrepareDefinition->attribute(); - if ($attr !== null) { - $attrNode->nodeValue = base64_encode(serialize($attr)); - } } } @@ -191,13 +153,8 @@ private function addServiceDelegateDefinitionsToDom(DOMElement $root, ContainerD $dom->createElementNS(self::XML_SCHEMA, 'delegateMethod', $serviceDelegateDefinition->delegateMethod()) ); $serviceDelegateDefinitionNode->appendChild( - $attrNode = $dom->createElementNS(self::XML_SCHEMA, 'attribute') + $dom->createElementNS(self::XML_SCHEMA, 'attribute', base64_encode(serialize($serviceDelegateDefinition->attribute()))) ); - - $attr = $serviceDelegateDefinition->attribute(); - if ($attr !== null) { - $attrNode->nodeValue = base64_encode(serialize($attr)); - } } } @@ -210,7 +167,7 @@ private function addInjectDefinitionsToDom(DOMElement $root, ContainerDefinition foreach ($containerDefinition->injectDefinitions() as $injectDefinition) { try { - $serializedValue = serialize($injectDefinition->value()); + $serializedAttribute = base64_encode(serialize($injectDefinition->attribute())); } catch (PhpException $exception) { throw InvalidInjectDefinition::fromValueNotSerializable($exception); } @@ -224,45 +181,62 @@ private function addInjectDefinitionsToDom(DOMElement $root, ContainerDefinition $this->addMethodParameterInjectDefinitionToDom($injectDefinitionNode, $injectDefinition); $injectDefinitionNode->appendChild( - $dom->createElementNS(self::XML_SCHEMA, 'valueType', base64_encode($injectDefinition->type()->name())) + $this->createAppropriateElementForValueType($dom, $injectDefinition) ); $injectDefinitionNode->appendChild( - $valueNode = $dom->createElementNS(self::XML_SCHEMA, 'value') - ); - - $valueNode->appendChild( - $dom->createCDATASection(base64_encode($serializedValue)) + $dom->createElementNS(self::XML_SCHEMA, 'attribute', $serializedAttribute) ); + } + } - $injectDefinitionNode->appendChild( - $profilesNode = $dom->createElementNS(self::XML_SCHEMA, 'profiles') - ); + private function createAppropriateElementForValueType(DOMDocument $dom, InjectDefinition $injectDefinition) : DOMElement { + $valueType = $injectDefinition->type(); + if ($valueType instanceof Type) { + $valueTypeElement = $this->createTypeElement($dom, $valueType); + } elseif ($valueType instanceof TypeUnion) { + $valueTypeElement = $this->createTypeUnionElement($dom, $valueType); + } elseif ($valueType instanceof TypeIntersect) { + $valueTypeElement = $this->createTypeIntersectElement($dom, $valueType); + } - foreach ($injectDefinition->profiles() as $profile) { - $profilesNode->appendChild( - $dom->createElementNS(self::XML_SCHEMA, 'profile', $profile) - ); - } + $valueTypeNode = $dom->createElementNS(self::XML_SCHEMA, 'valueType'); + $valueTypeNode->appendChild($valueTypeElement); - $injectDefinitionNode->appendChild( - $storeNode = $dom->createElementNS(self::XML_SCHEMA, 'store') - ); + return $valueTypeNode; + } - $injectDefinitionNode->appendChild( - $attrNode = $dom->createElementNS(self::XML_SCHEMA, 'attribute') - ); + private function createTypeElement(DOMDocument $dom, Type $type) : DOMElement { + return $dom->createElementNS( + self::XML_SCHEMA, + 'type', + $type->name(), + ); + } - $store = $injectDefinition->storeName(); - if ($store !== null) { - $storeNode->nodeValue = $store; + private function createTypeUnionElement(DOMDocument $dom, TypeUnion $type) : DOMElement { + $element = $dom->createElementNS(self::XML_SCHEMA, 'typeUnion'); + foreach ($type->types() as $typeOrTypeIntersect) { + if ($typeOrTypeIntersect instanceof Type) { + $element->appendChild($this->createTypeElement($dom, $typeOrTypeIntersect)); + } else { + $element->appendChild($this->createTypeIntersectElement($dom, $typeOrTypeIntersect)); } + } - $attr = $injectDefinition->attribute(); - if ($attr !== null) { - $attrNode->nodeValue = base64_encode(serialize($attr)); - } + return $element; + } + + private function createTypeIntersectElement(DOMDocument $dom, TypeIntersect $type) : DOMElement { + $valueTypeElement = $dom->createElementNS( + self::XML_SCHEMA, + 'typeIntersect' + ); + foreach ($type->types() as $t) { + $valueTypeElement->appendChild($this->createTypeElement($dom, $t)); } + + return $valueTypeElement; } private function addMethodParameterInjectDefinitionToDom(DOMElement $root, InjectDefinition $injectDefinition) : void { @@ -282,43 +256,47 @@ private function addMethodParameterInjectDefinitionToDom(DOMElement $root, Injec ); } - public function deserialize(SerializedContainerDefinition $serializedContainerDefinition) : ContainerDefinition { - $dom = new DOMDocument(encoding: 'UTF-8'); - - // The assert() calls and docblock annotations in other methods, on values provided in the serialized container - // definition are made because they are being asserted as part of the XML passing the container definition - // schema below. If the code executes beyond the call to $dom->schemaValidate() then we can assume the stuff - // covered by the schema definition is covered and we don't need to cover it again. + private function validateDom(DOMDocument $dom) : void { + $schemaPath = dirname(__DIR__, 3) . '/annotated-container-definition.xsd'; + if (!$dom->schemaValidate($schemaPath)) { + throw InvalidSerializedContainerDefinition::fromNotValidateXmlSchema(libxml_get_errors()); + } + } - libxml_use_internal_errors(true); + public function deserialize(SerializedContainerDefinition $serializedContainerDefinition) : ContainerDefinition { try { + libxml_use_internal_errors(true); + $dom = new DOMDocument(encoding: 'UTF-8'); + + // The assert() calls and docblock annotations in other methods, on values provided in the serialized container + // definition are made because they are being asserted as part of the XML passing the container definition + // schema below. If the code executes beyond the call to $dom->schemaValidate() then we can assume the stuff + // covered by the schema definition is covered and we don't need to cover it again. $dom->loadXML($serializedContainerDefinition->asString()); - $schemaPath = dirname(__DIR__, 3) . '/annotated-container-definition.xsd'; - if (!$dom->schemaValidate($schemaPath)) { - throw InvalidSerializedContainerDefinition::fromNotValidateXmlSchema(libxml_get_errors()); - } - } finally { - libxml_clear_errors(); - libxml_use_internal_errors(false); - } - $xpath = new DOMXPath($dom); - $xpath->registerNamespace('cd', self::XML_SCHEMA); + $this->validateDom($dom); - $version = (string) $xpath->query('/cd:annotatedContainerDefinition/@version')[0]?->nodeValue; - if ($version !== AnnotatedContainerVersion::version()) { - throw MismatchedContainerDefinitionSerializerVersions::fromVersionIsNotInstalledAnnotatedContainerVersion($version); - } + $xpath = new DOMXPath($dom); + $xpath->registerNamespace('cd', self::XML_SCHEMA); - $builder = ContainerDefinitionBuilder::newDefinition(); + $version = (string) $xpath->query('/cd:annotatedContainerDefinition/@version')[0]?->nodeValue; + if ($version !== AnnotatedContainerVersion::version()) { + throw MismatchedContainerDefinitionSerializerVersions::fromVersionIsNotInstalledAnnotatedContainerVersion($version); + } - $builder = $this->addServiceDefinitionsToBuilder($builder, $xpath); - $builder = $this->addAliasDefinitionsToBuilder($builder, $xpath); - $builder = $this->addServicePrepareDefinitionsToBuilder($builder, $xpath); - $builder = $this->addServiceDelegateDefinitionsToBuilder($builder, $xpath); - $builder = $this->addInjectDefinitionsToBuilder($builder, $xpath); + $builder = ContainerDefinitionBuilder::newDefinition(); - return $builder->build(); + $builder = $this->addServiceDefinitionsToBuilder($builder, $xpath); + $builder = $this->addAliasDefinitionsToBuilder($builder, $xpath); + $builder = $this->addServicePrepareDefinitionsToBuilder($builder, $xpath); + $builder = $this->addServiceDelegateDefinitionsToBuilder($builder, $xpath); + $builder = $this->addInjectDefinitionsToBuilder($builder, $xpath); + + return $builder->build(); + } finally { + libxml_clear_errors(); + libxml_use_internal_errors(false); + } } private function addServiceDefinitionsToBuilder(ContainerDefinitionBuilder $builder, DOMXPath $xpath) : ContainerDefinitionBuilder { @@ -328,46 +306,18 @@ private function addServiceDefinitionsToBuilder(ContainerDefinitionBuilder $buil foreach ($serviceDefinitions as $serviceDefinition) { $serviceType = $xpath->query('cd:type/text()', $serviceDefinition)[0]->nodeValue; assert(class_exists($serviceType)); - - $type = objectType($serviceType); - - $concreteOrAbstract = $xpath->query('cd:concreteOrAbstract/text()', $serviceDefinition)[0]->nodeValue; - $isPrimary = $xpath->query('@isPrimary', $serviceDefinition)[0]?->nodeValue; - if ($concreteOrAbstract === 'Concrete') { - $serviceBuilder = ServiceDefinitionBuilder::forConcrete($type, $isPrimary === 'true'); - } else { - $serviceBuilder = ServiceDefinitionBuilder::forAbstract($type); - } - - $name = $xpath->query('cd:name/text()', $serviceDefinition)[0]?->nodeValue; - if ($name !== null) { - // We make several assertions that a name cannot be an empty string before a container is serialized and - // a blank name should not be possible - assert($name !== ''); - $serviceBuilder = $serviceBuilder->withName($name); - } - - $profiles = $xpath->query('cd:profiles/cd:profile', $serviceDefinition); - $serviceProfiles = []; - foreach ($profiles as $profile) { - $value = $profile->nodeValue; - // The profileString type ensures that there is a value listed greater than 1 - assert($value !== null && $value !== ''); - $serviceProfiles[] = $value; - } - // The profilesType ensures there's at least 1 profile, additionally definitions are never assigned empty profiles - assert($serviceProfiles !== []); - - $serviceBuilder = $serviceBuilder->withProfiles($serviceProfiles); - - $attr = $xpath->query('cd:attribute/text()', $serviceDefinition)[0]?->nodeValue; - if ($attr !== null) { - $attrInstance = unserialize(base64_decode($attr)); - assert($attrInstance instanceof ServiceAttribute); - $serviceBuilder = $serviceBuilder->withAttribute($attrInstance); - } - - $builder = $builder->withServiceDefinition($serviceBuilder->build()); + $isConcrete = $xpath->query('@isConcrete', $serviceDefinition)[0]->nodeValue === 'true'; + $attr = unserialize(base64_decode( + $xpath->query('cd:attribute/text()', $serviceDefinition)[0]?->nodeValue + )); + + $builder = $builder->withServiceDefinition( + definitionFactory()->serviceDefinitionFromManualSetup( + types()->class($serviceType), + $attr, + $isConcrete + ) + ); } return $builder; @@ -385,7 +335,7 @@ private function addAliasDefinitionsToBuilder(ContainerDefinitionBuilder $builde assert(class_exists($concrete)); $builder = $builder->withAliasDefinition( - AliasDefinitionBuilder::forAbstract(objectType($abstract))->withConcrete(objectType($concrete))->build() + definitionFactory()->aliasDefinition(types()->class($abstract), types()->class($concrete)) ); } @@ -399,20 +349,14 @@ private function addServicePrepareDefinitionsToBuilder(ContainerDefinitionBuilde foreach ($prepareDefinitions as $prepareDefinition) { $service = $xpath->query('cd:type/text()', $prepareDefinition)[0]->nodeValue; $method = $xpath->query('cd:method/text()', $prepareDefinition)[0]->nodeValue; + $attr = unserialize(base64_decode($xpath->query('cd:attribute/text()', $prepareDefinition)[0]?->nodeValue)); assert(class_exists($service)); assert($method !== null && $method !== ''); - $servicePrepareBuilder = ServicePrepareDefinitionBuilder::forMethod(objectType($service), $method); - - $attr = $xpath->query('cd:attribute/text()', $prepareDefinition)[0]?->nodeValue; - if ($attr !== null) { - $attrObject = unserialize(base64_decode($attr)); - assert($attrObject instanceof ServicePrepareAttribute); - $servicePrepareBuilder = $servicePrepareBuilder->withAttribute($attrObject); - } - - $builder = $builder->withServicePrepareDefinition($servicePrepareBuilder->build()); + $builder = $builder->withServicePrepareDefinition( + definitionFactory()->servicePrepareDefinitionFromClassMethodAndAttribute(types()->class($service), $method, $attr) + ); } return $builder; @@ -426,22 +370,19 @@ private function addServiceDelegateDefinitionsToBuilder(ContainerDefinitionBuild $service = $xpath->query('cd:service/text()', $delegateDefinition)[0]->nodeValue; $delegateType = $xpath->query('cd:delegateType/text()', $delegateDefinition)[0]->nodeValue; $delegateMethod = $xpath->query('cd:delegateMethod/text()', $delegateDefinition)[0]->nodeValue; + $attr = unserialize(base64_decode($xpath->query('cd:attribute/text()', $delegateDefinition)[0]?->nodeValue)); assert(class_exists($service)); assert(class_exists($delegateType)); assert($delegateMethod !== null && $delegateMethod !== ''); - $serviceDelegateBuilder = ServiceDelegateDefinitionBuilder::forService(objectType($service)) - ->withDelegateMethod(objectType($delegateType), $delegateMethod); - - $attr = $xpath->query('cd:attribute/text()', $delegateDefinition)[0]?->nodeValue; - if ($attr !== null) { - $attrInstance = unserialize(base64_decode($attr)); - assert($attrInstance instanceof ServiceDelegateAttribute); - $serviceDelegateBuilder = $serviceDelegateBuilder->withAttribute($attrInstance); - } - - $builder = $builder->withServiceDelegateDefinition($serviceDelegateBuilder->build()); + $builder = $builder->withServiceDelegateDefinition( + definitionFactory()->serviceDelegateDefinitionFromClassMethodAndAttribute( + types()->class($delegateType), + $delegateMethod, + $attr + ) + ); } return $builder; @@ -452,56 +393,46 @@ private function addInjectDefinitionsToBuilder(ContainerDefinitionBuilder $build assert($injectDefinitions instanceof DOMNodeList); foreach ($injectDefinitions as $injectDefinition) { - $valueType = $xpath->query('cd:valueType/text()', $injectDefinition)[0]->nodeValue; - $store = $xpath->query('cd:store/text()', $injectDefinition)[0]?->nodeValue; - $attr = $xpath->query('cd:attribute/text()', $injectDefinition)[0]?->nodeValue; - $profiles = $xpath->query('cd:profiles/cd:profile/text()', $injectDefinition); - $encodedSerializedValue = $xpath->query('cd:value/text()', $injectDefinition)[0]->nodeValue; - - $serializedValue = base64_decode($encodedSerializedValue); - /** @var mixed $value */ - $value = unserialize($serializedValue); - /** @var non-empty-string $base64DecodedValueType */ - $base64DecodedValueType = base64_decode($valueType); - $valueType = $this->injectValueParser->convertStringToType($base64DecodedValueType); - $type = $xpath->query('cd:class/text()', $injectDefinition)[0]->nodeValue; $methodName = $xpath->query('cd:method/text()', $injectDefinition)[0]->nodeValue; $parameter = $xpath->query('cd:parameter/text()', $injectDefinition)[0]->nodeValue; + $attr = $xpath->query('cd:attribute/text()', $injectDefinition)[0]?->nodeValue; + $valueTypeName = $xpath->query('cd:valueType/*[1]', $injectDefinition)->item(0)->nodeName; assert(class_exists($type)); assert($methodName !== null && $methodName !== ''); assert($parameter !== null && $parameter !== ''); - $injectBuilder = InjectDefinitionBuilder::forService(objectType($type)) - ->withMethod($methodName, $valueType, $parameter); - - $injectBuilder = $injectBuilder->withValue($value); - - $injectProfiles = []; - foreach ($profiles as $profile) { - $value = $profile->nodeValue; - // The profileString type ensures that there is a value listed greater than 1 - assert($value !== null && $value !== ''); - $injectProfiles[] = $value; - } - // The profilesType ensures there's at least 1 profile, additionally definitions are never assigned empty profiles - assert($injectProfiles !== []); - - $injectBuilder = $injectBuilder->withProfiles(...$injectProfiles); - - if ($store !== null) { - assert($store !== ''); - $injectBuilder = $injectBuilder->withStore($store); - } - - if ($attr !== null) { - $attrInstance = unserialize(base64_decode($attr)); - assert($attrInstance instanceof InjectAttribute); - $injectBuilder = $injectBuilder->withAttribute($attrInstance); + if ($valueTypeName === 'type') { + $valueType = types()->fromName($xpath->query('cd:valueType/cd:type/text()', $injectDefinition)->item(0)->nodeValue); + } elseif ($valueTypeName === 'typeUnion') { + $valueType = types()->union( + ...array_map( + static fn(DOMElement $domElement) => types()->fromName($domElement->nodeValue), + iterator_to_array($xpath->query('cd:valueType/cd:typeUnion/*', $injectDefinition)) + ) + ); + } elseif ($valueTypeName === 'typeIntersect') { + $valueType = types()->intersect( + ...array_map( + static fn(DOMElement $domElement) => types()->class($domElement->nodeValue), + iterator_to_array($xpath->query('cd:valueType/cd:typeIntersect/*', $injectDefinition)) + ) + ); } - $builder = $builder->withInjectDefinition($injectBuilder->build()); + $attrInstance = unserialize(base64_decode($attr)); + assert($attrInstance instanceof InjectAttribute); + + $builder = $builder->withInjectDefinition( + definitionFactory()->injectDefinitionFromManualSetup( + types()->fromName($type), + $methodName, + $valueType, + $parameter, + $attrInstance + ) + ); } return $builder; diff --git a/src/Definition/ServiceDefinition.php b/src/Definition/ServiceDefinition.php index f3bd4710..baafa013 100644 --- a/src/Definition/ServiceDefinition.php +++ b/src/Definition/ServiceDefinition.php @@ -3,26 +3,23 @@ namespace Cspray\AnnotatedContainer\Definition; use Cspray\AnnotatedContainer\Attribute\ServiceAttribute; -use Cspray\Typiphy\ObjectType; +use Cspray\AnnotatedContainer\Reflection\Type; /** - * Defines a Service, a class or interface that should be shared or aliased on the wired Injector. - * - * @see ServiceDefinitionBuilder + * Defines an object that will be shared in the created AnnotatedContainer. */ interface ServiceDefinition { /** - * @return non-empty-string|null + * Returns the fully-qualified class/interface name for the given Service. + * */ - public function name() : ?string; + public function type() : Type; /** - * Returns the fully-qualified class/interface name for the given Service. - * - * @return ObjectType + * @return non-empty-string|null */ - public function type() : ObjectType; + public function name() : ?string; /** * Returns an array of profiles that this service is attached to. @@ -56,5 +53,5 @@ public function isConcrete() : bool; */ public function isAbstract() : bool; - public function attribute() : ?ServiceAttribute; + public function attribute() : ServiceAttribute; } diff --git a/src/Definition/ServiceDefinitionBuilder.php b/src/Definition/ServiceDefinitionBuilder.php deleted file mode 100644 index 0f5420cd..00000000 --- a/src/Definition/ServiceDefinitionBuilder.php +++ /dev/null @@ -1,123 +0,0 @@ - - */ - private array $profiles = []; - private bool $isPrimary = false; - - private function __construct() { - } - - public static function forAbstract(ObjectType $type) : self { - $instance = new self; - $instance->type = $type; - $instance->isAbstract = true; - return $instance; - } - - public static function forConcrete(ObjectType $type, bool $isPrimary = false) : self { - $instance = new self; - $instance->type = $type; - $instance->isAbstract = false; - $instance->isPrimary = $isPrimary; - return $instance; - } - - /** - * @param non-empty-string $name - * @return $this - */ - public function withName(string $name) : self { - $instance = clone $this; - $instance->name = $name; - return $instance; - } - - /** - * @param list $profiles - * @return $this - */ - public function withProfiles(array $profiles) : self { - $instance = clone $this; - $instance->profiles = $profiles; - return $instance; - } - - public function withAttribute(ServiceAttribute $attribute) : self { - $instance = clone $this; - $instance->attribute = $attribute; - return $instance; - } - - public function build() : ServiceDefinition { - $profiles = $this->profiles; - if (empty($profiles)) { - $profiles[] = 'default'; - } - return new class($this->name, $this->type, $this->isAbstract, $profiles, $this->isPrimary, $this->attribute) implements ServiceDefinition { - - /** - * @param ?non-empty-string $name - * @param list $profiles - */ - public function __construct( - private readonly ?string $name, - private readonly ObjectType $type, - private readonly bool $isAbstract, - private readonly array $profiles, - private readonly bool $isPrimary, - private readonly ?ServiceAttribute $attribute - ) { - } - - /** - * @return ?non-empty-string - */ - public function name() : ?string { - return $this->name; - } - - public function type() : ObjectType { - return $this->type; - } - - /** - * @return list - */ - public function profiles() : array { - return $this->profiles; - } - - public function isPrimary() : bool { - return $this->isPrimary; - } - - public function isConcrete() : bool { - return !$this->isAbstract; - } - - public function isAbstract() : bool { - return $this->isAbstract; - } - - public function attribute() : ?ServiceAttribute { - return $this->attribute; - } - }; - } -} diff --git a/src/Definition/ServiceDelegateDefinition.php b/src/Definition/ServiceDelegateDefinition.php index 3a45ff01..0a47f7df 100644 --- a/src/Definition/ServiceDelegateDefinition.php +++ b/src/Definition/ServiceDelegateDefinition.php @@ -3,6 +3,7 @@ namespace Cspray\AnnotatedContainer\Definition; use Cspray\AnnotatedContainer\Attribute\ServiceDelegateAttribute; +use Cspray\AnnotatedContainer\Reflection\Type; use Cspray\Typiphy\ObjectType; /** @@ -15,10 +16,8 @@ interface ServiceDelegateDefinition { * * Please note that you can specify other Services in the Container and have them injected into the constructor * of this factory class. - * - * @return ObjectType */ - public function delegateType() : ObjectType; + public function delegateType() : Type; /** * Return the method on the delegateType that should be invoked to create the Service. @@ -30,7 +29,7 @@ public function delegateType() : ObjectType; */ public function delegateMethod() : string; - public function serviceType() : ObjectType; + public function serviceType() : Type; - public function attribute() : ?ServiceDelegateAttribute; + public function attribute() : ServiceDelegateAttribute; } diff --git a/src/Definition/ServiceDelegateDefinitionBuilder.php b/src/Definition/ServiceDelegateDefinitionBuilder.php deleted file mode 100644 index 9f26687e..00000000 --- a/src/Definition/ServiceDelegateDefinitionBuilder.php +++ /dev/null @@ -1,87 +0,0 @@ -service = $service; - return $instance; - } - - /** - * @param ObjectType $delegateType - * @param non-empty-string $delegateMethod - * @return $this - * @throws InvalidServiceDelegateDefinition - */ - public function withDelegateMethod(ObjectType $delegateType, string $delegateMethod) : self { - if (trim($delegateMethod) === '') { - throw InvalidServiceDelegateDefinition::fromEmptyDelegateMethod(); - } - $instance = clone $this; - $instance->delegateType = $delegateType; - $instance->delegateMethod = $delegateMethod; - return $instance; - } - - public function withAttribute(ServiceDelegateAttribute $attribute) : self { - $instance = clone $this; - $instance->attribute = $attribute; - return $instance; - } - - public function build() : ServiceDelegateDefinition { - return new class($this->service, $this->delegateType, $this->delegateMethod, $this->attribute) implements ServiceDelegateDefinition { - - /** - * @param ObjectType $serviceDefinition - * @param ObjectType $delegateType - * @param non-empty-string $delegateMethod - * @param ServiceDelegateAttribute|null $attribute - */ - public function __construct( - private readonly ObjectType $serviceDefinition, - private readonly ObjectType $delegateType, - private readonly string $delegateMethod, - private readonly ?ServiceDelegateAttribute $attribute - ) { - } - - public function delegateType() : ObjectType { - return $this->delegateType; - } - - /** - * @return non-empty-string - */ - public function delegateMethod() : string { - return $this->delegateMethod; - } - - public function serviceType() : ObjectType { - return $this->serviceDefinition; - } - - public function attribute() : ?ServiceDelegateAttribute { - return $this->attribute; - } - }; - } -} diff --git a/src/Definition/ServicePrepareDefinition.php b/src/Definition/ServicePrepareDefinition.php index 27793a03..3bb29d7c 100644 --- a/src/Definition/ServicePrepareDefinition.php +++ b/src/Definition/ServicePrepareDefinition.php @@ -4,6 +4,7 @@ namespace Cspray\AnnotatedContainer\Definition; use Cspray\AnnotatedContainer\Attribute\ServicePrepareAttribute; +use Cspray\AnnotatedContainer\Reflection\Type; use Cspray\Typiphy\ObjectType; /** @@ -15,10 +16,8 @@ interface ServicePrepareDefinition { /** * The Service that requires some method to be invoked on it after it is instantiated. - * - * @return ObjectType */ - public function service() : ObjectType; + public function service() : Type; /** * The method that should be invoked on the Service. @@ -27,5 +26,5 @@ public function service() : ObjectType; */ public function methodName() : string; - public function attribute() : ?ServicePrepareAttribute; + public function attribute() : ServicePrepareAttribute; } diff --git a/src/Definition/ServicePrepareDefinitionBuilder.php b/src/Definition/ServicePrepareDefinitionBuilder.php deleted file mode 100644 index 81d702ec..00000000 --- a/src/Definition/ServicePrepareDefinitionBuilder.php +++ /dev/null @@ -1,74 +0,0 @@ -service = $serviceDefinition; - $instance->method = $method; - return $instance; - } - - public function withAttribute(ServicePrepareAttribute $attribute) : self { - $instance = clone $this; - $instance->attribute = $attribute; - return $instance; - } - - public function build() : ServicePrepareDefinition { - return new class($this->service, $this->method, $this->attribute) implements ServicePrepareDefinition { - - /** - * @param ObjectType $service - * @param non-empty-string $method - * @param ServicePrepareAttribute|null $attribute - */ - public function __construct( - private readonly ObjectType $service, - private readonly string $method, - private readonly ?ServicePrepareAttribute $attribute - ) { - } - - public function service() : ObjectType { - return $this->service; - } - - /** - * @return non-empty-string - */ - public function methodName() : string { - return $this->method; - } - - public function attribute() : ?ServicePrepareAttribute { - return $this->attribute; - } - }; - } -} diff --git a/src/Exception/InjectAttributeRequired.php b/src/Exception/InjectAttributeRequired.php new file mode 100644 index 00000000..879956c4 --- /dev/null +++ b/src/Exception/InjectAttributeRequired.php @@ -0,0 +1,16 @@ +name(), + $delegateMethod, + )); + } +} diff --git a/src/Exception/ServiceDelegateReturnsScalarType.php b/src/Exception/ServiceDelegateReturnsScalarType.php new file mode 100644 index 00000000..999588a2 --- /dev/null +++ b/src/Exception/ServiceDelegateReturnsScalarType.php @@ -0,0 +1,16 @@ +name(), + $method, + )); + } +} diff --git a/src/Exception/ServiceDelegateReturnsUnionType.php b/src/Exception/ServiceDelegateReturnsUnionType.php new file mode 100644 index 00000000..bdb02de9 --- /dev/null +++ b/src/Exception/ServiceDelegateReturnsUnionType.php @@ -0,0 +1,16 @@ +name(), + $delegateMethod, + )); + } +} diff --git a/src/Exception/ServiceDelegateReturnsUnknownType.php b/src/Exception/ServiceDelegateReturnsUnknownType.php new file mode 100644 index 00000000..5fc6d5a2 --- /dev/null +++ b/src/Exception/ServiceDelegateReturnsUnknownType.php @@ -0,0 +1,16 @@ +name(), + $method, + )); + } +} diff --git a/src/Exception/ServicePrepareAttributeRequired.php b/src/Exception/ServicePrepareAttributeRequired.php new file mode 100644 index 00000000..a97dfc30 --- /dev/null +++ b/src/Exception/ServicePrepareAttributeRequired.php @@ -0,0 +1,20 @@ +name; } - public function value() : ObjectType { + public function value() : Type { return $this->value; } diff --git a/src/Function/definitions.php b/src/Function/definitions.php index 20a20c61..c2ee6cfa 100644 --- a/src/Function/definitions.php +++ b/src/Function/definitions.php @@ -1,80 +1,59 @@ $profiles * @param bool $isPrimary * @return ServiceDefinition - * @throws ReflectionException */ -function service(ObjectType $type, ?string $name = null, array $profiles = [], bool $isPrimary = false) : ServiceDefinition { - $typeName = $type->name(); - $reflection = new ReflectionClass($typeName); - $methodArgs = [$type]; - $method = $reflection->isAbstract() || $reflection->isInterface() ? 'forAbstract' : 'forConcrete'; - /** @var ServiceDefinitionBuilder $serviceDefinitionBuilder */ - if ($method === 'forConcrete') { - $methodArgs[] = $isPrimary; - } - /** @var ServiceDefinitionBuilder $serviceDefinitionBuilder */ - $serviceDefinitionBuilder = ServiceDefinitionBuilder::$method(...$methodArgs); - if (isset($name)) { - $serviceDefinitionBuilder = $serviceDefinitionBuilder->withName($name); - } - - if (empty($profiles)) { - $profiles[] = 'default'; - } - $serviceDefinitionBuilder = $serviceDefinitionBuilder->withProfiles($profiles); - - return $serviceDefinitionBuilder->build(); +function service(Type $type, ?string $name = null, array $profiles = [], bool $isPrimary = false) : ServiceDefinition { + return definitionFactory()->serviceDefinitionFromObjectTypeAndAttribute( + $type, + new ServiceFromFunctionalApi($profiles, $isPrimary, $name) + ); } /** - * @param ObjectType $service - * @param ObjectType $factoryClass + * @param Type $factoryClass * @param non-empty-string $factoryMethod - * @return ServiceDelegateDefinition - * @throws Exception\InvalidServiceDelegateDefinition */ -function serviceDelegate(ObjectType $service, ObjectType $factoryClass, string $factoryMethod) : ServiceDelegateDefinition { - return ServiceDelegateDefinitionBuilder::forService($service) - ->withDelegateMethod($factoryClass, $factoryMethod)->build(); +function serviceDelegate(Type $factoryClass, string $factoryMethod) : ServiceDelegateDefinition { + return definitionFactory()->serviceDelegateDefinitionFromClassMethodAndAttribute( + $factoryClass, + $factoryMethod, + new ServiceDelegateFromFunctionalApi() + ); } /** - * @param ObjectType $service + * @param Type $service * @param non-empty-string $method * @return ServicePrepareDefinition - * @throws Exception\InvalidServicePrepareDefinition */ -function servicePrepare(ObjectType $service, string $method) : ServicePrepareDefinition { - return ServicePrepareDefinitionBuilder::forMethod($service, $method)->build(); +function servicePrepare(Type $service, string $method) : ServicePrepareDefinition { + return definitionFactory()->servicePrepareDefinitionFromClassMethodAndAttribute( + $service, + $method, + new ServicePrepareFromFunctionalApi() + ); } /** - * @param ObjectType $service + * @param Type $service * @param non-empty-string $method * @param non-empty-string $paramName * @param Type|TypeUnion|TypeIntersect $type @@ -82,10 +61,9 @@ function servicePrepare(ObjectType $service, string $method) : ServicePrepareDef * @param list $profiles * @param non-empty-string|null $from * @return InjectDefinition - * @throws Exception\InvalidInjectDefinition */ function inject( - ObjectType $service, + Type $service, string $method, string $paramName, Type|TypeUnion|TypeIntersect $type, @@ -93,17 +71,18 @@ function inject( array $profiles = [], string $from = null ) : InjectDefinition { - $injectDefinitionBuilder = InjectDefinitionBuilder::forService($service) - ->withMethod($method, $type, $paramName) - ->withValue($value); - - if (!empty($profiles)) { - $injectDefinitionBuilder = $injectDefinitionBuilder->withProfiles(...$profiles); - } - - if (isset($from)) { - $injectDefinitionBuilder = $injectDefinitionBuilder->withStore($from); - } + return definitionFactory()->injectDefinitionFromManualSetup( + $service, + $method, + $type, + $paramName, + new Inject($value, $from, $profiles) + ); +} - return $injectDefinitionBuilder->build(); +function definitionFactory() : DefinitionFactory { + /** @var ?DefinitionFactory $factory */ + static $factory = null; + $factory ??= new DefinitionFactory(); + return $factory; } diff --git a/src/Function/types.php b/src/Function/types.php new file mode 100644 index 00000000..474444a2 --- /dev/null +++ b/src/Function/types.php @@ -0,0 +1,9 @@ +convertStringToType($unionType); - } - /** @psalm-var non-empty-list $types */ - $type = typeUnion(...$types); - } elseif (str_contains($rawType, '&')) { - $types = []; - foreach (explode('&', $rawType) as $intersectType) { - assert(class_exists($intersectType)); - $parsedType = $this->convertStringToType($intersectType); - assert($parsedType instanceof ObjectType); - $types[] = $parsedType; - } - $type = typeIntersect(...$types); - } else { - $type = match ($rawType) { - 'string' => stringType(), - 'int', 'integer' => intType(), - 'float', 'double' => floatType(), - 'bool', 'boolean' => boolType(), - 'array' => arrayType(), - 'mixed' => mixedType(), - 'iterable' => iterableType(), - 'null', 'NULL' => nullType(), - 'void' => voidType(), - 'callable' => callableType(), - default => null - }; - - if ($type === null) { - assert(class_exists($rawType)); - $type = objectType($rawType); - } - } - - return $type; - } -} diff --git a/src/Internal/ServiceDelegateFromFunctionalApi.php b/src/Internal/ServiceDelegateFromFunctionalApi.php new file mode 100644 index 00000000..ab0f5d7c --- /dev/null +++ b/src/Internal/ServiceDelegateFromFunctionalApi.php @@ -0,0 +1,16 @@ +profiles; + } + + public function isPrimary() : bool { + return $this->isPrimary; + } + + public function name() : ?string { + return $this->name; + } +} diff --git a/src/Internal/ServicePrepareFromFunctionalApi.php b/src/Internal/ServicePrepareFromFunctionalApi.php new file mode 100644 index 00000000..37125c84 --- /dev/null +++ b/src/Internal/ServicePrepareFromFunctionalApi.php @@ -0,0 +1,12 @@ +delegateType()->name(), $definition->delegateMethod()); $delegateMap[$service] ??= []; $attribute = $definition->attribute(); - if ($attribute !== null) { - $message = sprintf('%s attributed with %s%s', $method, $definition->attribute()::class, PHP_EOL); - } else { + if ($attribute instanceof ServiceDelegateFromFunctionalApi) { $message = sprintf('%s added with serviceDelegate()%s', $method, PHP_EOL); + } else { + $message = sprintf('%s attributed with %s%s', $method, $definition->attribute()::class, PHP_EOL); } $delegateMap[$service][] = $message; } diff --git a/src/LogicalConstraint/Check/DuplicateServicePrepare.php b/src/LogicalConstraint/Check/DuplicateServicePrepare.php index 3d3e3e85..2912e5d0 100644 --- a/src/LogicalConstraint/Check/DuplicateServicePrepare.php +++ b/src/LogicalConstraint/Check/DuplicateServicePrepare.php @@ -4,6 +4,7 @@ use Cspray\AnnotatedContainer\Attribute\ServicePrepareAttribute; use Cspray\AnnotatedContainer\Definition\ContainerDefinition; +use Cspray\AnnotatedContainer\Internal\ServicePrepareFromFunctionalApi; use Cspray\AnnotatedContainer\LogicalConstraint\LogicalConstraint; use Cspray\AnnotatedContainer\LogicalConstraint\LogicalConstraintViolation; use Cspray\AnnotatedContainer\LogicalConstraint\LogicalConstraintViolationCollection; @@ -31,7 +32,7 @@ public function constraintViolations(ContainerDefinition $containerDefinition, P foreach ($servicePrepareMap as $classMethod => $attributes) { if (count($attributes) > 1) { $attributeTypes = trim(implode('- ', array_map( - static fn(?ServicePrepareAttribute $attribute) => ($attribute === null ? 'Call to servicePrepare() in DefinitionProvider' : 'Attributed with ' . $attribute::class) . PHP_EOL, + static fn(ServicePrepareAttribute $attribute) => ($attribute instanceof ServicePrepareFromFunctionalApi ? 'Call to servicePrepare() in DefinitionProvider' : 'Attributed with ' . $attribute::class) . PHP_EOL, $attributes ))); $message = << $attributes) { if (count($attributes) > 1) { $attributeTypes = trim(implode('- ', array_map( - static fn(?ServiceAttribute $attribute) => ($attribute === null ? 'Call to service() in DefinitionProvider' : 'Attributed with ' . $attribute::class) . PHP_EOL, + static fn(?ServiceAttribute $attribute) => ($attribute instanceof ServiceFromFunctionalApi ? 'Call to service() in DefinitionProvider' : 'Attributed with ' . $attribute::class) . PHP_EOL, $attributes ))); $message = <<mixed(); + } elseif ($reflectionType instanceof ReflectionNamedType) { + // if there is no name for the type it is implicitly mixed + $name = $reflectionType->getName() ?? 'mixed'; + $type = $this->fromName($name); + + if ($reflectionType->allowsNull() && $type !== $this->mixed() && $type !== $this->null()) { + $type = $this->union( + $this->null(), + $type + ); + } + } elseif ($reflectionType instanceof \ReflectionUnionType) { + $unionTypes = []; + foreach ($reflectionType->getTypes() as $rt) { + $unionTypes[] = $this->fromReflection($rt); + } + $type = $this->union(...$unionTypes); + } elseif ($reflectionType instanceof \ReflectionIntersectionType) { + $intersectTypes = []; + foreach ($reflectionType->getTypes() as $rt) { + $intersectTypes[] = $this->fromReflection($rt); + } + $type = $this->intersect(...$intersectTypes); + } + + return $type; + } + + public function fromName(string $name) : Type { + return match ($name) { + 'array' => $this->array(), + 'bool' => $this->bool(), + 'float' => $this->float(), + 'int' => $this->int(), + 'mixed' => $this->mixed(), + 'never' => $this->never(), + 'null' => $this->null(), + 'object' => $this->object(), + 'self' => $this->self(), + 'static' => $this->static(), + 'string' => $this->string(), + 'void' => $this->void(), + default => $this->class($name), + }; + } + + public function array() : Type { + static $type; + return $type ??= $this->createType('array'); + } + + public function bool() : Type { + static $type; + return $type ??= $this->createType('bool'); + } + + /** + * @param class-string $class + * @return self + */ + public function class(string $class) : Type { + static $types = []; + return $types[$class] ??= $this->createType($class); + } + + public function float() : Type { + static $type; + return $type ??= $this->createType('float'); + } + + public function int() : Type { + static $type; + return $type ??= $this->createType('int'); + } + + public function mixed() : Type { + static $type; + return $type ??= $this->createType('mixed'); + } + + public function never() : Type { + static $type; + return $type ??= $this->createType('never'); + } + + public function null() : Type { + static $type; + return $type ??= $this->createType('null'); + } + + public function object() : Type { + static $type; + return $type ??= $this->createType('object'); + } + + public function self() : Type { + static $type; + return $type ??= $this->createType('self'); + } + + public function static() : Type { + static $type; + return $type ??= $this->createType('static'); + } + + public function string() : Type { + static $type; + return $type ??= $this->createType('string'); + } + + public function void() : Type { + static $type; + return $type ??= $this->createType('void'); + } + + public function union(Type|TypeIntersect $first, Type|TypeIntersect $second, Type|TypeIntersect...$additional) : TypeUnion { + return $this->createTypeUnion( + $first, + $second, + ...$additional + ); + } + + public function nullable(Type $type) : TypeUnion { + return $this->createTypeUnion( + $this->null(), + $type + ); + } + + public function intersect(Type $first, Type $second, Type...$additional) : TypeIntersect { + return $this->createTypeIntersect( + $first, + $second, + ...$additional + ); + } + + private function createType(string $typeName) : Type { + return new class($typeName) implements Type { + public function __construct( + private readonly string $name + ) { + } + + public function name() : string { + return $this->name; + } + + public function equals(TypeUnion|TypeIntersect|Type $type) : bool { + if (!$type instanceof Type) { + return false; + } + + return $type->name() === $this->name(); + } + }; + } + + private function createTypeUnion(Type|TypeIntersect $one, Type|TypeIntersect $two, Type|TypeIntersect...$additional) : TypeUnion { + return new class([$one, $two, ...$additional]) implements TypeUnion { + private readonly string $name; + public function __construct( + private readonly array $types + ) { + $typeName = static fn(Type|TypeIntersect $type): string => + $type instanceof Type ? $type->name() : sprintf('(%s)', $type->name()); + $this->name = join('|', array_map($typeName, $this->types)); + } + + public function name() : string { + return $this->name; + } + + /** + * @return list + */ + public function types() : array { + return $this->types; + } + + public function equals(TypeUnion|TypeIntersect|Type $type) : bool { + if (!$type instanceof TypeUnion) { + return false; + } + + $comparatorTypes = array_map(static fn(Type|TypeIntersect $t) => $t->name(), $type->types()); + $theseTypes = array_map(static fn(Type|TypeIntersect $t) => $t->name(), $this->types()); + + sort($comparatorTypes); + sort($theseTypes); + + return $comparatorTypes === $theseTypes; + } + }; + } + + private function createTypeIntersect(Type $one, Type $two, Type...$additional) : TypeIntersect { + return new class([$one, $two, ...$additional]) implements TypeIntersect { + public function __construct( + private readonly array $types + ) { + } + + public function name() : string { + return sprintf( + '%s', + join('&', array_map(static fn(Type $t) => $t->name(), $this->types())) + ); + } + + public function types() : array { + return $this->types; + } + + public function equals(TypeUnion|TypeIntersect|Type $type) : bool { + if (!$type instanceof TypeIntersect) { + return false; + } + + $comparatorTypes = array_map(static fn(Type|TypeIntersect $t) => $t->name(), $type->types()); + $theseTypes = array_map(static fn(Type|TypeIntersect $t) => $t->name(), $this->types()); + + sort($comparatorTypes); + sort($theseTypes); + + return $comparatorTypes === $theseTypes; + } + }; + } +} diff --git a/src/Reflection/TypeIntersect.php b/src/Reflection/TypeIntersect.php new file mode 100644 index 00000000..1d85e1fb --- /dev/null +++ b/src/Reflection/TypeIntersect.php @@ -0,0 +1,16 @@ + + */ + public function types() : array; +} diff --git a/src/Reflection/TypeUnion.php b/src/Reflection/TypeUnion.php new file mode 100644 index 00000000..cc66df0b --- /dev/null +++ b/src/Reflection/TypeUnion.php @@ -0,0 +1,16 @@ + + */ + public function types() : array; +} diff --git a/src/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzer.php b/src/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzer.php index cb2b7230..677637e9 100644 --- a/src/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzer.php +++ b/src/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzer.php @@ -2,13 +2,15 @@ namespace Cspray\AnnotatedContainer\StaticAnalysis; -use Cspray\AnnotatedContainer\Definition\AliasDefinition; -use Cspray\AnnotatedContainer\Definition\AliasDefinitionBuilder; +use Cspray\AnnotatedContainer\Attribute\InjectAttribute; +use Cspray\AnnotatedContainer\Attribute\Service; +use Cspray\AnnotatedContainer\Attribute\ServiceAttribute; +use Cspray\AnnotatedContainer\Attribute\ServiceDelegateAttribute; +use Cspray\AnnotatedContainer\Attribute\ServicePrepareAttribute; use Cspray\AnnotatedContainer\Definition\ContainerDefinition; use Cspray\AnnotatedContainer\Definition\ContainerDefinitionBuilder; use Cspray\AnnotatedContainer\Definition\InjectDefinition; use Cspray\AnnotatedContainer\Definition\ServiceDefinition; -use Cspray\AnnotatedContainer\Definition\ServiceDefinitionBuilder; use Cspray\AnnotatedContainer\Definition\ServiceDelegateDefinition; use Cspray\AnnotatedContainer\Definition\ServicePrepareDefinition; use Cspray\AnnotatedContainer\Event\StaticAnalysisEmitter; @@ -16,14 +18,12 @@ use Cspray\AnnotatedContainer\Exception\InvalidServiceDelegate; use Cspray\AnnotatedContainer\Exception\InvalidServicePrepare; use Cspray\AnnotatedContainer\Internal\AttributeType; -use Cspray\AnnotatedTarget\AnnotatedTarget; +use Cspray\AnnotatedContainer\Reflection\Type; use Cspray\AnnotatedTarget\AnnotatedTargetParser; -use Cspray\AnnotatedTarget\AnnotatedTargetParserOptionsBuilder; +use Cspray\AnnotatedTarget\AnnotatedTargetParserOptions; use Cspray\AnnotatedTarget\Exception\InvalidArgumentException; -use Cspray\Typiphy\ObjectType; -use ReflectionClass; use stdClass; -use function Cspray\Typiphy\objectType; +use function Cspray\AnnotatedContainer\Definition\definitionFactory; /** * A ContainerDefinitionCompiler that utilizes the AnnotatedTarget concept by parsing given source code directories and @@ -40,7 +40,6 @@ final class AnnotatedTargetContainerDefinitionAnalyzer implements ContainerDefin public function __construct( private readonly AnnotatedTargetParser $annotatedTargetCompiler, - private readonly AnnotatedTargetDefinitionConverter $definitionConverter, private readonly StaticAnalysisEmitter $emitter ) { } @@ -100,33 +99,28 @@ private function parse( $consumer->servicePrepareDefinitions = []; $consumer->serviceDelegateDefinitions = []; $consumer->injectDefinitions = []; - $attributeTypes = array_map( - static function(AttributeType $attributeType) : ObjectType { - /** @var class-string $value */ - $value = $attributeType->value; - return objectType($value); - }, - AttributeType::cases() - ); $dirs = $containerDefinitionAnalysisOptions->scanDirectories(); - $options = AnnotatedTargetParserOptionsBuilder::scanDirectories(...$dirs) - ->filterAttributes(...$attributeTypes) - ->build(); + $options = AnnotatedTargetParserOptions::scanForSpecificAttributes( + $dirs, + array_map(static fn(AttributeType $attributeType) => $attributeType->value, AttributeType::cases()), + ); - /** @var AnnotatedTarget $target */ foreach ($this->annotatedTargetCompiler->parse($options) as $target) { - $definition = $this->definitionConverter->convert($target); - - if ($definition instanceof ServiceDefinition) { + $attribute = $target->attributeInstance(); + if ($attribute instanceof ServiceAttribute) { + $definition = definitionFactory()->serviceDefinitionFromAnnotatedTarget($target); $consumer->serviceDefinitions[] = $definition; $this->emitter->emitAnalyzedServiceDefinitionFromAttribute($target, $definition); - } elseif ($definition instanceof ServicePrepareDefinition) { + } elseif ($attribute instanceof ServicePrepareAttribute) { + $definition = definitionFactory()->servicePrepareDefinitionFromAnnotatedTarget($target); $consumer->servicePrepareDefinitions[] = $definition; $this->emitter->emitAnalyzedServicePrepareDefinitionFromAttribute($target, $definition); - } elseif ($definition instanceof ServiceDelegateDefinition) { + } elseif ($attribute instanceof ServiceDelegateAttribute) { + $definition = definitionFactory()->serviceDelegateDefinitionFromAnnotatedTarget($target); $consumer->serviceDelegateDefinitions[] = $definition; $this->emitter->emitAnalyzedServiceDelegateDefinitionFromAttribute($target, $definition); - } elseif ($definition instanceof InjectDefinition) { + } elseif ($attribute instanceof InjectAttribute) { + $definition = definitionFactory()->injectDefinitionFromAnnotatedTarget($target); $consumer->injectDefinitions[] = $definition; $this->emitter->emitAnalyzedInjectDefinitionFromAttribute($target, $definition); } @@ -156,14 +150,19 @@ private function addAnnotatedDefinitions( foreach ($consumer['serviceDelegateDefinitions'] as $serviceDelegateDefinition) { $serviceDef = $this->serviceDefinition($containerDefinitionBuilder, $serviceDelegateDefinition->serviceType()); + + // We need to handle the scenario where a user is using Annotated Container with limited or no Attributes + // In that use case the user is providing many ServiceDelegate attributes, we should not require manually + // defining those services, but we still want them to get added to the ContainerDefinition in the end + // to properly represent the state of the Container for tooling and analysis. if ($serviceDef === null) { - $reflection = new ReflectionClass($serviceDelegateDefinition->serviceType()->name()); - if ($reflection->isInterface() || $reflection->isAbstract()) { - $serviceDef = ServiceDefinitionBuilder::forAbstract($serviceDelegateDefinition->serviceType())->build(); - } else { - $serviceDef = ServiceDefinitionBuilder::forConcrete($serviceDelegateDefinition->serviceType())->build(); - } - $containerDefinitionBuilder = $containerDefinitionBuilder->withServiceDefinition($serviceDef); + $impliedThroughDelegationServiceDefinition = definitionFactory()->serviceDefinitionFromObjectTypeAndAttribute( + $serviceDelegateDefinition->serviceType(), + new Service() + ); + $containerDefinitionBuilder = $containerDefinitionBuilder->withServiceDefinition( + $impliedThroughDelegationServiceDefinition + ); } $containerDefinitionBuilder = $containerDefinitionBuilder->withServiceDelegateDefinition($serviceDelegateDefinition); } @@ -207,7 +206,7 @@ private function addAnnotatedDefinitions( return $containerDefinitionBuilder; } - private function serviceDefinition(ContainerDefinitionBuilder $containerDefinitionBuilder, ObjectType $objectType) : ?ServiceDefinition { + private function serviceDefinition(ContainerDefinitionBuilder $containerDefinitionBuilder, Type $objectType) : ?ServiceDefinition { $return = null; foreach ($containerDefinitionBuilder->serviceDefinitions() as $serviceDefinition) { if ($serviceDefinition->type() === $objectType) { @@ -263,8 +262,8 @@ public function addInjectDefinition(InjectDefinition $injectDefinition) : void { } private function addAliasDefinitions(ContainerDefinitionBuilder $containerDefinitionBuilder) : ContainerDefinitionBuilder { - /** @var list $abstractTypes */ - /** @var list $concreteTypes */ + /** @var list $abstractTypes */ + /** @var list $concreteTypes */ $abstractTypes = []; $concreteTypes = []; @@ -280,9 +279,7 @@ private function addAliasDefinitions(ContainerDefinitionBuilder $containerDefini foreach ($concreteTypes as $concreteType) { $abstractTypeString = $abstractType->name(); if (is_subclass_of($concreteType->name(), $abstractTypeString)) { - $aliasDefinition = AliasDefinitionBuilder::forAbstract($abstractType) - ->withConcrete($concreteType) - ->build(); + $aliasDefinition = definitionFactory()->aliasDefinition($abstractType, $concreteType); $containerDefinitionBuilder = $containerDefinitionBuilder->withAliasDefinition($aliasDefinition); $this->emitter->emitAddedAliasDefinition($aliasDefinition); } diff --git a/src/StaticAnalysis/AnnotatedTargetDefinitionConverter.php b/src/StaticAnalysis/AnnotatedTargetDefinitionConverter.php deleted file mode 100644 index c02e22a4..00000000 --- a/src/StaticAnalysis/AnnotatedTargetDefinitionConverter.php +++ /dev/null @@ -1,249 +0,0 @@ -attributeInstance(); - if ($attrInstance instanceof ServiceAttribute) { - return $this->buildServiceDefinition($target); - } - - if ($attrInstance instanceof InjectAttribute) { - return $this->buildInjectDefinition($target); - } - - if ($attrInstance instanceof ServiceDelegateAttribute) { - return $this->buildServiceDelegateDefinition($target); - } - - if ($attrInstance instanceof ServicePrepareAttribute) { - return $this->buildServicePrepareDefinition($target); - } - - throw InvalidAnnotatedTarget::fromAttributeInstanceNotKnownType(); - } - - private function buildServiceDefinition(AnnotatedTarget $target) : ServiceDefinition { - $reflection = $target->targetReflection(); - assert($reflection instanceof ReflectionClass); - $serviceType = objectType($reflection->getName()); - /** @var Service $attribute */ - $attribute = $target->attributeInstance(); - if ($reflection->isInterface() || $reflection->isAbstract()) { - $builder = ServiceDefinitionBuilder::forAbstract($serviceType); - } else { - $builder = ServiceDefinitionBuilder::forConcrete($serviceType, $attribute->isPrimary()); - } - - $builder = $builder->withAttribute($attribute); - - $profiles = $attribute->profiles(); - if ($profiles === []) { - $profiles = ['default']; - } - $builder = $builder->withProfiles($profiles); - $name = $attribute->name(); - if ($name !== null) { - $builder = $builder->withName($name); - } - - return $builder->build(); - } - - private function buildServiceDelegateDefinition(AnnotatedTarget $target) : ServiceDelegateDefinition { - $reflection = $target->targetReflection(); - assert($reflection instanceof ReflectionMethod); - $delegateType = $reflection->getDeclaringClass()->getName(); - $delegateMethod = $reflection->getName(); - $attribute = $target->attributeInstance(); - assert($attribute instanceof ServiceDelegateAttribute); - - /** @var class-string|null $service */ - $service = $attribute->service(); - if ($service !== null) { - return ServiceDelegateDefinitionBuilder::forService(objectType($service)) - ->withDelegateMethod(objectType($delegateType), $delegateMethod) - ->withAttribute($attribute) - ->build(); - } - - $returnType = $reflection->getReturnType(); - if ($returnType instanceof ReflectionIntersectionType) { - throw InvalidServiceDelegate::factoryMethodReturnsIntersectionType($delegateType, $delegateMethod); - } - - if ($returnType instanceof ReflectionUnionType) { - throw InvalidServiceDelegate::factoryMethodReturnsUnionType($delegateType, $delegateMethod); - } - - if ($returnType instanceof ReflectionNamedType) { - if (!class_exists($returnType->getName()) && !interface_exists($returnType->getName())) { - throw InvalidServiceDelegate::factoryMethodReturnsScalarType($delegateType, $delegateMethod); - } - return ServiceDelegateDefinitionBuilder::forService(objectType($returnType->getName())) - ->withDelegateMethod(objectType($delegateType), $delegateMethod) - ->withAttribute($attribute) - ->build(); - } - - throw InvalidServiceDelegate::factoryMethodDoesNotDeclareService($delegateType, $delegateMethod); - } - - private function buildServicePrepareDefinition(AnnotatedTarget $target) : ServicePrepareDefinition { - $reflection = $target->targetReflection(); - assert($reflection instanceof ReflectionMethod); - $prepareType = $reflection->getDeclaringClass()->getName(); - $method = $reflection->getName(); - $attribute = $target->attributeInstance(); - assert($attribute instanceof ServicePrepareAttribute); - - return ServicePrepareDefinitionBuilder::forMethod(objectType($prepareType), $method) - ->withAttribute($attribute) - ->build(); - } - - private function buildInjectDefinition(AnnotatedTarget $target) : InjectDefinition { - return $this->buildMethodInjectDefinition($target); - } - - private function buildMethodInjectDefinition(AnnotatedTarget $target) : InjectDefinition { - $targetReflection = $target->targetReflection(); - assert($targetReflection instanceof \ReflectionParameter); - $declaringClass = $targetReflection->getDeclaringClass(); - assert(!is_null($declaringClass)); - - $serviceType = objectType($declaringClass->getName()); - $method = $targetReflection->getDeclaringFunction()->getName(); - $param = $targetReflection->getName(); - $paramType = $this->convertReflectionType($targetReflection->getType()); - $attributeInstance = $target->attributeInstance(); - assert($attributeInstance instanceof InjectAttribute); - - $builder = InjectDefinitionBuilder::forService($serviceType)->withMethod($method, $paramType, $param); - - return $this->buildInjectFromAttributeData($builder, $attributeInstance); - } - - private function buildInjectFromAttributeData(InjectDefinitionBuilder $builder, InjectAttribute $inject) : InjectDefinition { - $builder = $builder->withAttribute($inject)->withValue($inject->value()); - $from = $inject->from(); - if ($from !== null) { - $builder = $builder->withStore($from); - } - - $profiles = $inject->profiles(); - if (count($profiles) === 0) { - $profiles[] = 'default'; - } - - $builder = $builder->withProfiles(...$profiles); - return $builder->build(); - } - - private function convertReflectionType(?ReflectionType $reflectionType) : Type|TypeUnion|TypeIntersect { - if ($reflectionType instanceof ReflectionNamedType) { - $paramType = $this->convertReflectionNamedType($reflectionType); - // The ?type syntax is not recognized as a TypeUnion but we normalize it to use with our type system - if ($paramType !== mixedType() && $reflectionType->allowsNull()) { - $paramType = typeUnion($paramType, nullType()); - } - } elseif ($reflectionType instanceof ReflectionUnionType || $reflectionType instanceof ReflectionIntersectionType) { - $types = []; - foreach ($reflectionType->getTypes() as $type) { - $types[] = $this->convertReflectionNamedType($type); - } - if ($reflectionType instanceof ReflectionUnionType) { - // At this point we know this is a non-empty list of types because we - // encountered a union type. This might include scalar values so we can't - // guarantee these are all object types. - /** @var non-empty-list $types */ - $paramType = typeUnion(...$types); - } else { - // At this point we know this is a non-empty list of object types because - // we encountered an intersection type so there must be something in the array - // of converted types AND the only types allowed in a type intersect at the - // language level are objects. - /** @var non-empty-list $types */ - $paramType = typeIntersect(...$types); - } - } else { - $paramType = mixedType(); - } - - return $paramType; - } - - private function convertReflectionNamedType(ReflectionNamedType $reflectionNamedType) : Type { - $type = $reflectionNamedType->getName(); - $parsedType = match ($type) { - 'int' => intType(), - 'string' => stringType(), - 'bool' => boolType(), - 'array' => arrayType(), - 'float' => floatType(), - 'mixed' => mixedType(), - default => null - }; - - if ($parsedType === null) { - assert(class_exists($type)); - $parsedType = objectType($type); - } - - return $parsedType; - } -} diff --git a/test/Fixture/AbstractClassAliasedServiceFixture.php b/test/Fixture/AbstractClassAliasedServiceFixture.php index a65d384d..25c3295a 100644 --- a/test/Fixture/AbstractClassAliasedServiceFixture.php +++ b/test/Fixture/AbstractClassAliasedServiceFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class AbstractClassAliasedServiceFixture implements Fixture { @@ -11,11 +11,11 @@ public function getPath() : string { return __DIR__ . '/AbstractClassImplicitAliasedServices'; } - public function fooAbstract() : ObjectType { - return objectType(AbstractClassImplicitAliasedServices\AbstractFoo::class); + public function fooAbstract() : Type { + return types()->class(AbstractClassImplicitAliasedServices\AbstractFoo::class); } - public function fooImplementation() : ObjectType { - return objectType(AbstractClassImplicitAliasedServices\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(AbstractClassImplicitAliasedServices\FooImplementation::class); } } diff --git a/test/Fixture/AmbiguousAliasedServicesFixture.php b/test/Fixture/AmbiguousAliasedServicesFixture.php index 7e445758..7c34c864 100644 --- a/test/Fixture/AmbiguousAliasedServicesFixture.php +++ b/test/Fixture/AmbiguousAliasedServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class AmbiguousAliasedServicesFixture implements Fixture { @@ -12,19 +12,19 @@ public function getPath() : string { return __DIR__ . '/AmbiguousAliasedServices'; } - public function fooInterface() : ObjectType { - return objectType(AmbiguousAliasedServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(AmbiguousAliasedServices\FooInterface::class); } - public function barImplementation() : ObjectType { - return objectType(AmbiguousAliasedServices\BarImplementation::class); + public function barImplementation() : Type { + return types()->class(AmbiguousAliasedServices\BarImplementation::class); } - public function bazImplementation() : ObjectType { - return objectType(AmbiguousAliasedServices\BazImplementation::class); + public function bazImplementation() : Type { + return types()->class(AmbiguousAliasedServices\BazImplementation::class); } - public function quxImplementation() : ObjectType { - return objectType(AmbiguousAliasedServices\QuxImplementation::class); + public function quxImplementation() : Type { + return types()->class(AmbiguousAliasedServices\QuxImplementation::class); } } diff --git a/test/Fixture/AutowireableFactoryServicesFixture.php b/test/Fixture/AutowireableFactoryServicesFixture.php index dc5cd82b..2b65c984 100644 --- a/test/Fixture/AutowireableFactoryServicesFixture.php +++ b/test/Fixture/AutowireableFactoryServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; class AutowireableFactoryServicesFixture implements Fixture { @@ -11,19 +11,19 @@ public function getPath() : string { return __DIR__ . '/AutowireableFactoryServices'; } - public function fooInterface() : ObjectType { - return objectType(AutowireableFactoryServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(AutowireableFactoryServices\FooInterface::class); } - public function fooImplementation() : ObjectType { - return objectType(AutowireableFactoryServices\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(AutowireableFactoryServices\FooImplementation::class); } - public function barImplementation() : ObjectType { - return objectType(AutowireableFactoryServices\BarImplementation::class); + public function barImplementation() : Type { + return types()->class(AutowireableFactoryServices\BarImplementation::class); } - public function factoryCreatedService() : ObjectType { - return objectType(AutowireableFactoryServices\FactoryCreatedService::class); + public function factoryCreatedService() : Type { + return types()->class(AutowireableFactoryServices\FactoryCreatedService::class); } } diff --git a/test/Fixture/BeanLikeConfigAbstractFixture.php b/test/Fixture/BeanLikeConfigAbstractFixture.php index af8a418a..58a67fd5 100644 --- a/test/Fixture/BeanLikeConfigAbstractFixture.php +++ b/test/Fixture/BeanLikeConfigAbstractFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class BeanLikeConfigAbstractFixture implements Fixture { @@ -11,7 +11,7 @@ public function getPath() : string { return __DIR__ . '/BeanLikeConfigAbstract'; } - public function abstractFooService() : ObjectType { - return objectType(BeanLikeConfigAbstract\AbstractFooService::class); + public function abstractFooService() : Type { + return types()->class(BeanLikeConfigAbstract\AbstractFooService::class); } } diff --git a/test/Fixture/BeanLikeConfigConcreteFixture.php b/test/Fixture/BeanLikeConfigConcreteFixture.php index 4e8b973a..04d93047 100644 --- a/test/Fixture/BeanLikeConfigConcreteFixture.php +++ b/test/Fixture/BeanLikeConfigConcreteFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class BeanLikeConfigConcreteFixture implements Fixture { @@ -11,7 +11,7 @@ public function getPath() : string { return __DIR__ . '/BeanLikeConfigConcrete'; } - public function fooService() : ObjectType { - return objectType(BeanLikeConfigConcrete\FooService::class); + public function fooService() : Type { + return types()->class(BeanLikeConfigConcrete\FooService::class); } } diff --git a/test/Fixture/BeanLikeConfigInterfaceFixture.php b/test/Fixture/BeanLikeConfigInterfaceFixture.php index ad632b08..909a4bf9 100644 --- a/test/Fixture/BeanLikeConfigInterfaceFixture.php +++ b/test/Fixture/BeanLikeConfigInterfaceFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class BeanLikeConfigInterfaceFixture implements Fixture { @@ -11,7 +11,7 @@ public function getPath() : string { return __DIR__ . '/BeanLikeConfigInterface'; } - public function fooInterface() : ObjectType { - return objectType(BeanLikeConfigInterface\FooInterface::class); + public function fooInterface() : Type { + return types()->class(BeanLikeConfigInterface\FooInterface::class); } } diff --git a/test/Fixture/ClassOnlyPrepareServicesFixture.php b/test/Fixture/ClassOnlyPrepareServicesFixture.php index bdb61149..d01b93c9 100644 --- a/test/Fixture/ClassOnlyPrepareServicesFixture.php +++ b/test/Fixture/ClassOnlyPrepareServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class ClassOnlyPrepareServicesFixture implements Fixture { @@ -11,11 +11,11 @@ public function getPath() : string { return __DIR__ . '/ClassOnlyPrepareServices'; } - public function fooInterface() : ObjectType { - return objectType(ClassOnlyPrepareServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(ClassOnlyPrepareServices\FooInterface::class); } - public function fooImplementation() : ObjectType { - return objectType(ClassOnlyPrepareServices\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(ClassOnlyPrepareServices\FooImplementation::class); } } diff --git a/test/Fixture/ClassOverridesPrepareServicesFixture.php b/test/Fixture/ClassOverridesPrepareServicesFixture.php index ac6aebc1..9dd683cc 100644 --- a/test/Fixture/ClassOverridesPrepareServicesFixture.php +++ b/test/Fixture/ClassOverridesPrepareServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class ClassOverridesPrepareServicesFixture implements Fixture { @@ -11,11 +11,11 @@ public function getPath() : string { return __DIR__ . '/ClassOverridesPrepareServices'; } - public function fooInterface() : ObjectType { - return objectType(ClassOverridesPrepareServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(ClassOverridesPrepareServices\FooInterface::class); } - public function fooImplementation() : ObjectType { - return objectType(ClassOverridesPrepareServices\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(ClassOverridesPrepareServices\FooImplementation::class); } } diff --git a/test/Fixture/CustomServiceAttributeFixture.php b/test/Fixture/CustomServiceAttributeFixture.php index 7130c57e..514a8978 100644 --- a/test/Fixture/CustomServiceAttributeFixture.php +++ b/test/Fixture/CustomServiceAttributeFixture.php @@ -4,8 +4,8 @@ use Cspray\AnnotatedContainer\Fixture\CustomServiceAttribute\OtherService; use Cspray\AnnotatedContainer\Fixture\CustomServiceAttribute\Repo; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class CustomServiceAttributeFixture implements Fixture { @@ -13,15 +13,15 @@ public function getPath() : string { return __DIR__ . '/CustomServiceAttribute'; } - public function repo() : ObjectType { - return objectType(Repo::class); + public function repo() : Type { + return types()->class(Repo::class); } - public function myRepo() : ObjectType { - return objectType(CustomServiceAttribute\MyRepo::class); + public function myRepo() : Type { + return types()->class(CustomServiceAttribute\MyRepo::class); } - public function otherService() : ObjectType { - return objectType(OtherService::class); + public function otherService() : Type { + return types()->class(OtherService::class); } } diff --git a/test/Fixture/DelegatedServiceFixture.php b/test/Fixture/DelegatedServiceFixture.php index 27289737..2e4c28b8 100644 --- a/test/Fixture/DelegatedServiceFixture.php +++ b/test/Fixture/DelegatedServiceFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class DelegatedServiceFixture implements Fixture { @@ -11,15 +11,15 @@ public function getPath() : string { return __DIR__ . '/DelegatedService'; } - public function serviceInterface() : ObjectType { - return objectType(DelegatedService\ServiceInterface::class); + public function serviceInterface() : Type { + return types()->class(DelegatedService\ServiceInterface::class); } - public function serviceFactory() : ObjectType { - return objectType(DelegatedService\ServiceFactory::class); + public function serviceFactory() : Type { + return types()->class(DelegatedService\ServiceFactory::class); } - public function fooService() : ObjectType { - return objectType(DelegatedService\FooService::class); + public function fooService() : Type { + return types()->class(DelegatedService\FooService::class); } } diff --git a/test/Fixture/DelegatedServiceStaticFactoryFixture.php b/test/Fixture/DelegatedServiceStaticFactoryFixture.php index 3d2ac97f..d4ddbf9d 100644 --- a/test/Fixture/DelegatedServiceStaticFactoryFixture.php +++ b/test/Fixture/DelegatedServiceStaticFactoryFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class DelegatedServiceStaticFactoryFixture implements Fixture { @@ -11,15 +11,15 @@ public function getPath() : string { return __DIR__ . '/DelegatedServiceStaticFactory'; } - public function serviceInterface() : ObjectType { - return objectType(DelegatedServiceStaticFactory\ServiceInterface::class); + public function serviceInterface() : Type { + return types()->class(DelegatedServiceStaticFactory\ServiceInterface::class); } - public function serviceFactory() : ObjectType { - return objectType(DelegatedServiceStaticFactory\ServiceFactory::class); + public function serviceFactory() : Type { + return types()->class(DelegatedServiceStaticFactory\ServiceFactory::class); } - public function fooService() : ObjectType { - return objectType(DelegatedServiceStaticFactory\FooService::class); + public function fooService() : Type { + return types()->class(DelegatedServiceStaticFactory\FooService::class); } } diff --git a/test/Fixture/DuplicateNamedServiceDifferentProfilesFixture.php b/test/Fixture/DuplicateNamedServiceDifferentProfilesFixture.php index 55f470ae..f859e5aa 100644 --- a/test/Fixture/DuplicateNamedServiceDifferentProfilesFixture.php +++ b/test/Fixture/DuplicateNamedServiceDifferentProfilesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class DuplicateNamedServiceDifferentProfilesFixture implements Fixture { @@ -11,11 +11,11 @@ public function getPath() : string { return __DIR__ . '/DuplicateNamedServiceDifferentProfiles'; } - public function barService() : ObjectType { - return objectType(DuplicateNamedServiceDifferentProfiles\BarService::class); + public function barService() : Type { + return types()->class(DuplicateNamedServiceDifferentProfiles\BarService::class); } - public function fooService() : ObjectType { - return objectType(DuplicateNamedServiceDifferentProfiles\FooService::class); + public function fooService() : Type { + return types()->class(DuplicateNamedServiceDifferentProfiles\FooService::class); } } diff --git a/test/Fixture/ImplicitAliasThroughAbstractClassServicesFixture.php b/test/Fixture/ImplicitAliasThroughAbstractClassServicesFixture.php index 75e155e3..c8cebea4 100644 --- a/test/Fixture/ImplicitAliasThroughAbstractClassServicesFixture.php +++ b/test/Fixture/ImplicitAliasThroughAbstractClassServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class ImplicitAliasThroughAbstractClassServicesFixture implements Fixture { @@ -11,15 +11,15 @@ public function getPath() : string { return __DIR__ . '/ImplicitAliasThroughAbstractClassServices'; } - public function fooAbstract() : ObjectType { - return objectType(ImplicitAliasThroughAbstractClassServices\AbstractFoo::class); + public function fooAbstract() : Type { + return types()->class(ImplicitAliasThroughAbstractClassServices\AbstractFoo::class); } - public function fooInterface() : ObjectType { - return objectType(ImplicitAliasThroughAbstractClassServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(ImplicitAliasThroughAbstractClassServices\FooInterface::class); } - public function fooImplementation() : ObjectType { - return objectType(ImplicitAliasThroughAbstractClassServices\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(ImplicitAliasThroughAbstractClassServices\FooImplementation::class); } } diff --git a/test/Fixture/ImplicitAliasedServicesFixture.php b/test/Fixture/ImplicitAliasedServicesFixture.php index b1843843..9fd17614 100755 --- a/test/Fixture/ImplicitAliasedServicesFixture.php +++ b/test/Fixture/ImplicitAliasedServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class ImplicitAliasedServicesFixture implements Fixture { @@ -11,11 +11,11 @@ public function getPath() : string { return __DIR__ . '/ImplicitAliasedServices'; } - public function fooInterface() : ObjectType { - return objectType(ImplicitAliasedServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(ImplicitAliasedServices\FooInterface::class); } - public function fooImplementation() : ObjectType { - return objectType(ImplicitAliasedServices\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(ImplicitAliasedServices\FooImplementation::class); } } diff --git a/test/Fixture/ImplicitServiceDelegateTypeFixture.php b/test/Fixture/ImplicitServiceDelegateTypeFixture.php index 888d395d..cd587a7c 100644 --- a/test/Fixture/ImplicitServiceDelegateTypeFixture.php +++ b/test/Fixture/ImplicitServiceDelegateTypeFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class ImplicitServiceDelegateTypeFixture implements Fixture { @@ -11,11 +11,11 @@ public function getPath() : string { return __DIR__ . '/ImplicitServiceDelegateType'; } - public function fooService() : ObjectType { - return objectType(ImplicitServiceDelegateType\FooService::class); + public function fooService() : Type { + return types()->class(ImplicitServiceDelegateType\FooService::class); } - public function fooServiceFactory() : ObjectType { - return objectType(ImplicitServiceDelegateType\FooServiceFactory::class); + public function fooServiceFactory() : Type { + return types()->class(ImplicitServiceDelegateType\FooServiceFactory::class); } } diff --git a/test/Fixture/ImplicitServiceDelegateUnionTypeFixture.php b/test/Fixture/ImplicitServiceDelegateUnionTypeFixture.php index 3b6a3877..1a801adf 100644 --- a/test/Fixture/ImplicitServiceDelegateUnionTypeFixture.php +++ b/test/Fixture/ImplicitServiceDelegateUnionTypeFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class ImplicitServiceDelegateUnionTypeFixture implements Fixture { @@ -11,15 +11,15 @@ public function getPath() : string { return __DIR__ . '/ImplicitServiceDelegateUnionType'; } - public function fooService() : ObjectType { - return objectType(Cspray\AnnotatedContainer\Fixture\ImplicitServiceDelegateUnionType\FooService::class); + public function fooService() : Type { + return types()->class(Cspray\AnnotatedContainer\Fixture\ImplicitServiceDelegateUnionType\FooService::class); } - public function barService() : ObjectType { - return objectType(Cspray\AnnotatedContainer\Fixture\ImplicitServiceDelegateUnionType\BarService::class); + public function barService() : Type { + return types()->class(Cspray\AnnotatedContainer\Fixture\ImplicitServiceDelegateUnionType\BarService::class); } - public function serviceFactory() : ObjectType { - return objectType(Cspray\AnnotatedContainer\Fixture\ImplicitServiceDelegateUnionType\ServiceFactory::class); + public function serviceFactory() : Type { + return types()->class(Cspray\AnnotatedContainer\Fixture\ImplicitServiceDelegateUnionType\ServiceFactory::class); } } diff --git a/test/Fixture/InjectConstructorServicesFixture.php b/test/Fixture/InjectConstructorServicesFixture.php index 0d4603f9..602e07d1 100644 --- a/test/Fixture/InjectConstructorServicesFixture.php +++ b/test/Fixture/InjectConstructorServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class InjectConstructorServicesFixture implements Fixture { @@ -11,47 +11,47 @@ public function getPath() : string { return __DIR__ . '/InjectConstructorServices'; } - public function injectArrayService() : ObjectType { - return objectType(InjectConstructorServices\ArrayInjectService::class); + public function injectArrayService() : Type { + return types()->class(InjectConstructorServices\ArrayInjectService::class); } - public function injectIntService() : ObjectType { - return objectType(InjectConstructorServices\IntInjectService::class); + public function injectIntService() : Type { + return types()->class(InjectConstructorServices\IntInjectService::class); } - public function injectBoolService() : ObjectType { - return objectType(InjectConstructorServices\BoolInjectService::class); + public function injectBoolService() : Type { + return types()->class(InjectConstructorServices\BoolInjectService::class); } - public function injectFloatService() : ObjectType { - return objectType(InjectConstructorServices\FloatInjectService::class); + public function injectFloatService() : Type { + return types()->class(InjectConstructorServices\FloatInjectService::class); } - public function injectStringService() : ObjectType { - return objectType(InjectConstructorServices\StringInjectService::class); + public function injectStringService() : Type { + return types()->class(InjectConstructorServices\StringInjectService::class); } - public function injectEnvService() : ObjectType { - return objectType(InjectConstructorServices\EnvInjectService::class); + public function injectEnvService() : Type { + return types()->class(InjectConstructorServices\EnvInjectService::class); } - public function injectExplicitMixedService() : ObjectType { - return objectType(InjectConstructorServices\ExplicitMixedInjectService::class); + public function injectExplicitMixedService() : Type { + return types()->class(InjectConstructorServices\ExplicitMixedInjectService::class); } - public function injectImplicitMixedService() : ObjectType { - return objectType(InjectConstructorServices\ImplicitMixedInjectService::class); + public function injectImplicitMixedService() : Type { + return types()->class(InjectConstructorServices\ImplicitMixedInjectService::class); } - public function injectNullableStringService() : ObjectType { - return objectType(InjectConstructorServices\NullableStringInjectService::class); + public function injectNullableStringService() : Type { + return types()->class(InjectConstructorServices\NullableStringInjectService::class); } - public function injectProfilesStringService() : ObjectType { - return objectType(InjectConstructorServices\ProfilesStringInjectService::class); + public function injectProfilesStringService() : Type { + return types()->class(InjectConstructorServices\ProfilesStringInjectService::class); } - public function injectTypeUnionService() : ObjectType { - return objectType(InjectConstructorServices\TypeUnionInjectService::class); + public function injectTypeUnionService() : Type { + return types()->class(InjectConstructorServices\TypeUnionInjectService::class); } } diff --git a/test/Fixture/InjectCustomStoreServicesFixture.php b/test/Fixture/InjectCustomStoreServicesFixture.php index 5ce3f361..c5534de1 100644 --- a/test/Fixture/InjectCustomStoreServicesFixture.php +++ b/test/Fixture/InjectCustomStoreServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class InjectCustomStoreServicesFixture implements Fixture { @@ -11,7 +11,7 @@ public function getPath() : string { return __DIR__ . '/InjectCustomStoreServices'; } - public function scalarInjector() : ObjectType { - return objectType(InjectCustomStoreServices\ScalarInjector::class); + public function scalarInjector() : Type { + return types()->class(InjectCustomStoreServices\ScalarInjector::class); } } diff --git a/test/Fixture/InjectEnumConstructorServicesFixture.php b/test/Fixture/InjectEnumConstructorServicesFixture.php index 0f2f4b93..1f09a79c 100644 --- a/test/Fixture/InjectEnumConstructorServicesFixture.php +++ b/test/Fixture/InjectEnumConstructorServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; class InjectEnumConstructorServicesFixture implements Fixture { @@ -11,7 +11,7 @@ public function getPath() : string { return __DIR__ . '/InjectEnumConstructorServices'; } - public function enumInjector() : ObjectType { - return objectType(InjectEnumConstructorServices\EnumInjector::class); + public function enumInjector() : Type { + return types()->class(InjectEnumConstructorServices\EnumInjector::class); } } diff --git a/test/Fixture/InjectIntersectCustomStoreServicesFixture.php b/test/Fixture/InjectIntersectCustomStoreServicesFixture.php index 7a22143f..ad76b72a 100644 --- a/test/Fixture/InjectIntersectCustomStoreServicesFixture.php +++ b/test/Fixture/InjectIntersectCustomStoreServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; class InjectIntersectCustomStoreServicesFixture implements Fixture { @@ -11,19 +11,19 @@ public function getPath() : string { return __DIR__ . '/InjectIntersectCustomStoreServices'; } - public function barInterface() : ObjectType { - return objectType(InjectIntersectCustomStoreServices\BarInterface::class); + public function barInterface() : Type { + return types()->class(InjectIntersectCustomStoreServices\BarInterface::class); } - public function fooInterface() : ObjectType { - return objectType(InjectIntersectCustomStoreServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(InjectIntersectCustomStoreServices\FooInterface::class); } - public function intersectInjector() : ObjectType { - return objectType(InjectIntersectCustomStoreServices\IntersectInjector::class); + public function intersectInjector() : Type { + return types()->class(InjectIntersectCustomStoreServices\IntersectInjector::class); } - public function fooBarImplementation() : ObjectType { - return objectType(InjectIntersectCustomStoreServices\FooBarImplementation::class); + public function fooBarImplementation() : Type { + return types()->class(InjectIntersectCustomStoreServices\FooBarImplementation::class); } } diff --git a/test/Fixture/InjectNamedServicesFixture.php b/test/Fixture/InjectNamedServicesFixture.php index b6bf5288..b9b6f7c2 100644 --- a/test/Fixture/InjectNamedServicesFixture.php +++ b/test/Fixture/InjectNamedServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; class InjectNamedServicesFixture implements Fixture { @@ -11,19 +11,19 @@ public function getPath() : string { return __DIR__ . '/InjectNamedServices'; } - public function fooInterface() : ObjectType { - return objectType(InjectNamedServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(InjectNamedServices\FooInterface::class); } - public function fooImplementation() : ObjectType { - return objectType(InjectNamedServices\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(InjectNamedServices\FooImplementation::class); } - public function barImplementation() : ObjectType { - return objectType(InjectNamedServices\BarImplementation::class); + public function barImplementation() : Type { + return types()->class(InjectNamedServices\BarImplementation::class); } - public function serviceConsumer() : ObjectType { - return objectType(InjectNamedServices\ServiceConsumer::class); + public function serviceConsumer() : Type { + return types()->class(InjectNamedServices\ServiceConsumer::class); } } diff --git a/test/Fixture/InjectPrepareServicesFixture.php b/test/Fixture/InjectPrepareServicesFixture.php index c5816c5b..323d983d 100644 --- a/test/Fixture/InjectPrepareServicesFixture.php +++ b/test/Fixture/InjectPrepareServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class InjectPrepareServicesFixture implements Fixture { @@ -11,23 +11,23 @@ public function getPath() : string { return __DIR__ . '/InjectPrepareServices'; } - public function fooInterface() : ObjectType { - return objectType(InjectPrepareServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(InjectPrepareServices\FooInterface::class); } - public function fooImplementation() : ObjectType { - return objectType(InjectPrepareServices\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(InjectPrepareServices\FooImplementation::class); } - public function barImplementation() : ObjectType { - return objectType(InjectPrepareServices\BarImplementation::class); + public function barImplementation() : Type { + return types()->class(InjectPrepareServices\BarImplementation::class); } - public function prepareInjector() : ObjectType { - return objectType(InjectPrepareServices\PrepareInjector::class); + public function prepareInjector() : Type { + return types()->class(InjectPrepareServices\PrepareInjector::class); } - public function serviceScalarUnionPrepareInjector() : ObjectType { - return objectType(InjectPrepareServices\ServiceScalarUnionPrepareInjector::class); + public function serviceScalarUnionPrepareInjector() : Type { + return types()->class(InjectPrepareServices\ServiceScalarUnionPrepareInjector::class); } } diff --git a/test/Fixture/InjectServiceCollectionDecoratorFixture.php b/test/Fixture/InjectServiceCollectionDecoratorFixture.php index 98759a26..5aafdfa0 100644 --- a/test/Fixture/InjectServiceCollectionDecoratorFixture.php +++ b/test/Fixture/InjectServiceCollectionDecoratorFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; class InjectServiceCollectionDecoratorFixture implements Fixture { @@ -11,27 +11,27 @@ public function getPath() : string { return __DIR__ . '/InjectServiceCollectionDecorator'; } - public function fooService() : ObjectType { - return objectType(InjectServiceCollectionDecorator\FooService::class); + public function fooService() : Type { + return types()->class(InjectServiceCollectionDecorator\FooService::class); } - public function compositeFoo() : ObjectType { - return objectType(InjectServiceCollectionDecorator\CompositeFooImplementation::class); + public function compositeFoo() : Type { + return types()->class(InjectServiceCollectionDecorator\CompositeFooImplementation::class); } - public function fooInterface() : ObjectType { - return objectType(InjectServiceCollectionDecorator\FooInterface::class); + public function fooInterface() : Type { + return types()->class(InjectServiceCollectionDecorator\FooInterface::class); } - public function fooImplementation() : ObjectType { - return objectType(InjectServiceCollectionDecorator\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(InjectServiceCollectionDecorator\FooImplementation::class); } - public function barImplementation() : ObjectType { - return objectType(InjectServiceCollectionDecorator\BarImplementation::class); + public function barImplementation() : Type { + return types()->class(InjectServiceCollectionDecorator\BarImplementation::class); } - public function bazImplementation() : ObjectType { - return objectType(InjectServiceCollectionDecorator\BazImplementation::class); + public function bazImplementation() : Type { + return types()->class(InjectServiceCollectionDecorator\BazImplementation::class); } } diff --git a/test/Fixture/InjectServiceCollectionFixture.php b/test/Fixture/InjectServiceCollectionFixture.php index f9975c72..dee1d41d 100644 --- a/test/Fixture/InjectServiceCollectionFixture.php +++ b/test/Fixture/InjectServiceCollectionFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; class InjectServiceCollectionFixture implements Fixture { @@ -11,11 +11,11 @@ public function getPath() : string { return __DIR__ . '/InjectServiceCollection'; } - public function collectionInjector() : ObjectType { - return objectType(InjectServiceCollection\CollectionInjector::class); + public function collectionInjector() : Type { + return types()->class(InjectServiceCollection\CollectionInjector::class); } - public function fooInterface() : ObjectType { - return objectType(InjectServiceCollection\FooInterface::class); + public function fooInterface() : Type { + return types()->class(InjectServiceCollection\FooInterface::class); } } diff --git a/test/Fixture/InjectServiceConstructorServicesFixture.php b/test/Fixture/InjectServiceConstructorServicesFixture.php index a9369095..6df7e26f 100644 --- a/test/Fixture/InjectServiceConstructorServicesFixture.php +++ b/test/Fixture/InjectServiceConstructorServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class InjectServiceConstructorServicesFixture implements Fixture { @@ -11,23 +11,23 @@ public function getPath() : string { return __DIR__ . '/InjectServiceConstructorServices'; } - public function fooInterface() : ObjectType { - return objectType(InjectServiceConstructorServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(InjectServiceConstructorServices\FooInterface::class); } - public function fooImplementation() : ObjectType { - return objectType(InjectServiceConstructorServices\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(InjectServiceConstructorServices\FooImplementation::class); } - public function barImplementation() : ObjectType { - return objectType(InjectServiceConstructorServices\BarImplementation::class); + public function barImplementation() : Type { + return types()->class(InjectServiceConstructorServices\BarImplementation::class); } - public function serviceInjector() : ObjectType { - return objectType(InjectServiceConstructorServices\ServiceInjector::class); + public function serviceInjector() : Type { + return types()->class(InjectServiceConstructorServices\ServiceInjector::class); } - public function nullableServiceInjector() : ObjectType { - return objectType(InjectServiceConstructorServices\NullableServiceInjector::class); + public function nullableServiceInjector() : Type { + return types()->class(InjectServiceConstructorServices\NullableServiceInjector::class); } } diff --git a/test/Fixture/InjectServiceDomainCollection/ListOfAsFooInterfaceCollection.php b/test/Fixture/InjectServiceDomainCollection/ListOfAsFooInterfaceCollection.php index 21f0f33b..057f5063 100644 --- a/test/Fixture/InjectServiceDomainCollection/ListOfAsFooInterfaceCollection.php +++ b/test/Fixture/InjectServiceDomainCollection/ListOfAsFooInterfaceCollection.php @@ -3,8 +3,8 @@ namespace Cspray\AnnotatedContainer\Fixture\InjectServiceDomainCollection; use Cspray\AnnotatedContainer\ContainerFactory\ListOf; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; /** * @implements ListOf @@ -16,8 +16,8 @@ public function __construct( ) { } - public function type() : ObjectType { - return objectType($this->type); + public function type() : Type { + return types()->class($this->type); } public function toCollection(array $servicesOfType) : FooInterfaceCollection { diff --git a/test/Fixture/InjectServiceDomainCollectionFixture.php b/test/Fixture/InjectServiceDomainCollectionFixture.php index 87e6f0cd..20c8b714 100644 --- a/test/Fixture/InjectServiceDomainCollectionFixture.php +++ b/test/Fixture/InjectServiceDomainCollectionFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; class InjectServiceDomainCollectionFixture implements Fixture { @@ -11,11 +11,11 @@ public function getPath() : string { return __DIR__ . '/InjectServiceDomainCollection'; } - public function collectionInjector() : ObjectType { - return objectType(InjectServiceDomainCollection\CollectionInjector::class); + public function collectionInjector() : Type { + return types()->class(InjectServiceDomainCollection\CollectionInjector::class); } - public function fooInterface() : ObjectType { - return objectType(InjectServiceDomainCollection\FooInterface::class); + public function fooInterface() : Type { + return types()->class(InjectServiceDomainCollection\FooInterface::class); } } diff --git a/test/Fixture/InjectServiceIntersectConstructorServicesFixture.php b/test/Fixture/InjectServiceIntersectConstructorServicesFixture.php index 4612892d..ea5c092d 100644 --- a/test/Fixture/InjectServiceIntersectConstructorServicesFixture.php +++ b/test/Fixture/InjectServiceIntersectConstructorServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class InjectServiceIntersectConstructorServicesFixture implements Fixture { @@ -11,23 +11,23 @@ public function getPath() : string { return __DIR__ . '/InjectServiceIntersectUnionServices'; } - public function fooInterface() : ObjectType { - return objectType(InjectServiceIntersectUnionServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(InjectServiceIntersectUnionServices\FooInterface::class); } - public function barInterface() : ObjectType { - return objectType(InjectServiceIntersectUnionServices\BarInterface::class); + public function barInterface() : Type { + return types()->class(InjectServiceIntersectUnionServices\BarInterface::class); } - public function fooBarImplementation() : ObjectType { - return objectType(InjectServiceIntersectUnionServices\FooBarImplementation::class); + public function fooBarImplementation() : Type { + return types()->class(InjectServiceIntersectUnionServices\FooBarImplementation::class); } - public function barImplementation() : ObjectType { - return objectType(InjectServiceIntersectUnionServices\BarImplementation::class); + public function barImplementation() : Type { + return types()->class(InjectServiceIntersectUnionServices\BarImplementation::class); } - public function fooBarConsumer() : ObjectType { - return objectType(InjectServiceIntersectUnionServices\FooBarConsumer::class); + public function fooBarConsumer() : Type { + return types()->class(InjectServiceIntersectUnionServices\FooBarConsumer::class); } } diff --git a/test/Fixture/InjectUnionCustomStoreServicesFixture.php b/test/Fixture/InjectUnionCustomStoreServicesFixture.php index 242d5d2b..1548b8a9 100644 --- a/test/Fixture/InjectUnionCustomStoreServicesFixture.php +++ b/test/Fixture/InjectUnionCustomStoreServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class InjectUnionCustomStoreServicesFixture implements Fixture { @@ -11,19 +11,19 @@ public function getPath() : string { return __DIR__ . '/InjectUnionCustomStoreServices'; } - public function fooInterface() : ObjectType { - return objectType(InjectUnionCustomStoreServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(InjectUnionCustomStoreServices\FooInterface::class); } - public function barInterface() : ObjectType { - return objectType(InjectUnionCustomStoreServices\BarInterface::class); + public function barInterface() : Type { + return types()->class(InjectUnionCustomStoreServices\BarInterface::class); } - public function fooImplementation() : ObjectType { - return objectType(InjectUnionCustomStoreServices\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(InjectUnionCustomStoreServices\FooImplementation::class); } - public function unionInjector() : ObjectType { - return objectType(InjectUnionCustomStoreServices\UnionInjector::class); + public function unionInjector() : Type { + return types()->class(InjectUnionCustomStoreServices\UnionInjector::class); } } diff --git a/test/Fixture/InterfacePrepareServicesFixture.php b/test/Fixture/InterfacePrepareServicesFixture.php index cc542a2a..0c4afd96 100644 --- a/test/Fixture/InterfacePrepareServicesFixture.php +++ b/test/Fixture/InterfacePrepareServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class InterfacePrepareServicesFixture implements Fixture { @@ -11,11 +11,11 @@ public function getPath() : string { return __DIR__ . '/InterfacePrepareServices'; } - public function fooInterface() : ObjectType { - return objectType(InterfacePrepareServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(InterfacePrepareServices\FooInterface::class); } - public function fooImplementation() : ObjectType { - return objectType(InterfacePrepareServices\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(InterfacePrepareServices\FooImplementation::class); } } diff --git a/test/Fixture/LogicalConstraints/DuplicateServiceDelegateFixture.php b/test/Fixture/LogicalConstraints/DuplicateServiceDelegateFixture.php index 38f52e7b..417f31fa 100644 --- a/test/Fixture/LogicalConstraints/DuplicateServiceDelegateFixture.php +++ b/test/Fixture/LogicalConstraints/DuplicateServiceDelegateFixture.php @@ -5,8 +5,8 @@ use Cspray\AnnotatedContainer\Fixture\Fixture; use Cspray\AnnotatedContainer\Fixture\LogicalConstraints\DuplicateServiceDelegate\Factory; use Cspray\AnnotatedContainer\Fixture\LogicalConstraints\DuplicateServiceDelegate\FooService; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; class DuplicateServiceDelegateFixture implements Fixture { @@ -14,11 +14,11 @@ public function getPath() : string { return __DIR__ . '/DuplicateServiceDelegate'; } - public function fooService() : ObjectType { - return objectType(FooService::class); + public function fooService() : Type { + return types()->class(FooService::class); } - public function factory() : ObjectType { - return objectType(Factory::class); + public function factory() : Type { + return types()->class(Factory::class); } } diff --git a/test/Fixture/LogicalConstraints/DuplicateServiceNameFixture.php b/test/Fixture/LogicalConstraints/DuplicateServiceNameFixture.php index 98b9d2f4..7d591ca4 100644 --- a/test/Fixture/LogicalConstraints/DuplicateServiceNameFixture.php +++ b/test/Fixture/LogicalConstraints/DuplicateServiceNameFixture.php @@ -5,8 +5,8 @@ use Cspray\AnnotatedContainer\Fixture\Fixture; use Cspray\AnnotatedContainer\Fixture\LogicalConstraints\DuplicateServiceName\BarService; use Cspray\AnnotatedContainer\Fixture\LogicalConstraints\DuplicateServiceName\FooService; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class DuplicateServiceNameFixture implements Fixture { @@ -14,11 +14,11 @@ public function getPath() : string { return __DIR__ . '/DuplicateServiceName'; } - public function getBarService() : ObjectType { - return objectType(BarService::class); + public function getBarService() : Type { + return types()->class(BarService::class); } - public function getFooService() : ObjectType { - return objectType(FooService::class); + public function getFooService() : Type { + return types()->class(FooService::class); } } diff --git a/test/Fixture/LogicalConstraints/DuplicateServicePrepareFixture.php b/test/Fixture/LogicalConstraints/DuplicateServicePrepareFixture.php index b322169c..6d8417c0 100644 --- a/test/Fixture/LogicalConstraints/DuplicateServicePrepareFixture.php +++ b/test/Fixture/LogicalConstraints/DuplicateServicePrepareFixture.php @@ -4,8 +4,8 @@ use Cspray\AnnotatedContainer\Fixture\Fixture; use Cspray\AnnotatedContainer\Fixture\LogicalConstraints\DuplicateServicePrepare\FooService; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class DuplicateServicePrepareFixture implements Fixture { @@ -13,7 +13,7 @@ public function getPath() : string { return __DIR__ . '/DuplicateServicePrepare'; } - public function fooService() : ObjectType { - return objectType(FooService::class); + public function fooService() : Type { + return types()->class(FooService::class); } } diff --git a/test/Fixture/LogicalConstraints/DuplicateServiceTypeFixture.php b/test/Fixture/LogicalConstraints/DuplicateServiceTypeFixture.php index 3241fb79..8df44994 100644 --- a/test/Fixture/LogicalConstraints/DuplicateServiceTypeFixture.php +++ b/test/Fixture/LogicalConstraints/DuplicateServiceTypeFixture.php @@ -4,8 +4,8 @@ use Cspray\AnnotatedContainer\Fixture\Fixture; use Cspray\AnnotatedContainer\Fixture\LogicalConstraints\DuplicateServiceType\FooService; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class DuplicateServiceTypeFixture implements Fixture { @@ -13,7 +13,7 @@ public function getPath() : string { return __DIR__ . '/DuplicateServiceType'; } - public function fooService() : ObjectType { - return objectType(FooService::class); + public function fooService() : Type { + return types()->class(FooService::class); } } diff --git a/test/Fixture/LogicalConstraints/MultiplePrimaryServiceFixture.php b/test/Fixture/LogicalConstraints/MultiplePrimaryServiceFixture.php index 3a9f830d..4693dce2 100644 --- a/test/Fixture/LogicalConstraints/MultiplePrimaryServiceFixture.php +++ b/test/Fixture/LogicalConstraints/MultiplePrimaryServiceFixture.php @@ -6,8 +6,8 @@ use Cspray\AnnotatedContainer\Fixture\LogicalConstraints\MultiplePrimaryService\BarService; use Cspray\AnnotatedContainer\Fixture\LogicalConstraints\MultiplePrimaryService\FooInterface; use Cspray\AnnotatedContainer\Fixture\LogicalConstraints\MultiplePrimaryService\FooService; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class MultiplePrimaryServiceFixture implements Fixture { @@ -15,15 +15,15 @@ public function getPath() : string { return __DIR__ . '/MultiplePrimaryService'; } - public function fooInterface() : ObjectType { - return objectType(FooInterface::class); + public function fooInterface() : Type { + return types()->class(FooInterface::class); } - public function fooService() : ObjectType { - return objectType(FooService::class); + public function fooService() : Type { + return types()->class(FooService::class); } - public function barService() : ObjectType { - return objectType(BarService::class); + public function barService() : Type { + return types()->class(BarService::class); } } diff --git a/test/Fixture/MultiplePrepareServicesFixture.php b/test/Fixture/MultiplePrepareServicesFixture.php index d20564db..dc148aa4 100644 --- a/test/Fixture/MultiplePrepareServicesFixture.php +++ b/test/Fixture/MultiplePrepareServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class MultiplePrepareServicesFixture implements Fixture { @@ -11,7 +11,7 @@ public function getPath() : string { return __DIR__ . '/MultiplePrepareServices'; } - public function fooImplementation() : ObjectType { - return objectType(MultiplePrepareServices\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(MultiplePrepareServices\FooImplementation::class); } } diff --git a/test/Fixture/NamedProfileResolvedServicesFixture.php b/test/Fixture/NamedProfileResolvedServicesFixture.php index f71b2867..4eb2f4ac 100644 --- a/test/Fixture/NamedProfileResolvedServicesFixture.php +++ b/test/Fixture/NamedProfileResolvedServicesFixture.php @@ -2,28 +2,28 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; class NamedProfileResolvedServicesFixture implements Fixture { - public function getPath(): string { + public function getPath() : string { return __DIR__ . '/NamedProfileResolvedServices'; } - public function fooInterface() : ObjectType { - return objectType(NamedProfileResolvedServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(NamedProfileResolvedServices\FooInterface::class); } - public function devImplementation() : ObjectType { - return objectType(NamedProfileResolvedServices\DevFooImplementation::class); + public function devImplementation() : Type { + return types()->class(NamedProfileResolvedServices\DevFooImplementation::class); } - public function prodImplementation() : ObjectType { - return objectType(NamedProfileResolvedServices\ProdFooImplementation::class); + public function prodImplementation() : Type { + return types()->class(NamedProfileResolvedServices\ProdFooImplementation::class); } - public function testImplementation() : ObjectType { - return objectType(NamedProfileResolvedServices\TestFooImplementation::class); + public function testImplementation() : Type { + return types()->class(NamedProfileResolvedServices\TestFooImplementation::class); } } diff --git a/test/Fixture/NamedServicesFixture.php b/test/Fixture/NamedServicesFixture.php index 86af5804..1a98f9a4 100644 --- a/test/Fixture/NamedServicesFixture.php +++ b/test/Fixture/NamedServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class NamedServicesFixture implements Fixture { @@ -11,11 +11,11 @@ public function getPath() : string { return __DIR__ . '/NamedServices'; } - public function fooInterface() : ObjectType { - return objectType(NamedServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(NamedServices\FooInterface::class); } - public function fooImplementation() : ObjectType { - return objectType(NamedServices\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(NamedServices\FooImplementation::class); } } diff --git a/test/Fixture/NonAnnotatedServicesFixture.php b/test/Fixture/NonAnnotatedServicesFixture.php index f615f337..dbf70ce1 100755 --- a/test/Fixture/NonAnnotatedServicesFixture.php +++ b/test/Fixture/NonAnnotatedServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class NonAnnotatedServicesFixture implements Fixture { @@ -11,11 +11,11 @@ public function getPath() : string { return __DIR__ . '/NonAnnotatedServices'; } - public function annotatedService() : ObjectType { - return objectType(NonAnnotatedServices\AnnotatedService::class); + public function annotatedService() : Type { + return types()->class(NonAnnotatedServices\AnnotatedService::class); } - public function nonAnnotatedService() : ObjectType { - return objectType(NonAnnotatedServices\NotAnnotatedObject::class); + public function nonAnnotatedService() : Type { + return types()->class(NonAnnotatedServices\NotAnnotatedObject::class); } } diff --git a/test/Fixture/PrimaryAliasedServicesFixture.php b/test/Fixture/PrimaryAliasedServicesFixture.php index 5204ea0f..5eba790c 100644 --- a/test/Fixture/PrimaryAliasedServicesFixture.php +++ b/test/Fixture/PrimaryAliasedServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class PrimaryAliasedServicesFixture implements Fixture { @@ -11,19 +11,19 @@ public function getPath() : string { return __DIR__ . '/PrimaryAliasedServices'; } - public function fooInterface() : ObjectType { - return objectType(PrimaryAliasedServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(PrimaryAliasedServices\FooInterface::class); } - public function barImplementation() : ObjectType { - return objectType(PrimaryAliasedServices\BarImplementation::class); + public function barImplementation() : Type { + return types()->class(PrimaryAliasedServices\BarImplementation::class); } - public function bazImplementation() : ObjectType { - return objectType(PrimaryAliasedServices\BazImplementation::class); + public function bazImplementation() : Type { + return types()->class(PrimaryAliasedServices\BazImplementation::class); } - public function fooImplementation() : ObjectType { - return objectType(PrimaryAliasedServices\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(PrimaryAliasedServices\FooImplementation::class); } } diff --git a/test/Fixture/ProfileResolvedServicesFixture.php b/test/Fixture/ProfileResolvedServicesFixture.php index 2eaa5013..1bd67c97 100644 --- a/test/Fixture/ProfileResolvedServicesFixture.php +++ b/test/Fixture/ProfileResolvedServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class ProfileResolvedServicesFixture implements Fixture { @@ -11,19 +11,19 @@ public function getPath() : string { return __DIR__ . '/ProfileResolvedServices'; } - public function fooInterface() : ObjectType { - return objectType(ProfileResolvedServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(ProfileResolvedServices\FooInterface::class); } - public function devImplementation() : ObjectType { - return objectType(ProfileResolvedServices\DevFooImplementation::class); + public function devImplementation() : Type { + return types()->class(ProfileResolvedServices\DevFooImplementation::class); } - public function testImplementation() : ObjectType { - return objectType(ProfileResolvedServices\TestFooImplementation::class); + public function testImplementation() : Type { + return types()->class(ProfileResolvedServices\TestFooImplementation::class); } - public function prodImplementation() : ObjectType { - return objectType(ProfileResolvedServices\ProdFooImplementation::class); + public function prodImplementation() : Type { + return types()->class(ProfileResolvedServices\ProdFooImplementation::class); } } diff --git a/test/Fixture/SingleConcreteServiceFixture.php b/test/Fixture/SingleConcreteServiceFixture.php index 18e7e2dc..1afb656a 100755 --- a/test/Fixture/SingleConcreteServiceFixture.php +++ b/test/Fixture/SingleConcreteServiceFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class SingleConcreteServiceFixture implements Fixture { @@ -11,7 +11,7 @@ public function getPath() : string { return __DIR__ . '/SingleConcreteService'; } - public function fooImplementation() : ObjectType { - return objectType(SingleConcreteService\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(SingleConcreteService\FooImplementation::class); } } diff --git a/test/Fixture/SubNamespacedServicesFixture.php b/test/Fixture/SubNamespacedServicesFixture.php index 3c11cf3e..ea152cb2 100644 --- a/test/Fixture/SubNamespacedServicesFixture.php +++ b/test/Fixture/SubNamespacedServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class SubNamespacedServicesFixture implements Fixture { @@ -11,27 +11,27 @@ public function getPath() : string { return __DIR__ . '/SubNamespacedServices'; } - public function barInterface() : ObjectType { - return objectType(SubNamespacedServices\BarInterface::class); + public function barInterface() : Type { + return types()->class(SubNamespacedServices\BarInterface::class); } - public function bazInterface() : ObjectType { - return objectType(SubNamespacedServices\BazInterface::class); + public function bazInterface() : Type { + return types()->class(SubNamespacedServices\BazInterface::class); } - public function fooInterface() : ObjectType { - return objectType(SubNamespacedServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(SubNamespacedServices\FooInterface::class); } - public function fooImplementation() : ObjectType { - return objectType(SubNamespacedServices\Foo\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(SubNamespacedServices\Foo\FooImplementation::class); } - public function barImplementation() : ObjectType { - return objectType(SubNamespacedServices\Foo\Bar\BarImplementation::class); + public function barImplementation() : Type { + return types()->class(SubNamespacedServices\Foo\Bar\BarImplementation::class); } - public function bazImplementation() : ObjectType { - return objectType(SubNamespacedServices\Foo\Bar\Baz\BazImplementation::class); + public function bazImplementation() : Type { + return types()->class(SubNamespacedServices\Foo\Bar\Baz\BazImplementation::class); } } diff --git a/test/Fixture/ThirdPartyDelegatedServicesFixture.php b/test/Fixture/ThirdPartyDelegatedServicesFixture.php index 38c4cef3..2e095316 100644 --- a/test/Fixture/ThirdPartyDelegatedServicesFixture.php +++ b/test/Fixture/ThirdPartyDelegatedServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class ThirdPartyDelegatedServicesFixture implements Fixture { @@ -11,7 +11,7 @@ public function getPath() : string { return __DIR__ . '/ThirdPartyDelegatedServices'; } - public function loggerFactory() : ObjectType { - return objectType(ThirdPartyDelegatedServices\LoggerFactory::class); + public function loggerFactory() : Type { + return types()->class(ThirdPartyDelegatedServices\LoggerFactory::class); } } diff --git a/test/Fixture/ThirdPartyKitchenSinkFixture.php b/test/Fixture/ThirdPartyKitchenSinkFixture.php index da90c139..bf2c8bca 100644 --- a/test/Fixture/ThirdPartyKitchenSinkFixture.php +++ b/test/Fixture/ThirdPartyKitchenSinkFixture.php @@ -2,9 +2,17 @@ namespace Cspray\AnnotatedContainer\Fixture; +use Cspray\AnnotatedContainer\Fixture\ThirdPartyKitchenSink\NonAnnotatedService; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; + class ThirdPartyKitchenSinkFixture implements Fixture { public function getPath() : string { return __DIR__ . '/ThirdPartyKitchenSink'; } + + public function nonAnnotatedService() : Type { + return types()->class(NonAnnotatedService::class); + } } diff --git a/test/Fixture/ThirdPartyServicesFixture.php b/test/Fixture/ThirdPartyServicesFixture.php index d7f95140..9db7a407 100644 --- a/test/Fixture/ThirdPartyServicesFixture.php +++ b/test/Fixture/ThirdPartyServicesFixture.php @@ -2,8 +2,8 @@ namespace Cspray\AnnotatedContainer\Fixture; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; final class ThirdPartyServicesFixture implements Fixture { @@ -11,11 +11,11 @@ public function getPath() : string { return __DIR__ . '/ThirdPartyServices'; } - public function fooInterface() : ObjectType { - return objectType(ThirdPartyServices\FooInterface::class); + public function fooInterface() : Type { + return types()->class(ThirdPartyServices\FooInterface::class); } - public function fooImplementation() : ObjectType { - return objectType(ThirdPartyServices\FooImplementation::class); + public function fooImplementation() : Type { + return types()->class(ThirdPartyServices\FooImplementation::class); } } diff --git a/test/Unit/Autowire/AutowireableFunctionsTest.php b/test/Unit/Autowire/AutowireableFunctionsTest.php index 074c7370..e1a6dfc8 100644 --- a/test/Unit/Autowire/AutowireableFunctionsTest.php +++ b/test/Unit/Autowire/AutowireableFunctionsTest.php @@ -6,10 +6,10 @@ use Cspray\AnnotatedContainer\Exception\InvalidAutowireParameter; use PHPUnit\Framework\TestCase; use stdClass; -use function Cspray\AnnotatedContainer\autowiredParams; -use function Cspray\AnnotatedContainer\rawParam; -use function Cspray\AnnotatedContainer\serviceParam; -use function Cspray\Typiphy\objectType; +use function Cspray\AnnotatedContainer\Autowire\autowiredParams; +use function Cspray\AnnotatedContainer\Autowire\rawParam; +use function Cspray\AnnotatedContainer\Autowire\serviceParam; +use function Cspray\AnnotatedContainer\Reflection\types; class AutowireableFunctionsTest extends TestCase { @@ -37,7 +37,7 @@ public function testRawParameterWithEmptyNameThrowsException() { #[\PHPUnit\Framework\Attributes\DataProvider('nameProvider')] public function testServiceParameterGetName(string $name) { - $param = serviceParam($name, objectType(static::class)); + $param = serviceParam($name, types()->class(static::class)); $this->assertSame($name, $param->name()); } @@ -45,7 +45,7 @@ public function testServiceParameterGetName(string $name) { public function testServiceParameterWithEmptyNameThrowsException() { $this->expectException(InvalidAutowireParameter::class); $this->expectExceptionMessage('A parameter name must have a non-empty value.'); - serviceParam('', objectType(static::class)); + serviceParam('', types()->class(static::class)); } public static function valueProvider() : array { @@ -67,7 +67,7 @@ public function testRawParameterGetValue(mixed $value) { } public function testServiceParameterGetValue() { - $param = serviceParam('foo', $type = objectType(static::class)); + $param = serviceParam('foo', $type = types()->class(static::class)); $this->assertSame($type, $param->value()); } @@ -77,7 +77,7 @@ public function testRawParameterIsServiceIdentifier() { } public function testServiceParameterIsServiceIdentifier() { - $this->assertTrue(serviceParam('foo', objectType(static::class))->isServiceIdentifier()); + $this->assertTrue(serviceParam('foo', types()->class(static::class))->isServiceIdentifier()); } public function testAutowireableSetWithNoParamsIsEmpty() { @@ -134,7 +134,7 @@ public function testAutowireableSetAddHas() { public function testAutowireableSetOriginalParameters() { $set = autowiredParams( $one = rawParam('foo', 'value'), - $two = serviceParam('bar', objectType(static::class)) + $two = serviceParam('bar', types()->class(static::class)) ); $arraySet = iterator_to_array($set); @@ -145,7 +145,7 @@ public function testAutowireableSetOriginalParameters() { public function testAutowireableSetAddWithOriginalParameters() { $set = autowiredParams( $one = rawParam('foo', 'value'), - $two = serviceParam('bar', objectType(static::class)) + $two = serviceParam('bar', types()->class(static::class)) ); $set->add($three = rawParam('baz', 1234)); @@ -156,6 +156,6 @@ public function testAutowireableSetAddWithOriginalParameters() { public function testAutowireableSetWithDuplicateParameterNamesThrowsException() { $this->expectException(InvalidAutowireParameter::class); $this->expectExceptionMessage('A parameter named "foo" has already been added to this set.'); - autowiredParams(rawParam('foo', 'value'), serviceParam('foo', objectType(static::class))); + autowiredParams(rawParam('foo', 'value'), serviceParam('foo', types()->class(static::class))); } } diff --git a/test/Unit/Bootstrap/ComposerRuntimePackagesComposerJsonPathProviderTest.php b/test/Unit/Bootstrap/ComposerRuntimePackagesComposerJsonPathProviderTest.php index d8e0e71a..6f95c21e 100644 --- a/test/Unit/Bootstrap/ComposerRuntimePackagesComposerJsonPathProviderTest.php +++ b/test/Unit/Bootstrap/ComposerRuntimePackagesComposerJsonPathProviderTest.php @@ -16,7 +16,6 @@ public function testCorrectPathsAreReturnedBasedOnInstalledPackages() : void { $vendorDir . '/cspray/annotated-target/composer.json', $vendorDir . '/cspray/architectural-decision/composer.json', $vendorDir . '/cspray/precision-stopwatch/composer.json', - $vendorDir . '/cspray/typiphy/composer.json', $vendorDir . '/illuminate/container/composer.json', $vendorDir . '/illuminate/contracts/composer.json', $vendorDir . '/jetbrains/phpstorm-attributes/composer.json', diff --git a/test/Unit/Bootstrap/EnvironmentParameterStoreTest.php b/test/Unit/Bootstrap/EnvironmentParameterStoreTest.php index 879dfae2..6885006e 100644 --- a/test/Unit/Bootstrap/EnvironmentParameterStoreTest.php +++ b/test/Unit/Bootstrap/EnvironmentParameterStoreTest.php @@ -5,6 +5,7 @@ use Cspray\AnnotatedContainer\ContainerFactory\EnvironmentParameterStore; use Cspray\AnnotatedContainer\Exception\EnvironmentVarNotFound; use PHPUnit\Framework\TestCase; +use function Cspray\AnnotatedContainer\Reflection\types; use function Cspray\Typiphy\stringType; class EnvironmentParameterStoreTest extends TestCase { @@ -15,12 +16,12 @@ public function testGetEnvironmentParameterStoreName() { public function testGetEnvironmentVariableExists() { putenv('ANNOTATED_CONTAINER_TEST_ENV=foobar'); - $this->assertSame('foobar', (new EnvironmentParameterStore())->fetch(stringType(), 'ANNOTATED_CONTAINER_TEST_ENV')); + $this->assertSame('foobar', (new EnvironmentParameterStore())->fetch(types()->string(), 'ANNOTATED_CONTAINER_TEST_ENV')); } public function testGetEnvironmentVariableDoesNotExistThrowsException() { $this->expectException(EnvironmentVarNotFound::class); $this->expectExceptionMessage('The key "ANNOTATED_CONTAINER_NOT_PRESENT" is not available in store "env".'); - (new EnvironmentParameterStore())->fetch(stringType(), 'ANNOTATED_CONTAINER_NOT_PRESENT'); + (new EnvironmentParameterStore())->fetch(types()->string(), 'ANNOTATED_CONTAINER_NOT_PRESENT'); } } diff --git a/test/Unit/Bootstrap/XmlBootstrappingConfigurationTest.php b/test/Unit/Bootstrap/XmlBootstrappingConfigurationTest.php index 832f8ae0..965d62be 100644 --- a/test/Unit/Bootstrap/XmlBootstrappingConfigurationTest.php +++ b/test/Unit/Bootstrap/XmlBootstrappingConfigurationTest.php @@ -20,6 +20,7 @@ use org\bovigo\vfs\vfsStreamDirectory as VirtualDirectory; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; +use function Cspray\AnnotatedContainer\Reflection\types; use function Cspray\Typiphy\stringType; class XmlBootstrappingConfigurationTest extends TestCase { @@ -273,7 +274,7 @@ public function createParameterStore(string $identifier) : ParameterStore { ); self::assertCount(1, $config->parameterStores()); - self::assertSame('passed to constructor my-key', $config->parameterStores()[0]->fetch(stringType(), 'my-key')); + self::assertSame('passed to constructor my-key', $config->parameterStores()[0]->fetch(types()->string(), 'my-key')); } public function testDefinitionProviderFactoryPresentRespected() : void { diff --git a/test/Unit/ContainerFactory/AurynContainerFactoryTest.php b/test/Unit/ContainerFactory/AurynContainerFactoryTest.php index 2ec3086b..74e3c8ce 100644 --- a/test/Unit/ContainerFactory/AurynContainerFactoryTest.php +++ b/test/Unit/ContainerFactory/AurynContainerFactoryTest.php @@ -6,8 +6,8 @@ use Cspray\AnnotatedContainer\ContainerFactory\AurynContainerFactory; use Cspray\AnnotatedContainer\ContainerFactory\ContainerFactory; use Cspray\AnnotatedContainer\Event\Emitter; -use Cspray\Typiphy\ObjectType; -use function Cspray\Typiphy\objectType; +use Cspray\AnnotatedContainer\Reflection\Type; +use function Cspray\AnnotatedContainer\Reflection\types; class AurynContainerFactoryTest extends ContainerFactoryTestCase { @@ -15,7 +15,7 @@ protected function getContainerFactory(Emitter $emitter = new Emitter()) : Conta return new AurynContainerFactory(emitter: $emitter); } - protected function getBackingContainerInstanceOf() : ObjectType { - return objectType(Injector::class); + protected function getBackingContainerInstanceOf() : Type { + return types()->class(Injector::class); } } diff --git a/test/Unit/ContainerFactory/ContainerFactoryTestCase.php b/test/Unit/ContainerFactory/ContainerFactoryTestCase.php index de8d45d4..16d568de 100644 --- a/test/Unit/ContainerFactory/ContainerFactoryTestCase.php +++ b/test/Unit/ContainerFactory/ContainerFactoryTestCase.php @@ -8,42 +8,40 @@ use Cspray\AnnotatedContainer\ContainerFactory\ContainerFactory; use Cspray\AnnotatedContainer\ContainerFactory\ContainerFactoryOptionsBuilder; use Cspray\AnnotatedContainer\ContainerFactory\ParameterStore; -use Cspray\AnnotatedContainer\Definition\AliasDefinitionBuilder; use Cspray\AnnotatedContainer\Definition\ContainerDefinition; use Cspray\AnnotatedContainer\Definition\ContainerDefinitionBuilder; use Cspray\AnnotatedContainer\Definition\Serializer\XmlContainerDefinitionSerializer; -use Cspray\AnnotatedContainer\Definition\ServiceDefinitionBuilder; use Cspray\AnnotatedContainer\Event\Emitter; use Cspray\AnnotatedContainer\Exception\InvalidAlias; use Cspray\AnnotatedContainer\Exception\ParameterStoreNotFound; use Cspray\AnnotatedContainer\Profiles; +use Cspray\AnnotatedContainer\Reflection\Type; +use Cspray\AnnotatedContainer\Reflection\TypeUnion; +use Cspray\AnnotatedContainer\Reflection\TypeIntersect; use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalyzer; -use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetDefinitionConverter; use Cspray\AnnotatedContainer\StaticAnalysis\ContainerDefinitionAnalysisOptionsBuilder; use Cspray\AnnotatedContainer\StaticAnalysis\ContainerDefinitionAnalyzer; +use Cspray\AnnotatedContainer\Unit\Helper\HasMockDefinitions; use Cspray\AnnotatedContainer\Unit\Helper\StubContainerFactoryListener; use Cspray\AnnotatedContainer\Unit\Helper\StubParameterStore; use Cspray\AnnotatedContainer\Fixture\Fixture; use Cspray\AnnotatedContainer\Fixture\Fixtures; use Cspray\AnnotatedTarget\PhpParserAnnotatedTargetParser; -use Cspray\Typiphy\ObjectType; -use Cspray\Typiphy\Type; -use Cspray\Typiphy\TypeIntersect; -use Cspray\Typiphy\TypeUnion; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Psr\Container\ContainerExceptionInterface; use Psr\Container\NotFoundExceptionInterface; -use function Cspray\AnnotatedContainer\autowiredParams; -use function Cspray\AnnotatedContainer\rawParam; -use function Cspray\AnnotatedContainer\serviceParam; -use function Cspray\Typiphy\objectType; +use function Cspray\AnnotatedContainer\Autowire\autowiredParams; +use function Cspray\AnnotatedContainer\Autowire\rawParam; +use function Cspray\AnnotatedContainer\Autowire\serviceParam; abstract class ContainerFactoryTestCase extends TestCase { + use HasMockDefinitions; + abstract protected function getContainerFactory(Emitter $emitter = new Emitter()) : ContainerFactory; - abstract protected function getBackingContainerInstanceOf() : ObjectType; + abstract protected function getBackingContainerInstanceOf() : Type; protected function supportsInjectingMultipleNamedServices() : bool { return true; @@ -52,7 +50,6 @@ protected function supportsInjectingMultipleNamedServices() : bool { private function getContainerDefinitionCompiler() : ContainerDefinitionAnalyzer { return new AnnotatedTargetContainerDefinitionAnalyzer( new PhpParserAnnotatedTargetParser(), - new AnnotatedTargetDefinitionConverter(), new Emitter() ); } @@ -169,18 +166,20 @@ public function testCreateInjectStringService() { } public function testConcreteAliasDefinitionDoesNotHaveServiceDefinition() { - $abstractService = Fixtures::implicitAliasedServices()->fooInterface()->name(); - $concreteService = Fixtures::implicitAliasedServices()->fooImplementation()->name(); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forAbstract($abstract = objectType($abstractService))->build() - ) - ->withAliasDefinition( - AliasDefinitionBuilder::forAbstract($abstract)->withConcrete($concrete = objectType($concreteService))->build() - )->build(); + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $this->abstractServiceDefinition(Fixtures::implicitAliasedServices()->fooInterface()), + ], + aliasDefinitions: [ + $this->aliasDefinition( + Fixtures::implicitAliasedServices()->fooInterface(), + Fixtures::implicitAliasedServices()->fooImplementation() + ) + ] + ); $this->expectException(InvalidAlias::class); - $this->expectExceptionMessage('An AliasDefinition has a concrete type, ' . $concrete->name() . ', that is not a registered ServiceDefinition.'); + $this->expectExceptionMessage('An AliasDefinition has a concrete type, ' . Fixtures::implicitAliasedServices()->fooImplementation()->name() . ', that is not a registered ServiceDefinition.'); $this->getContainerFactory()->createContainer($containerDefinition); } diff --git a/test/Unit/ContainerFactory/IlluminateContainerFactoryTest.php b/test/Unit/ContainerFactory/IlluminateContainerFactoryTest.php index 8e0fa14a..980f51c2 100644 --- a/test/Unit/ContainerFactory/IlluminateContainerFactoryTest.php +++ b/test/Unit/ContainerFactory/IlluminateContainerFactoryTest.php @@ -5,9 +5,9 @@ use Cspray\AnnotatedContainer\ContainerFactory\ContainerFactory; use Cspray\AnnotatedContainer\ContainerFactory\IlluminateContainerFactory; use Cspray\AnnotatedContainer\Event\Emitter; -use Cspray\Typiphy\ObjectType; +use Cspray\AnnotatedContainer\Reflection\Type; use Illuminate\Contracts\Container\Container; -use function Cspray\Typiphy\objectType; +use function Cspray\AnnotatedContainer\Reflection\types; class IlluminateContainerFactoryTest extends ContainerFactoryTestCase { @@ -15,8 +15,8 @@ protected function getContainerFactory(Emitter $emitter = new Emitter()) : Conta return new IlluminateContainerFactory(emitter: $emitter); } - protected function getBackingContainerInstanceOf() : ObjectType { - return objectType(Container::class); + protected function getBackingContainerInstanceOf() : Type { + return types()->class(Container::class); } protected function supportsInjectingMultipleNamedServices() : bool { diff --git a/test/Unit/ContainerFactory/PhpDiContainerFactoryTest.php b/test/Unit/ContainerFactory/PhpDiContainerFactoryTest.php index 9f42a0b6..5660f3cd 100644 --- a/test/Unit/ContainerFactory/PhpDiContainerFactoryTest.php +++ b/test/Unit/ContainerFactory/PhpDiContainerFactoryTest.php @@ -5,9 +5,9 @@ use Cspray\AnnotatedContainer\ContainerFactory\ContainerFactory; use Cspray\AnnotatedContainer\ContainerFactory\PhpDiContainerFactory; use Cspray\AnnotatedContainer\Event\Emitter; -use Cspray\Typiphy\ObjectType; +use Cspray\AnnotatedContainer\Reflection\Type; use DI\Container; -use function Cspray\Typiphy\objectType; +use function Cspray\AnnotatedContainer\Reflection\types; class PhpDiContainerFactoryTest extends ContainerFactoryTestCase { @@ -15,7 +15,7 @@ protected function getContainerFactory(Emitter $emitter = new Emitter()) : Conta return new PhpDiContainerFactory(emitter: $emitter); } - protected function getBackingContainerInstanceOf() : ObjectType { - return objectType(Container::class); + protected function getBackingContainerInstanceOf() : Type { + return types()->class(Container::class); } } diff --git a/test/Unit/ContainerFactory/StandardAliasDefinitionResolverTest.php b/test/Unit/ContainerFactory/StandardAliasDefinitionResolverTest.php index 83e7c1e7..da0a68c0 100644 --- a/test/Unit/ContainerFactory/StandardAliasDefinitionResolverTest.php +++ b/test/Unit/ContainerFactory/StandardAliasDefinitionResolverTest.php @@ -4,171 +4,138 @@ use Cspray\AnnotatedContainer\ContainerFactory\AliasResolution\AliasResolutionReason; use Cspray\AnnotatedContainer\ContainerFactory\AliasResolution\StandardAliasDefinitionResolver; -use Cspray\AnnotatedContainer\Definition\AliasDefinitionBuilder; -use Cspray\AnnotatedContainer\Definition\ContainerDefinitionBuilder; -use Cspray\AnnotatedContainer\Definition\ServiceDefinitionBuilder; -use Cspray\AnnotatedContainer\Definition\ServiceDelegateDefinitionBuilder; use Cspray\AnnotatedContainer\Fixture\Fixtures; +use Cspray\AnnotatedContainer\Unit\Helper\HasMockDefinitions; use PHPUnit\Framework\TestCase; final class StandardAliasDefinitionResolverTest extends TestCase { + use HasMockDefinitions; + public function testPassAbstractServiceDefinitionWithNoConcreteDefinitionReturnsCorrectResolution() : void { - $subject = new StandardAliasDefinitionResolver(); - $serviceDefinition = ServiceDefinitionBuilder::forAbstract(Fixtures::ambiguousAliasedServices()->fooInterface()) - ->build(); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition($serviceDefinition) - ->build(); + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $this->abstractServiceDefinition(Fixtures::ambiguousAliasedServices()->fooInterface()) + ] + ); - $resolution = $subject->resolveAlias($containerDefinition, $serviceDefinition->type()); + $subject = new StandardAliasDefinitionResolver(); + $resolution = $subject->resolveAlias($containerDefinition, Fixtures::ambiguousAliasedServices()->fooInterface()); self::assertSame(AliasResolutionReason::NoConcreteService, $resolution->aliasResolutionReason()); self::assertNull($resolution->aliasDefinition()); } public function testPassAbstractServiceDefinitionWithSingleConcreteDefinitionReturnsCorrectResolution() : void { + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $this->abstractServiceDefinition(Fixtures::ambiguousAliasedServices()->fooInterface()), + $this->concreteServiceDefinition(Fixtures::singleConcreteService()->fooImplementation()), + $this->concreteServiceDefinition(Fixtures::ambiguousAliasedServices()->barImplementation()), + ], + aliasDefinitions: [ + $aliasDefinition = $this->aliasDefinition( + Fixtures::ambiguousAliasedServices()->fooInterface(), + Fixtures::ambiguousAliasedServices()->barImplementation() + ) + ] + ); + $subject = new StandardAliasDefinitionResolver(); - $serviceDefinition = ServiceDefinitionBuilder::forAbstract(Fixtures::ambiguousAliasedServices()->fooInterface()) - ->build(); - $concrete1 = ServiceDefinitionBuilder::forConcrete(Fixtures::singleConcreteService()->fooImplementation()) - ->build(); - $concrete2 = ServiceDefinitionBuilder::forConcrete(Fixtures::ambiguousAliasedServices()->barImplementation()) - ->build(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition($serviceDefinition) - ->withServiceDefinition($concrete1) - ->withServiceDefinition($concrete2) - ->withAliasDefinition( - $aliasDefinition = AliasDefinitionBuilder::forAbstract($serviceDefinition->type()) - ->withConcrete($concrete2->type()) - ->build() - )->build(); - - $resolution = $subject->resolveAlias($containerDefinition, $serviceDefinition->type()); + $resolution = $subject->resolveAlias($containerDefinition, Fixtures::ambiguousAliasedServices()->fooInterface()); self::assertSame(AliasResolutionReason::SingleConcreteService, $resolution->aliasResolutionReason()); self::assertSame($aliasDefinition, $resolution->aliasDefinition()); } public function testPassAbstractServiceDefinitionWithMultipleConcreteDefinitionReturnsCorrectResolution() : void { + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $this->abstractServiceDefinition(Fixtures::ambiguousAliasedServices()->fooInterface()), + $this->concreteServiceDefinition(Fixtures::ambiguousAliasedServices()->bazImplementation()), + $this->concreteServiceDefinition(Fixtures::ambiguousAliasedServices()->barImplementation()), + ], + aliasDefinitions: [ + $this->aliasDefinition( + Fixtures::ambiguousAliasedServices()->fooInterface(), + Fixtures::ambiguousAliasedServices()->bazImplementation() + ), + $this->aliasDefinition( + Fixtures::ambiguousAliasedServices()->fooInterface(), + Fixtures::ambiguousAliasedServices()->barImplementation() + ) + ] + ); + $subject = new StandardAliasDefinitionResolver(); - $serviceDefinition = ServiceDefinitionBuilder::forAbstract(Fixtures::ambiguousAliasedServices()->fooInterface()) - ->build(); - $concrete1 = ServiceDefinitionBuilder::forConcrete(Fixtures::ambiguousAliasedServices()->bazImplementation()) - ->build(); - $concrete2 = ServiceDefinitionBuilder::forConcrete(Fixtures::ambiguousAliasedServices()->barImplementation()) - ->build(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition($serviceDefinition) - ->withServiceDefinition($concrete1) - ->withServiceDefinition($concrete2) - ->withAliasDefinition( - AliasDefinitionBuilder::forAbstract($serviceDefinition->type()) - ->withConcrete($concrete1->type()) - ->build() - )->withAliasDefinition( - AliasDefinitionBuilder::forAbstract($serviceDefinition->type()) - ->withConcrete($concrete2->type()) - ->build() - )->build(); - - $resolution = $subject->resolveAlias($containerDefinition, $serviceDefinition->type()); + $resolution = $subject->resolveAlias($containerDefinition, Fixtures::ambiguousAliasedServices()->fooInterface()); self::assertSame(AliasResolutionReason::MultipleConcreteService, $resolution->aliasResolutionReason()); self::assertNull($resolution->aliasDefinition()); } public function testPassAbstractServiceDefinitionWithMultipleConcreteDefinitionWithPrimaryReturnsCorrectResolution() : void { + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $this->abstractServiceDefinition(Fixtures::ambiguousAliasedServices()->fooInterface()), + $this->concreteServiceDefinition(Fixtures::ambiguousAliasedServices()->bazImplementation()), + $this->concreteServiceDefinition(Fixtures::ambiguousAliasedServices()->barImplementation(), isPrimary: true), + ], + aliasDefinitions: [ + $this->aliasDefinition(Fixtures::ambiguousAliasedServices()->fooInterface(), Fixtures::ambiguousAliasedServices()->bazImplementation()), + $aliasDefinition = $this->aliasDefinition(Fixtures::ambiguousAliasedServices()->fooInterface(), Fixtures::ambiguousAliasedServices()->barImplementation()), + ], + ); + $subject = new StandardAliasDefinitionResolver(); - $serviceDefinition = ServiceDefinitionBuilder::forAbstract(Fixtures::ambiguousAliasedServices()->fooInterface()) - ->build(); - $concrete1 = ServiceDefinitionBuilder::forConcrete(Fixtures::ambiguousAliasedServices()->bazImplementation()) - ->build(); - $concrete2 = ServiceDefinitionBuilder::forConcrete(Fixtures::ambiguousAliasedServices()->barImplementation(), true) - ->build(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition($serviceDefinition) - ->withServiceDefinition($concrete1) - ->withServiceDefinition($concrete2) - ->withAliasDefinition( - AliasDefinitionBuilder::forAbstract($serviceDefinition->type()) - ->withConcrete($concrete1->type()) - ->build() - )->withAliasDefinition( - $aliasDefinition = AliasDefinitionBuilder::forAbstract($serviceDefinition->type()) - ->withConcrete($concrete2->type()) - ->build() - )->build(); - - $resolution = $subject->resolveAlias($containerDefinition, $serviceDefinition->type()); + $resolution = $subject->resolveAlias($containerDefinition, Fixtures::ambiguousAliasedServices()->fooInterface()); self::assertSame(AliasResolutionReason::ConcreteServiceIsPrimary, $resolution->aliasResolutionReason()); self::assertSame($aliasDefinition, $resolution->aliasDefinition()); } public function testDelegatedAbstractServiceHasNoAlias() : void { - $subject = new StandardAliasDefinitionResolver(); + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $this->abstractServiceDefinition(Fixtures::delegatedService()->serviceInterface()), + $this->concreteServiceDefinition(Fixtures::delegatedService()->fooService()) + ], + serviceDelegateDefinitions: [ + $this->serviceDelegateDefinition( + Fixtures::delegatedService()->serviceInterface(), + Fixtures::delegatedService()->serviceFactory(), + 'createService', + ) + ], + aliasDefinitions: [ + $this->aliasDefinition(Fixtures::delegatedService()->serviceInterface(), Fixtures::delegatedService()->fooService()) + ] + ); - $abstract = ServiceDefinitionBuilder::forAbstract( - Fixtures::delegatedService()->serviceInterface() - )->build(); - $concrete = ServiceDefinitionBuilder::forConcrete( - Fixtures::delegatedService()->fooService() - )->build(); - $alias = AliasDefinitionBuilder::forAbstract($abstract->type())->withConcrete($concrete->type())->build(); - $delegate = ServiceDelegateDefinitionBuilder::forService($abstract->type()) - ->withDelegateMethod( - Fixtures::delegatedService()->serviceFactory(), - 'createService' - )->build(); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition($abstract) - ->withServiceDefinition($concrete) - ->withAliasDefinition($alias) - ->withServiceDelegateDefinition($delegate) - ->build(); - - $resolution = $subject->resolveAlias($containerDefinition, $abstract->type()); + $subject = new StandardAliasDefinitionResolver(); + $resolution = $subject->resolveAlias($containerDefinition, Fixtures::delegatedService()->serviceInterface()); - self::assertNull($resolution->aliasDefinition()); self::assertSame(AliasResolutionReason::ServiceIsDelegated, $resolution->aliasResolutionReason()); + self::assertNull($resolution->aliasDefinition()); } public function testMultiplePrimaryServiceIsNull() : void { - $subject = new StandardAliasDefinitionResolver(); + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $this->abstractServiceDefinition(Fixtures::ambiguousAliasedServices()->fooInterface()), + $this->concreteServiceDefinition(Fixtures::ambiguousAliasedServices()->barImplementation(), isPrimary: true), + $this->concreteServiceDefinition(Fixtures::ambiguousAliasedServices()->bazImplementation(), isPrimary: true), + ], + aliasDefinitions: [ + $this->aliasDefinition(Fixtures::ambiguousAliasedServices()->fooInterface(), Fixtures::ambiguousAliasedServices()->barImplementation()), + $this->aliasDefinition(Fixtures::ambiguousAliasedServices()->fooInterface(), Fixtures::ambiguousAliasedServices()->bazImplementation()) + ] + ); - $abstract = ServiceDefinitionBuilder::forAbstract( - Fixtures::ambiguousAliasedServices()->fooInterface() - )->build(); - $one = ServiceDefinitionBuilder::forConcrete( - Fixtures::ambiguousAliasedServices()->barImplementation(), - true - )->build(); - $two = ServiceDefinitionBuilder::forConcrete( - Fixtures::ambiguousAliasedServices()->bazImplementation(), - true - )->build(); - $oneAlias = AliasDefinitionBuilder::forAbstract($abstract->type()) - ->withConcrete($one->type()) - ->build(); - $twoAlias = AliasDefinitionBuilder::forAbstract($abstract->type()) - ->withConcrete($two->type()) - ->build(); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition($abstract) - ->withServiceDefinition($one) - ->withServiceDefinition($two) - ->withAliasDefinition($oneAlias) - ->withAliasDefinition($twoAlias) - ->build(); - - $resolution = $subject->resolveAlias($containerDefinition, $abstract->type()); + $subject = new StandardAliasDefinitionResolver(); + $resolution = $subject->resolveAlias($containerDefinition, Fixtures::ambiguousAliasedServices()->fooInterface()); - self::assertNull($resolution->aliasDefinition()); self::assertSame(AliasResolutionReason::MultiplePrimaryService, $resolution->aliasResolutionReason()); + self::assertNull($resolution->aliasDefinition()); } } diff --git a/test/Unit/Definition/AliasDefinitionBuilderTest.php b/test/Unit/Definition/AliasDefinitionBuilderTest.php deleted file mode 100644 index d43287dc..00000000 --- a/test/Unit/Definition/AliasDefinitionBuilderTest.php +++ /dev/null @@ -1,30 +0,0 @@ -fooInterface(); - $concrete = Fixtures::implicitAliasedServices()->fooImplementation(); - $builder1 = AliasDefinitionBuilder::forAbstract($abstract); - $builder2 = $builder1->withConcrete($concrete); - - $this->assertNotSame($builder1, $builder2); - } - - public function testWithConcreteReturnsCorrectServiceDefinitions() { - $abstract = Fixtures::implicitAliasedServices()->fooInterface(); - $concrete = Fixtures::implicitAliasedServices()->fooImplementation(); - $aliasDefinition = AliasDefinitionBuilder::forAbstract($abstract) - ->withConcrete($concrete) - ->build(); - - $this->assertSame($abstract, $aliasDefinition->abstractService()); - $this->assertSame($concrete, $aliasDefinition->concreteService()); - } -} diff --git a/test/Unit/Definition/AssertExpectedInjectDefinitionTest.php b/test/Unit/Definition/AssertExpectedInjectDefinitionTest.php index 4ce3ed94..b7bb14fb 100644 --- a/test/Unit/Definition/AssertExpectedInjectDefinitionTest.php +++ b/test/Unit/Definition/AssertExpectedInjectDefinitionTest.php @@ -3,22 +3,23 @@ namespace Cspray\AnnotatedContainer\Unit\Definition; use Cspray\AnnotatedContainer\Definition\ContainerDefinitionBuilder; -use Cspray\AnnotatedContainer\Definition\InjectDefinitionBuilder; +use Cspray\AnnotatedContainer\Unit\Helper\HasMockDefinitions; use Cspray\AnnotatedContainer\Unit\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalysisTests\DataProviderExpects\ExpectedInject; use Cspray\AnnotatedContainer\Unit\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalysisTests\HasTestsTrait\AssertExpectedInjectDefinition; use Cspray\AnnotatedContainer\Fixture\Fixtures; use PHPUnit\Framework\AssertionFailedError; use PHPUnit\Framework\TestCase; -use function Cspray\Typiphy\arrayType; -use function Cspray\Typiphy\stringType; +use function Cspray\AnnotatedContainer\Reflection\types; class AssertExpectedInjectDefinitionTest extends TestCase { + use HasMockDefinitions; + private function getArrayConstructorExpectedInject(array $profiles = ['default'], string $store = null) : ExpectedInject { return ExpectedInject::forConstructParam( Fixtures::injectConstructorServices()->injectArrayService(), 'values', - arrayType(), + types()->array(), ['dependency', 'injection', 'rocks'], profiles: $profiles, store: $store @@ -31,7 +32,7 @@ public function testExpectedInjectServiceNotFound() : void { $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage(sprintf( 'Could not find an InjectDefinition for %s in the provided ContainerDefinition.', - Fixtures::injectConstructorServices()->injectArrayService() + Fixtures::injectConstructorServices()->injectArrayService()->name(), )); $assertion->assert( @@ -42,18 +43,22 @@ public function testExpectedInjectServiceNotFound() : void { public function testExpectedInjectMethodNameNotFound() : void { $assertion = new AssertExpectedInjectDefinition($this); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectConstructorServices()->injectArrayService()) - ->withMethod('notConstruct', arrayType(), 'values') - ->withValue([1, 2, 3]) - ->build() - )->build(); + $containerDefinition = $this->containerDefinition( + injectDefinitions: [ + $this->injectDefinition( + Fixtures::injectConstructorServices()->injectArrayService(), + 'notConstruct', + 'values', + types()->array(), + [1, 2, 3] + ) + ] + ); $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage(sprintf( 'Could not find an InjectDefinition for method %s::%s.', - Fixtures::injectConstructorServices()->injectArrayService(), + Fixtures::injectConstructorServices()->injectArrayService()->name(), '__construct' )); @@ -62,19 +67,23 @@ public function testExpectedInjectMethodNameNotFound() : void { public function testExpectedInjectMethodParamNotFound() : void { $assertion = new AssertExpectedInjectDefinition($this); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectConstructorServices()->injectArrayService()) - ->withMethod('__construct', arrayType(), 'notValues') - ->withValue(['dependency', 'injection', 'rocks']) - ->build() - )->build(); + $containerDefinition = $this->containerDefinition( + injectDefinitions: [ + $this->injectDefinition( + Fixtures::injectConstructorServices()->injectArrayService(), + '__construct', + 'notValues', + types()->array(), + ['dependency', 'injection', 'rocks'], + ) + ] + ); $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage(sprintf( 'Could not find an InjectDefinition for parameter \'%s\' on method %s::%s.', 'values', - Fixtures::injectConstructorServices()->injectArrayService(), + Fixtures::injectConstructorServices()->injectArrayService()->name(), '__construct' )); @@ -83,36 +92,44 @@ public function testExpectedInjectMethodParamNotFound() : void { public function testExpectedInjectMethodParamWrongType() : void { $assertion = new AssertExpectedInjectDefinition($this); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectConstructorServices()->injectArrayService()) - ->withMethod('__construct', stringType(), 'values') - ->withValue('a string') - ->build() - )->build(); + $containerDefinition = $this->containerDefinition( + injectDefinitions: [ + $this->injectDefinition( + Fixtures::injectConstructorServices()->injectArrayService(), + '__construct', + 'values', + types()->string(), + 'a string' + ) + ] + ); $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage(sprintf( 'Could not find an InjectDefinition for parameter \'values\' on method %s::__construct with type \'array\'.', - Fixtures::injectConstructorServices()->injectArrayService(), + Fixtures::injectConstructorServices()->injectArrayService()->name(), )); $assertion->assert($this->getArrayConstructorExpectedInject(), $containerDefinition); } public function testExpectedInjectMethodParamWrongValues() : void { $assertion = new AssertExpectedInjectDefinition($this); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectConstructorServices()->injectArrayService()) - ->withMethod('__construct', arrayType(), 'values') - ->withValue(['service', 'registry', 'booo']) - ->build() - )->build(); + $containerDefinition = $this->containerDefinition( + injectDefinitions: [ + $this->injectDefinition( + Fixtures::injectConstructorServices()->injectArrayService(), + '__construct', + 'values', + types()->array(), + ['service', 'registry', 'boo'] + ) + ] + ); $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage(sprintf( 'Could not find an InjectDefinition for parameter \'values\' on method %s::__construct with a value matching:%s %s', - Fixtures::injectConstructorServices()->injectArrayService(), + Fixtures::injectConstructorServices()->injectArrayService()->name(), str_repeat(PHP_EOL, 2), var_export(['dependency', 'injection', 'rocks'], true) )); @@ -121,88 +138,107 @@ public function testExpectedInjectMethodParamWrongValues() : void { public function testExpectedInjectMethodParamWrongProfiles() : void { $assertion = new AssertExpectedInjectDefinition($this); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectConstructorServices()->injectArrayService()) - ->withMethod('__construct', arrayType(), 'values') - ->withValue(['dependency', 'injection', 'rocks']) - ->withProfiles('foo') - ->build() - )->build(); + $containerDefinition = $this->containerDefinition( + injectDefinitions: [ + $this->injectDefinition( + Fixtures::injectConstructorServices()->injectArrayService(), + '__construct', + 'values', + types()->array(), + ['dependency', 'injection', 'rocks'], + profiles: ['foo'] + ) + ] + ); $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage(sprintf( 'Could not find an InjectDefinition for parameter \'values\' on method %s::__construct with profiles: \'default\'.', - Fixtures::injectConstructorServices()->injectArrayService() + Fixtures::injectConstructorServices()->injectArrayService()->name() )); $assertion->assert($this->getArrayConstructorExpectedInject(), $containerDefinition); } public function testExpectedInjectMethodParamWrongProfilesAlternateMessage() : void { $assertion = new AssertExpectedInjectDefinition($this); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectConstructorServices()->injectArrayService()) - ->withMethod('__construct', arrayType(), 'values') - ->withValue(['dependency', 'injection', 'rocks']) - ->build() - )->build(); + $containerDefinition = $this->containerDefinition( + injectDefinitions: [ + $this->injectDefinition( + Fixtures::injectConstructorServices()->injectArrayService(), + '__construct', + 'values', + types()->array(), + ['dependency', 'injection', 'rocks'], + ) + ] + ); $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage(sprintf( 'Could not find an InjectDefinition for parameter \'values\' on method %s::__construct with profiles: \'foo\', \'bar\'.', - Fixtures::injectConstructorServices()->injectArrayService() + Fixtures::injectConstructorServices()->injectArrayService()->name(), )); $assertion->assert($this->getArrayConstructorExpectedInject(profiles: ['foo', 'bar']), $containerDefinition); } public function testExpectedInjectWrongStoreName() : void { $assertion = new AssertExpectedInjectDefinition($this); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectConstructorServices()->injectArrayService()) - ->withMethod('__construct', arrayType(), 'values') - ->withValue(['dependency', 'injection', 'rocks']) - ->withStore('store-name') - ->build() - )->build(); + $containerDefinition = $this->containerDefinition( + injectDefinitions: [ + $this->injectDefinition( + Fixtures::injectConstructorServices()->injectArrayService(), + '__construct', + 'values', + types()->array(), + ['dependency', 'injection', 'rocks'], + store: 'store-name' + ) + ] + ); $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage(sprintf( 'Could not find an InjectDefinition for parameter \'values\' on method %s::__construct with no store name.', - Fixtures::injectConstructorServices()->injectArrayService() + Fixtures::injectConstructorServices()->injectArrayService()->name(), )); $assertion->assert($this->getArrayConstructorExpectedInject(), $containerDefinition); } public function testExpectedInjectWrongStoreNameAlternateMessage() : void { $assertion = new AssertExpectedInjectDefinition($this); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectConstructorServices()->injectArrayService()) - ->withMethod('__construct', arrayType(), 'values') - - ->withValue(['dependency', 'injection', 'rocks']) - ->build() - )->build(); + $containerDefinition = $this->containerDefinition( + injectDefinitions: [ + $this->injectDefinition( + Fixtures::injectConstructorServices()->injectArrayService(), + '__construct', + 'values', + types()->array(), + ['dependency', 'injection', 'rocks'], + ) + ] + ); $this->expectException(AssertionFailedError::class); $this->expectExceptionMessage(sprintf( 'Could not find an InjectDefinition for parameter \'values\' on method %s::__construct with store name: \'foo-store\'.', - Fixtures::injectConstructorServices()->injectArrayService() + Fixtures::injectConstructorServices()->injectArrayService()->name() )); $assertion->assert($this->getArrayConstructorExpectedInject(store: 'foo-store'), $containerDefinition); } public function testFoundInjectDefinitionIncreasesAssertionCount() : void { $assertion = new AssertExpectedInjectDefinition($this); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectConstructorServices()->injectArrayService()) - ->withMethod('__construct', arrayType(), 'values') - ->withValue(['dependency', 'injection', 'rocks']) - ->build() - )->build(); + $containerDefinition = $this->containerDefinition( + injectDefinitions: [ + $this->injectDefinition( + Fixtures::injectConstructorServices()->injectArrayService(), + '__construct', + 'values', + types()->array(), + ['dependency', 'injection', 'rocks'], + ) + ] + ); $beforeCount = $this->numberOfAssertionsPerformed(); @@ -213,14 +249,18 @@ public function testFoundInjectDefinitionIncreasesAssertionCount() : void { public function testFoundInjectDefinitionWithCustomStoreIncreasesAssertionCount() : void { $assertion = new AssertExpectedInjectDefinition($this); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectConstructorServices()->injectArrayService()) - ->withMethod('__construct', arrayType(), 'values') - ->withValue(['dependency', 'injection', 'rocks']) - ->withStore('foo-store') - ->build() - )->build(); + $containerDefinition = $this->containerDefinition( + injectDefinitions: [ + $this->injectDefinition( + Fixtures::injectConstructorServices()->injectArrayService(), + '__construct', + 'values', + types()->array(), + ['dependency', 'injection', 'rocks'], + store: 'foo-store' + ) + ] + ); $beforeCount = $this->numberOfAssertionsPerformed(); @@ -231,14 +271,18 @@ public function testFoundInjectDefinitionWithCustomStoreIncreasesAssertionCount( public function testFoundInjectDefinitionWithCustomProfilesIncreasesAssertionCount() : void { $assertion = new AssertExpectedInjectDefinition($this); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectConstructorServices()->injectArrayService()) - ->withMethod('__construct', arrayType(), 'values') - ->withValue(['dependency', 'injection', 'rocks']) - ->withProfiles('foo', 'bar') - ->build() - )->build(); + $containerDefinition = $this->containerDefinition( + injectDefinitions: [ + $this->injectDefinition( + Fixtures::injectConstructorServices()->injectArrayService(), + '__construct', + 'values', + types()->array(), + ['dependency', 'injection', 'rocks'], + profiles: ['foo', 'bar'] + ) + ] + ); $beforeCount = $this->numberOfAssertionsPerformed(); diff --git a/test/Unit/Definition/DefinitionFactoryTest.php b/test/Unit/Definition/DefinitionFactoryTest.php new file mode 100644 index 00000000..3c1a786f --- /dev/null +++ b/test/Unit/Definition/DefinitionFactoryTest.php @@ -0,0 +1,1323 @@ +subject = new DefinitionFactory(); + } + + public function testServiceDefinitionFromAnnotatedTargetWithWrongAttributeThrowsException() : void { + $target = $this->createMock(AnnotatedTarget::class); + $attribute = $this->createMock(ServicePrepareAttribute::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + + $this->expectException(ServiceAttributeRequired::class); + $this->expectExceptionMessage( + 'The AnnotatedTarget::attributeInstance MUST return a type of ' . ServiceAttribute::class . ' but ' . + $attribute::class . ' was provided.' + ); + + $this->subject->serviceDefinitionFromAnnotatedTarget($target); + } + + public function testServiceDefinitionFromAnnotatedTargetWithWrongTargetReflectionThrowsException() : void { + $target = $this->createMock(AnnotatedTarget::class); + $attribute = $this->createMock(ServiceAttribute::class); + + $target->expects($this->once()) + ->method('attributeInstance') + ->willReturn($attribute); + + $target->expects($this->once()) + ->method('targetReflection') + ->willReturn(new \ReflectionMethod( + Fixtures::singleConcreteService()->fooImplementation()->name(), + 'postConstruct' + )); + + $this->expectException(WrongTargetForServiceAttribute::class); + $this->expectExceptionMessage( + 'The AnnotatedTarget::targetReflection MUST return an instance of ReflectionClass but ReflectionMethod was provided.' + ); + + $this->subject->serviceDefinitionFromAnnotatedTarget($target); + } + + public static function singleConcreteServiceCreatorProvider() : array { + return [ + 'annotatedTarget' => [ + function(ServiceAttribute $attribute) : ServiceDefinition { + $target = $this->createMock(AnnotatedTarget::class); + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + new \ReflectionClass( + Fixtures::singleConcreteService()->fooImplementation()->name() + ) + ); + + return $this->subject->serviceDefinitionFromAnnotatedTarget($target); + } + ], + 'objectType' => [ + fn(ServiceAttribute $attribute) : ServiceDefinition => + $this->subject->serviceDefinitionFromObjectTypeAndAttribute( + Fixtures::singleConcreteService()->fooImplementation(), + $attribute + ) + ], + 'manualSetup' => [ + fn(ServiceAttribute $attribute) : ServiceDefinition => + $this->subject->serviceDefinitionFromManualSetup( + Fixtures::singleConcreteService()->fooImplementation(), + $attribute, + true + ) + ] + ]; + } + + public static function interfaceAbstractServiceCreatorProvider() : array { + return [ + 'annotatedTarget' => [ + function(ServiceAttribute $attribute) : ServiceDefinition { + $target = $this->createMock(AnnotatedTarget::class); + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + new \ReflectionClass( + Fixtures::implicitAliasedServices()->fooInterface()->name() + ) + ); + + return $this->subject->serviceDefinitionFromAnnotatedTarget($target); + } + ], + 'objectType' => [ + fn(ServiceAttribute $attribute) : ServiceDefinition => + $this->subject->serviceDefinitionFromObjectTypeAndAttribute( + Fixtures::implicitAliasedServices()->fooInterface(), + $attribute + ) + ], + 'manualSetup' => [ + fn(ServiceAttribute $attribute) : ServiceDefinition => + $this->subject->serviceDefinitionFromManualSetup( + Fixtures::implicitAliasedServices()->fooInterface(), + $attribute, + false + ) + ] + ]; + } + + public static function abstractClassAbstractServiceCreatorProvider() : array { + return [ + 'annotatedTarget' => [ + function(ServiceAttribute $attribute) : ServiceDefinition { + $target = $this->createMock(AnnotatedTarget::class); + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + new \ReflectionClass( + Fixtures::abstractClassAliasedService()->fooAbstract()->name() + ) + ); + + return $this->subject->serviceDefinitionFromAnnotatedTarget($target); + } + ], + 'objectType' => [ + fn(ServiceAttribute $attribute) => + $this->subject->serviceDefinitionFromObjectTypeAndAttribute( + Fixtures::abstractClassAliasedService()->fooAbstract(), + $attribute + ) + ], + 'manualSetup' => [ + fn(ServiceAttribute $attribute) => + $this->subject->serviceDefinitionFromManualSetup( + Fixtures::abstractClassAliasedService()->fooAbstract(), + $attribute, + false + ) + ] + ]; + } + + #[DataProvider('singleConcreteServiceCreatorProvider')] + /** + * @param Closure(ServiceAttribute):ServiceDefinition $definitionCreator + */ + public function testServiceDefinitionWithMinimallyValidAttributeCreatesCorrectDefinition( + Closure $definitionCreator + ) : void { + $attribute = $this->createMock(ServiceAttribute::class); + $attribute->expects($this->once())->method('isPrimary')->willReturn(false); + $attribute->expects($this->once())->method('name')->willReturn(null); + $attribute->expects($this->once())->method('profiles')->willReturn([]); + + $definition = ($definitionCreator->bindTo($this, $this))($attribute); + + self::assertSame( + Fixtures::singleConcreteService()->fooImplementation(), + $definition->type() + ); + self::assertNull($definition->name()); + self::assertFalse($definition->isPrimary()); + self::assertSame(['default'], $definition->profiles()); + self::assertTrue($definition->isConcrete()); + self::assertFalse($definition->isAbstract()); + self::assertSame($attribute, $definition->attribute()); + } + + #[DataProvider('singleConcreteServiceCreatorProvider')] + /** + * @param Closure(ServiceAttribute):ServiceDefinition $definitionCreator + */ + public function testServiceDefinitionWithAttributeDefinedProfiles( + Closure $definitionCreator + ) : void { + $attribute = $this->createMock(ServiceAttribute::class); + + $attribute->expects($this->once())->method('isPrimary')->willReturn(false); + $attribute->expects($this->once())->method('name')->willReturn(null); + $attribute->expects($this->once())->method('profiles')->willReturn(['foo', 'bar']); + + $definition = ($definitionCreator->bindTo($this, $this))($attribute); + + self::assertSame( + Fixtures::singleConcreteService()->fooImplementation(), + $definition->type() + ); + self::assertNull($definition->name()); + self::assertFalse($definition->isPrimary()); + self::assertSame(['foo', 'bar'], $definition->profiles()); + self::assertTrue($definition->isConcrete()); + self::assertFalse($definition->isAbstract()); + self::assertSame($attribute, $definition->attribute()); + } + + #[DataProvider('singleConcreteServiceCreatorProvider')] + /** + * @param Closure(ServiceAttribute):ServiceDefinition $definitionCreator + */ + public function testServiceDefinitionWithAttributeDefinedName( + Closure $definitionCreator + ) : void { + $attribute = $this->createMock(ServiceAttribute::class); + $attribute->expects($this->once())->method('isPrimary')->willReturn(false); + $attribute->expects($this->once())->method('name')->willReturn('serviceName'); + $attribute->expects($this->once())->method('profiles')->willReturn([]); + + $definition = ($definitionCreator->bindTo($this, $this))($attribute); + + self::assertSame( + Fixtures::singleConcreteService()->fooImplementation(), + $definition->type() + ); + self::assertSame('serviceName', $definition->name()); + self::assertFalse($definition->isPrimary()); + self::assertSame(['default'], $definition->profiles()); + self::assertTrue($definition->isConcrete()); + self::assertFalse($definition->isAbstract()); + self::assertSame($attribute, $definition->attribute()); + } + + #[DataProvider('singleConcreteServiceCreatorProvider')] + /** + * @param Closure(ServiceAttribute):ServiceDefinition $definitionCreator + */ + public function testServiceDefinitionFromAnnotatedTargetWithAttributeDefinedIsPrimary( + Closure $definitionCreator + ) : void { + $attribute = $this->createMock(ServiceAttribute::class); + $attribute->expects($this->once())->method('isPrimary')->willReturn(true); + $attribute->expects($this->once())->method('name')->willReturn('serviceName'); + $attribute->expects($this->once())->method('profiles')->willReturn([]); + + $definition = ($definitionCreator->bindTo($this, $this))($attribute); + + self::assertSame( + Fixtures::singleConcreteService()->fooImplementation(), + $definition->type() + ); + self::assertSame('serviceName', $definition->name()); + self::assertTrue($definition->isPrimary()); + self::assertSame(['default'], $definition->profiles()); + self::assertTrue($definition->isConcrete()); + self::assertFalse($definition->isAbstract()); + self::assertSame($attribute, $definition->attribute()); + } + + #[DataProvider('interfaceAbstractServiceCreatorProvider')] + /** + * @param Closure(ServiceAttribute):ServiceDefinition $definitionCreator + */ + public function testServiceDefinitionIsInterfaceMarkedAsAbstract( + Closure $definitionCreator + ) : void { + $attribute = $this->createMock(ServiceAttribute::class); + $attribute->expects($this->once())->method('isPrimary')->willReturn(false); + $attribute->expects($this->once())->method('name')->willReturn('serviceName'); + $attribute->expects($this->once())->method('profiles')->willReturn([]); + + $definition = ($definitionCreator->bindTo($this, $this))($attribute); + + self::assertSame( + Fixtures::implicitAliasedServices()->fooInterface(), + $definition->type() + ); + self::assertSame('serviceName', $definition->name()); + self::assertFalse($definition->isPrimary()); + self::assertSame(['default'], $definition->profiles()); + self::assertFalse($definition->isConcrete()); + self::assertTrue($definition->isAbstract()); + self::assertSame($attribute, $definition->attribute()); + } + + #[DataProvider('abstractClassAbstractServiceCreatorProvider')] + /** + * @param Closure(ServiceAttribute):ServiceDefinition $definitionCreator + */ + public function testServiceDefinitionFromAnnotatedTargetWithAttributeDefinedIsAbstractClassMarkedAsAbstract( + Closure $definitionCreator + ) : void { + $attribute = $this->createMock(ServiceAttribute::class); + $attribute->expects($this->once())->method('isPrimary')->willReturn(false); + $attribute->expects($this->once())->method('name')->willReturn('serviceName'); + $attribute->expects($this->once())->method('profiles')->willReturn([]); + + $definition = ($definitionCreator->bindTo($this, $this))($attribute); + + self::assertSame( + Fixtures::abstractClassAliasedService()->fooAbstract(), + $definition->type() + ); + self::assertSame('serviceName', $definition->name()); + self::assertFalse($definition->isPrimary()); + self::assertSame(['default'], $definition->profiles()); + self::assertFalse($definition->isConcrete()); + self::assertTrue($definition->isAbstract()); + self::assertSame($attribute, $definition->attribute()); + } + + public function testServicePrepareDefinitionFromAnnotatedTargetWithWrongAttributeThrowsException() : void { + $target = $this->createMock(AnnotatedTarget::class); + $attribute = $this->createMock(ServiceAttribute::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + + $this->expectException(ServicePrepareAttributeRequired::class); + $this->expectExceptionMessage( + 'The AnnotatedTarget::attributeInstance MUST return a type of ' . ServicePrepareAttribute::class . ' but ' . + $attribute::class . ' was provided.' + ); + + $this->subject->servicePrepareDefinitionFromAnnotatedTarget($target); + } + + public function testServicePrepareDefinitionFromAnnotatedTargetWithWrongTargetReflectionThrowsException() : void { + $target = $this->createMock(AnnotatedTarget::class); + $attribute = $this->createMock(ServicePrepareAttribute::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + new \ReflectionClass(Fixtures::singleConcreteService()->fooImplementation()->name()) + ); + + $this->expectException(WrongTargetForServicePrepareAttribute::class); + $this->expectExceptionMessage( + 'The AnnotatedTarget::targetReflection MUST return an instance of ReflectionMethod but ReflectionClass was provided.' + ); + + $this->subject->servicePrepareDefinitionFromAnnotatedTarget($target); + } + + public static function servicePrepareDefinitionCreatorProvider() : array { + return [ + 'annotatedTarget' => [ + function(ServicePrepareAttribute $servicePrepareAttribute) : ServicePrepareDefinition { + $target = $this->createMock(AnnotatedTarget::class); + $target->expects($this->once())->method('attributeInstance')->willReturn($servicePrepareAttribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + new \ReflectionMethod(LoggerAwareInterface::class, 'setLogger') + ); + + return $this->subject->servicePrepareDefinitionFromAnnotatedTarget($target); + } + ], + 'classMethod' => [ + fn(ServicePrepareAttribute $servicePrepareAttribute) => + $this->subject->servicePrepareDefinitionFromClassMethodAndAttribute( + types()->class(LoggerAwareInterface::class), + 'setLogger', + $servicePrepareAttribute, + ) + ] + ]; + } + + #[DataProvider('servicePrepareDefinitionCreatorProvider')] + /** + * @param Closure(ServicePrepareAttribute):ServicePrepareDefinition $definitionCreator + */ + public function testServicePrepareDefinitionFromAnnotatedTargetWithValidParametersReturnsCorrectDefinition( + Closure $definitionCreator + ) : void { + $attribute = $this->createMock(ServicePrepareAttribute::class); + $definition = ($definitionCreator->bindTo($this, $this))($attribute); + + self::assertSame( + types()->class(LoggerAwareInterface::class), + $definition->service() + ); + self::assertSame( + 'setLogger', + $definition->methodName() + ); + self::assertSame($attribute, $definition->attribute()); + } + + public function testServiceDelegateDefinitionFromAnnotatedTargetWithWrongAttributeThrowsException() : void { + $target = $this->createMock(AnnotatedTarget::class); + $attribute = $this->createMock(ServiceAttribute::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + + $this->expectException(ServiceDelegateAttributeRequired::class); + $this->expectExceptionMessage(sprintf( + 'The AnnotatedTarget::attributeInstance MUST return a type of %s but %s was provided.', + ServiceDelegateAttribute::class, + $attribute::class + )); + + $this->subject->serviceDelegateDefinitionFromAnnotatedTarget($target); + } + + public function testServiceDelegateDefinitionFromAnnotatedTargetWithWrongTargetReflectionThrowsException() : void { + $target = $this->createMock(AnnotatedTarget::class); + $attribute = $this->createMock(ServiceDelegateAttribute::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + new \ReflectionClass(Fixtures::singleConcreteService()->fooImplementation()->name()) + ); + + $this->expectException(WrongTargetForServiceDelegateAttribute::class); + $this->expectExceptionMessage( + 'The AnnotatedTarget::targetReflection MUST return an instance of ReflectionMethod but ReflectionClass was provided.' + ); + + $this->subject->serviceDelegateDefinitionFromAnnotatedTarget($target); + } + + public function testServiceDelegateDefinitionFromAnnotatedTargetWithNonObjectReturnTypeThrowsException() : void { + $target = $this->createMock(AnnotatedTarget::class); + $attribute = $this->createMock(ServiceDelegateAttribute::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + new \ReflectionMethod( + ImplicitServiceDelegateScalarType\FooFactory::class, + 'create' + ) + ); + + $this->expectException(ServiceDelegateReturnsScalarType::class); + $this->expectExceptionMessage(sprintf( + 'The ServiceDelegate %s::create returns a scalar type. All ServiceDelegates MUST return an object type.', + ImplicitServiceDelegateScalarType\FooFactory::class + )); + + $this->subject->serviceDelegateDefinitionFromAnnotatedTarget($target); + } + + public function testServiceDelegateDefinitionFromAnnotatedTargetWithIntersectionReturnTypeThrowsException() : void { + $target = $this->createMock(AnnotatedTarget::class); + $attribute = $this->createMock(ServiceDelegateAttribute::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + new \ReflectionMethod( + ImplicitServiceDelegateIntersectionType\FooFactory::class, + 'create' + ) + ); + + $this->expectException(ServiceDelegateReturnsIntersectionType::class); + $this->expectExceptionMessage(sprintf( + 'The ServiceDelegate %s::create returns an intersection type. At this time intersection types are not supported.', + ImplicitServiceDelegateIntersectionType\FooFactory::class + )); + + $this->subject->serviceDelegateDefinitionFromAnnotatedTarget($target); + } + + public function testServiceDelegateDefinitionFromAnnotatedTargetWithUnionReturnTypeThrowsException() : void { + $target = $this->createMock(AnnotatedTarget::class); + $attribute = $this->createMock(ServiceDelegateAttribute::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + new \ReflectionMethod( + ImplicitServiceDelegateUnionType\FooFactory::class, + 'create' + ) + ); + + $this->expectException(ServiceDelegateReturnsUnionType::class); + $this->expectExceptionMessage(sprintf( + 'The ServiceDelegate %s::create returns a union type. At this time union types are not supported.', + ImplicitServiceDelegateUnionType\FooFactory::class + )); + + $this->subject->serviceDelegateDefinitionFromAnnotatedTarget($target); + } + + public function testServiceDelegateDefinitionFromAnnotatedTargetWithNullReturnTypeThrowsException() : void { + $target = $this->createMock(AnnotatedTarget::class); + $attribute = $this->createMock(ServiceDelegateAttribute::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + new \ReflectionMethod( + ImplicitServiceDelegateNoType\FooFactory::class, + 'create' + ) + ); + + $this->expectException(ServiceDelegateReturnsUnknownType::class); + $this->expectExceptionMessage(sprintf( + 'The ServiceDelegate %s::create does not have a return type. A ServiceDelegate MUST declare an object return type.', + ImplicitServiceDelegateNoType\FooFactory::class, + )); + + $this->subject->serviceDelegateDefinitionFromAnnotatedTarget($target); + } + + public function testServiceDelegateDefinitionFromClassMethodAndAttributeWithNonObjectReturnTypeThrowsException() : void { + $attribute = $this->createMock(ServiceDelegateAttribute::class); + + $this->expectException(ServiceDelegateReturnsScalarType::class); + $this->expectExceptionMessage(sprintf( + 'The ServiceDelegate %s::create returns a scalar type. All ServiceDelegates MUST return an object type.', + ImplicitServiceDelegateScalarType\FooFactory::class + )); + + $this->subject->serviceDelegateDefinitionFromClassMethodAndAttribute( + types()->class(ImplicitServiceDelegateScalarType\FooFactory::class), + 'create', + $attribute + ); + } + + public function testServiceDelegateDefinitionFromClassMethodAndAttributeWithIntersectionReturnTypeThrowsException() : void { + $attribute = $this->createMock(ServiceDelegateAttribute::class); + + $this->expectException(ServiceDelegateReturnsIntersectionType::class); + $this->expectExceptionMessage(sprintf( + 'The ServiceDelegate %s::create returns an intersection type. At this time intersection types are not supported.', + ImplicitServiceDelegateIntersectionType\FooFactory::class + )); + + $this->subject->serviceDelegateDefinitionFromClassMethodAndAttribute( + types()->class(ImplicitServiceDelegateIntersectionType\FooFactory::class), + 'create', + $attribute + ); + } + + public function testServiceDelegateDefinitionFromClassMethodAndAttributeWithUnionReturnTypeThrowsException() : void { + $attribute = $this->createMock(ServiceDelegateAttribute::class); + + $this->expectException(ServiceDelegateReturnsUnionType::class); + $this->expectExceptionMessage(sprintf( + 'The ServiceDelegate %s::create returns a union type. At this time union types are not supported.', + ImplicitServiceDelegateUnionType\FooFactory::class + )); + + $this->subject->serviceDelegateDefinitionFromClassMethodAndAttribute( + types()->class(ImplicitServiceDelegateUnionType\FooFactory::class), + 'create', + $attribute + ); + } + + public function testServiceDelegateDefinitionFromClassMethodAndAttributeWithNullReturnTypeThrowsException() : void { + $attribute = $this->createMock(ServiceDelegateAttribute::class); + + $this->expectException(ServiceDelegateReturnsUnknownType::class); + $this->expectExceptionMessage(sprintf( + 'The ServiceDelegate %s::create does not have a return type. A ServiceDelegate MUST declare an object return type.', + ImplicitServiceDelegateNoType\FooFactory::class, + )); + + $this->subject->serviceDelegateDefinitionFromClassMethodAndAttribute( + types()->class(ImplicitServiceDelegateNoType\FooFactory::class), + 'create', + $attribute + ); + } + + public static function serviceDelegateDefinitionCreatorProvider() : array { + return [ + 'annotatedTarget' => [ + function(ServiceDelegateAttribute $attribute) : ServiceDelegateDefinition { + $target = $this->createMock(AnnotatedTarget::class); + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + new \ReflectionMethod( + Fixtures::delegatedService()->serviceFactory()->name(), + 'createService' + ) + ); + + return $this->subject->serviceDelegateDefinitionFromAnnotatedTarget($target); + } + ], + 'classMethod' => [ + fn(ServiceDelegateAttribute $attribute) : ServiceDelegateDefinition => + $this->subject->serviceDelegateDefinitionFromClassMethodAndAttribute( + Fixtures::delegatedService()->serviceFactory(), + 'createService', + $attribute + ) + ], + ]; + } + + #[DataProvider('serviceDelegateDefinitionCreatorProvider')] + /** + * @param Closure(ServiceDelegateAttribute):ServiceDelegateDefinition $definitionCreator + */ + public function testServiceDelegateDefinitionFromAnnotatedTargetWithValidParametersCreatesDefinition( + Closure $definitionCreator + ) : void { + $attribute = $this->createMock(ServiceDelegateAttribute::class); + + $definition = ($definitionCreator->bindTo($this, $this))($attribute); + + self::assertSame( + Fixtures::delegatedService()->serviceInterface(), + $definition->serviceType() + ); + self::assertSame( + Fixtures::delegatedService()->serviceFactory(), + $definition->delegateType() + ); + self::assertSame( + 'createService', + $definition->delegateMethod(), + ); + self::assertSame($attribute, $definition->attribute()); + } + + public function testServiceDelegateDefinitionFromStaticFactoryReturnsSelfCreatesObject() : void { + $attribute = $this->createMock(ServiceDelegateAttribute::class); + + $definition = $this->subject->serviceDelegateDefinitionFromClassMethodAndAttribute( + Fixtures::thirdPartyKitchenSink()->nonAnnotatedService(), + 'create', + $attribute + ); + + self::assertSame( + Fixtures::thirdPartyKitchenSink()->nonAnnotatedService(), + $definition->serviceType() + ); + self::assertSame( + Fixtures::thirdPartyKitchenSink()->nonAnnotatedService(), + $definition->delegateType() + ); + self::assertSame( + 'create', + $definition->delegateMethod(), + ); + self::assertSame($attribute, $definition->attribute()); + } + + public function testInjectDefinitionFromAnnotatedTargetNotInjectAttributeThrowsException() : void { + $target = $this->createMock(AnnotatedTarget::class); + $attribute = $this->createMock(ServiceAttribute::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + + $this->expectException(InjectAttributeRequired::class); + $this->expectExceptionMessage(sprintf( + 'An AnnotatedTarget::attributeInstance() MUST return an instance of %s but %s was provided.', + InjectAttribute::class, + $attribute::class + )); + + $this->subject->injectDefinitionFromAnnotatedTarget($target); + } + + public function testInjectDefinitionFromAnnotatedTargetNotReflectionParameterThrowsException() : void { + $target = $this->createMock(AnnotatedTarget::class); + $attribute = $this->createMock(InjectAttribute::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + new \ReflectionClass(Fixtures::injectServiceConstructorServices()->serviceInjector()->name()) + ); + + $this->expectException(WrongTargetForInjectAttribute::class); + $this->expectExceptionMessage( + 'The AnnotatedTarget::targetReflection MUST return an instance of ReflectionParameter but ReflectionClass was provided.' + ); + + $this->subject->injectDefinitionFromAnnotatedTarget($target); + } + + public static function injectTypeProvider() : array { + return [ + 'array from AnnotatedTarget' => [ + Fixtures::injectConstructorServices()->injectArrayService(), + ['inject', 'values'], + types()->array(), + 'values', + function (InjectAttribute $attribute) : InjectDefinition { + $target = $this->createMock(AnnotatedTarget::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + (new \ReflectionClass(Fixtures::injectConstructorServices()->injectArrayService()->name()))->getConstructor()?->getParameters()[0] + ); + + return $this->subject->injectDefinitionFromAnnotatedTarget($target); + }, + ], + 'array from ReflectionParameter' => [ + Fixtures::injectConstructorServices()->injectArrayService(), + ['inject', 'values'], + types()->array(), + 'values', + function (InjectAttribute $attribute) : InjectDefinition { + $reflection = (new \ReflectionClass(Fixtures::injectConstructorServices()->injectArrayService()->name()))->getConstructor()?->getParameters()[0]; + + return $this->subject->injectDefinitionFromReflectionParameterAndAttribute($reflection, $attribute); + }, + ], + 'array from manual setup' => [ + Fixtures::injectConstructorServices()->injectArrayService(), + ['inject', 'values'], + types()->array(), + 'values', + function (InjectAttribute $attribute) : InjectDefinition { + return $this->subject->injectDefinitionFromManualSetup( + Fixtures::injectConstructorServices()->injectArrayService(), + '__construct', + types()->array(), + 'values', + $attribute + ); + }, + ], + 'bool from AnnotatedTarget' => [ + Fixtures::injectConstructorServices()->injectBoolService(), + false, + types()->bool(), + 'flag', + function (InjectAttribute $attribute) : InjectDefinition { + $target = $this->createMock(AnnotatedTarget::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + (new \ReflectionClass(Fixtures::injectConstructorServices()->injectBoolService()->name()))->getConstructor()?->getParameters()[0] + ); + + return $this->subject->injectDefinitionFromAnnotatedTarget($target); + }, + ], + 'bool from ReflectionParameter' => [ + Fixtures::injectConstructorServices()->injectBoolService(), + false, + types()->bool(), + 'flag', + function (InjectAttribute $attribute) : InjectDefinition { + $reflection = (new \ReflectionClass(Fixtures::injectConstructorServices()->injectBoolService()->name()))->getConstructor()?->getParameters()[0]; + + return $this->subject->injectDefinitionFromReflectionParameterAndAttribute($reflection, $attribute); + }, + ], + 'bool from manual setup' => [ + Fixtures::injectConstructorServices()->injectBoolService(), + false, + types()->bool(), + 'flag', + function (InjectAttribute $attribute) : InjectDefinition { + return $this->subject->injectDefinitionFromManualSetup( + Fixtures::injectConstructorServices()->injectBoolService(), + '__construct', + types()->bool(), + 'flag', + $attribute, + ); + } + ], + 'explicit mixed from AnnotatedTarget' => [ + Fixtures::injectConstructorServices()->injectExplicitMixedService(), + 'whatever', + types()->mixed(), + 'value', + function (InjectAttribute $attribute) : InjectDefinition { + $target = $this->createMock(AnnotatedTarget::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + (new \ReflectionClass(Fixtures::injectConstructorServices()->injectExplicitMixedService()->name()))->getConstructor()?->getParameters()[0] + ); + + return $this->subject->injectDefinitionFromAnnotatedTarget($target); + }, + ], + 'explicit mixed from ReflectionParameter' => [ + Fixtures::injectConstructorServices()->injectExplicitMixedService(), + 'whatever', + types()->mixed(), + 'value', + function (InjectAttribute $attribute) : InjectDefinition { + $reflection = (new \ReflectionClass(Fixtures::injectConstructorServices()->injectExplicitMixedService()->name()))->getConstructor()?->getParameters()[0]; + + return $this->subject->injectDefinitionFromReflectionParameterAndAttribute($reflection, $attribute); + }, + ], + 'explicit mixed from manual setup' => [ + Fixtures::injectConstructorServices()->injectExplicitMixedService(), + 'whatever', + types()->mixed(), + 'value', + function (InjectAttribute $attribute) : InjectDefinition { + return $this->subject->injectDefinitionFromManualSetup( + Fixtures::injectConstructorServices()->injectExplicitMixedService(), + '__construct', + types()->mixed(), + 'value', + $attribute + ); + }, + ], + 'float from AnnotatedTarget' => [ + Fixtures::injectConstructorServices()->injectFloatService(), + 4.19, + types()->float(), + 'dessert', + function (InjectAttribute $attribute) : InjectDefinition { + $target = $this->createMock(AnnotatedTarget::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + (new \ReflectionClass(Fixtures::injectConstructorServices()->injectFloatService()->name()))->getConstructor()?->getParameters()[0] + ); + + return $this->subject->injectDefinitionFromAnnotatedTarget($target); + }, + ], + 'float from ReflectionParameter' => [ + Fixtures::injectConstructorServices()->injectFloatService(), + 4.19, + types()->float(), + 'dessert', + function (InjectAttribute $attribute) : InjectDefinition { + $reflection = (new \ReflectionClass(Fixtures::injectConstructorServices()->injectFloatService()->name()))->getConstructor()?->getParameters()[0]; + + return $this->subject->injectDefinitionFromReflectionParameterAndAttribute($reflection, $attribute); + }, + ], + 'float from manual setup' => [ + Fixtures::injectConstructorServices()->injectFloatService(), + 4.19, + types()->float(), + 'dessert', + function (InjectAttribute $attribute) : InjectDefinition { + return $this->subject->injectDefinitionFromManualSetup( + Fixtures::injectConstructorServices()->injectFloatService(), + '__construct', + types()->float(), + 'dessert', + $attribute + ); + }, + ], + 'implicit mixed from AnnotatedTarget' => [ + Fixtures::injectConstructorServices()->injectImplicitMixedService(), + 'boo, mixed', + types()->mixed(), + 'val', + function (InjectAttribute $attribute) : InjectDefinition { + $target = $this->createMock(AnnotatedTarget::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + (new \ReflectionClass(Fixtures::injectConstructorServices()->injectImplicitMixedService()->name()))->getConstructor()?->getParameters()[0] + ); + + return $this->subject->injectDefinitionFromAnnotatedTarget($target); + }, + ], + 'implicit mixed from ReflectionParameter' => [ + Fixtures::injectConstructorServices()->injectImplicitMixedService(), + 'boo, mixed', + types()->mixed(), + 'val', + function (InjectAttribute $attribute) : InjectDefinition { + $reflection = (new \ReflectionClass(Fixtures::injectConstructorServices()->injectImplicitMixedService()->name()))->getConstructor()?->getParameters()[0]; + + return $this->subject->injectDefinitionFromReflectionParameterAndAttribute($reflection, $attribute); + }, + ], + 'implicit mixed from manual setup' => [ + Fixtures::injectConstructorServices()->injectImplicitMixedService(), + 'boo, mixed', + types()->mixed(), + 'val', + function (InjectAttribute $attribute) : InjectDefinition { + return $this->subject->injectDefinitionFromManualSetup( + Fixtures::injectConstructorServices()->injectImplicitMixedService(), + '__construct', + types()->mixed(), + 'val', + $attribute + ); + }, + ], + 'int from AnnotatedTarget' => [ + Fixtures::injectConstructorServices()->injectIntService(), + 42, + types()->int(), + 'meaningOfLife', + function (InjectAttribute $attribute) : InjectDefinition { + $target = $this->createMock(AnnotatedTarget::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + (new \ReflectionClass(Fixtures::injectConstructorServices()->injectIntService()->name()))->getConstructor()?->getParameters()[0] + ); + + return $this->subject->injectDefinitionFromAnnotatedTarget($target); + }, + ], + 'int from ReflectionParameter' => [ + Fixtures::injectConstructorServices()->injectIntService(), + 42, + types()->int(), + 'meaningOfLife', + function (InjectAttribute $attribute) : InjectDefinition { + $reflection = (new \ReflectionClass(Fixtures::injectConstructorServices()->injectIntService()->name()))->getConstructor()?->getParameters()[0]; + + return $this->subject->injectDefinitionFromReflectionParameterAndAttribute($reflection, $attribute); + }, + ], + 'int from manual setup' => [ + Fixtures::injectConstructorServices()->injectIntService(), + 42, + types()->int(), + 'meaningOfLife', + function (InjectAttribute $attribute) : InjectDefinition { + return $this->subject->injectDefinitionFromManualSetup( + Fixtures::injectConstructorServices()->injectIntService(), + '__construct', + types()->int(), + 'meaningOfLife', + $attribute + ); + }, + ], + 'string from AnnotatedTarget' => [ + Fixtures::injectConstructorServices()->injectStringService(), + 'semantics, whatever', + types()->string(), + 'val', + function (InjectAttribute $attribute) : InjectDefinition { + $target = $this->createMock(AnnotatedTarget::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + (new \ReflectionClass(Fixtures::injectConstructorServices()->injectStringService()->name()))->getConstructor()?->getParameters()[0] + ); + + return $this->subject->injectDefinitionFromAnnotatedTarget($target); + }, + ], + 'string from ReflectionParameter' => [ + Fixtures::injectConstructorServices()->injectStringService(), + 'semantics, whatever', + types()->string(), + 'val', + function (InjectAttribute $attribute) : InjectDefinition { + $reflection = (new \ReflectionClass(Fixtures::injectConstructorServices()->injectStringService()->name()))->getConstructor()?->getParameters()[0]; + + return $this->subject->injectDefinitionFromReflectionParameterAndAttribute($reflection, $attribute); + }, + ], + 'string from manual setup' => [ + Fixtures::injectConstructorServices()->injectStringService(), + 'semantics, whatever', + types()->string(), + 'val', + function (InjectAttribute $attribute) : InjectDefinition { + return $this->subject->injectDefinitionFromManualSetup( + Fixtures::injectConstructorServices()->injectStringService(), + '__construct', + types()->string(), + 'val', + $attribute + ); + }, + ], + 'class from AnnotatedTarget' => [ + Fixtures::injectServiceConstructorServices()->serviceInjector(), + Fixtures::injectServiceConstructorServices()->fooInterface()->name(), + Fixtures::injectServiceConstructorServices()->fooInterface(), + 'foo', + function (InjectAttribute $attribute) : InjectDefinition { + $target = $this->createMock(AnnotatedTarget::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + (new \ReflectionClass(Fixtures::injectServiceConstructorServices()->serviceInjector()->name()))->getConstructor()?->getParameters()[0] + ); + + return $this->subject->injectDefinitionFromAnnotatedTarget($target); + }, + ], + 'class from ReflectionParameter' => [ + Fixtures::injectServiceConstructorServices()->serviceInjector(), + Fixtures::injectServiceConstructorServices()->fooInterface()->name(), + Fixtures::injectServiceConstructorServices()->fooInterface(), + 'foo', + function (InjectAttribute $attribute) : InjectDefinition { + $reflection = (new \ReflectionClass(Fixtures::injectServiceConstructorServices()->serviceInjector()->name()))->getConstructor()?->getParameters()[0]; + + return $this->subject->injectDefinitionFromReflectionParameterAndAttribute($reflection, $attribute); + }, + ], + 'class from manual setup' => [ + Fixtures::injectServiceConstructorServices()->serviceInjector(), + Fixtures::injectServiceConstructorServices()->fooInterface()->name(), + Fixtures::injectServiceConstructorServices()->fooInterface(), + 'foo', + function (InjectAttribute $attribute) : InjectDefinition { + return $this->subject->injectDefinitionFromManualSetup( + Fixtures::injectServiceConstructorServices()->serviceInjector(), + '__construct', + Fixtures::injectServiceConstructorServices()->fooInterface(), + 'foo', + $attribute + ); + }, + ], + 'union from AnnotatedTarget' => [ + Fixtures::injectUnionCustomStoreServices()->unionInjector(), + 'foo', + types()->union( + Fixtures::injectUnionCustomStoreServices()->fooInterface(), + Fixtures::injectUnionCustomStoreServices()->barInterface() + ), + 'fooOrBar', + function (InjectAttribute $attribute) : InjectDefinition { + $target = $this->createMock(AnnotatedTarget::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + (new \ReflectionClass(Fixtures::injectUnionCustomStoreServices()->unionInjector()->name()))->getConstructor()?->getParameters()[0] + ); + + return $this->subject->injectDefinitionFromAnnotatedTarget($target); + }, + ], + 'union from ReflectionParameter' => [ + Fixtures::injectUnionCustomStoreServices()->unionInjector(), + 'foo', + types()->union( + Fixtures::injectUnionCustomStoreServices()->fooInterface(), + Fixtures::injectUnionCustomStoreServices()->barInterface() + ), + 'fooOrBar', + function (InjectAttribute $attribute) : InjectDefinition { + $reflection = (new \ReflectionClass(Fixtures::injectUnionCustomStoreServices()->unionInjector()->name()))->getConstructor()?->getParameters()[0]; + + return $this->subject->injectDefinitionFromReflectionParameterAndAttribute($reflection, $attribute); + }, + ], + 'union from manual setup' => [ + Fixtures::injectUnionCustomStoreServices()->unionInjector(), + 'foo', + types()->union( + Fixtures::injectUnionCustomStoreServices()->fooInterface(), + Fixtures::injectUnionCustomStoreServices()->barInterface() + ), + 'fooOrBar', + function (InjectAttribute $attribute) : InjectDefinition { + return $this->subject->injectDefinitionFromManualSetup( + Fixtures::injectUnionCustomStoreServices()->unionInjector(), + '__construct', + types()->union( + Fixtures::injectUnionCustomStoreServices()->fooInterface(), + Fixtures::injectUnionCustomStoreServices()->barInterface() + ), + 'fooOrBar', + $attribute, + ); + }, + ], + 'intersect from AnnotatedTarget' => [ + Fixtures::injectIntersectCustomStoreServices()->intersectInjector(), + 'fooBar', + types()->intersect( + Fixtures::injectIntersectCustomStoreServices()->fooInterface(), + Fixtures::injectIntersectCustomStoreServices()->barInterface(), + ), + 'fooAndBar', + function (InjectAttribute $attribute) : InjectDefinition { + $target = $this->createMock(AnnotatedTarget::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + (new \ReflectionClass(Fixtures::injectIntersectCustomStoreServices()->intersectInjector()->name()))->getConstructor()?->getParameters()[0] + ); + + return $this->subject->injectDefinitionFromAnnotatedTarget($target); + }, + ], + 'intersect from ReflectionParameter' => [ + Fixtures::injectIntersectCustomStoreServices()->intersectInjector(), + 'fooBar', + types()->intersect( + Fixtures::injectIntersectCustomStoreServices()->fooInterface(), + Fixtures::injectIntersectCustomStoreServices()->barInterface(), + ), + 'fooAndBar', + function (InjectAttribute $attribute) : InjectDefinition { + $reflection = (new \ReflectionClass(Fixtures::injectIntersectCustomStoreServices()->intersectInjector()->name()))->getConstructor()?->getParameters()[0]; + + return $this->subject->injectDefinitionFromReflectionParameterAndAttribute($reflection, $attribute); + }, + ], + 'intersect from manual setup' => [ + Fixtures::injectIntersectCustomStoreServices()->intersectInjector(), + 'fooBar', + types()->intersect( + Fixtures::injectIntersectCustomStoreServices()->fooInterface(), + Fixtures::injectIntersectCustomStoreServices()->barInterface(), + ), + 'fooAndBar', + function (InjectAttribute $attribute) : InjectDefinition { + return $this->subject->injectDefinitionFromManualSetup( + Fixtures::injectIntersectCustomStoreServices()->intersectInjector(), + '__construct', + types()->intersect( + Fixtures::injectIntersectCustomStoreServices()->fooInterface(), + Fixtures::injectIntersectCustomStoreServices()->barInterface(), + ), + 'fooAndBar', + $attribute, + ); + }, + ], + 'nullable-string from AnnotatedTarget' => [ + Fixtures::injectConstructorServices()->injectNullableStringService(), + 'stabbing science into your brain', + types()->nullable(types()->string()), + 'maybe', + function (InjectAttribute $attribute) : InjectDefinition { + $target = $this->createMock(AnnotatedTarget::class); + + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + (new \ReflectionClass(Fixtures::injectConstructorServices()->injectNullableStringService()->name()))->getConstructor()?->getParameters()[0] + ); + + return $this->subject->injectDefinitionFromAnnotatedTarget($target); + }, + ], + 'nullable-string from ReflectionParameter' => [ + Fixtures::injectConstructorServices()->injectNullableStringService(), + 'stabbing science into your brain', + types()->nullable(types()->string()), + 'maybe', + function (InjectAttribute $attribute) : InjectDefinition { + $reflection = (new \ReflectionClass(Fixtures::injectConstructorServices()->injectNullableStringService()->name()))->getConstructor()?->getParameters()[0]; + + return $this->subject->injectDefinitionFromReflectionParameterAndAttribute($reflection, $attribute); + }, + ], + 'nullable-string from manual setup' => [ + Fixtures::injectConstructorServices()->injectNullableStringService(), + 'stabbing science into your brain', + types()->nullable(types()->string()), + 'maybe', + function (InjectAttribute $attribute) : InjectDefinition { + return $this->subject->injectDefinitionFromManualSetup( + Fixtures::injectConstructorServices()->injectNullableStringService(), + '__construct', + types()->nullable(types()->string()), + 'maybe', + $attribute, + ); + }, + ] + ]; + } + + /** + * @param Closure(InjectAttribute):InjectDefinition $definitionCreator + */ + #[DataProvider('injectTypeProvider')] + public function testInjectDefinitionFromAnnotatedTargetWithTypeHasCorrectInformation( + Type $service, + mixed $value, + Type|TypeUnion|TypeIntersect $type, + string $parameterName, + Closure $definitionCreator + ) : void { + $attribute = $this->createMock(InjectAttribute::class); + $attribute->expects($this->once())->method('value')->willReturn($value); + $attribute->expects($this->once())->method('from')->willReturn(null); + $attribute->expects($this->once())->method('profiles')->willReturn([]); + + $definition = ($definitionCreator->bindTo($this, $this))($attribute); + + self::assertSame($service, $definition->class()); + self::assertSame('__construct', $definition->methodName()); + self::assertSame($parameterName, $definition->parameterName()); + if ($type instanceof Type) { + self::assertSame($type, $definition->type()); + } else { + self::assertSame($type->types(), $definition->type()->types()); + } + + self::assertSame($value, $definition->value()); + self::assertSame(['default'], $definition->profiles()); + self::assertNull($definition->storeName()); + self::assertSame($attribute, $definition->attribute()); + } + + public static function injectWithCustomAttributeDefinitionCreatorProvider() : array { + return [ + 'annotatedTarget' => [ + function (InjectAttribute $attribute) : InjectDefinition { + $target = $this->createMock(AnnotatedTarget::class); + $target->expects($this->once())->method('attributeInstance')->willReturn($attribute); + $target->expects($this->once())->method('targetReflection')->willReturn( + (new \ReflectionClass(Fixtures::injectConstructorServices()->injectArrayService()->name()))->getConstructor()?->getParameters()[0] + ); + + return $this->subject->injectDefinitionFromAnnotatedTarget($target); + }, + ], + 'reflectionParameter' => [ + function (InjectAttribute $attribute) : InjectDefinition { + $reflection = (new \ReflectionClass(Fixtures::injectConstructorServices()->injectArrayService()->name()))->getConstructor()?->getParameters()[0]; + + return $this->subject->injectDefinitionFromReflectionParameterAndAttribute($reflection, $attribute); + } + ] + ]; + } + + #[DataProvider('injectWithCustomAttributeDefinitionCreatorProvider')] + /** + * @param Closure(InjectAttribute):InjectDefinition $definitionCreator + */ + public function testInjectDefinitionFromAnnotatedTargetWithExplicitProfiles(Closure $definitionCreator) : void { + $attribute = $this->createMock(InjectAttribute::class); + + $service = Fixtures::injectConstructorServices()->injectArrayService(); + + $attribute->expects($this->once())->method('value')->willReturn(['foo', 'bar']); + $attribute->expects($this->once())->method('from')->willReturn(null); + $attribute->expects($this->once())->method('profiles')->willReturn(['test']); + + $definition = ($definitionCreator->bindTo($this, $this))($attribute); + + self::assertSame($service, $definition->class()); + self::assertSame('__construct', $definition->methodName()); + self::assertSame('values', $definition->parameterName()); + self::assertSame(types()->array(), $definition->type()); + self::assertSame(['foo', 'bar'], $definition->value()); + self::assertSame(['test'], $definition->profiles()); + self::assertNull($definition->storeName()); + self::assertSame($attribute, $definition->attribute()); + } + + #[DataProvider('injectWithCustomAttributeDefinitionCreatorProvider')] + /** + * @param Closure(InjectAttribute):InjectDefinition $definitionCreator + */ + public function testInjectDefinitionWithExplicitWithDefinedStoreName(Closure $definitionCreator) : void { + $attribute = $this->createMock(InjectAttribute::class); + + $service = Fixtures::injectConstructorServices()->injectArrayService(); + + $attribute->expects($this->once())->method('value')->willReturn(['foo', 'bar']); + $attribute->expects($this->once())->method('from')->willReturn('some store name'); + $attribute->expects($this->once())->method('profiles')->willReturn([]); + + $definition = ($definitionCreator->bindTo($this, $this))($attribute); + + self::assertSame($service, $definition->class()); + self::assertSame('__construct', $definition->methodName()); + self::assertSame('values', $definition->parameterName()); + self::assertSame(types()->array(), $definition->type()); + self::assertSame(['foo', 'bar'], $definition->value()); + self::assertSame(['default'], $definition->profiles()); + self::assertSame('some store name', $definition->storeName()); + self::assertSame($attribute, $definition->attribute()); + } + + public function testAliasDefinition() : void { + $definition = $this->subject->aliasDefinition( + Fixtures::ambiguousAliasedServices()->fooInterface(), + Fixtures::ambiguousAliasedServices()->barImplementation() + ); + + self::assertSame( + Fixtures::ambiguousAliasedServices()->fooInterface(), + $definition->abstractService() + ); + self::assertSame( + Fixtures::ambiguousAliasedServices()->barImplementation(), + $definition->concreteService() + ); + } +} diff --git a/test/Unit/Definition/InjectDefinitionBuilderTest.php b/test/Unit/Definition/InjectDefinitionBuilderTest.php deleted file mode 100644 index e9696372..00000000 --- a/test/Unit/Definition/InjectDefinitionBuilderTest.php +++ /dev/null @@ -1,135 +0,0 @@ -prepareInjector()); - - $this->expectException(InvalidInjectDefinition::class); - $this->expectExceptionMessage('A method to inject into MUST be provided before building an InjectDefinition.'); - $builder->build(); - } - - public function testInjectDefinitionWithoutValueThrowsException() { - $builder = InjectDefinitionBuilder::forService(Fixtures::injectPrepareServices()->serviceScalarUnionPrepareInjector()); - - $builder = $builder->withMethod('does-not-matter', stringType(), 'else'); - - $this->expectException(InvalidInjectDefinition::class); - $this->expectExceptionMessage('A value MUST be provided when building an InjectDefinition.'); - $builder->build(); - } - - public function testInjectDefinitionWithMethodHasDifferentObject() { - $builder = InjectDefinitionBuilder::forService(Fixtures::injectPrepareServices()->prepareInjector()); - - $this->assertNotSame($builder, $builder->withMethod('foo', stringType(), 'baz')); - } - - public function testInjectDefinitionWithValueHasDifferentObject() { - $builder = InjectDefinitionBuilder::forService(Fixtures::injectPrepareServices()->prepareInjector()); - - $this->assertNotSame($builder, $builder->withValue('foo')); - } - - public function testInjectDefinitionWithStoreHasDifferentObject() { - $builder = InjectDefinitionBuilder::forService(Fixtures::injectPrepareServices()->prepareInjector()); - - $this->assertNotSame($builder, $builder->withStore('foo-store')); - } - - public function testInjectDefinitionWithProfilesHasDifferentObject() { - $builder = InjectDefinitionBuilder::forService(Fixtures::injectPrepareServices()->prepareInjector()); - - $this->assertNotSame($builder, $builder->withProfiles('profile')); - } - - public function testInjectDefinitionWithAttributeHasDifferentObject() : void { - $builder = InjectDefinitionBuilder::forService(Fixtures::injectPrepareServices()->prepareInjector()); - - $this->assertNotSame($builder, $builder->withAttribute(new Inject('my-value'))); - } - - public function testValidMethodInjectDefinitionGetTargetIdentifierGetName() { - $injectDefinition = InjectDefinitionBuilder::forService(Fixtures::injectPrepareServices()->prepareInjector()) - ->withMethod('methodName', stringType(), 'paramName') - ->withValue('foobar') - ->build(); - - $this->assertSame('paramName', $injectDefinition->parameterName()); - } - - public function testValidMethodInjectDefinitionTargetIdentifierGetValue() { - $injectDefinition = InjectDefinitionBuilder::forService(Fixtures::injectPrepareServices()->prepareInjector()) - ->withMethod('methodName', stringType(), 'paramName') - ->withValue('foobar') - ->build(); - - $this->assertSame('methodName', $injectDefinition->methodName()); - } - - public function testValidMethodInjectDefinitionTargetIdentifierGetClass() { - $injectDefinition = InjectDefinitionBuilder::forService(Fixtures::injectPrepareServices()->prepareInjector()) - ->withMethod('methodName', stringType(), 'paramName') - ->withValue('foobar') - ->build(); - - $this->assertSame(Fixtures::injectPrepareServices()->prepareInjector(), $injectDefinition->class()); - } - - public function testValidMethodInjectDefinitionGetType() { - $injectDefinition = InjectDefinitionBuilder::forService(Fixtures::injectPrepareServices()->prepareInjector()) - ->withMethod('methodName', $expectedType = stringType(), 'paramName') - ->withValue('foobar') - ->build(); - - $this->assertSame($expectedType, $injectDefinition->type()); - } - - public function testValidMethodInjectDefinitionGetValue() { - $injectDefinition = InjectDefinitionBuilder::forService(Fixtures::injectPrepareServices()->prepareInjector()) - ->withMethod('methodName', stringType(), 'paramName') - ->withValue('foobar') - ->build(); - - $this->assertSame('foobar', $injectDefinition->value()); - } - - public function testValidMethodInjectDefinitionWithNoProfilesGetProfiles() { - $injectDefinition = InjectDefinitionBuilder::forService(Fixtures::injectPrepareServices()->prepareInjector()) - ->withMethod('methodName', stringType(), 'paramName') - ->withValue('foobar') - ->build(); - - $this->assertSame(['default'], $injectDefinition->profiles()); - } - - public function testValidMethodInjectDefinitionWithOneProfileGetProfiles() { - $injectDefinition = InjectDefinitionBuilder::forService(Fixtures::injectPrepareServices()->prepareInjector()) - ->withMethod('methodName', stringType(), 'paramName') - ->withValue('foobar') - ->withProfiles('foo') - ->build(); - - $this->assertSame(['foo'], $injectDefinition->profiles()); - } - - public function testValidMethodInjectDefinitionWithAdditionalProfilesGetProfiles() { - $injectDefinition = InjectDefinitionBuilder::forService(Fixtures::injectPrepareServices()->prepareInjector()) - ->withMethod('methodName', stringType(), 'paramName') - ->withValue('foobar') - ->withProfiles('foo', 'bar', 'baz') - ->build(); - - $this->assertSame(['foo', 'bar', 'baz'], $injectDefinition->profiles()); - } -} diff --git a/test/Unit/Definition/ProfilesAwareContainerDefinitionTest.php b/test/Unit/Definition/ProfilesAwareContainerDefinitionTest.php index 0912b296..162ac12b 100644 --- a/test/Unit/Definition/ProfilesAwareContainerDefinitionTest.php +++ b/test/Unit/Definition/ProfilesAwareContainerDefinitionTest.php @@ -2,54 +2,46 @@ namespace Cspray\AnnotatedContainer\Unit\Definition; -use Cspray\AnnotatedContainer\Definition\AliasDefinitionBuilder; use Cspray\AnnotatedContainer\Definition\ContainerDefinition; -use Cspray\AnnotatedContainer\Definition\ContainerDefinitionBuilder; -use Cspray\AnnotatedContainer\Definition\InjectDefinitionBuilder; use Cspray\AnnotatedContainer\Definition\ProfilesAwareContainerDefinition; -use Cspray\AnnotatedContainer\Definition\ServiceDefinitionBuilder; use Cspray\AnnotatedContainer\Exception\InvalidAlias; use Cspray\AnnotatedContainer\Profiles; use Cspray\AnnotatedContainer\Fixture\Fixtures; +use Cspray\AnnotatedContainer\Unit\Helper\HasMockDefinitions; use PHPUnit\Framework\TestCase; -use function Cspray\Typiphy\stringType; +use function Cspray\AnnotatedContainer\Reflection\types; -class ProfilesAwareContainerDefinitionTest extends TestCase { +final class ProfilesAwareContainerDefinitionTest extends TestCase { + + use HasMockDefinitions; public function testGetServiceDefinitionsOnlyReturnThoseMatchingProfiles() : void { - $serviceDefinition1 = ServiceDefinitionBuilder::forConcrete(Fixtures::singleConcreteService()->fooImplementation()) - ->withProfiles(['foo']) - ->build(); - $serviceDefinition2 = ServiceDefinitionBuilder::forConcrete(Fixtures::ambiguousAliasedServices()->quxImplementation()) - ->withProfiles(['default', 'bar', 'baz']) - ->build(); - $serviceDefinition3 = ServiceDefinitionBuilder::forAbstract(Fixtures::ambiguousAliasedServices()->fooInterface()) - ->withProfiles(['foo', 'qux', 'test']) - ->build(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition($serviceDefinition1) - ->withServiceDefinition($serviceDefinition2) - ->withServiceDefinition($serviceDefinition3) - ->build(); + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $fooImplementation = $this->concreteServiceDefinition(Fixtures::singleConcreteService()->fooImplementation(), profiles: ['foo']), + $this->concreteServiceDefinition(Fixtures::ambiguousAliasedServices()->quxImplementation(), profiles: ['default', 'bar', 'baz']), + $fooInterface = $this->abstractServiceDefinition(Fixtures::ambiguousAliasedServices()->fooInterface(), profiles: ['foo', 'qux', 'test']), + ] + ); $subject = new ProfilesAwareContainerDefinition($containerDefinition, Profiles::fromList(['foo'])); - self::assertSame([$serviceDefinition1, $serviceDefinition3], $subject->serviceDefinitions()); + self::assertSame([$fooImplementation, $fooInterface], $subject->serviceDefinitions()); } public function testGetAliasDefinitionsDoNotIncludeAliasWithInvalidAbstractProfiles() : void { - $abstract = ServiceDefinitionBuilder::forAbstract(Fixtures::ambiguousAliasedServices()->fooInterface()) - ->withProfiles(['bar']) - ->build(); - $concrete = ServiceDefinitionBuilder::forConcrete(Fixtures::ambiguousAliasedServices()->barImplementation()) - ->build(); - $alias = AliasDefinitionBuilder::forAbstract($abstract->type())->withConcrete($concrete->type())->build(); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition($abstract) - ->withServiceDefinition($concrete) - ->withAliasDefinition($alias) - ->build(); + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $this->abstractServiceDefinition(Fixtures::ambiguousAliasedServices()->fooInterface(), profiles: ['bar']), + $this->concreteServiceDefinition(Fixtures::ambiguousAliasedServices()->barImplementation()), + ], + aliasDefinitions: [ + $this->aliasDefinition( + Fixtures::ambiguousAliasedServices()->fooInterface(), + Fixtures::ambiguousAliasedServices()->barImplementation() + ) + ], + ); $subject = new ProfilesAwareContainerDefinition($containerDefinition, Profiles::fromList(['default'])); @@ -58,17 +50,18 @@ public function testGetAliasDefinitionsDoNotIncludeAliasWithInvalidAbstractProfi public function testGetAliasDefinitionsDoNotIncludeAliasWithInvalidConcreteProfiles() : void { - $abstract = ServiceDefinitionBuilder::forAbstract(Fixtures::ambiguousAliasedServices()->fooInterface()) - ->build(); - $concrete = ServiceDefinitionBuilder::forConcrete(Fixtures::ambiguousAliasedServices()->barImplementation()) - ->withProfiles(['foo']) - ->build(); - $alias = AliasDefinitionBuilder::forAbstract($abstract->type())->withConcrete($concrete->type())->build(); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition($abstract) - ->withServiceDefinition($concrete) - ->withAliasDefinition($alias) - ->build(); + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $this->abstractServiceDefinition(Fixtures::ambiguousAliasedServices()->fooInterface()), + $this->concreteServiceDefinition(Fixtures::ambiguousAliasedServices()->barImplementation(), profiles: ['foo']), + ], + aliasDefinitions: [ + $this->aliasDefinition( + Fixtures::ambiguousAliasedServices()->fooInterface(), + Fixtures::ambiguousAliasedServices()->barImplementation(), + ), + ], + ); $subject = new ProfilesAwareContainerDefinition($containerDefinition, Profiles::fromList(['default'])); @@ -76,16 +69,18 @@ public function testGetAliasDefinitionsDoNotIncludeAliasWithInvalidConcreteProfi } public function testGetAliasDefinitionsIncludeCorrectProfiles() : void { - $abstract = ServiceDefinitionBuilder::forAbstract(Fixtures::ambiguousAliasedServices()->fooInterface()) - ->build(); - $concrete = ServiceDefinitionBuilder::forConcrete(Fixtures::ambiguousAliasedServices()->barImplementation()) - ->build(); - $alias = AliasDefinitionBuilder::forAbstract($abstract->type())->withConcrete($concrete->type())->build(); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition($abstract) - ->withServiceDefinition($concrete) - ->withAliasDefinition($alias) - ->build(); + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $this->abstractServiceDefinition(Fixtures::ambiguousAliasedServices()->fooInterface()), + $this->concreteServiceDefinition(Fixtures::ambiguousAliasedServices()->barImplementation()), + ], + aliasDefinitions: [ + $this->aliasDefinition( + Fixtures::ambiguousAliasedServices()->fooInterface(), + Fixtures::ambiguousAliasedServices()->barImplementation(), + ), + ], + ); $subject = new ProfilesAwareContainerDefinition($containerDefinition, Profiles::fromList(['default'])); @@ -93,15 +88,17 @@ public function testGetAliasDefinitionsIncludeCorrectProfiles() : void { } public function testGetAliasDefinitionAbstractNotServiceDefinitionThrowsException() : void { - $concrete = ServiceDefinitionBuilder::forConcrete(Fixtures::ambiguousAliasedServices()->barImplementation()) - ->build(); - $alias = AliasDefinitionBuilder::forAbstract(Fixtures::ambiguousAliasedServices()->fooInterface()) - ->withConcrete($concrete->type()) - ->build(); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition($concrete) - ->withAliasDefinition($alias) - ->build(); + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $this->concreteServiceDefinition(Fixtures::ambiguousAliasedServices()->barImplementation()), + ], + aliasDefinitions: [ + $this->aliasDefinition( + Fixtures::ambiguousAliasedServices()->fooInterface(), + Fixtures::ambiguousAliasedServices()->barImplementation(), + ), + ], + ); $subject = new ProfilesAwareContainerDefinition($containerDefinition, Profiles::fromList(['default'])); @@ -115,15 +112,17 @@ public function testGetAliasDefinitionAbstractNotServiceDefinitionThrowsExceptio } public function testGetAliasDefinitionConcreteNotServiceDefinitionThrowsException() : void { - $abstract = ServiceDefinitionBuilder::forAbstract(Fixtures::ambiguousAliasedServices()->fooInterface()) - ->build(); - $alias = AliasDefinitionBuilder::forAbstract($abstract->type()) - ->withConcrete(Fixtures::ambiguousAliasedServices()->barImplementation()) - ->build(); - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition($abstract) - ->withAliasDefinition($alias) - ->build(); + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $this->abstractServiceDefinition(Fixtures::ambiguousAliasedServices()->fooInterface()), + ], + aliasDefinitions: [ + $this->aliasDefinition( + Fixtures::ambiguousAliasedServices()->fooInterface(), + Fixtures::ambiguousAliasedServices()->barImplementation() + ), + ], + ); $subject = new ProfilesAwareContainerDefinition($containerDefinition, Profiles::fromList(['default'])); @@ -159,28 +158,33 @@ public function testGetServiceDelegateDefinitionsDelegatesToInjectedContainerDef } public function testGetInjectDefinitionsRespectProfiles() : void { - $service = ServiceDefinitionBuilder::forConcrete(Fixtures::injectConstructorServices()->injectProfilesStringService()) - ->build(); - $injectDefinition1 = InjectDefinitionBuilder::forService($service->type()) - ->withMethod('__construct', stringType(), 'val') - ->withValue('a string') - ->withProfiles('test') - ->build(); - $injectDefinition2 = InjectDefinitionBuilder::forService($service->type()) - ->withMethod('__construct', stringType(), 'val') - ->withValue('a different string') - ->withProfiles('prod') - ->build(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition($service) - ->withInjectDefinition($injectDefinition1) - ->withInjectDefinition($injectDefinition2) - ->build(); + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $this->concreteServiceDefinition(Fixtures::injectConstructorServices()->injectProfilesStringService()), + ], + injectDefinitions: [ + $this->injectDefinition( + Fixtures::injectConstructorServices()->injectProfilesStringService(), + '__construct', + 'val', + types()->string(), + 'a string', + profiles: ['test'], + ), + $injectDefinition = $this->injectDefinition( + Fixtures::injectConstructorServices()->injectProfilesStringService(), + '__construct', + 'val', + types()->string(), + 'a different string', + profiles: ['prod'], + ), + ] + ); $subject = new ProfilesAwareContainerDefinition($containerDefinition, Profiles::fromList(['prod'])); - $expected = [$injectDefinition2]; + $expected = [$injectDefinition]; self::assertSame($expected, $subject->injectDefinitions()); } } diff --git a/test/Unit/Definition/ServiceDefinitionBuilderTest.php b/test/Unit/Definition/ServiceDefinitionBuilderTest.php deleted file mode 100644 index f9391175..00000000 --- a/test/Unit/Definition/ServiceDefinitionBuilderTest.php +++ /dev/null @@ -1,121 +0,0 @@ -fooInterface()->name(); - } - - private function getConcreteType() : string { - return Fixtures::implicitAliasedServices()->fooImplementation()->name(); - } - - public function testBuildingTypeForAbstractHasCorrectServiceDefinitionType() { - $type = objectType($this->getAbstractType()); - $serviceDefinition = ServiceDefinitionBuilder::forAbstract($type)->build(); - - $this->assertSame($type, $serviceDefinition->type()); - } - - public function testBuildingTypeForAbstractIsAbstract() { - $serviceDefinition = ServiceDefinitionBuilder::forAbstract(objectType($this->getAbstractType()))->build(); - - $this->assertTrue($serviceDefinition->isAbstract()); - } - - public function testBuildingTypeForAbstractIsNotConcrete() { - $serviceDefinition = ServiceDefinitionBuilder::forAbstract(objectType($this->getAbstractType()))->build(); - - $this->assertFalse($serviceDefinition->isConcrete()); - } - - public function testBuildingTypeForAbstractWithNoProfilesSpecifiedIncludesDefault() { - $serviceDefinition = ServiceDefinitionBuilder::forAbstract(objectType($this->getAbstractType()))->build(); - - $this->assertSame(['default'], $serviceDefinition->profiles()); - } - - public function testBuildingTypeForConcreteHasCorrectServiceDefinitionType() { - $type = objectType($this->getConcreteType()); - $serviceDefinition = ServiceDefinitionBuilder::forConcrete($type)->build(); - - $this->assertSame($type, $serviceDefinition->type()); - } - - public function testBuildingTypeForConcreteIsNotAbstract() { - $serviceDefinition = ServiceDefinitionBuilder::forConcrete(objectType($this->getConcreteType()))->build(); - - $this->assertFalse($serviceDefinition->isAbstract()); - } - - public function testBuildingTypeForConcreteIsConcrete() { - $serviceDefinition = ServiceDefinitionBuilder::forConcrete(objectType($this->getConcreteType()))->build(); - - $this->assertTrue($serviceDefinition->isConcrete()); - } - - public function testWithProfilesImmutableBuilder() { - $serviceDefinition1 = ServiceDefinitionBuilder::forConcrete(objectType($this->getConcreteType())); - $serviceDefinition2 = $serviceDefinition1->withProfiles(['dev']); - - $this->assertNotSame($serviceDefinition1, $serviceDefinition2); - } - - public function testWithNameImmutableBuilder() : void { - $serviceDefinition1 = ServiceDefinitionBuilder::forConcrete(objectType($this->getConcreteType())); - $serviceDefinition2 = $serviceDefinition1->withName('name'); - - self::assertNotSame($serviceDefinition1, $serviceDefinition2); - } - - public function testWithAttributeImmutableBuilder() : void { - $serviceDefinition1 = ServiceDefinitionBuilder::forConcrete(objectType($this->getConcreteType())); - $serviceDefinition2 = $serviceDefinition1->withAttribute(new Service()); - - self::assertNotSame($serviceDefinition1, $serviceDefinition2); - } - - public function testWithProfileReplacesDefault() { - $serviceDefinition = ServiceDefinitionBuilder::forConcrete(objectType($this->getConcreteType())) - ->withProfiles(['dev'])->build(); - - $this->assertSame(['dev'], $serviceDefinition->profiles()); - } - - public function testWithMultipleProfilesAllIncluded() { - $serviceDefinition = ServiceDefinitionBuilder::forConcrete(objectType($this->getConcreteType())) - ->withProfiles(['default', 'dev', 'local']) - ->build(); - - $this->assertSame(['default', 'dev', 'local'], $serviceDefinition->profiles()); - } - - public function testWithNoAttributeDefinitionAttributeIsNull() : void { - $serviceDefinition = ServiceDefinitionBuilder::forAbstract(objectType($this->getAbstractType()))->build(); - - self::assertNull($serviceDefinition->attribute()); - } - - public function testWithAttributeDefinitionAttributeIsSame() : void { - $serviceDefinition = ServiceDefinitionBuilder::forAbstract(objectType($this->getAbstractType())) - ->withAttribute($attr = new Service()) - ->build(); - - self::assertSame($attr, $serviceDefinition->attribute()); - } -} diff --git a/test/Unit/Definition/ServiceDelegateDefinitionBuilderTest.php b/test/Unit/Definition/ServiceDelegateDefinitionBuilderTest.php deleted file mode 100644 index c886fd8a..00000000 --- a/test/Unit/Definition/ServiceDelegateDefinitionBuilderTest.php +++ /dev/null @@ -1,74 +0,0 @@ -expectException(InvalidServiceDelegateDefinition::class); - $this->expectExceptionMessage('The delegate method for a ServiceDelegateDefinition must not be blank.'); - ServiceDelegateDefinitionBuilder::forService(Fixtures::delegatedService()->serviceInterface()) - ->withDelegateMethod(Fixtures::delegatedService()->serviceFactory(), ''); - } - - public function testWithDelegateMethodImmutableBuilder() { - $builder1 = ServiceDelegateDefinitionBuilder::forService(Fixtures::delegatedService()->serviceInterface()); - $builder2 = $builder1->withDelegateMethod(Fixtures::delegatedService()->serviceFactory(), 'createService'); - - $this->assertNotSame($builder1, $builder2); - } - - public function testWithAttributeImmutableBuilder() { - $builder1 = ServiceDelegateDefinitionBuilder::forService(Fixtures::delegatedService()->serviceInterface()); - $builder2 = $builder1->withAttribute(new ServiceDelegate()); - - self::assertNotSame($builder1, $builder2); - } - - public function testBuildHasServiceDefinition() { - $delegateDefinition = ServiceDelegateDefinitionBuilder::forService(Fixtures::delegatedService()->serviceInterface()) - ->withDelegateMethod(Fixtures::delegatedService()->serviceFactory(), 'createService') - ->build(); - - $this->assertSame(Fixtures::delegatedService()->serviceInterface(), $delegateDefinition->serviceType()); - } - - public function testBuildHasDelegateType() { - $delegateDefinition = ServiceDelegateDefinitionBuilder::forService(Fixtures::delegatedService()->serviceInterface()) - ->withDelegateMethod(Fixtures::delegatedService()->serviceFactory(), 'createService') - ->build(); - - $this->assertSame(Fixtures::delegatedService()->serviceFactory(), $delegateDefinition->delegateType()); - } - - public function testBuildHasDelegateMethod() { - $delegateDefinition = ServiceDelegateDefinitionBuilder::forService(Fixtures::delegatedService()->serviceInterface()) - ->withDelegateMethod(Fixtures::delegatedService()->serviceFactory(), 'createService') - ->build(); - - $this->assertSame('createService', $delegateDefinition->delegateMethod()); - } - - public function testBuildWithNoAttributeReturnsNull() : void { - $delegateDefinition = ServiceDelegateDefinitionBuilder::forService(Fixtures::delegatedService()->serviceInterface()) - ->withDelegateMethod(Fixtures::delegatedService()->serviceFactory(), 'createService') - ->build(); - - self::assertNull($delegateDefinition->attribute()); - } - - public function testBuildWithAttributeReturnsSameInstance() : void { - $delegateDefinition = ServiceDelegateDefinitionBuilder::forService(Fixtures::delegatedService()->serviceInterface()) - ->withDelegateMethod(Fixtures::delegatedService()->serviceFactory(), 'createService') - ->withAttribute($attr = new ServiceDelegate()) - ->build(); - - self::assertSame($attr, $delegateDefinition->attribute()); - } -} diff --git a/test/Unit/Definition/ServicePrepareDefinitionBuilderTest.php b/test/Unit/Definition/ServicePrepareDefinitionBuilderTest.php deleted file mode 100644 index c520b7e1..00000000 --- a/test/Unit/Definition/ServicePrepareDefinitionBuilderTest.php +++ /dev/null @@ -1,57 +0,0 @@ -fooInterface(), 'setBar')->build(); - - $this->assertSame(Fixtures::interfacePrepareServices()->fooInterface(), $prepareDefinition->service()); - } - - public function testBuildHasMethod() { - $prepareDefinition = ServicePrepareDefinitionBuilder::forMethod(Fixtures::interfacePrepareServices()->fooInterface(), 'setBar')->build(); - - $this->assertSame('setBar', $prepareDefinition->methodName()); - } - - public function testExceptionThrownIfMethodEmpty() { - $this->expectException(InvalidServicePrepareDefinition::class); - $this->expectExceptionMessage('A method for a ServicePrepareDefinition must not be blank.'); - ServicePrepareDefinitionBuilder::forMethod(objectType(static::class), '')->build(); - } - - public function testWithAttributeIsImmutable() : void { - $prepareDefinition = ServicePrepareDefinitionBuilder::forMethod( - Fixtures::interfacePrepareServices()->fooInterface(), - 'setBar' - ); - self::assertNotSame($prepareDefinition, $prepareDefinition->withAttribute(new ServicePrepare())); - } - - public function testNoAttributeDefinitionAttributeIsNull() : void { - $prepareDefinition = ServicePrepareDefinitionBuilder::forMethod( - Fixtures::interfacePrepareServices()->fooInterface(), - 'setBar' - )->build(); - - self::assertNull($prepareDefinition->attribute()); - } - - public function testWithAttributeDefinitionAttributeIsSameInstance() : void { - $prepareDefinition = ServicePrepareDefinitionBuilder::forMethod( - Fixtures::interfacePrepareServices()->fooInterface(), - 'setBar' - )->withAttribute($attr = new ServicePrepare())->build(); - - self::assertSame($attr, $prepareDefinition->attribute()); - } -} diff --git a/test/Unit/Helper/HasMockDefinitions.php b/test/Unit/Helper/HasMockDefinitions.php new file mode 100644 index 00000000..a9894b38 --- /dev/null +++ b/test/Unit/Helper/HasMockDefinitions.php @@ -0,0 +1,152 @@ + $serviceDefinitions + * @param list $serviceDelegateDefinitions + * @param list $servicePrepareDefinitions + * @param list $injectDefinitions + * @Param list $aliasDefinitions + */ + private function containerDefinition( + array $serviceDefinitions = [], + array $serviceDelegateDefinitions = [], + array $servicePrepareDefinitions = [], + array $injectDefinitions = [], + array $aliasDefinitions = [], + ) : ContainerDefinition&MockObject { + $mock = $this->createMock(ContainerDefinition::class); + $mock->method('serviceDefinitions')->willReturn($serviceDefinitions); + $mock->method('serviceDelegateDefinitions')->willReturn($serviceDelegateDefinitions); + $mock->method('servicePrepareDefinitions')->willReturn($servicePrepareDefinitions); + $mock->method('injectDefinitions')->willReturn($injectDefinitions); + $mock->method('aliasDefinitions')->willReturn($aliasDefinitions); + + return $mock; + } + + private function concreteServiceDefinition( + Type $type, + array $profiles = ['default'], + ?string $name = null, + bool $isPrimary = false, + ) : ServiceDefinition { + $mock = $this->createMock(ServiceDefinition::class); + $mock->method('type')->willReturn($type); + $mock->method('name')->willReturn($name); + $mock->method('profiles')->willReturn($profiles); + $mock->method('isPrimary')->willReturn($isPrimary); + $mock->method('isConcrete')->willReturn(true); + $mock->method('isAbstract')->willReturn(false); + $serviceAttribute = $this->createMock(ServiceAttribute::class); + $serviceAttribute->method('profiles')->willReturn([]); + $serviceAttribute->method('isPrimary')->willReturn(false); + $serviceAttribute->method('name')->willReturn(null); + $mock->method('attribute')->willReturn($serviceAttribute); + + return $mock; + } + + private function abstractServiceDefinition( + Type $type, + array $profiles = ['default'] + ) : ServiceDefinition { + $mock = $this->createMock(ServiceDefinition::class); + $mock->method('type')->willReturn($type); + $mock->method('name')->willReturn(null); + $mock->method('profiles')->willReturn($profiles); + $mock->method('isPrimary')->willReturn(false); + $mock->method('isConcrete')->willReturn(false); + $mock->method('isAbstract')->willReturn(true); + $serviceAttribute = $this->createMock(ServiceAttribute::class); + $serviceAttribute->method('profiles')->willReturn([]); + $serviceAttribute->method('isPrimary')->willReturn(false); + $serviceAttribute->method('name')->willReturn(null); + $mock->method('attribute')->willReturn($serviceAttribute); + + return $mock; + } + + private function servicePrepareDefinition( + Type $service, + string $method + ) : ServicePrepareDefinition { + $mock = $this->createMock(ServicePrepareDefinition::class); + $mock->method('service')->willReturn($service); + $mock->method('methodName')->willReturn($method); + $attribute = $this->createMock(ServicePrepareAttribute::class); + $mock->method('attribute')->willReturn($attribute); + + return $mock; + } + + private function serviceDelegateDefinition( + Type $service, + Type $factory, + string $method + ) : ServiceDelegateDefinition { + $mock = $this->createMock(ServiceDelegateDefinition::class); + $mock->method('delegateType')->willReturn($factory); + $mock->method('delegateMethod')->willReturn($method); + $mock->method('serviceType')->willReturn($service); + $attribute = $this->createMock(ServiceDelegateAttribute::class); + $attribute->method('service')->willReturn(null); + $mock->method('attribute')->willReturn($attribute); + + return $mock; + } + + private function aliasDefinition(Type $abstractService, Type $concreteService) : AliasDefinition { + $mock = $this->createMock(AliasDefinition::class); + $mock->method('abstractService')->willReturn($abstractService); + $mock->method('concreteService')->willReturn($concreteService); + + return $mock; + } + + private function injectDefinition( + Type $service, + string $method, + string $parameter, + Type|TypeUnion|TypeIntersect $type, + mixed $value, + array $profiles = ['default'], + ?string $store = null + ) { + $mock = $this->createMock(InjectDefinition::class); + $mock->method('class')->willReturn($service); + $mock->method('methodName')->willReturn($method); + $mock->method('parameterName')->willReturn($parameter); + $mock->method('type')->willReturn($type); + $mock->method('value')->willReturn($value); + $mock->method('profiles')->willReturn($profiles); + $mock->method('storeName')->willReturn($store); + $attribute = $this->createMock(InjectAttribute::class); + $attribute->method('value')->willReturn($value); + $attribute->method('from')->willReturn($store); + $attribute->method('profiles')->willReturn([]); + $mock->method('attribute')->willReturn($attribute); + + return $mock; + } +} diff --git a/test/Unit/Helper/StubDefinitionProvider.php b/test/Unit/Helper/StubDefinitionProvider.php index ef2d2c4d..e612a0f8 100644 --- a/test/Unit/Helper/StubDefinitionProvider.php +++ b/test/Unit/Helper/StubDefinitionProvider.php @@ -5,7 +5,7 @@ use Cspray\AnnotatedContainer\StaticAnalysis\DefinitionProvider; use Cspray\AnnotatedContainer\StaticAnalysis\DefinitionProviderContext; use Cspray\AnnotatedContainer\Fixture\Fixtures; -use function Cspray\AnnotatedContainer\service; +use function Cspray\AnnotatedContainer\Definition\service; final class StubDefinitionProvider implements DefinitionProvider { diff --git a/test/Unit/Helper/StubDefinitionProviderWithDependencies.php b/test/Unit/Helper/StubDefinitionProviderWithDependencies.php index acc339e8..a50ec6be 100644 --- a/test/Unit/Helper/StubDefinitionProviderWithDependencies.php +++ b/test/Unit/Helper/StubDefinitionProviderWithDependencies.php @@ -2,14 +2,14 @@ namespace Cspray\AnnotatedContainer\Unit\Helper; +use Cspray\AnnotatedContainer\Reflection\Type; use Cspray\AnnotatedContainer\StaticAnalysis\DefinitionProvider; use Cspray\AnnotatedContainer\StaticAnalysis\DefinitionProviderContext; -use Cspray\Typiphy\ObjectType; -use function Cspray\AnnotatedContainer\service; +use function Cspray\AnnotatedContainer\Definition\service; final class StubDefinitionProviderWithDependencies implements DefinitionProvider { - public function __construct(private readonly ObjectType $service) { + public function __construct(private readonly Type $service) { } public function consume(DefinitionProviderContext $context) : void { diff --git a/test/Unit/Helper/StubParameterStore.php b/test/Unit/Helper/StubParameterStore.php index ce57befa..f453ee5e 100644 --- a/test/Unit/Helper/StubParameterStore.php +++ b/test/Unit/Helper/StubParameterStore.php @@ -3,9 +3,9 @@ namespace Cspray\AnnotatedContainer\Unit\Helper; use Cspray\AnnotatedContainer\ContainerFactory\ParameterStore; -use Cspray\Typiphy\Type; -use Cspray\Typiphy\TypeIntersect; -use Cspray\Typiphy\TypeUnion; +use Cspray\AnnotatedContainer\Reflection\Type; +use Cspray\AnnotatedContainer\Reflection\TypeUnion; +use Cspray\AnnotatedContainer\Reflection\TypeIntersect; final class StubParameterStore implements ParameterStore { @@ -13,7 +13,7 @@ public function name() : string { return 'test-store'; } - public function fetch(TypeUnion|Type|TypeIntersect $type, string $key) : string { + public function fetch(Type|TypeUnion|TypeIntersect $type, string $key) : string { return 'from test-store ' . $key; } } diff --git a/test/Unit/Helper/StubParameterStoreWithDependencies.php b/test/Unit/Helper/StubParameterStoreWithDependencies.php index 34d045e8..05b89d70 100644 --- a/test/Unit/Helper/StubParameterStoreWithDependencies.php +++ b/test/Unit/Helper/StubParameterStoreWithDependencies.php @@ -3,9 +3,9 @@ namespace Cspray\AnnotatedContainer\Unit\Helper; use Cspray\AnnotatedContainer\ContainerFactory\ParameterStore; -use Cspray\Typiphy\Type; -use Cspray\Typiphy\TypeIntersect; -use Cspray\Typiphy\TypeUnion; +use Cspray\AnnotatedContainer\Reflection\Type; +use Cspray\AnnotatedContainer\Reflection\TypeUnion; +use Cspray\AnnotatedContainer\Reflection\TypeIntersect; final class StubParameterStoreWithDependencies implements ParameterStore { @@ -16,7 +16,7 @@ public function name() : string { return 'test-store'; } - public function fetch(TypeUnion|Type|TypeIntersect $type, string $key) : string { + public function fetch(Type|TypeUnion|TypeIntersect $type, string $key) : string { return $this->prefix . $key; } } diff --git a/test/Unit/Internal/SerializerInjectValueParserTest.php b/test/Unit/Internal/SerializerInjectValueParserTest.php deleted file mode 100644 index 94dd82de..00000000 --- a/test/Unit/Internal/SerializerInjectValueParserTest.php +++ /dev/null @@ -1,45 +0,0 @@ -convertStringToType($stringType); - - self::assertSame($type, $actual); - } -} diff --git a/test/Unit/LogicalConstraint/Check/DuplicateServiceDelegateTest.php b/test/Unit/LogicalConstraint/Check/DuplicateServiceDelegateTest.php index 0914a820..49528094 100644 --- a/test/Unit/LogicalConstraint/Check/DuplicateServiceDelegateTest.php +++ b/test/Unit/LogicalConstraint/Check/DuplicateServiceDelegateTest.php @@ -12,7 +12,7 @@ use Cspray\AnnotatedContainer\StaticAnalysis\DefinitionProviderContext; use Cspray\AnnotatedContainer\Fixture\Fixtures; use Cspray\AnnotatedContainer\Fixture\LogicalConstraints\LogicalConstraintFixtures; -use function Cspray\AnnotatedContainer\serviceDelegate; +use function Cspray\AnnotatedContainer\Definition\serviceDelegate; final class DuplicateServiceDelegateTest extends LogicalConstraintTestCase { @@ -77,7 +77,6 @@ public function testDuplicateDelegateAddedWithFunctionalApi() : void { public function consume(DefinitionProviderContext $context) : void { $context->addServiceDelegateDefinition( serviceDelegate( - Fixtures::implicitServiceDelegateType()->fooService(), Fixtures::implicitServiceDelegateType()->fooServiceFactory(), 'create' ) diff --git a/test/Unit/LogicalConstraint/Check/DuplicateServicePrepareTest.php b/test/Unit/LogicalConstraint/Check/DuplicateServicePrepareTest.php index 437d22af..91a9f394 100644 --- a/test/Unit/LogicalConstraint/Check/DuplicateServicePrepareTest.php +++ b/test/Unit/LogicalConstraint/Check/DuplicateServicePrepareTest.php @@ -13,8 +13,8 @@ use Cspray\AnnotatedContainer\Fixture\Fixtures; use Cspray\AnnotatedContainer\Fixture\LogicalConstraints\DuplicateServicePrepare\DummyPrepare; use Cspray\AnnotatedContainer\Fixture\LogicalConstraints\LogicalConstraintFixtures; -use function Cspray\Typiphy\objectType; -use function Cspray\AnnotatedContainer\servicePrepare; +use function Cspray\AnnotatedContainer\Definition\servicePrepare; +use function Cspray\AnnotatedContainer\Reflection\types; final class DuplicateServicePrepareTest extends LogicalConstraintTestCase { @@ -81,12 +81,12 @@ public function testDuplicatePreparesWithDefinitionProviderHasViolation() : void new class implements DefinitionProvider { public function consume(DefinitionProviderContext $context) : void { $context->addServicePrepareDefinition( - servicePrepare(objectType( + servicePrepare(types()->class( Fixtures::singleConcreteService()->fooImplementation()->name() ), 'postConstruct') ); $context->addServicePrepareDefinition( - servicePrepare(objectType( + servicePrepare(types()->class( Fixtures::singleConcreteService()->fooImplementation()->name() ), 'postConstruct') ); diff --git a/test/Unit/LogicalConstraint/Check/DuplicateServiceTypeTest.php b/test/Unit/LogicalConstraint/Check/DuplicateServiceTypeTest.php index 48c7b1f0..01ea4a82 100644 --- a/test/Unit/LogicalConstraint/Check/DuplicateServiceTypeTest.php +++ b/test/Unit/LogicalConstraint/Check/DuplicateServiceTypeTest.php @@ -15,8 +15,8 @@ use Cspray\AnnotatedContainer\Fixture\LogicalConstraints\DuplicateServiceType\FooService as DuplicateAttributeFooService; use Cspray\AnnotatedContainer\Fixture\LogicalConstraints\LogicalConstraintFixtures; use Cspray\AnnotatedContainer\Fixture\NonAnnotatedServices\NotAnnotatedObject; -use function Cspray\AnnotatedContainer\service; -use function Cspray\Typiphy\objectType; +use function Cspray\AnnotatedContainer\Definition\service; +use function Cspray\AnnotatedContainer\Reflection\types; final class DuplicateServiceTypeTest extends LogicalConstraintTestCase { @@ -79,10 +79,9 @@ public function testDuplicateServiceTypesWithOnlyMultipleFunctionCalls() : void Fixtures::nonAnnotatedServices()->getPath() )->withDefinitionProvider( new class implements DefinitionProvider { - public function consume(DefinitionProviderContext $context) : void { - $context->addServiceDefinition(service(objectType(NotAnnotatedObject::class))); - $context->addServiceDefinition(service(objectType(NotAnnotatedObject::class))); + $context->addServiceDefinition(service(types()->class(NotAnnotatedObject::class))); + $context->addServiceDefinition(service(types()->class(NotAnnotatedObject::class))); } } )->build() diff --git a/test/Unit/LogicalConstraint/Check/LogicalConstraintTestCase.php b/test/Unit/LogicalConstraint/Check/LogicalConstraintTestCase.php index 7a171c63..db400335 100644 --- a/test/Unit/LogicalConstraint/Check/LogicalConstraintTestCase.php +++ b/test/Unit/LogicalConstraint/Check/LogicalConstraintTestCase.php @@ -4,7 +4,6 @@ use Cspray\AnnotatedContainer\Event\Emitter; use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalyzer; -use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetDefinitionConverter; use Cspray\AnnotatedContainer\StaticAnalysis\ContainerDefinitionAnalyzer; use Cspray\AnnotatedTarget\PhpParserAnnotatedTargetParser; use PHPUnit\Framework\TestCase; @@ -14,7 +13,6 @@ abstract class LogicalConstraintTestCase extends TestCase { protected function getAnalyzer() : ContainerDefinitionAnalyzer { return new AnnotatedTargetContainerDefinitionAnalyzer( new PhpParserAnnotatedTargetParser(), - new AnnotatedTargetDefinitionConverter(), new Emitter() ); } diff --git a/test/Unit/LogicalConstraint/LogicalConstraintValidatorTest.php b/test/Unit/LogicalConstraint/LogicalConstraintValidatorTest.php index d2c3f860..055991d1 100644 --- a/test/Unit/LogicalConstraint/LogicalConstraintValidatorTest.php +++ b/test/Unit/LogicalConstraint/LogicalConstraintValidatorTest.php @@ -12,7 +12,6 @@ use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalyzer; use Cspray\AnnotatedContainer\StaticAnalysis\ContainerDefinitionAnalysisOptionsBuilder; use Cspray\AnnotatedContainer\StaticAnalysis\ContainerDefinitionAnalyzer; -use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetDefinitionConverter; use Cspray\AnnotatedContainer\Fixture\Fixtures; use Cspray\AnnotatedTarget\PhpParserAnnotatedTargetParser; use PHPUnit\Framework\TestCase; @@ -24,7 +23,6 @@ class LogicalConstraintValidatorTest extends TestCase { protected function setUp(): void { $this->analyzer = new AnnotatedTargetContainerDefinitionAnalyzer( new PhpParserAnnotatedTargetParser(), - new AnnotatedTargetDefinitionConverter(), new Emitter() ); } diff --git a/test/Unit/Reflection/TypeFactoryTest.php b/test/Unit/Reflection/TypeFactoryTest.php new file mode 100644 index 00000000..1ce5b1b0 --- /dev/null +++ b/test/Unit/Reflection/TypeFactoryTest.php @@ -0,0 +1,451 @@ + [static fn(TypeFactory $typeFactory) => $typeFactory->array(), 'array'], + 'bool' => [static fn(TypeFactory $typeFactory) => $typeFactory->bool(), 'bool'], + 'class' => [static fn(TypeFactory $typeFactory) => $typeFactory->class(Type::class), Type::class], + 'float' => [static fn(TypeFactory $typeFactory) => $typeFactory->float(), 'float'], + 'int' => [static fn(TypeFactory $typeFactory) => $typeFactory->int(), 'int'], + 'mixed' => [static fn(TypeFactory $typeFactory) => $typeFactory->mixed(), 'mixed'], + 'never' => [static fn(TypeFactory $typeFactory) => $typeFactory->never(), 'never'], + 'null' => [static fn(TypeFactory $typeFactory) => $typeFactory->null(), 'null'], + 'object' => [static fn(TypeFactory $typeFactory) => $typeFactory->object(), 'object'], + 'string' => [static fn(TypeFactory $typeFactory) => $typeFactory->string(), 'string'], + 'void' => [static fn(TypeFactory $typeFactory) => $typeFactory->void(), 'void'], + 'self' => [static fn(TypeFactory $typeFactory) => $typeFactory->self(), 'self'], + 'static' => [static fn(TypeFactory $typeFactory) => $typeFactory->static(), 'static'], + ]; + } + + #[DataProvider('typeProvider')] + /** + * @param Closure(TypeFactory):Type $typeCreator + * @param non-empty-string $expectedName + * @return void + */ + public function testTypeReturnsCorrectName( + Closure $typeCreator, + string $expectedName + ) : void { + $typeFactory = new TypeFactory(); + self::assertSame($expectedName, $typeCreator($typeFactory)->name()); + } + + #[DataProvider('typeProvider')] + /** + * @param Closure(TypeFactory):Type $typeCreator + * @return void + */ + public function testTypeFactoryReturnsSameObjectEachTimeForNonUnionOrIntersectTypes(Closure $typeCreator) : void { + $typeFactory = new TypeFactory(); + self::assertSame($typeCreator($typeFactory), $typeCreator($typeFactory)); + } + + public function testTypeFactoryUnionReturnsAppropriateTypes() : void { + $typeFactory = new TypeFactory(); + + $one = $typeFactory->string(); + $two = $typeFactory->float(); + + $union = $typeFactory->union($one, $two); + + self::assertSame([$one, $two], $union->types()); + } + + public function testTypeFactoryIntersectReturnsAppropriateTypes() : void { + $typeFactory = new TypeFactory(); + + $one = $typeFactory->class(Type::class); + $two = $typeFactory->class(TypeIntersect::class); + + $intersect = $typeFactory->intersect($one, $two); + + self::assertSame([$one, $two], $intersect->types()); + } + + public function testTypeFactoryUnionSupportsMoreThanTwoTypesIncludingTypeIntersect() : void { + $typeFactory = new TypeFactory(); + + $one = $typeFactory->int(); + $two = $typeFactory->string(); + $three = $typeFactory->intersect( + $typeFactory->class(Type::class), + $typeFactory->class(TestCase::class) + ); + $four = $typeFactory->float(); + + $union = $typeFactory->union( + $one, + $two, + $three, + $four + ); + + self::assertSame([$one, $two, $three, $four], $union->types()); + self::assertSame( + sprintf('int|string|(%s&%s)|float', Type::class, TestCase::class), + $union->name() + ); + } + + public function testTypeFactoryIntersectSupportsMoreThanTwoTypes() : void { + $typeFactory = new TypeFactory(); + + $one = $typeFactory->class(Type::class); + $two = $typeFactory->class(TypeUnion::class); + $three = $typeFactory->class(TypeIntersect::class); + $four = $typeFactory->class(TypeFactory::class); + + $intersect = $typeFactory->intersect($one, $two, $three, $four); + + self::assertSame([$one, $two, $three, $four], $intersect->types()); + } + + public function testTypeFactoryNullableCreatesCorrectUnion() : void { + $typeFactory = new TypeFactory(); + + $type = $typeFactory->nullable($typeFactory->int()); + + self::assertSame([$typeFactory->null(), $typeFactory->int()], $type->types()); + } + + public static function typeFromReflectionProvider(): array { + return [ + 'array' => ['array', static fn(TypeFactory $typeFactory) => $typeFactory->array()], + 'bool' => ['bool', static fn(TypeFactory $typeFactory) => $typeFactory->bool()], + 'float' => ['float', static fn(TypeFactory $typeFactory) => $typeFactory->float()], + 'int' => ['int', static fn(TypeFactory $typeFactory) => $typeFactory->int()], + 'explicit-mixed' => ['mixed', static fn(TypeFactory $typeFactory) => $typeFactory->mixed()], + 'implicit-mixed' => ['implicitMixed', static fn(TypeFactory $typeFactory) => $typeFactory->mixed()], + 'never' => ['never', static fn(TypeFactory $typeFactory) => $typeFactory->never()], + 'null' => ['null', static fn(TypeFactory $typeFactory) => $typeFactory->null()], + 'object' => ['object', static fn(TypeFactory $typeFactory) => $typeFactory->object()], + 'class' => ['class', static fn(TypeFactory $typeFactory) => $typeFactory->class(TypeFactory::class)], + 'self' => ['self', static fn(TypeFactory $typeFactory) => $typeFactory->self()], + 'static' => ['static', static fn(TypeFactory $typeFactory) => $typeFactory->static()], + ]; + } + + #[DataProvider('typeFromReflectionProvider')] + /** + * @param Closure(TypeFactory):Type $expectedTypeCreator + */ + public function testTypeFromReflectionType(string $method, Closure $expectedTypeCreator): void { + $reflection = new \ReflectionObject($this->reflectionTypeClass()); + $method = $reflection->getMethod($method); + $reflectionType = $method->getReturnType(); + + $typeFactory = new TypeFactory(); + $actual = $typeFactory->fromReflection($reflectionType); + + self::assertSame( + $actual, + $expectedTypeCreator($typeFactory), + ); + } + + public static function typeUnionFromReflectionProvider() : array { + return [ + 'nullable' => ['nullableInt', static fn(TypeFactory $typeFactory) => $typeFactory->union( + $typeFactory->null(), + $typeFactory->int() + ), 'null|int'], + 'numbers' => ['numbers', static fn(TypeFactory $typeFactory) => $typeFactory->union( + $typeFactory->int(), + $typeFactory->float() + ), 'int|float'], + 'manyTypesInUnion' => ['manyTypesInUnion', static fn(TypeFactory $typeFactory) => $typeFactory->union( + $typeFactory->int(), + $typeFactory->float(), + $typeFactory->bool(), + $typeFactory->string(), + ), 'string|int|float|bool'] + ]; + } + + #[DataProvider('typeUnionFromReflectionProvider')] + /** + * @param Closure(TypeFactory):TypeUnion $typeCreator + */ + public function testTypeUnionFromReflectionTypeHasCorrectTypes(string $method, Closure $typeCreator, string $expectedName): void { + $reflection = new \ReflectionObject($this->reflectionTypeClass()); + $method = $reflection->getMethod($method); + $reflectionType = $method->getReturnType(); + + $typeFactory = new TypeFactory(); + $actual = $typeFactory->fromReflection($reflectionType); + + $expectedTypes = $typeCreator($typeFactory)->types(); + $actualTypes = $actual->types(); + $sortByName = static fn(Type $a, Type $b) => $a->name() <=> $b->name(); + usort($expectedTypes, $sortByName); + usort($actualTypes, $sortByName); + + self::assertInstanceOf(TypeUnion::class, $actual); + self::assertSame($expectedTypes, $actualTypes); + self::assertSame($expectedName, $actual->name()); + } + + public static function typeIntersectFromReflectionProvider() : array { + return [ + 'simple-type-intersect' => ['intersect', static fn(TypeFactory $typeFactory) => $typeFactory->intersect( + $typeFactory->class(Type::class), + $typeFactory->class(TypeUnion::class) + ), sprintf('%s&%s', Type::class, TypeUnion::class)] + ]; + } + + #[DataProvider('typeIntersectFromReflectionProvider')] + /** + * @param Closure(TypeFactory):TypeIntersect $typeCreator + */ + public function testTypeIntersectFromReflectionType(string $method, Closure $typeCreator, string $expectedName): void { + $reflection = new \ReflectionObject($this->reflectionTypeClass()); + $method = $reflection->getMethod($method); + $reflectionType = $method->getReturnType(); + + $typeFactory = new TypeFactory(); + $actual = $typeFactory->fromReflection($reflectionType); + + $expectedTypes = $typeCreator($typeFactory)->types(); + $actualTypes = $actual->types(); + $sortByName = static fn(Type $a, Type $b) => $a->name() <=> $b->name(); + usort($expectedTypes, $sortByName); + usort($actualTypes, $sortByName); + + self::assertInstanceOf(TypeIntersect::class, $actual); + self::assertSame($expectedTypes, $actualTypes); + self::assertSame($expectedName, $actual->name()); + } + + public static function typeFromNameProvider() : array { + return [ + 'array' => ['array', static fn(TypeFactory $typeFactory) => $typeFactory->array()], + 'bool' => ['bool', static fn(TypeFactory $typeFactory) => $typeFactory->bool()], + 'float' => ['float', static fn(TypeFactory $typeFactory) => $typeFactory->float()], + 'int' => ['int', static fn(TypeFactory $typeFactory) => $typeFactory->int()], + 'mixed' => ['mixed', static fn(TypeFactory $typeFactory) => $typeFactory->mixed()], + 'never' => ['never', static fn(TypeFactory $typeFactory) => $typeFactory->never()], + 'null' => ['null', static fn(TypeFactory $typeFactory) => $typeFactory->null()], + 'object' => ['object', static fn(TypeFactory $typeFactory) => $typeFactory->object()], + 'self' => ['self', static fn(TypeFactory $typeFactory) => $typeFactory->self()], + 'static' => ['static', static fn(TypeFactory $typeFactory) => $typeFactory->static()], + 'string' => ['string', static fn(TypeFactory $typeFactory) => $typeFactory->string()], + 'void' => ['void', static fn(TypeFactory $typeFactory) => $typeFactory->void()], + 'class' => [TypeFactory::class, static fn(TypeFactory $typeFactory) => $typeFactory->class(TypeFactory::class)], + ]; + } + + #[DataProvider('typeFromNameProvider')] + /** + * @param string $typeName + * @param Closure $expectedTypeCreator + * @return void + */ + public function testTypeFromNameCreatesCorrectObject(string $typeName, Closure $expectedTypeCreator) : void { + $typeFactory = new TypeFactory(); + $actual = $typeFactory->fromName($typeName); + + self::assertSame($actual, $expectedTypeCreator($typeFactory)); + } + + public static function typeEqualityProvider() : array { + return [ + 'stringAndString' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->string(), + static fn(TypeFactory $typeFactory) => $typeFactory->string(), + true, + ], + 'stringAndInt' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->string(), + static fn(TypeFactory $typeFactory) => $typeFactory->int(), + false, + ], + 'intAndClass' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->int(), + static fn(TypeFactory $typeFactory) => $typeFactory->class(TypeFactory::class), + false, + ], + 'sameClass' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->class(TypeFactory::class), + static fn(TypeFactory $typeFactory) => $typeFactory->class(TypeFactory::class), + true, + ], + 'differentClasses' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->class(TypeFactory::class), + static fn(TypeFactory $typeFactory) => $typeFactory->class(Type::class), + false, + ], + 'typeAndTypeUnion' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->string(), + static fn(TypeFactory $typeFactory) => $typeFactory->nullable($typeFactory->string()), + false, + ], + 'typeAndTypeIntersect' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->class(Type::class), + static fn(TypeFactory $typeFactory) => $typeFactory->intersect( + $typeFactory->class(Type::class), + $typeFactory->class(TypeEqualityComparator::class), + ), + false + ], + 'nullableSameTypes' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->nullable($typeFactory->string()), + static fn(TypeFactory $typeFactory) => $typeFactory->nullable($typeFactory->string()), + true, + ], + 'typeUnionAndType' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->union($typeFactory->int(), $typeFactory->float()), + static fn(TypeFactory $typeFactory) => $typeFactory->float(), + false, + ], + 'typeUnionAndTypeIntersect' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->union($typeFactory->class(Type::class), $typeFactory->class(TypeUnion::class)), + static fn(TypeFactory $typeFactory) => $typeFactory->intersect($typeFactory->class(Type::class), $typeFactory->class(TypeUnion::class)), + false, + ], + 'typeUnionDifferentTypes' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->union($typeFactory->int(), $typeFactory->float()), + static fn(TypeFactory $typeFactory) => $typeFactory->union($typeFactory->string(), $typeFactory->int()), + false, + ], + 'typeUnionDifferentOrders' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->union($typeFactory->int(), $typeFactory->float()), + static fn(TypeFactory $typeFactory) => $typeFactory->union($typeFactory->float(), $typeFactory->int()), + true + ], + 'typeIntersectSameClasses' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->intersect($typeFactory->class(Type::class), $typeFactory->class(TypeIntersect::class)), + static fn(TypeFactory $typeFactory) => $typeFactory->intersect($typeFactory->class(Type::class), $typeFactory->class(TypeIntersect::class)), + true + ], + 'typeIntersectAndType' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->intersect($typeFactory->class(Type::class), $typeFactory->class(TypeEqualityComparator::class)), + static fn(TypeFactory $typeFactory) => $typeFactory->array(), + false, + ], + 'typeIntersectAndTypeUnion' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->intersect($typeFactory->class(Type::class), $typeFactory->class(TypeEqualityComparator::class)), + static fn(TypeFactory $typeFactory) => $typeFactory->union($typeFactory->string(), $typeFactory->float()), + false, + ], + 'typeIntersectDifferentClasses' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->intersect($typeFactory->class(Type::class), $typeFactory->class(TypeEqualityComparator::class)), + static fn(TypeFactory $typeFactory) => $typeFactory->intersect($typeFactory->class(Type::class), $typeFactory->class(TypeFactory::class)), + false, + ], + 'typeIntersectDifferentOrders' => [ + static fn(TypeFactory $typeFactory) => $typeFactory->intersect($typeFactory->class(Type::class), $typeFactory->class(TypeIntersect::class)), + static fn(TypeFactory $typeFactory) => $typeFactory->intersect($typeFactory->class(TypeIntersect::class), $typeFactory->class(Type::class)), + true + ] + ]; + } + + #[DataProvider('typeEqualityProvider')] + /** + * @param Closure():Type|TypeUnion|TypeIntersect $aType + * @param Closure():Type|TypeUnion|TypeIntersect $bType + * @param bool $expected + * @return void + */ + public function testTypeEqualityComparison( + Closure $aType, + Closure $bType, + bool $expected + ) : void { + $typeFactory = new TypeFactory(); + $a = $aType($typeFactory); + $b = $bType($typeFactory); + + self::assertSame($expected, $a->equals($b)); + } + + private function reflectionTypeClass(): object { + return new class { + public function array() : array { + return []; + } + + public function bool() : bool { + return true; + } + + public function float() : float { + return 3.14; + } + + public function int() : int { + return 0; + } + + public function mixed() : mixed { + return 'mixed'; + } + + public function implicitMixed() { + return $this->mixed(); + } + + public function never() : never { + throw new \RuntimeException(); + } + + public function null() : null { + return null; + } + + public function object() : object { + return new \stdClass(); + } + + public function self() : self { + return $this; + } + + public function static() : static { + return $this; + } + + public function string() : string { + return 'string'; + } + + public function void() : void { + } + + public function class() : TypeFactory { + return new TypeFactory(); + } + + public function nullableInt() : ?int { + return null; + } + + public function numbers() : int|float { + return 1; + } + + public function intersect() : Type&TypeUnion { + } + + public function manyTypesInUnion() : int|float|bool|string { + return false; + } + }; + } +} diff --git a/test/Unit/Serializer/XmlContainerDefinitionSerializerTest.php b/test/Unit/Serializer/XmlContainerDefinitionSerializerTest.php index 7434d12a..425a3fc5 100644 --- a/test/Unit/Serializer/XmlContainerDefinitionSerializerTest.php +++ b/test/Unit/Serializer/XmlContainerDefinitionSerializerTest.php @@ -7,21 +7,16 @@ use Cspray\AnnotatedContainer\Attribute\Service; use Cspray\AnnotatedContainer\Attribute\ServiceDelegate; use Cspray\AnnotatedContainer\Attribute\ServicePrepare; -use Cspray\AnnotatedContainer\Definition\AliasDefinitionBuilder; -use Cspray\AnnotatedContainer\Definition\ContainerDefinitionBuilder; -use Cspray\AnnotatedContainer\Definition\InjectDefinitionBuilder; +use Cspray\AnnotatedContainer\Definition\ContainerDefinition; use Cspray\AnnotatedContainer\Definition\Serializer\SerializedContainerDefinition; use Cspray\AnnotatedContainer\Definition\Serializer\XmlContainerDefinitionSerializer; -use Cspray\AnnotatedContainer\Definition\ServiceDefinitionBuilder; -use Cspray\AnnotatedContainer\Definition\ServiceDelegateDefinitionBuilder; -use Cspray\AnnotatedContainer\Definition\ServicePrepareDefinitionBuilder; use Cspray\AnnotatedContainer\Event\Emitter; use Cspray\AnnotatedContainer\Exception\InvalidSerializedContainerDefinition; use Cspray\AnnotatedContainer\Exception\InvalidInjectDefinition; use Cspray\AnnotatedContainer\Exception\MismatchedContainerDefinitionSerializerVersions; use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalyzer; -use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetDefinitionConverter; use Cspray\AnnotatedContainer\StaticAnalysis\ContainerDefinitionAnalysisOptionsBuilder; +use Cspray\AnnotatedContainer\Unit\Helper\HasMockDefinitions; use Cspray\AnnotatedContainer\Unit\Helper\UnserializableObject; use Cspray\AnnotatedContainer\Fixture\Fixture; use Cspray\AnnotatedContainer\Fixture\Fixtures; @@ -30,67 +25,41 @@ use Cspray\AssertThrows\ThrowableAssert; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; -use function Cspray\Typiphy\intType; -use function Cspray\Typiphy\objectType; -use function Cspray\Typiphy\stringType; +use function Cspray\AnnotatedContainer\Reflection\types; -class XmlContainerDefinitionSerializerTest extends TestCase { +final class XmlContainerDefinitionSerializerTest extends TestCase { - private const BASE_64_ENCODED_STRING = 'c3RyaW5n'; - private const BASE_64_ENCODED_INT = 'aW50'; - private const BASE_64_ENCODED_CARDINAL_DIRECTIONS = 'Q3NwcmF5XEFubm90YXRlZENvbnRhaW5lclxGaXh0dXJlXEluamVjdEVudW1Db25zdHJ1Y3RvclNlcnZpY2VzXENhcmRpbmFsRGlyZWN0aW9ucw=='; + use HasMockDefinitions; - public function testSerializingSingleConcreteService() : void { - $version = AnnotatedContainerVersion::version(); - $expected = << - - - - Cspray\AnnotatedContainer\Fixture\SingleConcreteService\FooImplementation - - - default - - Concrete - - - - - - - - - -XML; + private function version() : string { + return AnnotatedContainerVersion::version(); + } - $subject = new XmlContainerDefinitionSerializer(); + private function encodedAndSerialized(mixed $value) : string { + return $this->encoded(serialize($value)); + } - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forConcrete(Fixtures::singleConcreteService()->fooImplementation())->build() - )->build(); + private function encoded(mixed $value) : string { + return base64_encode($value); + } - $actual = $subject->serialize($containerDefinition); + private function assertSerializedContainerDefinitionEquals(string $expected, ContainerDefinition $containerDefinition) : void { + $actual = (new XmlContainerDefinitionSerializer())->serialize($containerDefinition); self::assertSame($expected, $actual->asString()); } - public function testSerializingSingleConcreteServiceWithAttribute() : void { - $attributeVal = base64_encode(serialize($attr = new Service())); - $version = AnnotatedContainerVersion::version(); + public function testSerializingSingleConcreteService() : void { + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [$serviceDefinition = $this->concreteServiceDefinition(Fixtures::singleConcreteService()->fooImplementation())], + ); $expected = << - + - - Cspray\AnnotatedContainer\Fixture\SingleConcreteService\FooImplementation - - - default - - Concrete - {$attributeVal} + + {$serviceDefinition->type()->name()} + {$this->encodedAndSerialized($serviceDefinition->attribute())} @@ -101,35 +70,23 @@ public function testSerializingSingleConcreteServiceWithAttribute() : void { XML; - $subject = new XmlContainerDefinitionSerializer(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forConcrete(Fixtures::singleConcreteService()->fooImplementation()) - ->withAttribute($attr) - ->build() - )->build(); - - $actual = $subject->serialize($containerDefinition); - - self::assertSame($expected, $actual->asString()); + $this->assertSerializedContainerDefinitionEquals($expected, $containerDefinition); } public function testSerializingServiceWithExplicitProfiles() : void { - $version = AnnotatedContainerVersion::version(); + $containerDefinition = $this->containerDefinition( + [$serviceDefinition = $this->concreteServiceDefinition( + Fixtures::singleConcreteService()->fooImplementation(), + profiles: ['my-profile', 'my-other-profile'] + )] + ); $expected = << - + - + Cspray\AnnotatedContainer\Fixture\SingleConcreteService\FooImplementation - - - my-profile - my-other-profile - - Concrete - + {$this->encodedAndSerialized($serviceDefinition->attribute())} @@ -140,43 +97,30 @@ public function testSerializingServiceWithExplicitProfiles() : void { XML; - $subject = new XmlContainerDefinitionSerializer(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forConcrete(Fixtures::singleConcreteService()->fooImplementation()) - ->withProfiles(['my-profile', 'my-other-profile']) - ->build() - )->build(); - - $actual = $subject->serialize($containerDefinition); - - self::assertSame($expected, $actual->asString()); + $this->assertSerializedContainerDefinitionEquals($expected, $containerDefinition); } public function testSerializingServicesWithAliases() : void { - $version = AnnotatedContainerVersion::version(); + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $abstractDefinition = $this->abstractServiceDefinition(Fixtures::implicitAliasedServices()->fooInterface()), + $concreteDefinition = $this->concreteServiceDefinition(Fixtures::implicitAliasedServices()->fooImplementation()), + ], + aliasDefinitions: [ + $this->aliasDefinition(Fixtures::implicitAliasedServices()->fooInterface(), Fixtures::implicitAliasedServices()->fooImplementation()) + ] + ); $expected = << - + - + Cspray\AnnotatedContainer\Fixture\ImplicitAliasedServices\FooInterface - - - default - - Abstract - + {$this->encodedAndSerialized($abstractDefinition->attribute())} - + Cspray\AnnotatedContainer\Fixture\ImplicitAliasedServices\FooImplementation - - - default - - Concrete - + {$this->encodedAndSerialized($concreteDefinition->attribute())} @@ -192,38 +136,23 @@ public function testSerializingServicesWithAliases() : void { XML; - $subject = new XmlContainerDefinitionSerializer(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forAbstract(Fixtures::implicitAliasedServices()->fooInterface())->build() - )->withServiceDefinition( - ServiceDefinitionBuilder::forConcrete(Fixtures::implicitAliasedServices()->fooImplementation())->build() - )->withAliasDefinition( - AliasDefinitionBuilder::forAbstract(Fixtures::implicitAliasedServices()->fooInterface()) - ->withConcrete(Fixtures::implicitAliasedServices()->fooImplementation()) - ->build() - )->build(); - - $actual = $subject->serialize($containerDefinition); - - self::assertSame($expected, $actual->asString()); + $this->assertSerializedContainerDefinitionEquals($expected, $containerDefinition); } public function testSerializingServiceIsPrimary() : void { - $version = AnnotatedContainerVersion::version(); + $containerDefinition = $this->containerDefinition( + [$serviceDefinition = $this->concreteServiceDefinition( + Fixtures::singleConcreteService()->fooImplementation(), + isPrimary: true + )] + ); $expected = << - + - + Cspray\AnnotatedContainer\Fixture\SingleConcreteService\FooImplementation - - - default - - Concrete - + {$this->encodedAndSerialized($serviceDefinition->attribute())} @@ -234,32 +163,20 @@ public function testSerializingServiceIsPrimary() : void { XML; - $subject = new XmlContainerDefinitionSerializer(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forConcrete(Fixtures::singleConcreteService()->fooImplementation(), true)->build() - )->build(); - - $actual = $subject->serialize($containerDefinition); - - self::assertSame($expected, $actual->asString()); + $this->assertSerializedContainerDefinitionEquals($expected, $containerDefinition); } public function testSerializingServiceWithName() : void { - $version = AnnotatedContainerVersion::version(); + $containerDefinition = $this->containerDefinition( + [$serviceDefinition = $this->concreteServiceDefinition(Fixtures::singleConcreteService()->fooImplementation(), name: 'my-name')] + ); $expected = << - + - + Cspray\AnnotatedContainer\Fixture\SingleConcreteService\FooImplementation - my-name - - default - - Concrete - + {$this->encodedAndSerialized($serviceDefinition->attribute())} @@ -270,83 +187,23 @@ public function testSerializingServiceWithName() : void { XML; - $subject = new XmlContainerDefinitionSerializer(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forConcrete(Fixtures::singleConcreteService()->fooImplementation()) - ->withName('my-name') - ->build() - )->build(); - - $actual = $subject->serialize($containerDefinition); - - self::assertSame($expected, $actual->asString()); + $this->assertSerializedContainerDefinitionEquals($expected, $containerDefinition); } public function testSerializingServicePrepareDefinition() : void { - $version = AnnotatedContainerVersion::version(); - $expected = << - - - - Cspray\AnnotatedContainer\Fixture\InterfacePrepareServices\FooInterface - - - default - - Abstract - - - - - - - Cspray\AnnotatedContainer\Fixture\InterfacePrepareServices\FooInterface - setBar - - - - - - - -XML; - - $subject = new XmlContainerDefinitionSerializer(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forAbstract(Fixtures::interfacePrepareServices()->fooInterface()) - ->build() - )->withServicePrepareDefinition( - ServicePrepareDefinitionBuilder::forMethod( - Fixtures::interfacePrepareServices()->fooInterface(), - 'setBar' - )->build() - )->build(); - - $actual = $subject->serialize($containerDefinition); - - self::assertSame($expected, $actual->asString()); - } - - public function testSerializingServicePrepareDefinitionWithAttribute() : void { - $attrVal = base64_encode(serialize(new ServicePrepare())); - $version = AnnotatedContainerVersion::version(); + $containerDefinition = $this->containerDefinition( + [$serviceDefinition = $this->abstractServiceDefinition(Fixtures::interfacePrepareServices()->fooInterface())], + servicePrepareDefinitions: [ + $servicePrepareDefinition = $this->servicePrepareDefinition(Fixtures::interfacePrepareServices()->fooInterface(), 'setBar') + ] + ); $expected = << - + - + Cspray\AnnotatedContainer\Fixture\InterfacePrepareServices\FooInterface - - - default - - Abstract - + {$this->encodedAndSerialized($serviceDefinition->attribute())} @@ -354,7 +211,7 @@ public function testSerializingServicePrepareDefinitionWithAttribute() : void { Cspray\AnnotatedContainer\Fixture\InterfacePrepareServices\FooInterface setBar - {$attrVal} + {$this->encodedAndSerialized($servicePrepareDefinition->attribute())} @@ -363,38 +220,29 @@ public function testSerializingServicePrepareDefinitionWithAttribute() : void { XML; - $subject = new XmlContainerDefinitionSerializer(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forAbstract(Fixtures::interfacePrepareServices()->fooInterface()) - ->build() - )->withServicePrepareDefinition( - ServicePrepareDefinitionBuilder::forMethod( - Fixtures::interfacePrepareServices()->fooInterface(), - 'setBar' - )->withAttribute(new ServicePrepare())->build() - )->build(); - - $actual = $subject->serialize($containerDefinition); - - self::assertSame($expected, $actual->asString()); + $this->assertSerializedContainerDefinitionEquals($expected, $containerDefinition); } public function testSerializingServiceDelegateDefinition() : void { - $version = AnnotatedContainerVersion::version(); + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $serviceDefinition = $this->abstractServiceDefinition(Fixtures::delegatedService()->serviceInterface()) + ], + serviceDelegateDefinitions: [ + $delegateDefinition = $this->serviceDelegateDefinition( + Fixtures::delegatedService()->serviceInterface(), + Fixtures::delegatedService()->serviceFactory(), + 'createService' + ) + ] + ); $expected = << - + - + Cspray\AnnotatedContainer\Fixture\DelegatedService\ServiceInterface - - - default - - Abstract - + {$this->encodedAndSerialized($serviceDefinition->attribute())} @@ -404,7 +252,7 @@ public function testSerializingServiceDelegateDefinition() : void { Cspray\AnnotatedContainer\Fixture\DelegatedService\ServiceInterface Cspray\AnnotatedContainer\Fixture\DelegatedService\ServiceFactory createService - + {$this->encodedAndSerialized($delegateDefinition->attribute())} @@ -412,88 +260,31 @@ public function testSerializingServiceDelegateDefinition() : void { XML; - $subject = new XmlContainerDefinitionSerializer(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forAbstract(Fixtures::delegatedService()->serviceInterface())->build() - )->withServiceDelegateDefinition( - ServiceDelegateDefinitionBuilder::forService(Fixtures::delegatedService()->serviceInterface()) - ->withDelegateMethod(Fixtures::delegatedService()->serviceFactory(), 'createService') - ->build() - )->build(); - - $actual = $subject->serialize($containerDefinition); - - self::assertSame($expected, $actual->asString()); - } - - public function testSerializingServiceDelegateDefinitionWithAttribute() : void { - $attrVal = base64_encode(serialize(new ServiceDelegate())); - $version = AnnotatedContainerVersion::version(); - $expected = << - - - - Cspray\AnnotatedContainer\Fixture\DelegatedService\ServiceInterface - - - default - - Abstract - - - - - - - - Cspray\AnnotatedContainer\Fixture\DelegatedService\ServiceInterface - Cspray\AnnotatedContainer\Fixture\DelegatedService\ServiceFactory - createService - {$attrVal} - - - - - -XML; - - $subject = new XmlContainerDefinitionSerializer(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forAbstract(Fixtures::delegatedService()->serviceInterface())->build() - )->withServiceDelegateDefinition( - ServiceDelegateDefinitionBuilder::forService(Fixtures::delegatedService()->serviceInterface()) - ->withDelegateMethod(Fixtures::delegatedService()->serviceFactory(), 'createService') - ->withAttribute(new ServiceDelegate()) - ->build() - )->build(); - - $actual = $subject->serialize($containerDefinition); - - self::assertSame($expected, $actual->asString()); + $this->assertSerializedContainerDefinitionEquals($expected, $containerDefinition); } public function testSerializingInjectMethodParameterStringValue() : void { - $attrVal = base64_encode(serialize(new Inject('foobar'))); - $version = AnnotatedContainerVersion::version(); - $encodedVal = base64_encode(serialize('foobar')); - $type = self::BASE_64_ENCODED_STRING; + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $serviceDefinition = $this->concreteServiceDefinition(Fixtures::injectConstructorServices()->injectStringService()) + ], + injectDefinitions: [ + $injectDefinition = $this->injectDefinition( + Fixtures::injectConstructorServices()->injectStringService(), + '__construct', + 'val', + types()->string(), + 'my string value', + ) + ] + ); $expected = << - + - + Cspray\AnnotatedContainer\Fixture\InjectConstructorServices\StringInjectService - - - default - - Concrete - + {$this->encodedAndSerialized($serviceDefinition->attribute())} @@ -504,53 +295,41 @@ public function testSerializingInjectMethodParameterStringValue() : void { Cspray\AnnotatedContainer\Fixture\InjectConstructorServices\StringInjectService __construct val - {$type} - - - default - - - {$attrVal} + + string + + {$this->encodedAndSerialized($injectDefinition->attribute())} XML; - $subject = new XmlContainerDefinitionSerializer(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forConcrete(Fixtures::injectConstructorServices()->injectStringService())->build() - )->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectConstructorServices()->injectStringService()) - ->withMethod('__construct', stringType(), 'val') - ->withValue('foobar') - ->withAttribute(new Inject('foobar')) - ->build() - )->build(); - - $actual = $subject->serialize($containerDefinition); - - self::assertSame($expected, $actual->asString()); + $this->assertSerializedContainerDefinitionEquals($expected, $containerDefinition); } public function testSerializingInjectMethodParameterIntValue() : void { - $version = AnnotatedContainerVersion::version(); - $encodedVal = base64_encode(serialize(42)); - $type = self::BASE_64_ENCODED_INT; + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $injectIntService = $this->concreteServiceDefinition(Fixtures::injectConstructorServices()->injectIntService()), + ], + injectDefinitions: [ + $injectDefinition = $this->injectDefinition( + $injectIntService->type(), + '__construct', + 'meaningOfLife', + types()->int(), + 42 + ) + ] + ); $expected = << - + - + Cspray\AnnotatedContainer\Fixture\InjectConstructorServices\IntInjectService - - - default - - Concrete - + {$this->encodedAndSerialized($injectIntService->attribute())} @@ -561,52 +340,41 @@ public function testSerializingInjectMethodParameterIntValue() : void { Cspray\AnnotatedContainer\Fixture\InjectConstructorServices\IntInjectService __construct meaningOfLife - {$type} - - - default - - - + + int + + {$this->encodedAndSerialized($injectDefinition->attribute())} XML; - $subject = new XmlContainerDefinitionSerializer(); - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forConcrete(Fixtures::injectConstructorServices()->injectIntService())->build() - )->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectConstructorServices()->injectIntService()) - ->withMethod('__construct', intType(), 'meaningOfLife') - ->withValue(42) - ->build() - )->build(); - - $actual = $subject->serialize($containerDefinition); - - self::assertSame($expected, $actual->asString()); + $this->assertSerializedContainerDefinitionEquals($expected, $containerDefinition); } public function testSerializingInjectMethodParameterUnitEnumValue() : void { - $version = AnnotatedContainerVersion::version(); - $encodedVal = base64_encode(serialize(CardinalDirections::West)); - $type = self::BASE_64_ENCODED_CARDINAL_DIRECTIONS; + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $serviceDefinition = $this->concreteServiceDefinition(Fixtures::injectEnumConstructorServices()->enumInjector()) + ], + injectDefinitions: [ + $injectDefinition = $this->injectDefinition( + $serviceDefinition->type(), + '__construct', + 'directions', + types()->class(CardinalDirections::class), + CardinalDirections::West + ) + ], + ); $expected = << - + - + Cspray\AnnotatedContainer\Fixture\InjectEnumConstructorServices\EnumInjector - - - default - - Concrete - + {$this->encodedAndSerialized($serviceDefinition->attribute())} @@ -617,51 +385,42 @@ public function testSerializingInjectMethodParameterUnitEnumValue() : void { Cspray\AnnotatedContainer\Fixture\InjectEnumConstructorServices\EnumInjector __construct directions - {$type} - - - default - - - + + Cspray\AnnotatedContainer\Fixture\InjectEnumConstructorServices\CardinalDirections + + {$this->encodedAndSerialized($injectDefinition->attribute())} XML; - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forConcrete(Fixtures::injectEnumConstructorServices()->enumInjector())->build() - )->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectEnumConstructorServices()->enumInjector()) - ->withMethod('__construct', objectType(CardinalDirections::class), 'directions') - ->withValue(CardinalDirections::West) - ->build() - )->build(); - - $subject = new XmlContainerDefinitionSerializer(); - $actual = $subject->serialize($containerDefinition); - - self::assertSame($expected, $actual->asString()); + $this->assertSerializedContainerDefinitionEquals($expected, $containerDefinition); } public function testSerializingInjectMethodParameterWithStore() : void { - $version = AnnotatedContainerVersion::version(); - $encodedVal = base64_encode(serialize('key')); - $type = self::BASE_64_ENCODED_STRING; + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $serviceDefinition = $this->concreteServiceDefinition(Fixtures::injectCustomStoreServices()->scalarInjector()) + ], + injectDefinitions: [ + $injectDefinition = $this->injectDefinition( + $serviceDefinition->type(), + '__construct', + 'key', + types()->string(), + 'key', + store: 'test-store', + ), + ], + ); $expected = << - + - + Cspray\AnnotatedContainer\Fixture\InjectCustomStoreServices\ScalarInjector - - - default - - Concrete - + {$this->encodedAndSerialized($serviceDefinition->attribute())} @@ -672,53 +431,42 @@ public function testSerializingInjectMethodParameterWithStore() : void { Cspray\AnnotatedContainer\Fixture\InjectCustomStoreServices\ScalarInjector __construct key - {$type} - - - default - - test-store - + + string + + {$this->encodedAndSerialized($injectDefinition->attribute())} XML; - - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forConcrete(Fixtures::injectCustomStoreServices()->scalarInjector())->build() - )->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectCustomStoreServices()->scalarInjector()) - ->withMethod('__construct', stringType(), 'key') - ->withStore('test-store') - ->withValue('key') - ->build() - )->build(); - - $subject = new XmlContainerDefinitionSerializer(); - $actual = $subject->serialize($containerDefinition); - - self::assertSame($expected, $actual->asString()); + $this->assertSerializedContainerDefinitionEquals($expected, $containerDefinition); } public function testSerializingInjectMethodParameterExplicitProfiles() : void { - $version = AnnotatedContainerVersion::version(); - $encodedVal = base64_encode(serialize('foobar')); - $type = self::BASE_64_ENCODED_STRING; + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $serviceDefinition = $this->concreteServiceDefinition(Fixtures::injectConstructorServices()->injectStringService()) + ], + injectDefinitions: [ + $injectDefinition = $this->injectDefinition( + $serviceDefinition->type(), + '__construct', + 'val', + types()->string(), + 'foobar', + ['foo', 'baz'] + ), + ], + ); $expected = << - + - + Cspray\AnnotatedContainer\Fixture\InjectConstructorServices\StringInjectService - - - default - - Concrete - + {$this->encodedAndSerialized($serviceDefinition->attribute())} @@ -729,48 +477,198 @@ public function testSerializingInjectMethodParameterExplicitProfiles() : void { Cspray\AnnotatedContainer\Fixture\InjectConstructorServices\StringInjectService __construct val - {$type} - - - foo - baz - - - + + string + + {$this->encodedAndSerialized($injectDefinition->attribute())} XML; - $subject = new XmlContainerDefinitionSerializer(); + $this->assertSerializedContainerDefinitionEquals($expected, $containerDefinition); + } - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forConcrete(Fixtures::injectConstructorServices()->injectStringService())->build() - )->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectConstructorServices()->injectStringService()) - ->withMethod('__construct', stringType(), 'val') - ->withValue('foobar') - ->withProfiles('foo', 'baz') - ->build() - )->build(); + public function testSerializeInjectWithTypeUnion() : void { + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $serviceDefinition = $this->concreteServiceDefinition(Fixtures::injectUnionCustomStoreServices()->unionInjector()) + ], + injectDefinitions: [ + $injectDefinition = $this->injectDefinition( + $serviceDefinition->type(), + '__construct', + 'fooOrBar', + types()->union( + Fixtures::injectUnionCustomStoreServices()->fooInterface(), + Fixtures::injectUnionCustomStoreServices()->barInterface() + ), + 'foo', + store: 'union-store' + ) + ] + ); + $expected = << + + + + Cspray\AnnotatedContainer\Fixture\InjectUnionCustomStoreServices\UnionInjector + {$this->encodedAndSerialized($serviceDefinition->attribute())} + + + + + + + + Cspray\AnnotatedContainer\Fixture\InjectUnionCustomStoreServices\UnionInjector + __construct + fooOrBar + + + Cspray\AnnotatedContainer\Fixture\InjectUnionCustomStoreServices\FooInterface + Cspray\AnnotatedContainer\Fixture\InjectUnionCustomStoreServices\BarInterface + + + {$this->encodedAndSerialized($injectDefinition->attribute())} + + + - $actual = $subject->serialize($containerDefinition); +XML; - self::assertSame($expected, $actual->asString()); + $this->assertSerializedContainerDefinitionEquals($expected, $containerDefinition); + } + + public function testSerializeInjectWithTypeIntersect() : void { + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $serviceDefinition = $this->concreteServiceDefinition(Fixtures::injectIntersectCustomStoreServices()->intersectInjector()) + ], + injectDefinitions: [ + $injectDefinition = $this->injectDefinition( + $serviceDefinition->type(), + '__construct', + 'fooAndBar', + types()->intersect( + Fixtures::injectIntersectCustomStoreServices()->fooInterface(), + Fixtures::injectIntersectCustomStoreServices()->barInterface() + ), + 'foobar', + store: 'intersect-store' + ) + ] + ); + $expected = << + + + + Cspray\AnnotatedContainer\Fixture\InjectIntersectCustomStoreServices\IntersectInjector + {$this->encodedAndSerialized($serviceDefinition->attribute())} + + + + + + + + Cspray\AnnotatedContainer\Fixture\InjectIntersectCustomStoreServices\IntersectInjector + __construct + fooAndBar + + + Cspray\AnnotatedContainer\Fixture\InjectIntersectCustomStoreServices\FooInterface + Cspray\AnnotatedContainer\Fixture\InjectIntersectCustomStoreServices\BarInterface + + + {$this->encodedAndSerialized($injectDefinition->attribute())} + + + + +XML; + + $this->assertSerializedContainerDefinitionEquals($expected, $containerDefinition); + } + + public function testSerializeInjectWithTypeUnionAndTypeIntersect() : void { + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $serviceDefinition = $this->concreteServiceDefinition(Fixtures::injectUnionCustomStoreServices()->unionInjector()) + ], + injectDefinitions: [ + $injectDefinition = $this->injectDefinition( + $serviceDefinition->type(), + '__construct', + 'fooOrBar', + types()->union( + Fixtures::injectUnionCustomStoreServices()->fooInterface(), + Fixtures::injectUnionCustomStoreServices()->barInterface(), + types()->intersect( + Fixtures::injectIntersectCustomStoreServices()->barInterface(), + Fixtures::injectIntersectCustomStoreServices()->fooInterface(), + ), + ), + 'foo', + store: 'union-store' + ) + ] + ); + $expected = << + + + + Cspray\AnnotatedContainer\Fixture\InjectUnionCustomStoreServices\UnionInjector + {$this->encodedAndSerialized($serviceDefinition->attribute())} + + + + + + + + Cspray\AnnotatedContainer\Fixture\InjectUnionCustomStoreServices\UnionInjector + __construct + fooOrBar + + + Cspray\AnnotatedContainer\Fixture\InjectUnionCustomStoreServices\FooInterface + Cspray\AnnotatedContainer\Fixture\InjectUnionCustomStoreServices\BarInterface + + Cspray\AnnotatedContainer\Fixture\InjectIntersectCustomStoreServices\BarInterface + Cspray\AnnotatedContainer\Fixture\InjectIntersectCustomStoreServices\FooInterface + + + + {$this->encodedAndSerialized($injectDefinition->attribute())} + + + + +XML; + + $this->assertSerializedContainerDefinitionEquals($expected, $containerDefinition); } public function testSerializingInjectDefinitionWithUnserializableValueThrowsException() : void { - $containerDefinition = ContainerDefinitionBuilder::newDefinition() - ->withServiceDefinition( - ServiceDefinitionBuilder::forConcrete(Fixtures::injectEnumConstructorServices()->enumInjector())->build() - )->withInjectDefinition( - InjectDefinitionBuilder::forService(Fixtures::injectEnumConstructorServices()->enumInjector()) - ->withMethod('__construct', objectType(UnserializableObject::class), 'directions') - ->withValue(new UnserializableObject()) - ->build() - )->build(); + $containerDefinition = $this->containerDefinition( + serviceDefinitions: [ + $this->concreteServiceDefinition(Fixtures::injectEnumConstructorServices()->enumInjector()) + ], + injectDefinitions: [ + $this->injectDefinition( + Fixtures::injectEnumConstructorServices()->enumInjector(), + '__construct', + 'directions', + types()->class(UnserializableObject::class), + new UnserializableObject() + ), + ], + ); $subject = new XmlContainerDefinitionSerializer(); @@ -781,19 +679,13 @@ public function testSerializingInjectDefinitionWithUnserializableValueThrowsExce } public function testDeserializingConcreteServiceDefinition() : void { - $version = AnnotatedContainerVersion::version(); $xml = << - + - + Cspray\AnnotatedContainer\Fixture\SingleConcreteService\FooImplementation - - - default - - Concrete - + {$this->encodedAndSerialized($attribute = new Service())} @@ -814,6 +706,7 @@ public function testDeserializingConcreteServiceDefinition() : void { $serviceDefinition = $serviceDefinitions[0]; self::assertSame(Fixtures::singleConcreteService()->fooImplementation(), $serviceDefinition->type()); + self::assertEquals($attribute, $serviceDefinition->attribute()); self::assertSame(['default'], $serviceDefinition->profiles()); self::assertNull($serviceDefinition->name()); self::assertFalse($serviceDefinition->isPrimary()); @@ -822,19 +715,13 @@ public function testDeserializingConcreteServiceDefinition() : void { } public function testDeserializingNamedConcreteServiceDefinition() : void { - $version = AnnotatedContainerVersion::version(); $xml = << - + - + Cspray\AnnotatedContainer\Fixture\SingleConcreteService\FooImplementation - my_service_name - - default - - Concrete - + {$this->encodedAndSerialized($attribute = new Service(name: 'my_service_name'))} @@ -855,6 +742,7 @@ public function testDeserializingNamedConcreteServiceDefinition() : void { $serviceDefinition = $serviceDefinitions[0]; self::assertSame(Fixtures::singleConcreteService()->fooImplementation(), $serviceDefinition->type()); + self::assertEquals($attribute, $serviceDefinition->attribute()); self::assertSame(['default'], $serviceDefinition->profiles()); self::assertSame('my_service_name', $serviceDefinition->name()); self::assertFalse($serviceDefinition->isPrimary()); @@ -868,14 +756,9 @@ public function testDeserializingPrimaryConcreteServiceDefinition() : void { - + Cspray\AnnotatedContainer\Fixture\SingleConcreteService\FooImplementation - - - default - - Concrete - + {$this->encodedAndSerialized(new Service(primary: true))} @@ -909,16 +792,9 @@ public function testDeserializingServiceDefinitionWithProfiles() : void { - + Cspray\AnnotatedContainer\Fixture\SingleConcreteService\FooImplementation - - - foo - bar - baz - - Concrete - + {$this->encodedAndSerialized($attribute = new Service(profiles: ['foo', 'bar', 'baz']))} @@ -939,6 +815,7 @@ public function testDeserializingServiceDefinitionWithProfiles() : void { $serviceDefinition = $serviceDefinitions[0]; self::assertSame(Fixtures::singleConcreteService()->fooImplementation(), $serviceDefinition->type()); + self::assertEquals($attribute, $serviceDefinition->attribute()); self::assertSame(['foo', 'bar', 'baz'], $serviceDefinition->profiles()); self::assertNull($serviceDefinition->name()); self::assertFalse($serviceDefinition->isPrimary()); @@ -952,14 +829,9 @@ public function testDeserializeAbstractServiceDefinition() : void { - + Cspray\AnnotatedContainer\Fixture\ImplicitAliasedServices\FooInterface - - - default - - Abstract - + {$this->encodedAndSerialized($attribute = new Service())} @@ -979,6 +851,7 @@ public function testDeserializeAbstractServiceDefinition() : void { $serviceDefinition = $serviceDefinitions[0]; self::assertSame(Fixtures::implicitAliasedServices()->fooInterface(), $serviceDefinition->type()); + self::assertEquals($attribute, $serviceDefinition->attribute()); self::assertSame(['default'], $serviceDefinition->profiles()); self::assertNull($serviceDefinition->name()); self::assertFalse($serviceDefinition->isPrimary()); @@ -992,23 +865,13 @@ public function testDeserializeAliasDefinitions() : void { - + Cspray\AnnotatedContainer\Fixture\ImplicitAliasedServices\FooInterface - - - default - - Abstract - + {$this->encodedAndSerialized(new Service())} - + Cspray\AnnotatedContainer\Fixture\ImplicitAliasedServices\FooImplementation - - - default - - Concrete - + {$this->encodedAndSerialized(new Service())} @@ -1039,14 +902,9 @@ public function testDeserializeServicePrepareDefinitions() : void { - + Cspray\AnnotatedContainer\Fixture\InterfacePrepareServices\FooInterface - - - default - - Abstract - + {$this->encodedAndSerialized(new Service())} @@ -1054,7 +912,7 @@ public function testDeserializeServicePrepareDefinitions() : void { Cspray\AnnotatedContainer\Fixture\InterfacePrepareServices\FooInterface setBar - + {$this->encodedAndSerialized($attribute = new ServicePrepare())} @@ -1070,6 +928,7 @@ public function testDeserializeServicePrepareDefinitions() : void { $prepareDefinition = $actual->servicePrepareDefinitions()[0]; self::assertSame(Fixtures::interfacePrepareServices()->fooInterface(), $prepareDefinition->service()); self::assertSame('setBar', $prepareDefinition->methodName()); + self::assertEquals($attribute, $prepareDefinition->attribute()); } public function testDeserializeServiceDelegateDefinitions() : void { @@ -1078,14 +937,9 @@ public function testDeserializeServiceDelegateDefinitions() : void { - + Cspray\AnnotatedContainer\Fixture\DelegatedService\ServiceInterface - - - default - - Abstract - + {$this->encodedAndSerialized(new Service())} @@ -1095,7 +949,7 @@ public function testDeserializeServiceDelegateDefinitions() : void { Cspray\AnnotatedContainer\Fixture\DelegatedService\ServiceInterface Cspray\AnnotatedContainer\Fixture\DelegatedService\ServiceFactory createService - + {$this->encodedAndSerialized($attribute = new ServiceDelegate())} @@ -1112,24 +966,17 @@ public function testDeserializeServiceDelegateDefinitions() : void { self::assertSame(Fixtures::delegatedService()->serviceInterface(), $delegateDefinition->serviceType()); self::assertSame(Fixtures::delegatedService()->serviceFactory(), $delegateDefinition->delegateType()); self::assertSame('createService', $delegateDefinition->delegateMethod()); + self::assertEquals($attribute, $delegateDefinition->attribute()); } public function testDeserializeInjectMethodParameter() : void { - $type = self::BASE_64_ENCODED_STRING; - $version = AnnotatedContainerVersion::version(); - $encodedVal = base64_encode(serialize('foobar')); $xml = << - + - + Cspray\AnnotatedContainer\Fixture\InjectConstructorServices\StringInjectService - - - default - - Concrete - + {$this->encodedAndSerialized(new Service())} @@ -1140,13 +987,10 @@ public function testDeserializeInjectMethodParameter() : void { Cspray\AnnotatedContainer\Fixture\InjectConstructorServices\StringInjectService __construct val - {$type} - - - default - - - + + string + + {$this->encodedAndSerialized($attribute = new Inject('foobar'))} @@ -1164,30 +1008,23 @@ public function testDeserializeInjectMethodParameter() : void { Fixtures::injectConstructorServices()->injectStringService(), $injectDefinition->class() ); + self::assertEquals($attribute, $injectDefinition->attribute()); self::assertSame('__construct', $injectDefinition->methodName()); self::assertSame('val', $injectDefinition->parameterName()); - self::assertSame(stringType(), $injectDefinition->type()); + self::assertSame(types()->string(), $injectDefinition->type()); self::assertSame('foobar', $injectDefinition->value()); self::assertSame(['default'], $injectDefinition->profiles()); self::assertNull($injectDefinition->storeName()); } public function testDeserializeInjectDefinitionUnitEnumValueMethodParameter() : void { - $version = AnnotatedContainerVersion::version(); - $encodedVal = base64_encode(serialize(CardinalDirections::West)); - $type = self::BASE_64_ENCODED_CARDINAL_DIRECTIONS; $xml = << - + - + Cspray\AnnotatedContainer\Fixture\InjectEnumConstructorServices\EnumInjector - - - default - - Concrete - + {$this->encodedAndSerialized(new Service())} @@ -1198,13 +1035,10 @@ public function testDeserializeInjectDefinitionUnitEnumValueMethodParameter() : Cspray\AnnotatedContainer\Fixture\InjectEnumConstructorServices\EnumInjector __construct directions - {$type} - - - default - - - + + Cspray\AnnotatedContainer\Fixture\InjectEnumConstructorServices\CardinalDirections + + {$this->encodedAndSerialized($attribute = new Inject(CardinalDirections::West))} @@ -1223,29 +1057,22 @@ public function testDeserializeInjectDefinitionUnitEnumValueMethodParameter() : $injectDefinition->class() ); self::assertSame('__construct', $injectDefinition->methodName()); + self::assertEquals($attribute, $injectDefinition->attribute()); self::assertSame('directions', $injectDefinition->parameterName()); - self::assertSame(objectType(CardinalDirections::class), $injectDefinition->type()); + self::assertSame(types()->class(CardinalDirections::class), $injectDefinition->type()); self::assertSame(CardinalDirections::West, $injectDefinition->value()); self::assertSame(['default'], $injectDefinition->profiles()); self::assertNull($injectDefinition->storeName()); } public function testDeserializeInjectDefinitionMethodParameterWithStore() : void { - $version = AnnotatedContainerVersion::version(); - $encodedVal = base64_encode(serialize('key')); - $type = self::BASE_64_ENCODED_STRING; $xml = << - + - + Cspray\AnnotatedContainer\Fixture\InjectCustomStoreServices\ScalarInjector - - - default - - Concrete - + {$this->encodedAndSerialized(new Service())} @@ -1256,13 +1083,10 @@ public function testDeserializeInjectDefinitionMethodParameterWithStore() : void Cspray\AnnotatedContainer\Fixture\InjectCustomStoreServices\ScalarInjector __construct key - {$type} - - - default - - test-store - + + string + + {$this->encodedAndSerialized($attribute = new Inject('key', 'test-store'))} @@ -1281,29 +1105,22 @@ public function testDeserializeInjectDefinitionMethodParameterWithStore() : void $injectDefinition->class() ); self::assertSame('__construct', $injectDefinition->methodName()); + self::assertEquals($attribute, $injectDefinition->attribute()); self::assertSame('key', $injectDefinition->parameterName()); - self::assertSame(stringType(), $injectDefinition->type()); + self::assertSame(types()->string(), $injectDefinition->type()); self::assertSame('key', $injectDefinition->value()); self::assertSame(['default'], $injectDefinition->profiles()); self::assertSame('test-store', $injectDefinition->storeName()); } public function testDeserializeInjectMethodWithProfiles() : void { - $version = AnnotatedContainerVersion::version(); - $encodedVal = base64_encode(serialize('annotated container')); - $type = self::BASE_64_ENCODED_STRING; $xml = << - + - + Cspray\AnnotatedContainer\Fixture\InjectConstructorServices\StringInjectService - - - default - - Concrete - + {$this->encodedAndSerialized(new Service())} @@ -1314,14 +1131,10 @@ public function testDeserializeInjectMethodWithProfiles() : void { Cspray\AnnotatedContainer\Fixture\InjectConstructorServices\StringInjectService __construct val - {$type} - - - foo - baz - - - + + string + + {$this->encodedAndSerialized($attribute = new Inject('annotated container', profiles: ['foo', 'baz']))} @@ -1339,9 +1152,10 @@ public function testDeserializeInjectMethodWithProfiles() : void { Fixtures::injectConstructorServices()->injectStringService(), $injectDefinition->class() ); + self::assertEquals($attribute, $injectDefinition->attribute()); self::assertSame('__construct', $injectDefinition->methodName()); self::assertSame('val', $injectDefinition->parameterName()); - self::assertSame(stringType(), $injectDefinition->type()); + self::assertSame(types()->string(), $injectDefinition->type()); self::assertSame('annotated container', $injectDefinition->value()); self::assertSame(['foo', 'baz'], $injectDefinition->profiles()); self::assertNull($injectDefinition->storeName()); @@ -1352,13 +1166,8 @@ public function testDeserializeWithMismatchedVersionThrowsException() : void { - + Cspray\AnnotatedContainer\Fixture\SingleConcreteService\FooImplementation - - - default - - Concrete @@ -1398,7 +1207,6 @@ public static function fixturesDirProvider() : array { public function testScannedAndSerializedContainerDefinitionMatchesDeserialized(Fixture $fixture) : void { $compiler = new AnnotatedTargetContainerDefinitionAnalyzer( new PhpParserAnnotatedTargetParser(), - new AnnotatedTargetDefinitionConverter(), new Emitter() ); diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/AnnotatedTargetContainerDefinitionAnalyzerTestCase.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/AnnotatedTargetContainerDefinitionAnalyzerTestCase.php index c099f5ec..5283d081 100755 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/AnnotatedTargetContainerDefinitionAnalyzerTestCase.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/AnnotatedTargetContainerDefinitionAnalyzerTestCase.php @@ -5,7 +5,6 @@ use Cspray\AnnotatedContainer\Definition\ContainerDefinition; use Cspray\AnnotatedContainer\Event\Emitter; use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalyzer; -use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetDefinitionConverter; use Cspray\AnnotatedContainer\StaticAnalysis\ContainerDefinitionAnalysisOptionsBuilder; use Cspray\AnnotatedContainer\StaticAnalysis\DefinitionProvider; use Cspray\AnnotatedContainer\Unit\ContainerDefinitionAssertionsTrait; @@ -41,7 +40,6 @@ protected function setUp() : void { $this->analyzer = new AnnotatedTargetContainerDefinitionAnalyzer( new PhpParserAnnotatedTargetParser(), - new AnnotatedTargetDefinitionConverter(), $emitter, ); diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/DataProviderExpects/ExpectedAliasDefinition.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/DataProviderExpects/ExpectedAliasDefinition.php index 28e6a421..00296185 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/DataProviderExpects/ExpectedAliasDefinition.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/DataProviderExpects/ExpectedAliasDefinition.php @@ -2,13 +2,13 @@ namespace Cspray\AnnotatedContainer\Unit\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalysisTests\DataProviderExpects; -use Cspray\Typiphy\ObjectType; +use Cspray\AnnotatedContainer\Reflection\Type; final class ExpectedAliasDefinition { public function __construct( - public readonly ObjectType $abstractType, - public readonly ObjectType $concreteType + public readonly Type $abstractType, + public readonly Type $concreteType ) { } } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/DataProviderExpects/ExpectedConfigurationName.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/DataProviderExpects/ExpectedConfigurationName.php deleted file mode 100644 index e50830f8..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/DataProviderExpects/ExpectedConfigurationName.php +++ /dev/null @@ -1,14 +0,0 @@ -service + $expectedInject->service->name() )); } return $definitionsForService; @@ -43,7 +44,7 @@ private function filterMethodName(ExpectedInject $expectedInject, array $injectD if (empty($definitionsForInjectTarget)) { Assert::fail(sprintf( 'Could not find an InjectDefinition for method %s::%s.', - $expectedInject->service, + $expectedInject->service->name(), $expectedInject->methodName )); } @@ -56,7 +57,7 @@ private function filterMethodParameter(ExpectedInject $expectedInject, array $in Assert::fail(sprintf( 'Could not find an InjectDefinition for parameter \'%s\' on method %s::%s.', $expectedInject->tarname, - $expectedInject->service, + $expectedInject->service->name(), $expectedInject->methodName )); } @@ -64,14 +65,14 @@ private function filterMethodParameter(ExpectedInject $expectedInject, array $in } private function validateMethodType(ExpectedInject $expectedInject, array $injectDefinitions) : void { - $definitionsWithTypes = array_filter($injectDefinitions, fn($injectDefinition) => $injectDefinition->type() === $expectedInject->type); + $definitionsWithTypes = array_filter($injectDefinitions, static fn(InjectDefinition $injectDefinition): bool => $injectDefinition->type()->equals($expectedInject->type)); if (empty($definitionsWithTypes)) { Assert::fail(sprintf( 'Could not find an InjectDefinition for parameter \'%s\' on method %s::%s with type \'%s\'.', $expectedInject->tarname, - $expectedInject->service, + $expectedInject->service->name(), $expectedInject->methodName, - $expectedInject->type + $expectedInject->type->name() )); } } @@ -82,8 +83,8 @@ private function validatePropertyType(ExpectedInject $expectedInject, array $inj Assert::fail(sprintf( 'Could not find an InjectDefinition for property \'%s\' on %s with type \'%s\'.', $expectedInject->tarname, - $expectedInject->service, - $expectedInject->type + $expectedInject->service->name(), + $expectedInject->type->name() )); } } @@ -94,7 +95,7 @@ private function validateValue(ExpectedInject $expectedInject, array $injectDefi $message = sprintf( 'Could not find an InjectDefinition for parameter \'%s\' on method %s::%s with a value matching:%s %s.', $expectedInject->tarname, - $expectedInject->service, + $expectedInject->service->name(), $expectedInject->methodName, str_repeat(PHP_EOL, 2), var_export($expectedInject->value, true) @@ -112,7 +113,7 @@ private function validateProfiles(ExpectedInject $expectedInject, array $injectD $message = sprintf( 'Could not find an InjectDefinition for parameter \'%s\' on method %s::%s with %s.', $expectedInject->tarname, - $expectedInject->service, + $expectedInject->service->name(), $expectedInject->methodName, $profileDescriptor() ); @@ -127,7 +128,7 @@ private function validateStoreName(ExpectedInject $expectedInject, array $inject $message = sprintf( 'Could not find an InjectDefinition for parameter \'%s\' on method %s::%s with %s.', $expectedInject->tarname, - $expectedInject->service, + $expectedInject->service->name(), $expectedInject->methodName, $storeDescriptor() ); diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasConfigurationDefinitionTestsTrait.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasConfigurationDefinitionTestsTrait.php deleted file mode 100644 index a52f29b5..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasConfigurationDefinitionTestsTrait.php +++ /dev/null @@ -1,46 +0,0 @@ -configurationTypeProvider()); - - $this->assertSame($expected, count($this->getSubject()->getConfigurationDefinitions())); - } - - final public function testConfigurationNameCount() : void { - $expected = count($this->configurationNameProvider()); - - $this->assertSame($expected, count($this->getSubject()->getConfigurationDefinitions())); - } - - #[DataProvider('configurationTypeProvider')] - final public function testConfigurationType(ExpectedConfigurationType $expectedConfigurationType) : void { - $configurationDefinition = $this->getConfigurationDefinition($this->getSubject()->getConfigurationDefinitions(), $expectedConfigurationType->configuration->name()); - - $this->assertNotNull($configurationDefinition); - } - - #[DataProvider('configurationNameProvider')] - final public function testConfigurationName(ExpectedConfigurationName $expectedConfigurationName) : void { - $configurationDefinition = $this->getConfigurationDefinition($this->getSubject()->getConfigurationDefinitions(), $expectedConfigurationName->configuration->name()); - - $this->assertSame($expectedConfigurationName->name, $configurationDefinition->name()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasNoConfigurationDefinitionsTrait.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasNoConfigurationDefinitionsTrait.php deleted file mode 100644 index 3541fff1..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasNoConfigurationDefinitionsTrait.php +++ /dev/null @@ -1,14 +0,0 @@ -assertEmpty($this->getSubject()->getConfigurationDefinitions()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasServiceDefinitionTestsTrait.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasServiceDefinitionTestsTrait.php index 695fe649..31179f31 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasServiceDefinitionTestsTrait.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/HasTestsTrait/HasServiceDefinitionTestsTrait.php @@ -106,7 +106,7 @@ final public function testExpectedServiceTypes(ExpectedServiceType $expectedServ $this->assertNotNull( $serviceDefinition, - sprintf('Could not find a service that matches the expected type \'%s\'.', $expectedServiceType->type) + sprintf('Could not find a service that matches the expected type \'%s\'.', $expectedServiceType->type->name()) ); } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectConstructorServicesTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectConstructorServicesTest.php index e8476f12..254a7823 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectConstructorServicesTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectConstructorServicesTest.php @@ -18,14 +18,7 @@ use Cspray\AnnotatedContainer\Unit\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalysisTests\HasTestsTrait\HasServiceDefinitionTestsTrait; use Cspray\AnnotatedContainer\Fixture\Fixture; use Cspray\AnnotatedContainer\Fixture\Fixtures; -use function Cspray\Typiphy\arrayType; -use function Cspray\Typiphy\boolType; -use function Cspray\Typiphy\floatType; -use function Cspray\Typiphy\intType; -use function Cspray\Typiphy\mixedType; -use function Cspray\Typiphy\nullType; -use function Cspray\Typiphy\stringType; -use function Cspray\Typiphy\typeUnion; +use function Cspray\AnnotatedContainer\Reflection\types; class InjectConstructorServicesTest extends AnnotatedTargetContainerDefinitionAnalyzerTestCase { @@ -45,83 +38,83 @@ public static function injectProvider() : array { [ExpectedInject::forConstructParam( Fixtures::injectConstructorServices()->injectArrayService(), 'values', - arrayType(), + types()->array(), ['dependency', 'injection', 'rocks'] )], [ExpectedInject::forConstructParam( Fixtures::injectConstructorServices()->injectIntService(), 'meaningOfLife', - intType(), + types()->int(), 42 )], [ExpectedInject::forConstructParam( Fixtures::injectConstructorServices()->injectBoolService(), 'flag', - boolType(), + types()->bool(), false )], [ExpectedInject::forConstructParam( Fixtures::injectConstructorServices()->injectFloatService(), 'dessert', - floatType(), + types()->float(), 3.14 )], [ExpectedInject::forConstructParam( Fixtures::injectConstructorServices()->injectStringService(), 'val', - stringType(), + types()->string(), 'foobar' )], [ExpectedInject::forConstructParam( Fixtures::injectConstructorServices()->injectEnvService(), 'user', - stringType(), + types()->string(), 'USER', store: 'env' )], [ExpectedInject::forConstructParam( Fixtures::injectConstructorServices()->injectExplicitMixedService(), 'value', - mixedType(), + types()->mixed(), 'whatever' )], [ExpectedInject::forConstructParam( Fixtures::injectConstructorServices()->injectImplicitMixedService(), 'val', - mixedType(), + types()->mixed(), 'something' )], [ExpectedInject::forConstructParam( Fixtures::injectConstructorServices()->injectNullableStringService(), 'maybe', - typeUnion(nullType(), stringType()), + types()->nullable(types()->string()), null )], [ExpectedInject::forConstructParam( Fixtures::injectConstructorServices()->injectProfilesStringService(), 'val', - stringType(), + types()->string(), 'from-dev', ['dev'] )], [ExpectedInject::forConstructParam( Fixtures::injectConstructorServices()->injectProfilesStringService(), 'val', - stringType(), + types()->string(), 'from-test', ['test'] )], [ExpectedInject::forConstructParam( Fixtures::injectConstructorServices()->injectProfilesStringService(), 'val', - stringType(), + types()->string(), 'from-prod', ['prod'] )], [ExpectedInject::forConstructParam( Fixtures::injectConstructorServices()->injectTypeUnionService(), 'value', - typeUnion(stringType(), intType(), floatType()), + types()->union(types()->string(), types()->int(), types()->float()), 4.20 )] ]; diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectPrepareServicesTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectPrepareServicesTest.php index 53d7f64a..050b4f20 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectPrepareServicesTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectPrepareServicesTest.php @@ -20,9 +20,7 @@ use Cspray\AnnotatedContainer\Unit\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalysisTests\HasTestsTrait\HasServicePrepareDefinitionTestsTrait; use Cspray\AnnotatedContainer\Fixture\Fixture; use Cspray\AnnotatedContainer\Fixture\Fixtures; -use function Cspray\Typiphy\floatType; -use function Cspray\Typiphy\stringType; -use function Cspray\Typiphy\typeUnion; +use function Cspray\AnnotatedContainer\Reflection\types; class InjectPrepareServicesTest extends AnnotatedTargetContainerDefinitionAnalyzerTestCase { @@ -50,7 +48,7 @@ public static function injectProvider() : array { Fixtures::injectPrepareServices()->prepareInjector(), 'setVals', 'val', - stringType(), + types()->string(), 'foo' )], [ExpectedInject::forMethodParam( @@ -64,7 +62,7 @@ public static function injectProvider() : array { Fixtures::injectPrepareServices()->serviceScalarUnionPrepareInjector(), 'setValue', 'val', - typeUnion(floatType(), Fixtures::injectPrepareServices()->fooInterface()), + types()->union(types()->float(), Fixtures::injectPrepareServices()->fooInterface()), 3.14 )] ]; diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectServiceConstructorServicesTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectServiceConstructorServicesTest.php index 18988887..8b26adb9 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectServiceConstructorServicesTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/InjectServiceConstructorServicesTest.php @@ -19,8 +19,7 @@ use Cspray\AnnotatedContainer\Unit\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalysisTests\HasTestsTrait\HasServiceDefinitionTestsTrait; use Cspray\AnnotatedContainer\Fixture\Fixture; use Cspray\AnnotatedContainer\Fixture\Fixtures; -use function Cspray\Typiphy\nullType; -use function Cspray\Typiphy\typeUnion; +use function Cspray\AnnotatedContainer\Reflection\types; class InjectServiceConstructorServicesTest extends AnnotatedTargetContainerDefinitionAnalyzerTestCase { @@ -53,7 +52,7 @@ public static function injectProvider() : array { [ExpectedInject::forConstructParam( Fixtures::injectServiceConstructorServices()->nullableServiceInjector(), 'maybeFoo', - typeUnion(nullType(), Fixtures::injectServiceConstructorServices()->fooInterface()), + types()->nullable(Fixtures::injectServiceConstructorServices()->fooInterface()), null )] ]; diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/ThirdPartyDelegatedServicesTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/ThirdPartyDelegatedServicesTest.php index 22bd212f..8505c45e 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/ThirdPartyDelegatedServicesTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/ThirdPartyDelegatedServicesTest.php @@ -23,8 +23,8 @@ use Cspray\AnnotatedContainer\Fixture\Fixtures; use Cspray\AnnotatedContainer\Fixture\ThirdPartyDelegatedServicesFixture; use Psr\Log\LoggerInterface; -use function Cspray\AnnotatedContainer\service; -use function Cspray\Typiphy\objectType; +use function Cspray\AnnotatedContainer\Definition\service; +use function Cspray\AnnotatedContainer\Reflection\types; class ThirdPartyDelegatedServicesTest extends AnnotatedTargetContainerDefinitionAnalyzerTestCase { @@ -41,50 +41,50 @@ protected function getFixtures() : Fixture { protected function getDefinitionProvider() : ?DefinitionProvider { return new CallableDefinitionProvider(function(DefinitionProviderContext $context) { - $context->addServiceDefinition(service(objectType(LoggerInterface::class))); + $context->addServiceDefinition(service(types()->class(LoggerInterface::class))); }); } public static function serviceTypeProvider() : array { return [ - [new ExpectedServiceType(objectType(LoggerInterface::class))] + [new ExpectedServiceType(types()->class(LoggerInterface::class))] ]; } public static function serviceNameProvider() : array { return [ - [new ExpectedServiceName(objectType(LoggerInterface::class), null)] + [new ExpectedServiceName(types()->class(LoggerInterface::class), null)] ]; } public static function serviceIsPrimaryProvider() : array { return [ - [new ExpectedServiceIsPrimary(objectType(LoggerInterface::class), false)] + [new ExpectedServiceIsPrimary(types()->class(LoggerInterface::class), false)] ]; } public static function serviceIsConcreteProvider() : array { return [ - [new ExpectedServiceIsConcrete(objectType(LoggerInterface::class), false)] + [new ExpectedServiceIsConcrete(types()->class(LoggerInterface::class), false)] ]; } public static function serviceIsAbstractProvider() : array { return [ - [new ExpectedServiceIsAbstract(objectType(LoggerInterface::class), true)] + [new ExpectedServiceIsAbstract(types()->class(LoggerInterface::class), true)] ]; } public static function serviceProfilesProvider() : array { return [ - [new ExpectedServiceProfiles(objectType(LoggerInterface::class), ['default'])] + [new ExpectedServiceProfiles(types()->class(LoggerInterface::class), ['default'])] ]; } public static function serviceDelegateProvider() : array { return [ [new ExpectedServiceDelegate( - objectType(LoggerInterface::class), + types()->class(LoggerInterface::class), Fixtures::thirdPartyDelegatedServices()->loggerFactory(), 'create' )] diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/ThirdPartyEventEmittingTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/ThirdPartyEventEmittingTest.php index 8d35f088..8ff786d6 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/ThirdPartyEventEmittingTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/ThirdPartyEventEmittingTest.php @@ -26,12 +26,11 @@ use Cspray\AnnotatedContainer\Fixture\Fixtures; use Cspray\AnnotatedContainer\Fixture\ThirdPartyKitchenSink\NonAnnotatedInterface; use Cspray\AnnotatedContainer\Fixture\ThirdPartyKitchenSink\NonAnnotatedService; -use function Cspray\AnnotatedContainer\inject; -use function Cspray\AnnotatedContainer\service; -use function Cspray\AnnotatedContainer\serviceDelegate; -use function Cspray\AnnotatedContainer\servicePrepare; -use function Cspray\Typiphy\objectType; -use function Cspray\Typiphy\stringType; +use function Cspray\AnnotatedContainer\Definition\inject; +use function Cspray\AnnotatedContainer\Definition\service; +use function Cspray\AnnotatedContainer\Definition\serviceDelegate; +use function Cspray\AnnotatedContainer\Definition\servicePrepare; +use function Cspray\AnnotatedContainer\Reflection\types; class ThirdPartyEventEmittingTest extends AnnotatedTargetContainerDefinitionAnalyzerTestCase { @@ -47,27 +46,26 @@ protected function getFixtures() : array|Fixture { protected function getDefinitionProvider() : ?DefinitionProvider { return new CallableDefinitionProvider(static function(DefinitionProviderContext $context) { - $context->addServiceDefinition(service(objectType(NonAnnotatedInterface::class))); - $context->addServiceDefinition(service(objectType(NonAnnotatedService::class))); + $context->addServiceDefinition(service(types()->class(NonAnnotatedInterface::class))); + $context->addServiceDefinition(service(types()->class(NonAnnotatedService::class))); $context->addServiceDelegateDefinition( serviceDelegate( - objectType(NonAnnotatedService::class), - objectType(NonAnnotatedService::class), + types()->class(NonAnnotatedService::class), 'create' ) ); $context->addServicePrepareDefinition( servicePrepare( - objectType(NonAnnotatedService::class), + types()->class(NonAnnotatedService::class), 'init' ) ); $context->addInjectDefinition( inject( - objectType(NonAnnotatedService::class), + types()->class(NonAnnotatedService::class), 'init', 'value', - stringType(), + types()->string(), 'calledFromApi' ) ); @@ -87,17 +85,17 @@ protected function assertEmittedEvents(AnalysisEventCollection $analysisEventCol public static function aliasProvider() : array { return [ - [new ExpectedAliasDefinition(objectType(NonAnnotatedInterface::class), objectType(NonAnnotatedService::class))] + [new ExpectedAliasDefinition(types()->class(NonAnnotatedInterface::class), types()->class(NonAnnotatedService::class))] ]; } public static function injectProvider() : array { return [ [ExpectedInject::forMethodParam( - objectType(NonAnnotatedService::class), + types()->class(NonAnnotatedService::class), 'init', 'value', - stringType(), + types()->string(), 'calledFromApi' )] ]; @@ -105,55 +103,55 @@ public static function injectProvider() : array { public static function serviceTypeProvider() : array { return [ - [new ExpectedServiceType(objectType(NonAnnotatedInterface::class))], - [new ExpectedServiceType(objectType(NonAnnotatedService::class))], + [new ExpectedServiceType(types()->class(NonAnnotatedInterface::class))], + [new ExpectedServiceType(types()->class(NonAnnotatedService::class))], ]; } public static function serviceNameProvider() : array { return [ - [new ExpectedServiceName(objectType(NonAnnotatedInterface::class), null)], - [new ExpectedServiceName(objectType(NonAnnotatedService::class), null)] + [new ExpectedServiceName(types()->class(NonAnnotatedInterface::class), null)], + [new ExpectedServiceName(types()->class(NonAnnotatedService::class), null)] ]; } public static function serviceIsPrimaryProvider() : array { return [ - [new ExpectedServiceIsPrimary(objectType(NonAnnotatedInterface::class), false)], - [new ExpectedServiceIsPrimary(objectType(NonAnnotatedService::class), false)], + [new ExpectedServiceIsPrimary(types()->class(NonAnnotatedInterface::class), false)], + [new ExpectedServiceIsPrimary(types()->class(NonAnnotatedService::class), false)], ]; } public static function serviceIsConcreteProvider() : array { return [ - [new ExpectedServiceIsConcrete(objectType(NonAnnotatedInterface::class), false)], - [new ExpectedServiceIsConcrete(objectType(NonAnnotatedService::class), true)], + [new ExpectedServiceIsConcrete(types()->class(NonAnnotatedInterface::class), false)], + [new ExpectedServiceIsConcrete(types()->class(NonAnnotatedService::class), true)], ]; } public static function serviceIsAbstractProvider() : array { return [ - [new ExpectedServiceIsAbstract(objectType(NonAnnotatedInterface::class), true)], - [new ExpectedServiceIsAbstract(objectType(NonAnnotatedService::class), false)], + [new ExpectedServiceIsAbstract(types()->class(NonAnnotatedInterface::class), true)], + [new ExpectedServiceIsAbstract(types()->class(NonAnnotatedService::class), false)], ]; } public static function serviceProfilesProvider() : array { return [ - [new ExpectedServiceProfiles(objectType(NonAnnotatedInterface::class), ['default'])], - [new ExpectedServiceProfiles(objectType(NonAnnotatedService::class), ['default'])], + [new ExpectedServiceProfiles(types()->class(NonAnnotatedInterface::class), ['default'])], + [new ExpectedServiceProfiles(types()->class(NonAnnotatedService::class), ['default'])], ]; } public static function serviceDelegateProvider() : array { return [ - [new ExpectedServiceDelegate(objectType(NonAnnotatedService::class), objectType(NonAnnotatedService::class), 'create')], + [new ExpectedServiceDelegate(types()->class(NonAnnotatedService::class), types()->class(NonAnnotatedService::class), 'create')], ]; } public static function servicePrepareProvider() : array { return [ - [new ExpectedServicePrepare(objectType(NonAnnotatedService::class), 'init')] + [new ExpectedServicePrepare(types()->class(NonAnnotatedService::class), 'init')] ]; } } diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/ThirdPartyServicesTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/ThirdPartyServicesTest.php index 22d57344..81b327fe 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/ThirdPartyServicesTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalysisTests/ThirdPartyServicesTest.php @@ -21,7 +21,7 @@ use Cspray\AnnotatedContainer\Unit\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalysisTests\HasTestsTrait\HasServiceDefinitionTestsTrait; use Cspray\AnnotatedContainer\Fixture\Fixture; use Cspray\AnnotatedContainer\Fixture\Fixtures; -use function Cspray\AnnotatedContainer\service; +use function Cspray\AnnotatedContainer\Definition\service; class ThirdPartyServicesTest extends AnnotatedTargetContainerDefinitionAnalyzerTestCase { diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzerTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzerTest.php index 5a53666e..6ac19e5e 100644 --- a/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzerTest.php +++ b/test/Unit/StaticAnalysis/AnnotatedTargetContainerDefinitionAnalyzerTest.php @@ -7,6 +7,10 @@ use Cspray\AnnotatedContainer\Exception\InvalidScanDirectories; use Cspray\AnnotatedContainer\Exception\InvalidServiceDelegate; use Cspray\AnnotatedContainer\Exception\InvalidServicePrepare; +use Cspray\AnnotatedContainer\Exception\ServiceDelegateReturnsIntersectionType; +use Cspray\AnnotatedContainer\Exception\ServiceDelegateReturnsScalarType; +use Cspray\AnnotatedContainer\Exception\ServiceDelegateReturnsUnionType; +use Cspray\AnnotatedContainer\Exception\ServiceDelegateReturnsUnknownType; use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalyzer; use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetDefinitionConverter; use Cspray\AnnotatedContainer\StaticAnalysis\ContainerDefinitionAnalysisOptionsBuilder; @@ -26,7 +30,6 @@ class AnnotatedTargetContainerDefinitionAnalyzerTest extends TestCase { public function setUp() : void { $this->subject = new AnnotatedTargetContainerDefinitionAnalyzer( new PhpParserAnnotatedTargetParser(), - new AnnotatedTargetDefinitionConverter(), new Emitter() ); } @@ -73,36 +76,36 @@ public function testDuplicateScanDirectoriesThrowsException() { } public function testImplicitServiceDelegateHasNoReturnType() { - $this->expectException(InvalidServiceDelegate::class); + $this->expectException(ServiceDelegateReturnsUnknownType::class); $this->expectExceptionMessage( - 'The #[ServiceDelegate] Attribute on ' . LogicalErrorApps\ImplicitServiceDelegateNoType\FooFactory::class . '::create does not declare a service in the Attribute or as a return type of the method.' + 'The ServiceDelegate ' . LogicalErrorApps\ImplicitServiceDelegateNoType\FooFactory::class . '::create does not have a return type. A ServiceDelegate MUST declare an object return type.' ); $this->runAnalysisDirectory(__DIR__ . '/../LogicalErrorApps/ImplicitServiceDelegateNoType'); } public function testImplicitServiceDelegateHasScalarReturnType() { - $this->expectException(InvalidServiceDelegate::class); + $this->expectException(ServiceDelegateReturnsScalarType::class); $this->expectExceptionMessage( - 'The #[ServiceDelegate] Attribute on ' . LogicalErrorApps\ImplicitServiceDelegateScalarType\FooFactory::class . '::create declares a scalar value as a service type.' + 'The ServiceDelegate ' . LogicalErrorApps\ImplicitServiceDelegateScalarType\FooFactory::class . '::create returns a scalar type. All ServiceDelegates MUST return an object type.' ); $this->runAnalysisDirectory(__DIR__ . '/../LogicalErrorApps/ImplicitServiceDelegateScalarType'); } public function testImplicitServiceDelegateHasIntersectionReturnType() { - $this->expectException(InvalidServiceDelegate::class); + $this->expectException(ServiceDelegateReturnsIntersectionType::class); $this->expectExceptionMessage( - 'The #[ServiceDelegate] Attribute on ' . LogicalErrorApps\ImplicitServiceDelegateIntersectionType\FooFactory::class . '::create declares an unsupported intersection as a service type.' + 'The ServiceDelegate ' . LogicalErrorApps\ImplicitServiceDelegateIntersectionType\FooFactory::class . '::create returns an intersection type. At this time intersection types are not supported.' ); $this->runAnalysisDirectory(__DIR__ . '/../LogicalErrorApps/ImplicitServiceDelegateIntersectionType'); } public function testImplicitServiceDelegateHasUnionReturnType() { - $this->expectException(InvalidServiceDelegate::class); + $this->expectException(ServiceDelegateReturnsUnionType::class); $this->expectExceptionMessage( - 'The #[ServiceDelegate] Attribute on ' . LogicalErrorApps\ImplicitServiceDelegateUnionType\FooFactory::class . '::create declares an unsupported union as a service type.' + 'The ServiceDelegate ' . LogicalErrorApps\ImplicitServiceDelegateUnionType\FooFactory::class . '::create returns a union type. At this time union types are not supported.' ); $this->runAnalysisDirectory(__DIR__ . '/../LogicalErrorApps/ImplicitServiceDelegateUnionType'); diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTest.php deleted file mode 100644 index 28084b21..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTest.php +++ /dev/null @@ -1,26 +0,0 @@ -createMock(AnnotatedTarget::class); - $target->expects($this->once())->method('attributeInstance')->willReturn(new \stdClass()); - - $this->expectException(InvalidAnnotatedTarget::class); - $this->expectExceptionMessage( - 'Received an AnnotatedTarget with an attribute instance of an unknown type. This is indicative of an ' . - 'internal error and should be reported to https://github.com/cspray/annotated-container.' - ); - - $subject->convert($target); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/AbstractSharedServicesTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/AbstractSharedServicesTest.php deleted file mode 100644 index 2a2dff9c..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/AbstractSharedServicesTest.php +++ /dev/null @@ -1,42 +0,0 @@ -getAnnotatedTarget(AttributeType::Service, new ReflectionClass( - Fixtures::abstractClassAliasedService()->fooAbstract()->name() - )); - } - - public function testGetServiceDefinitionInstance() { - $this->assertInstanceOf(ServiceDefinition::class, $this->definition); - } - - public function testGetServiceDefinitionType() { - $this->assertSame(Fixtures::abstractClassAliasedService()->fooAbstract(), $this->definition->type()); - } - - public function testServiceIsAbstract() { - $this->assertTrue($this->definition->isAbstract()); - } - - public function testServiceNameIsNull() { - $this->assertNull($this->definition->name()); - } - - public function testServiceIsPrimary() { - $this->assertFalse($this->definition->isPrimary()); - } - - public function testServiceProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/AnnotatedTargetDefinitionConverterTestCase.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/AnnotatedTargetDefinitionConverterTestCase.php deleted file mode 100644 index 1dc91b49..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/AnnotatedTargetDefinitionConverterTestCase.php +++ /dev/null @@ -1,57 +0,0 @@ -definition = $subject->convert($this->getSubjectTarget()); - } - - protected function getAnnotatedTarget(AttributeType $attributeType, ReflectionClass|ReflectionMethod|ReflectionParameter|ReflectionProperty $reflection, int $attributeIndex = 0) : AnnotatedTarget { - return new class($attributeType, $reflection, $attributeIndex) implements AnnotatedTarget { - - public function __construct( - private readonly AttributeType $attributeType, - private readonly ReflectionClass|ReflectionMethod|ReflectionParameter|ReflectionProperty $reflection, - private readonly int $attributeIndex - ) { - } - - public function targetReflection(): ReflectionClass|ReflectionMethod|ReflectionParameter|ReflectionProperty { - return $this->reflection; - } - - public function attributeReflection() : ReflectionAttribute { - return $this->reflection->getAttributes($this->attributeType->value, ReflectionAttribute::IS_INSTANCEOF)[$this->attributeIndex]; - } - - public function attributeInstance(): Service|ServicePrepare|ServiceDelegate|Inject { - return $this->attributeReflection()->newInstance(); - } - }; - } - - abstract protected function getSubjectTarget() : AnnotatedTarget; -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectArrayMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectArrayMethodParamTest.php deleted file mode 100644 index f5025233..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectArrayMethodParamTest.php +++ /dev/null @@ -1,60 +0,0 @@ -getAnnotatedTarget( - AttributeType::Inject, - new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectArrayService()->name(), '__construct'], - 'values' - ) - ); - } - - public function testDefinitionInstanceOf() : void { - self::assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() : void { - self::assertSame(Fixtures::injectConstructorServices()->injectArrayService(), $this->definition->class()); - } - - public function testDefinitionGetMethod() : void { - self::assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() : void { - self::assertSame('values', $this->definition->parameterName()); - } - - public function testDefinitionGetType() : void { - self::assertSame(arrayType(), $this->definition->type()); - } - - public function testGetValue() : void { - self::assertSame(['dependency', 'injection', 'rocks'], $this->definition->value()); - } - - public function testGetStore() : void { - self::assertNull($this->definition->storeName()); - } - - public function testGetProfiles() : void { - self::assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() : void { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame(['dependency', 'injection', 'rocks'], $this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectBoolMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectBoolMethodParamTest.php deleted file mode 100644 index c7c2fe1e..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectBoolMethodParamTest.php +++ /dev/null @@ -1,60 +0,0 @@ -getAnnotatedTarget( - AttributeType::Inject, - new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectBoolService()->name(), '__construct'], - 'flag' - ) - ); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectConstructorServices()->injectBoolService(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('flag', $this->definition->parameterName()); - } - - public function testDefinitionGetType() { - $this->assertSame(boolType(), $this->definition->type()); - } - - public function testGetValue() { - $this->assertFalse($this->definition->value()); - } - - public function testGetStore() { - $this->assertNull($this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertFalse($this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectEnvMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectEnvMethodParamTest.php deleted file mode 100644 index 1364c190..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectEnvMethodParamTest.php +++ /dev/null @@ -1,58 +0,0 @@ -getAnnotatedTarget(AttributeType::Inject, new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectEnvService()->name(), '__construct'], - 'user' - )); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectConstructorServices()->injectEnvService(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('user', $this->definition->parameterName()); - } - - public function testDefinitionGetType() { - $this->assertSame(stringType(), $this->definition->type()); - } - - public function testGetValue() { - $this->assertSame('USER', $this->definition->value()); - } - - public function testGetStore() { - $this->assertSame('env', $this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame('USER', $this->definition->attribute()->value()); - self::assertSame('env', $this->definition->attribute()->from()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectExplicitMixedMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectExplicitMixedMethodParamTest.php deleted file mode 100644 index c0a990ef..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectExplicitMixedMethodParamTest.php +++ /dev/null @@ -1,60 +0,0 @@ -getAnnotatedTarget( - AttributeType::Inject, - new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectExplicitMixedService()->name(), '__construct'], - 'value' - ) - ); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectConstructorServices()->injectExplicitMixedService(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('value', $this->definition->parameterName()); - } - - public function testDefinitionGetType() { - $this->assertSame(mixedType(), $this->definition->type()); - } - - public function testGetValue() { - $this->assertSame('whatever', $this->definition->value()); - } - - public function testGetStore() { - $this->assertNull($this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame('whatever', $this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectFloatMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectFloatMethodParamTest.php deleted file mode 100644 index 8b9dae6d..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectFloatMethodParamTest.php +++ /dev/null @@ -1,60 +0,0 @@ -getAnnotatedTarget( - AttributeType::Inject, - new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectFloatService()->name(), '__construct'], - 'dessert' - ) - ); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectConstructorServices()->injectFloatService(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('dessert', $this->definition->parameterName()); - } - - public function testDefinitionGetType() { - $this->assertSame(floatType(), $this->definition->type()); - } - - public function testGetValue() { - $this->assertSame(3.14, $this->definition->value()); - } - - public function testGetStore() { - $this->assertNull($this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame(3.14, $this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectImplicitMixedMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectImplicitMixedMethodParamTest.php deleted file mode 100644 index bb5457e1..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectImplicitMixedMethodParamTest.php +++ /dev/null @@ -1,60 +0,0 @@ -getAnnotatedTarget( - AttributeType::Inject, - new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectImplicitMixedService()->name(), '__construct'], - 'val' - ) - ); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectConstructorServices()->injectImplicitMixedService(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('val', $this->definition->parameterName()); - } - - public function testDefinitionGetType() { - $this->assertSame(mixedType(), $this->definition->type()); - } - - public function testGetValue() { - $this->assertSame('something', $this->definition->value()); - } - - public function testGetStore() { - $this->assertNull($this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame('something', $this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectIntMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectIntMethodParamTest.php deleted file mode 100644 index 94e0de11..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectIntMethodParamTest.php +++ /dev/null @@ -1,60 +0,0 @@ -getAnnotatedTarget( - AttributeType::Inject, - new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectIntService()->name(), '__construct'], - 'meaningOfLife' - ) - ); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectConstructorServices()->injectIntService(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('meaningOfLife', $this->definition->parameterName()); - } - - public function testDefinitionGetType() { - $this->assertSame(intType(), $this->definition->type()); - } - - public function testGetValue() { - $this->assertSame(42, $this->definition->value()); - } - - public function testGetStore() { - $this->assertNull($this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame(42, $this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesFirstMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesFirstMethodParamTest.php deleted file mode 100644 index 50351e47..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesFirstMethodParamTest.php +++ /dev/null @@ -1,57 +0,0 @@ -getAnnotatedTarget(AttributeType::Inject, new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectProfilesStringService()->name(), '__construct'], - 'val' - )); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectConstructorServices()->injectProfilesStringService(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('val', $this->definition->parameterName()); - } - - public function testDefinitionGetType() { - $this->assertSame(stringType(), $this->definition->type()); - } - - public function testGetValue() { - $this->assertSame('from-dev', $this->definition->value()); - } - - public function testGetStore() { - $this->assertNull($this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['dev'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame('from-dev', $this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesSecondMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesSecondMethodParamTest.php deleted file mode 100644 index d5144f58..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesSecondMethodParamTest.php +++ /dev/null @@ -1,57 +0,0 @@ -getAnnotatedTarget(AttributeType::Inject, new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectProfilesStringService()->name(), '__construct'], - 'val' - ), 1); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectConstructorServices()->injectProfilesStringService(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('val', $this->definition->parameterName()); - } - - public function testDefinitionGetType() { - $this->assertSame(stringType(), $this->definition->type()); - } - - public function testGetValue() { - $this->assertSame('from-test', $this->definition->value()); - } - - public function testGetStore() { - $this->assertNull($this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['test'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame('from-test', $this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesThirdMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesThirdMethodParamTest.php deleted file mode 100644 index b6e6bde2..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectMultipleProfilesThirdMethodParamTest.php +++ /dev/null @@ -1,57 +0,0 @@ -getAnnotatedTarget(AttributeType::Inject, new \ReflectionParameter( - [Fixtures::injectConstructorServices()->injectProfilesStringService()->name(), '__construct'], - 'val' - ), 2); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectConstructorServices()->injectProfilesStringService(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('val', $this->definition->parameterName()); - } - - public function testDefinitionGetType() { - $this->assertSame(stringType(), $this->definition->type()); - } - - public function testGetValue() { - $this->assertSame('from-prod', $this->definition->value()); - } - - public function testGetStore() { - $this->assertNull($this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['prod'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame('from-prod', $this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectNullableServiceMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectNullableServiceMethodParamTest.php deleted file mode 100644 index ecf8cb99..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectNullableServiceMethodParamTest.php +++ /dev/null @@ -1,58 +0,0 @@ -getAnnotatedTarget( - AttributeType::Inject, - new \ReflectionParameter([Fixtures::injectServiceConstructorServices()->nullableServiceInjector()->name(), '__construct'], 'maybeFoo') - ); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectServiceConstructorServices()->nullableServiceInjector(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('maybeFoo', $this->definition->parameterName()); - } - - public function testDefinitionGetType() { - $this->assertSame(typeUnion(nullType(), Fixtures::injectServiceConstructorServices()->fooInterface()), $this->definition->type()); - } - - public function testGetValue() { - $this->assertSame(null, $this->definition->value()); - } - - public function testGetStore() { - $this->assertNull($this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertNull($this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectNullableStringMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectNullableStringMethodParamTest.php deleted file mode 100644 index 64acfb00..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectNullableStringMethodParamTest.php +++ /dev/null @@ -1,59 +0,0 @@ -getAnnotatedTarget( - AttributeType::Inject, - new \ReflectionParameter([Fixtures::injectConstructorServices()->injectNullableStringService()->name(), '__construct'], 'maybe') - ); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectConstructorServices()->injectNullableStringService(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('maybe', $this->definition->parameterName()); - } - - public function testDefinitionGetTypeUnion() { - $this->assertSame(typeUnion(stringType(), nullType()), $this->definition->type()); - } - - public function testGetValue() { - $this->assertNull($this->definition->value()); - } - - public function testGetStore() { - $this->assertNull($this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertNull($this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectScalarTypeUnionMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectScalarTypeUnionMethodParamTest.php deleted file mode 100644 index 86972e10..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectScalarTypeUnionMethodParamTest.php +++ /dev/null @@ -1,60 +0,0 @@ -getAnnotatedTarget( - AttributeType::Inject, - new \ReflectionParameter([Fixtures::injectConstructorServices()->injectTypeUnionService()->name(), '__construct'], 'value') - ); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectConstructorServices()->injectTypeUnionService(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('value', $this->definition->parameterName()); - } - - public function testDefinitionGetTypeUnion() { - $this->assertSame(typeUnion(stringType(), intType(), floatType()), $this->definition->type()); - } - - public function testGetValue() { - $this->assertSame(4.20, $this->definition->value()); - } - - public function testGetStore() { - $this->assertNull($this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame(4.20, $this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceMethodParamTest.php deleted file mode 100644 index 73a30fbc..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceMethodParamTest.php +++ /dev/null @@ -1,56 +0,0 @@ -getAnnotatedTarget( - AttributeType::Inject, - new \ReflectionParameter([Fixtures::injectServiceConstructorServices()->serviceInjector()->name(), '__construct'], 'foo') - ); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectServiceConstructorServices()->serviceInjector(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('foo', $this->definition->parameterName()); - } - - public function testDefinitionGetType() { - $this->assertSame(Fixtures::injectServiceConstructorServices()->fooInterface(), $this->definition->type()); - } - - public function testGetValue() { - $this->assertSame(Fixtures::injectServiceConstructorServices()->fooImplementation()->name(), $this->definition->value()); - } - - public function testGetStore() { - $this->assertNull($this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame(Fixtures::injectServiceConstructorServices()->fooImplementation()->name(), $this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceScalarTypeUnionMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceScalarTypeUnionMethodParamTest.php deleted file mode 100644 index a6e0e18f..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceScalarTypeUnionMethodParamTest.php +++ /dev/null @@ -1,58 +0,0 @@ -getAnnotatedTarget( - AttributeType::Inject, - new \ReflectionParameter([Fixtures::injectPrepareServices()->serviceScalarUnionPrepareInjector()->name(), 'setValue'], 'val') - ); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectPrepareServices()->serviceScalarUnionPrepareInjector(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('setValue', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('val', $this->definition->parameterName()); - } - - public function testDefinitionGetTypeUnion() { - $this->assertSame(typeUnion(floatType(), Fixtures::injectPrepareServices()->fooInterface()), $this->definition->type()); - } - - public function testGetValue() { - $this->assertSame(3.14, $this->definition->value()); - } - - public function testGetStore() { - $this->assertNull($this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame(3.14, $this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceTypeIntersectMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceTypeIntersectMethodParamTest.php deleted file mode 100644 index c76bddd4..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectServiceTypeIntersectMethodParamTest.php +++ /dev/null @@ -1,60 +0,0 @@ -getAnnotatedTarget( - AttributeType::Inject, - new \ReflectionParameter([Fixtures::injectServiceIntersectConstructorServices()->fooBarConsumer()->name(), '__construct'], 'fooBar') - ); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectServiceIntersectConstructorServices()->fooBarConsumer(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('fooBar', $this->definition->parameterName()); - } - - public function testDefinitionGetTypeIntersect() { - $this->assertSame( - typeIntersect(Fixtures::injectServiceIntersectConstructorServices()->fooInterface(), Fixtures::injectServiceIntersectConstructorServices()->barInterface()), - $this->definition->type() - ); - } - - public function testGetValue() { - $this->assertSame(Fixtures::injectServiceIntersectConstructorServices()->fooBarImplementation()->name(), $this->definition->value()); - } - - public function testGetStore() { - $this->assertNull($this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame(Fixtures::injectServiceIntersectConstructorServices()->fooBarImplementation()->name(), $this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectStringMethodParamTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectStringMethodParamTest.php deleted file mode 100644 index f4737357..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/InjectStringMethodParamTest.php +++ /dev/null @@ -1,57 +0,0 @@ -getAnnotatedTarget( - AttributeType::Inject, - new \ReflectionParameter([Fixtures::injectConstructorServices()->injectStringService()->name(), '__construct'], 'val') - ); - } - - public function testDefinitionInstanceOf() { - $this->assertInstanceOf(InjectDefinition::class, $this->definition); - } - - public function testDefinitionGetService() { - $this->assertSame(Fixtures::injectConstructorServices()->injectStringService(), $this->definition->class()); - } - - public function testDefinitionGetMethod() { - $this->assertSame('__construct', $this->definition->methodName()); - } - - public function testDefinitionGetParamName() { - $this->assertSame('val', $this->definition->parameterName()); - } - - public function testDefinitionGetType() { - $this->assertSame(stringType(), $this->definition->type()); - } - - public function testGetValue() { - $this->assertSame('foobar', $this->definition->value()); - } - - public function testGetStore() { - $this->assertNull($this->definition->storeName()); - } - - public function testGetProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() { - self::assertInstanceOf(Inject::class, $this->definition->attribute()); - self::assertSame('foobar', $this->definition->attribute()->value()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/MultipleServicesWithPrimaryTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/MultipleServicesWithPrimaryTest.php deleted file mode 100644 index a5a58df4..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/MultipleServicesWithPrimaryTest.php +++ /dev/null @@ -1,48 +0,0 @@ -getAnnotatedTarget( - AttributeType::Service, - new ReflectionClass(Fixtures::primaryAliasedServices()->fooImplementation()->name()) - ); - } - public function testGetServiceDefinitionInstance() { - $this->assertInstanceOf(ServiceDefinition::class, $this->definition); - } - - public function testGetServiceDefinitionType() { - $this->assertSame(Fixtures::primaryAliasedServices()->fooImplementation(), $this->definition->type()); - } - - public function testServiceIsConcrete() { - $this->assertTrue($this->definition->isConcrete()); - } - - public function testServiceNameIsNull() { - $this->assertNull($this->definition->name()); - } - - public function testServiceIsPrimary() { - $this->assertTrue($this->definition->isPrimary()); - } - - public function testServiceProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() : void { - self::assertInstanceOf(Service::class, $this->definition->attribute()); - self::assertTrue($this->definition->attribute()->isPrimary()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/NamedServiceConverterTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/NamedServiceConverterTest.php deleted file mode 100644 index 9f95534a..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/NamedServiceConverterTest.php +++ /dev/null @@ -1,45 +0,0 @@ -getAnnotatedTarget(AttributeType::Service, new ReflectionClass(Fixtures::namedServices()->fooInterface()->name())); - } - public function testGetServiceDefinitionInstance() { - $this->assertInstanceOf(ServiceDefinition::class, $this->definition); - } - - public function testGetServiceDefinitionType() { - $this->assertSame(Fixtures::namedServices()->fooInterface(), $this->definition->type()); - } - - public function testServiceIsAbstract() { - $this->assertTrue($this->definition->isAbstract()); - } - - public function testServiceName() { - $this->assertSame('foo', $this->definition->name()); - } - - public function testServiceIsPrimary() { - $this->assertFalse($this->definition->isPrimary()); - } - - public function testServiceProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() : void { - self::assertInstanceOf(Service::class, $this->definition->attribute()); - self::assertSame('foo', $this->definition->attribute()->name()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ProfileResolvedServicesConverterTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ProfileResolvedServicesConverterTest.php deleted file mode 100644 index 711f6724..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ProfileResolvedServicesConverterTest.php +++ /dev/null @@ -1,46 +0,0 @@ -getAnnotatedTarget(AttributeType::Service, new ReflectionClass(Fixtures::profileResolvedServices()->devImplementation()->name())); - } - - public function testGetServiceDefinitionInstance() { - $this->assertInstanceOf(ServiceDefinition::class, $this->definition); - } - - public function testGetServiceDefinitionType() { - $this->assertSame(Fixtures::profileResolvedServices()->devImplementation(), $this->definition->type()); - } - - public function testServiceIsConcrete() { - $this->assertTrue($this->definition->isConcrete()); - } - - public function testServiceNameIsNull() { - $this->assertNull($this->definition->name()); - } - - public function testServiceIsPrimary() { - $this->assertFalse($this->definition->isPrimary()); - } - - public function testServiceProfiles() { - $this->assertSame(['dev'], $this->definition->profiles()); - } - - public function testGetAttribute() : void { - self::assertInstanceOf(Service::class, $this->definition->attribute()); - self::assertSame(['dev'], $this->definition->attribute()->profiles()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ServiceDelegateConverterTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ServiceDelegateConverterTest.php deleted file mode 100644 index 16be5429..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ServiceDelegateConverterTest.php +++ /dev/null @@ -1,40 +0,0 @@ -getAnnotatedTarget(AttributeType::ServiceDelegate, new ReflectionMethod( - Fixtures::delegatedService()->serviceFactory()->name(), - 'createService' - )); - } - - public function testGetServiceDelegateDefinitionInstance() { - $this->assertInstanceOf(ServiceDelegateDefinition::class, $this->definition); - } - - public function testGetDelegateTypeIsServiceFactory() { - $this->assertSame(Fixtures::delegatedService()->serviceFactory(), $this->definition->delegateType()); - } - - public function testGetDelegateMethodIsCorrect() { - $this->assertSame('createService', $this->definition->delegateMethod()); - } - - public function testGetServiceType() { - $this->assertSame(Fixtures::delegatedService()->serviceInterface(), $this->definition->serviceType()); - } - - public function testGetAttribute() : void { - self::assertInstanceOf(ServiceDelegate::class, $this->definition->attribute()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ServicePrepareConverterTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ServicePrepareConverterTest.php deleted file mode 100644 index 37a9c592..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/ServicePrepareConverterTest.php +++ /dev/null @@ -1,36 +0,0 @@ -getAnnotatedTarget(AttributeType::ServicePrepare, new ReflectionMethod( - Fixtures::interfacePrepareServices()->fooInterface()->name(), - 'setBar' - )); - } - - public function testGetServiceDelegateDefinitionInstance() { - $this->assertInstanceOf(ServicePrepareDefinition::class, $this->definition); - } - - public function testGetService() { - $this->assertSame(Fixtures::interfacePrepareServices()->fooInterface(), $this->definition->service()); - } - - public function testGetMethodIsCorrect() { - $this->assertSame('setBar', $this->definition->methodName()); - } - - public function testGetAttribute() : void { - self::assertInstanceOf(ServicePrepare::class, $this->definition->attribute()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/SingleAliasedServiceConverterTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/SingleAliasedServiceConverterTest.php deleted file mode 100644 index 9b27d9d8..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/SingleAliasedServiceConverterTest.php +++ /dev/null @@ -1,50 +0,0 @@ -fooInterface()->name(); - } - - protected function getSubjectTarget(): AnnotatedTarget { - return $this->getAnnotatedTarget(AttributeType::Service, new ReflectionClass($this->getClass())); - } - - public function testGetServiceDefinitionInstance() { - $this->assertInstanceOf(ServiceDefinition::class, $this->definition); - } - - public function testGetServiceDefinitionType() { - $this->assertSame(objectType($this->getClass()), $this->definition->type()); - } - - public function testServiceIsAbstract() { - $this->assertTrue($this->definition->isAbstract()); - } - - public function testServiceNameIsNull() { - $this->assertNull($this->definition->name()); - } - - public function testServiceIsPrimary() { - $this->assertFalse($this->definition->isPrimary()); - } - - public function testServiceProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() : void { - self::assertInstanceOf(Service::class, $this->definition->attribute()); - } -} diff --git a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/SingleConcreteServiceConverterTest.php b/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/SingleConcreteServiceConverterTest.php deleted file mode 100644 index 2d3a67c9..00000000 --- a/test/Unit/StaticAnalysis/AnnotatedTargetDefinitionConverterTests/SingleConcreteServiceConverterTest.php +++ /dev/null @@ -1,50 +0,0 @@ -fooImplementation()->name(); - } - - protected function getSubjectTarget(): AnnotatedTarget { - return $this->getAnnotatedTarget(AttributeType::Service, reflection: new ReflectionClass($this->getClass())); - } - - public function testGetServiceDefinitionInstance() { - $this->assertInstanceOf(ServiceDefinition::class, $this->definition); - } - - public function testGetServiceDefinitionType() { - $this->assertSame(objectType($this->getClass()), $this->definition->type()); - } - - public function testServiceIsConcrete() { - $this->assertTrue($this->definition->isConcrete()); - } - - public function testServiceNameIsNull() { - $this->assertNull($this->definition->name()); - } - - public function testServiceIsPrimary() { - $this->assertFalse($this->definition->isPrimary()); - } - - public function testServiceProfiles() { - $this->assertSame(['default'], $this->definition->profiles()); - } - - public function testGetAttribute() : void { - self::assertInstanceOf(Service::class, $this->definition->attribute()); - } -} diff --git a/test/Unit/StaticAnalysis/CacheAwareContainerDefinitionAnalyzerTest.php b/test/Unit/StaticAnalysis/CacheAwareContainerDefinitionAnalyzerTest.php index 26b03c3c..2f39d3a4 100644 --- a/test/Unit/StaticAnalysis/CacheAwareContainerDefinitionAnalyzerTest.php +++ b/test/Unit/StaticAnalysis/CacheAwareContainerDefinitionAnalyzerTest.php @@ -6,7 +6,6 @@ use Cspray\AnnotatedContainer\Definition\Cache\ContainerDefinitionCache; use Cspray\AnnotatedContainer\Event\Emitter; use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetContainerDefinitionAnalyzer; -use Cspray\AnnotatedContainer\StaticAnalysis\AnnotatedTargetDefinitionConverter; use Cspray\AnnotatedContainer\StaticAnalysis\CacheAwareContainerDefinitionAnalyzer; use Cspray\AnnotatedContainer\StaticAnalysis\ContainerDefinitionAnalysisOptionsBuilder; use Cspray\AnnotatedContainer\StaticAnalysis\ContainerDefinitionAnalyzer; @@ -24,7 +23,6 @@ protected function setUp(): void { $this->cache = $this->getMockBuilder(ContainerDefinitionCache::class)->getMock(); $this->annotatedTargetContainerDefinitionAnalyzer = new AnnotatedTargetContainerDefinitionAnalyzer( new PhpParserAnnotatedTargetParser(), - new AnnotatedTargetDefinitionConverter(), new Emitter() ); } diff --git a/test/Unit/ThirdPartyFunctionsTest.php b/test/Unit/ThirdPartyFunctionsTest.php index c7e262b9..ebf667f1 100644 --- a/test/Unit/ThirdPartyFunctionsTest.php +++ b/test/Unit/ThirdPartyFunctionsTest.php @@ -2,21 +2,13 @@ namespace Cspray\AnnotatedContainer\Unit; -use Cspray\AnnotatedContainer\Definition\AliasDefinition; -use Cspray\AnnotatedContainer\Definition\InjectDefinition; -use Cspray\AnnotatedContainer\Definition\ServiceDefinition; -use Cspray\AnnotatedContainer\Definition\ServiceDelegateDefinition; -use Cspray\AnnotatedContainer\Definition\ServicePrepareDefinition; -use Cspray\AnnotatedContainer\StaticAnalysis\DefinitionProviderContext; -use Cspray\AnnotatedContainer\Definition\ContainerDefinitionBuilder; use Cspray\AnnotatedContainer\Fixture\Fixtures; use PHPUnit\Framework\TestCase; -use function Cspray\AnnotatedContainer\alias; -use function Cspray\AnnotatedContainer\inject; -use function Cspray\AnnotatedContainer\serviceDelegate; -use function Cspray\AnnotatedContainer\servicePrepare; -use function Cspray\Typiphy\intType; -use function Cspray\AnnotatedContainer\service; +use function Cspray\AnnotatedContainer\Definition\inject; +use function Cspray\AnnotatedContainer\Definition\serviceDelegate; +use function Cspray\AnnotatedContainer\Definition\servicePrepare; +use function Cspray\AnnotatedContainer\Definition\service; +use function Cspray\AnnotatedContainer\Reflection\types; class ThirdPartyFunctionsTest extends TestCase { @@ -63,8 +55,7 @@ public function testSingleConcreteServiceIsPrimary() { } public function testServiceDelegateDefinition() { - $service = Fixtures::delegatedService()->serviceInterface(); - $serviceDelegateDefinition = serviceDelegate($service, Fixtures::delegatedService()->serviceFactory(), 'createService'); + $serviceDelegateDefinition = serviceDelegate(Fixtures::delegatedService()->serviceFactory(), 'createService'); $this->assertSame(Fixtures::delegatedService()->serviceInterface()->name(), $serviceDelegateDefinition->serviceType()->name()); $this->assertSame(Fixtures::delegatedService()->serviceFactory()->name(), $serviceDelegateDefinition->delegateType()->name()); @@ -84,14 +75,14 @@ public function testInjectMethodParam() { Fixtures::injectConstructorServices()->injectFloatService(), '__construct', 'dessert', - intType(), + types()->int(), 42 ); $this->assertSame(Fixtures::injectConstructorServices()->injectFloatService(), $inject->class()); $this->assertSame('__construct', $inject->methodName()); $this->assertSame('dessert', $inject->parameterName()); - $this->assertSame(intType(), $inject->type()); + $this->assertSame(types()->int(), $inject->type()); $this->assertSame(42, $inject->value()); $this->assertSame(['default'], $inject->profiles()); $this->assertNull($inject->storeName()); @@ -102,7 +93,7 @@ public function testInjectMethodParamProfiles() { Fixtures::injectConstructorServices()->injectFloatService(), '__construct', 'dessert', - intType(), + types()->int(), 42, ['foo', 'bar', 'baz'] ); @@ -115,7 +106,7 @@ public function testInjectMethodParamStoreName() { Fixtures::injectConstructorServices()->injectFloatService(), '__construct', 'dessert', - intType(), + types()->int(), 42, from: 'store-name' );