Aggregate Container (FastForward\Container\Tests\AggregateContainer)
- Has returns true for alias and class bindings
- Has returns false for unknown key
- Get returns self for alias and class bindings
- Has returns true if sub container has entry
- Get returns resolved entry from sub container
- Get skips containers throwing not found exception
- Get skips containers throwing standard interfaces
- Get throws when no container can resolve
- Get preserves first construction failure when fallback is exhausted
- Append adds container at the end
- Prepend adds container at the beginning
- Get uses internal cache after first resolution
Aggregate Service Provider (FastForward\Container\Tests\ServiceProvider\AggregateServiceProvider)
- Get factories merges all providers and includes self
- Get extensions merges all providers and composes same key
- Numeric identifiers retain factory precedence extensions and caching with data set "zero"
- Numeric identifiers retain factory precedence extensions and caching with data set "positive"
- Numeric identifiers retain factory precedence extensions and caching with data set "negative"
- Numeric identifiers retain factory precedence extensions and caching with data set "leading zeros"
- Distinct numeric identifiers are not renumbered or introduced
- Get extensions throws if extension is not callable
Alias Factory (FastForward\Container\Tests\Factory\AliasFactory)
- Invoke resolves aliased service from container
- Get returns same instance for same alias
- Get returns new instance for different aliases
Array Service Provider (FastForward\Container\Tests\ServiceProvider\ArrayServiceProvider)
- Implements service provider interface
- Returns given factories
- Returns given extensions
- Returns empty arrays by default
Autowire Container (FastForward\Container\Tests\AutowireContainer)
- Standalone container resolves and shares concrete dependencies with data set "omitted delegate"
- Standalone container resolves and shares concrete dependencies with data set "explicit null delegate"
- Standalone containers have independent instances
- Delegate entries take precedence for direct and nested dependencies
- Get delegates to internal container
- Has returns false when service not present
- Has does not attempt known delegate resolution
- Known class with uninferable arguments keeps its construction error
- Known throwing constructor is only executed by get
- Known factory is only executed by get and preserves its failure
- Known optional cycle keeps its cycle error
- Has returns true when service is resolvable
- Autowire container accepts aggregate container directly
Autowire Optional Dependency (FastForward\Container\Tests\AutowireOptionalDependency)
- Optional concrete dependency is autowired before using null default
Autowiring Exception (FastForward\Container\Tests\Exception\AutowiringException)
- For unresolvable parameter preserves details and cause
- For unresolvable parameter identifies untyped arguments
Callable Factory (FastForward\Container\Tests\Factory\CallableFactory)
- Invoke will return provided callable returns
- Closure receives container dependencies as argument
- Invoke will throw runtime exception if parameter is not a class
- Union parameter receives invalid type diagnostic
- Intersection parameter receives invalid type diagnostic
- Nullable named parameter still resolves dependency
- Dnf parameter receives invalid type diagnostic
- Untyped parameter receives invalid type diagnostic
Container Builder (FastForward\Container\Tests\ContainerBuilder)
- Successive builds resolve services lazily with independent caches
- Later registrations affect only subsequent builds
- Fluent named registrations retain precedence and cross source dependencies
- Supplied containers are reused across builds
- Class string containers are constructed for each build
- Invalid optional configuration keeps prior and later explicit sources
- Unsupported class strings are rejected during build with data set "unknown class"
- Unsupported class strings are rejected during build with data set "unsupported object"
Container Exception (FastForward\Container\Tests\Exception\ContainerException)
- For circular dependency preserves the resolution path with data set "self dependency"
- For circular dependency preserves the resolution path with data set "nested dependency"
- For invalid service will return proper exception
- For invalid service preserves cause with string code
Container Factory (FastForward\Container\Tests\ContainerFactory)
- Successive calls create independent container caches
- Providers retain precedence and resolve through the aggregate
- Accepts class strings and nested configuration providers
- Invalid nested initializer stops expansion and keeps explicit sources
Container Function (FastForward\Container\Tests\ContainerFunction)
- Returns autowire container wrapping aggregate
- Accepts psr container as initializer
- Accepts service provider as initializer
- Accepts config interface as initializer
- Accepts instantiable string
- Throws for unsupported initializer
- Throws for existing unsupported initializer
- Config container with nested initializers
- Container skips throwable thrown by config container
Invalid Argument Exception (FastForward\Container\Tests\Exception\InvalidArgumentException)
- For unsupported initializer returns exception with correct message
- For unsupported initializer with object
- For unsupported initializer with scalar
Invokable Factory (FastForward\Container\Tests\Factory\InvokableFactory)
- Invoke instantiates class without arguments
- Invoke instantiates class with arguments
- Invoke resolves string arguments from container
Method Factory (FastForward\Container\Tests\Factory\MethodFactory)
- Invoke instance method
- Invoke static method
- Invoke resolves arguments from container
- Invoke throws for non public method
- Invoke will construct target if container does not provide
- Constructor dependency is resolved from container
- Invokes configured target through a non class service id
- Resolves an interface binding using its actual object
- Rejects non public methods on a service id target
- Rejects an unknown method on a service id target
- Existing target failures propagate unchanged with data set "container failure"
- Existing target failures propagate unchanged with data set "missing nested dependency"
- Existing target failures propagate unchanged with data set "execution exception"
- Existing target failures propagate unchanged with data set "execution error"
- Retains the cause of a registered factory failure
- Retains not found for a non class service id
- Preserves named method arguments
- Class name bindings use the actual object method with data set "introduced method"
- Class name bindings use the actual object method with data set "widened visibility"
- Resolves abstract static contracts through their configured object
Not Found Exception (FastForward\Container\Tests\Exception\NotFoundException)
- For service i d returns expected message
Production Consumer (FastForward\Container\Tests\Integration\ProductionConsumer)
- Real configuration and providers resolve through independent compositions
Reflection Container (FastForward\Container\Tests\Autowire\ReflectionContainer)
- Registered interface overrides optional default
- Autowired class overrides non null default and is shared
- Explicit concrete entry takes precedence over autowiring
- Registered null overrides non null default
- Missing interface uses declared default
- Unavailable nested graph uses declared default
- Unavailable graph retains its non null default
- Defaults and empty variadics do not infer parameter name bindings
- Unsupported optional types use their defaults
- Unavailable required arguments have actionable errors with data set "scalar"
- Unavailable required arguments have actionable errors with data set "nullable without default"
- Unavailable required arguments have actionable errors with data set "union"
- Unavailable required arguments have actionable errors with data set "intersection"
- Unavailable required arguments have actionable errors with data set "untyped"
- Required nullable argument accepts registered null
- Inherited self type uses constructor declaring class
- Parent type resolves the parent class
- Runtime constructor failure does not use optional default
- Runtime factory failure does not use optional default
- Unavailable default constant is wrapped without poisoning retries
- Unavailable default constant does not trigger an optional fallback
- Failure while constructing a default value preserves its cause
- Wrong registered type is a construction failure
- Optional cycle reports path instead of using default
- Failed resolution does not poison retry or independent services
- Provider factories and native dependencies resolve across sources
- Each builder build has an independent autowiring cache
- Internal has inspects metadata without running constructors
- Internal resolver caches its successful objects
- Internal resolver rejects unknown entries
- Autoloader failures preserve their cause across retries with data set "internal has"
- Autoloader failures preserve their cause across retries with data set "internal get"
- Autoloader failures preserve their cause across retries with data set "composed get"
- Internal optional arguments without reflected defaults are omitted
- Constructor reference arguments have independent storage
Runtime Exception (FastForward\Container\Tests\Exception\RuntimeException)
- For non callable extension returns proper exception
- For non public method returns proper exception
- For invalid parameter type returns proper exception
Service Factory (FastForward\Container\Tests\Factory\ServiceFactory)
- Invoke returns same instance
Service Provider Class Extension (FastForward\Container\Tests\ServiceProviderClassExtension)
- Distinct objects receive their class extension in either order with data set "class first"
- Distinct objects receive their class extension in either order with data set "named first"
- Aliases of the cached class object do not repeat its extension with data set "class first"
- Aliases of the cached class object do not repeat its extension with data set "alias first"
- Aliases of the cached class object do not repeat its extension with data set "nested alias first"
- Aliases reuse objects constructed by class identifier extensions with data set "class first"
- Aliases reuse objects constructed by class identifier extensions with data set "alias first"
- Aliases reuse objects constructed by class identifier extensions with data set "nested alias first"
- Named aliases retain the extended object with data set "class first, mutation"
- Named aliases retain the extended object with data set "named alias first, mutation"
- Named aliases retain the extended object with data set "class first, replacement"
- Named aliases retain the extended object with data set "named alias first, replacement"
- Wrapper backed aliases share their class extension result with data set "none, object"
- Wrapper backed aliases share their class extension result with data set "none, null"
- Wrapper backed aliases share their class extension result with data set "none, scalar"
- Wrapper backed aliases share their class extension result with data set "before, object"
- Wrapper backed aliases share their class extension result with data set "before, null"
- Wrapper backed aliases share their class extension result with data set "before, scalar"
- Wrapper backed aliases share their class extension result with data set "after, object"
- Wrapper backed aliases share their class extension result with data set "after, null"
- Wrapper backed aliases share their class extension result with data set "after, scalar"
- Aliases still apply their individual identifier extensions
- Replaced inputs can be collected while their result remains cached
- Failed class extensions can be retried for the same input
- Different class results can receive their own class extension with data set "class first, mutation"
- Different class results can receive their own class extension with data set "named first, mutation"
- Different class results can receive their own class extension with data set "class first, replacement"
- Different class results can receive their own class extension with data set "named first, replacement"
- Mapped class identifiers still apply the replacement class extension with data set "class first, mutation"
- Mapped class identifiers still apply the replacement class extension with data set "named alias first, mutation"
- Mapped class identifiers still apply the replacement class extension with data set "class first, replacement"
- Mapped class identifiers still apply the replacement class extension with data set "named alias first, replacement"
- Wrapper alias identifier extensions modify the reused result with data set "plain first"
- Wrapper alias identifier extensions modify the reused result with data set "mutating first"
- Wrapper alias identifier extensions modify the reused result with data set "void first"
- Alias identifier extensions receive the latest completed class result
- Extension callbacks reuse previously completed results with data set "id, object"
- Extension callbacks reuse previously completed results with data set "id, null"
- Extension callbacks reuse previously completed results with data set "id, scalar"
- Extension callbacks reuse previously completed results with data set "class, object"
- Extension callbacks reuse previously completed results with data set "class, null"
- Extension callbacks reuse previously completed results with data set "class, scalar"
- Completed result cycles remain bounded without repeating extensions with data set "class first"
- Completed result cycles remain bounded without repeating extensions with data set "named first"
- Distinct object can be replaced after the class entry has been cached
Service Provider Container (FastForward\Container\Tests\ServiceProviderContainer)
- Has returns true for cached service
- Has returns true for existing factory
- Has returns false for unknown id
- Get returns service from factory
- Get applies extension if available
- Get throws not found exception for missing factory
- Get wraps container exception
- Get will return from cache when serice already resolved
- Apply service extension by class name
- Apply service extension by id and class
- Apply service ignores non callable extensions
Service Provider Cycle (FastForward\Container\Tests\ServiceProviderCycle)
- Alias cycles fail before the fixture recursion limit with data set "self alias"
- Alias cycles fail before the fixture recursion limit with data set "two aliases"
- Alias cycles fail before the fixture recursion limit with data set "nested cycle"
- Factory cycles across providers retain the complete wrapper path
- Same identifier can fall back to another provider during construction
- Extension cycle cleanup allows retries and independent services
- Ordinary factory failure does not poison retries
- Repeated missing entries remain not found
- Independent wrappers can resolve the same identifier
- Ordinary aliases share the completed service
- Completed resolution does not retain its wrapper
- Concurrent fibers may resolve the same entry without a false cycle
- Completing one fiber does not erase another fibers cycle path
- The main context is independent of a suspended fiber
- A fiber can retry after a resolution failure
- A fiber may nest independent wrappers with the same identifier
Service Provider Resolution (FastForward\Container\Tests\ServiceProviderResolution)
- Has finds extension only entry without executing it
- Non callable factory does not make an entry discoverable
- Callable extension can provide entry with non callable factory
- Extension creates shared entry from null
- Factory values are shared including null with data set "null"
- Factory values are shared including null with data set "false"
- Factory values are shared including null with data set "zero"
- Factory values are shared including null with data set "float"
- Factory values are shared including null with data set "empty string"
- Factory values are shared including null with data set "string"
- Factory values are shared including null with data set "array"
- Extension values are shared including null with data set "null"
- Extension values are shared including null with data set "false"
- Extension values are shared including null with data set "zero"
- Extension values are shared including null with data set "float"
- Extension values are shared including null with data set "empty string"
- Extension values are shared including null with data set "string"
- Extension values are shared including null with data set "array"
- Extension replaces factory result and caches final class
- Inferred class alias does not override defined factory
- Inferred class alias does not override defined extension
- Extension can replace object with null
- Class extension receives id extension result
- Merged providers apply extensions after factories in registration order
- Composed extension only chain can start at null
- Merged void extension preserves previous value
- Separate providers retain first match precedence
- Helper keeps null extension result present and shared
- Extension receives wrapper container
- Incompatible extension fails with preserved cause
- Extension failure is not cached
- Resolution preserves string coded failure with data set "factory"
- Resolution preserves string coded failure with data set "extension"
- Metadata failure preserves cause with data set "get factory metadata"
- Metadata failure preserves cause with data set "get extension metadata"
- Metadata failure preserves cause with data set "has factory metadata"
- Metadata failure preserves cause with data set "has extension metadata"
Skill Examples (FastForward\Container\Tests\Integration\SkillExamples)
- Example against consumer autoloader with data set "configuration"
- Example against consumer autoloader with data set "composition"
- Example against consumer autoloader with data set "autowiring"
- Example against consumer autoloader with data set "provider corrections"
- Provider metadata failures do not try later sources