Features tested in end-to-end tests
INJECT macro
- TODO Typical use-case
- TODO With assisted params
- TODO Check what happens with non-normalized types (all kinds)
Binding to an instance
- Using
bind(x)
or bind<fruit::Annotated<A, T>>(x)
. - Check that calling bindInstance with a non-normalized type (e.g. const pointer, nonconst ptr, etc.) causes an error
- Abstract class (ok)
- Mismatched type arguments
- Bind to subclass
Interface bindings
- Check that bind<T, T> causes an easy-to-understand error
- bind<T, Annotated<A, T>>
- Check that bind<X, Y>, bind<Y, Z> is allowed if Z derives from Y and Y derives from X
- bind<X, Y> with X not a base class of Y
- Check that the types passed to bind<> are normalized
- Check that bind<I, C> also means bind<std::function<std::unique_ptr(Args...)>, std::function<std::unique_ptr(Args...)>> (with and without Args)
Binding to a constructor
- Explicitly, with a non-signature (not ok)
- Implicitly, with a non-signature (not ok)
- Implicitly, with a signature “returning” another type (not ok)
- Implicitly, with a signature “returning” an annotated type (not ok)
- Explicitly, with a signature that doesn‘t match any of the type’s constructors
- Implicitly, with a signature that doesn‘t match any of the type’s constructors
- TODO Using the Inject typedef
- TODO Using the INJECT macro
- TODO Also with no params
- TODO Also for a templated class
- TODO Also for a templated constructor (only explicitly or using Inject)
- TODO With all kinds of non-normalized params (esp. with INJECT)
- TODO With a constructor mistakenly taking an Assisted or Annotated<A,X> parameter (instead of just using Assisted/Annotated in the Inject typedef)
- For an abstract type (not ok), both implicit and explicit
- TODO Check that a default-constructible type without an Inject typedef can't be auto-injected
Binding to a provider
- Returning a value
- TODO: ownership check Returning a pointer (also check that Fruit takes ownership)
- Check that lambdas with captures are forbidden
- TODO Check that non-lambda functors/functions are forbidden
- TODO Check that objects without operator() are forbidden
- Passing a non-signature type
- TODO Passing a signature type incompatible with the lambda's signature
- TODO With a lambda mistakenly taking an Assisted or Annotated<A,X> parameter (instead of just using Assisted/Annotated in the Inject typedef)
- TODO For an abstract type (ok)
- With a provider that returns nullptr (runtime error)
Factory bindings
- Explicit, using
registerFactory()
- Implicitly, with a signature “returning” an annotated type (not ok)
- TODO Explicit, using
registerFactory()
, but passing a non-signature - Explicit, using
registerFactory()
, but with a lambda that has a different signature compared to the one given explicitly - Implicitly, with a signature that doesn‘t match any of the type’s constructors
- Check that lambdas with captures are forbidden in
registerFactory()
- TODO Check that non-lambda functors/functions are forbidden in
registerFactory()
- TODO Check that objects without operator() are forbidden in
registerFactory()
- Using the INJECT macro
- With some assisted params and some injected params
- TODO With no assisted params but some injected params
- With some assisted params but no injected params
- TODO With no assisted params and no injected params
- TODO Using the factory in another class' constructor instead of getting it from the injector directly
- TODO With a lambda mistakenly taking a Assisted/Annotated<A,X> parameter (instead of just using Assisted/Annotated in the Inject typedef)
- Explicit, for an abstract type (ok)
- Implicit, for an abstract class (not ok)
- Explicit, with a lambda returning a pointer (not supported)
- Explicit, with a lambda returning a unique ptr (ok)
- TODO With assisted params of all kinds of non-normalized types (especially in ASSISTED)
- Implicitly, registering a
std::function<T(...)>
instead of a std::function<std::unique_ptr<T>(...)>
- Explicitly, registering a
std::function<T(...)>
instead of a std::function<std::unique_ptr<T>(...)>
- Implicitly, generating a binding for std::function<T()> when there is a binding for T
- Implicitly, generating a binding for std::function<std::unique_ptr()> when there is a binding for T
- TODO Check that assisted params are passed in the right order when there are multiple
- TODO Try calling the factory multiple times
- Injecting a std::function<std::unique_ptr(...)> with T not movable
Annotated bindings
- TODO Using
fruit::Annotated<>
- TODO Using the ANNOTATED macro (only in constructors using INJECT)
- TODO Check possibly-misleading behavior of binding Annotated<A1, I> and Annotated<A2, I> to C (only 1 C instance is created and shared)
- TODO With assisted params of all kinds of non-normalized types (especially in ANNOTATED)
Multibindings
- Interface multibindings
- TODO Check that addMultibinding<I, I> causes an easy-to-understand error
- Instance multibindings
- TODO Check that calling addInstanceMultibinding with a non-normalized type (e.g. const pointer, nonconst ptr, etc.) causes an error
- TODO
addInstanceMultibindings(x)
, addInstanceMultibindings<T>(x)
and addInstanceMultibindings<Annotated<A, T>>(x)
- TODO
addInstanceMultibindings()
with an empty vector - TODO Check that calling
addInstanceMultibindings()
with a non-normalized type causes an error addMultibindingProvider
:- Returning a value
- TODO: ownership check Returning a pointer (also check that Fruit takes ownership)
- Check that lambdas with captures are forbidden
- TODO Check that non-lambda functors/functions are forbidden
- TODO Check that objects without operator() are forbidden
- Passing a non-signature type
- TODO Passing a signature type incompatible with the lambda's signature
- TODO With a lambda mistakenly taking an Assisted or Annotated<A,X> parameter (instead of just using Assisted/Annotated in the Inject typedef)
- For an abstract type (not ok)
- With a provider that returns nullptr (runtime error)
PartialComponent and Component
- copy a Component
- move a Component
- move a PartialComponent
- construction of a Component from another Component
- construction of a Component from a PartialComponent
- install() (old and new style)
- Type already bound (various combinations, incl. binding+install)
- No binding found for abstract class
- Dependency loops
- Run-time error for multiple inconsistent bindings in different components
- Class-level static_asserts in Component
- Check that there are no repeated types
- Check that no type is both in Required<> and outside
- Check that all types are normalized
- Check that Required only appears once
- Check that Required only appears as first parameter (if at all)
Normalized components
- Constructing an injector from NC + C
- TODO Constructing an injector from NC + C with empty NC or empty C
- With requirements
- Class-level static_asserts
- Check that there are no repeated types
- Check that no type is both in Required<> and outside
- TODO Check that all types are normalized
- Check that Required only appears once
- Check that Required only appears as first parameter (if at all)
Components with requirements
- Usual case (where the required type is only forward-declared, with no definition available)
- Usual case (where the required type is defined but it's an abstract class)
- TODO Check that requirements aren't allowed in injectors
- Check that multiple Required<...> params are not allowed
- Check that the Required<...> param is only allowed if it's the 1st
- TODO Check that an empty Required<...> param is allowed
Injectors
- TODO
std::move()
-ing an injector - Getting instances from an Injector:
- TODO Using
get<T>
(for all type variations) - TODO Using
get()
or casting to try to get a value that the injector doesn't provide - TODO Casting the injector to the desired type
- Getting multibindings from an Injector
- for a type that has no multibindings
- for a type that has 1 multibinding
- for a type that has >1 multibindings
- TODO Eager injection
- TODO Check that the component (in the constructor from C) has no requirements
- TODO Check that the resulting component (in the constructor from C+NC) has no requirements
- TODO: partial Empty injector (construct, get multibindings, eager injection, etc.)
- TODO Injector with a single instance type bound and nothing else
- TODO Injector with a single bindProvider and nothing else
- TODO Injector with a single multibinding and nothing else
- TODO Injector with a single factory and nothing else
- Injector where the C doesn't provide T
- Injector where the C+NC don't provide T
- Class-level static_asserts
- Check that there are no repeated types
- Check that all types are normalized
- Check that there are no Required types
Injecting Provider<>s
- TODO In constructors
- Getting a Provider<> from an injector using get<> or casting the injector)
- TODO Getting a Provider<> from an injector by casting the injector
- In a constructor and calling get() before the constructor completes
- TODO casting a Provider to the desired value instead of calling
get()
- TODO Calling either
get<T>()
or get()
on the Provider - TODO Check that a Provider's type argument is normalized and not annotated
- Copying a Provider and using the copy
- Using
get()
to try to get a value that the provider doesn't provide - Class-level static_asserts
- Check that the type is normalized
- Check that the type is not annotated