Home | History | Annotate | Download | only in tests
      1 
      2 # Features tested in end-to-end tests
      3 
      4 #### INJECT macro
      5 * **TODO** Typical use-case
      6 * **TODO** With assisted params
      7 * **TODO** Check what happens with non-normalized types (all kinds)
      8 
      9 #### Binding to an instance
     10 * Using `bind(x)` or `bind<fruit::Annotated<A, T>>(x)`.
     11 * Check that calling bindInstance with a non-normalized type (e.g. const pointer, nonconst ptr, etc.) causes an error
     12 * Abstract class (ok)
     13 * Mismatched type arguments
     14 * Bind to subclass
     15 
     16 #### Interface bindings
     17 * Check that bind<T, T> causes an easy-to-understand error
     18 * bind<T, Annotated<A, T>>
     19 * Check that bind<X, Y>, bind<Y, Z> is allowed if Z derives from Y and Y derives from X
     20 * bind<X, Y> with X not a base class of Y
     21 * Check that the types passed to bind<> are normalized
     22 * Check that bind<I, C> also means bind<std::function<std::unique_ptr<I>(Args...)>, std::function<std::unique_ptr<C>(Args...)>> (with and without Args)  
     23 
     24 ##### Binding to a constructor
     25 * Explicitly, with a non-signature (not ok)
     26 * Implicitly, with a non-signature (not ok)
     27 * Implicitly, with a signature "returning" another type (not ok)
     28 * Implicitly, with a signature "returning" an annotated type (not ok)
     29 * Explicitly, with a signature that doesn't match any of the type's constructors
     30 * Implicitly, with a signature that doesn't match any of the type's constructors
     31 * **TODO** Using the Inject typedef
     32 * **TODO** Using the INJECT macro
     33 * **TODO** Also with no params
     34 * **TODO** Also for a templated class
     35 * **TODO** Also for a templated constructor (only explicitly or using Inject)
     36 * **TODO** With all kinds of non-normalized params (esp. with INJECT)
     37 * **TODO** With a constructor mistakenly taking an Assisted<X> or Annotated<A,X> parameter (instead of just using Assisted/Annotated in the Inject typedef)
     38 * For an abstract type (not ok), both implicit and explicit
     39 * **TODO** Check that a default-constructible type without an Inject typedef can't be auto-injected
     40 
     41 ##### Binding to a provider
     42 * Returning a value
     43 * **TODO: ownership check** Returning a pointer (also check that Fruit takes ownership)
     44 * Check that lambdas with captures are forbidden
     45 * **TODO** Check that non-lambda functors/functions are forbidden
     46 * **TODO** Check that objects without operator() are forbidden
     47 * Passing a non-signature type
     48 * **TODO** Passing a signature type incompatible with the lambda's signature
     49 * **TODO** With a lambda mistakenly taking an Assisted<X> or Annotated<A,X> parameter (instead of just using Assisted/Annotated in the Inject typedef)
     50 * **TODO** For an abstract type (ok)
     51 * With a provider that returns nullptr (runtime error)
     52 
     53 #### Factory bindings
     54 * Explicit, using `registerFactory()`
     55 * Implicitly, with a signature "returning" an annotated type (not ok)
     56 * **TODO** Explicit, using `registerFactory()`, but passing a non-signature
     57 * Explicit, using `registerFactory()`, but with a lambda that has a different signature compared to the one given explicitly
     58 * Implicitly, with a signature that doesn't match any of the type's constructors
     59 * Check that lambdas with captures are forbidden in `registerFactory()`
     60 * **TODO** Check that non-lambda functors/functions are forbidden in `registerFactory()`
     61 * **TODO** Check that objects without operator() are forbidden in `registerFactory()`
     62 * Using the INJECT macro
     63 * With some assisted params and some injected params
     64 * **TODO** With no assisted params but some injected params
     65 * With some assisted params but no injected params
     66 * **TODO** With no assisted params and no injected params
     67 * **TODO** Using the factory in another class' constructor instead of getting it from the injector directly
     68 * **TODO** With a lambda mistakenly taking a Assisted<X>/Annotated<A,X> parameter (instead of just using Assisted/Annotated in the Inject typedef)
     69 * Explicit, for an abstract type (ok)
     70 * Implicit, for an abstract class (not ok)
     71 * Explicit, with a lambda returning a pointer (not supported)
     72 * Explicit, with a lambda returning a unique ptr (ok)
     73 * **TODO** With assisted params of all kinds of non-normalized types (especially in ASSISTED)
     74 * Implicitly, registering a `std::function<T(...)>` instead of a `std::function<std::unique_ptr<T>(...)>`  
     75 * Explicitly, registering a `std::function<T(...)>` instead of a `std::function<std::unique_ptr<T>(...)>`
     76 * Implicitly, generating a binding for std::function<T()> when there is a binding for T
     77 * Implicitly, generating a binding for std::function<std::unique_ptr<T>()> when there is a binding for T
     78 * **TODO** Check that assisted params are passed in the right order when there are multiple
     79 * **TODO** Try calling the factory multiple times
     80 * Injecting a std::function<std::unique_ptr<T>(...)> with T not movable
     81 
     82 #### Annotated bindings
     83 * **TODO** Using `fruit::Annotated<>`
     84 * **TODO** Using the ANNOTATED macro (only in constructors using INJECT)
     85 * **TODO** Check possibly-misleading behavior of binding Annotated<A1, I> and Annotated<A2, I> to C (only 1 C instance is created and shared)  
     86 * **TODO** With assisted params of all kinds of non-normalized types (especially in ANNOTATED)
     87 
     88 #### Multibindings
     89 * Interface multibindings
     90 * **TODO** Check that addMultibinding<I, I> causes an easy-to-understand error
     91 * Instance multibindings
     92 * **TODO** Check that calling addInstanceMultibinding with a non-normalized type (e.g. const pointer, nonconst ptr, etc.) causes an error
     93 * **TODO** `addInstanceMultibindings(x)`, `addInstanceMultibindings<T>(x)` and `addInstanceMultibindings<Annotated<A, T>>(x)`
     94 * **TODO** `addInstanceMultibindings()` with an empty vector
     95 * **TODO** Check that calling `addInstanceMultibindings()` with a non-normalized type causes an error
     96 * `addMultibindingProvider`:
     97   * Returning a value
     98   * **TODO: ownership check** Returning a pointer (also check that Fruit takes ownership)
     99   * Check that lambdas with captures are forbidden
    100   * **TODO** Check that non-lambda functors/functions are forbidden
    101   * **TODO** Check that objects without operator() are forbidden
    102   * Passing a non-signature type
    103   * **TODO** Passing a signature type incompatible with the lambda's signature
    104   * **TODO** With a lambda mistakenly taking an Assisted<X> or Annotated<A,X> parameter (instead of just using Assisted/Annotated in the Inject typedef)
    105   * For an abstract type (not ok)
    106   * With a provider that returns nullptr (runtime error)
    107 
    108 #### PartialComponent and Component
    109 * copy a Component
    110 * move a Component
    111 * move a PartialComponent
    112 * construction of a Component from another Component
    113 * construction of a Component from a PartialComponent
    114 * install() (old and new style)
    115 * Type already bound (various combinations, incl. binding+install)
    116 * No binding found for abstract class
    117 * Dependency loops
    118 * Run-time error for multiple inconsistent bindings in different components
    119 * Class-level static_asserts in Component
    120   * Check that there are no repeated types
    121   * Check that no type is both in Required<> and outside
    122   * Check that all types are normalized
    123   * Check that Required only appears once
    124   * Check that Required only appears as first parameter (if at all)
    125 
    126 #### Normalized components
    127 * Constructing an injector from NC + C
    128 * **TODO** Constructing an injector from NC + C with empty NC or empty C
    129 * With requirements
    130 * Class-level static_asserts
    131   * Check that there are no repeated types
    132   * Check that no type is both in Required<> and outside
    133   * **TODO** Check that all types are normalized
    134   * Check that Required only appears once
    135   * Check that Required only appears as first parameter (if at all)
    136 
    137 #### Components with requirements
    138 * Usual case (where the required type is only forward-declared, with no definition available)
    139 * Usual case (where the required type is defined but it's an abstract class)
    140 * **TODO** Check that requirements aren't allowed in injectors
    141 * Check that multiple Required<...> params are not allowed
    142 * Check that the Required<...> param is only allowed if it's the 1st 
    143 * **TODO** Check that an empty Required<...> param is allowed 
    144 
    145 #### Injectors
    146 * **TODO** `std::move()`-ing an injector
    147 * Getting instances from an Injector:
    148   * **TODO** Using `get<T>` (for all type variations)
    149   * **TODO** Using `get()` or casting to try to get a value that the injector doesn't provide
    150   * **TODO** Casting the injector to the desired type
    151 * Getting multibindings from an Injector
    152   * for a type that has no multibindings
    153   * for a type that has 1 multibinding
    154   * for a type that has >1 multibindings
    155 * **TODO** Eager injection
    156 * **TODO** Check that the component (in the constructor from C) has no requirements
    157 * **TODO** Check that the resulting component (in the constructor from C+NC) has no requirements
    158 * **TODO: partial** Empty injector (construct, get multibindings, eager injection, etc.)
    159 * **TODO** Injector with a single instance type bound and nothing else
    160 * **TODO** Injector with a single bindProvider and nothing else
    161 * **TODO** Injector with a single multibinding and nothing else
    162 * **TODO** Injector with a single factory and nothing else
    163 * Injector<T> where the C doesn't provide T
    164 * Injector<T> where the C+NC don't provide T
    165 * Class-level static_asserts
    166   * Check that there are no repeated types
    167   * Check that all types are normalized
    168   * Check that there are no Required types
    169 
    170 #### Injecting Provider<>s
    171 * **TODO** In constructors
    172 * Getting a Provider<> from an injector using get<> or casting the injector)
    173 * **TODO** Getting a Provider<> from an injector by casting the injector
    174 * In a constructor and calling get() before the constructor completes
    175 * **TODO** casting a Provider to the desired value instead of calling `get()`
    176 * **TODO** Calling either `get<T>()` or `get()` on the Provider
    177 * **TODO** Check that a Provider's type argument is normalized and not annotated
    178 * Copying a Provider and using the copy
    179 * Using `get()` to try to get a value that the provider doesn't provide
    180 * Class-level static_asserts
    181   * Check that the type is normalized
    182   * Check that the type is not annotated
    183