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