From 8ba907a14891c31cdcceee4e69a847699598e15d Mon Sep 17 00:00:00 2001 From: Marco Poletti Date: Mon, 31 Jul 2017 23:35:06 +0100 Subject: [PATCH] Deprecate the old Injector and NormalizedComponent constructors and introduce the new Fruit 3.x variants. Also change PartialComponent::install to allow implicit conversions in the arguments (as in Fruit 3.x). --- examples/annotated_injection/main.cpp | 2 +- examples/hello_world/main.cpp | 2 +- examples/multibindings/main.cpp | 2 +- examples/scaling_doubles/main.cpp | 2 +- examples/server/main.cpp | 2 +- examples/server/server.cpp | 20 +- examples/simple_injection/main.cpp | 2 +- examples/simple_injection/main_v1.cpp | 2 +- include/fruit/component.h | 8 +- include/fruit/impl/component.defn.h | 10 +- include/fruit/impl/injector.defn.h | 49 ++++- .../fruit/impl/normalized_component.defn.h | 18 +- include/fruit/injector.h | 41 +++- include/fruit/normalized_component.h | 10 +- tests/test_bind_instance.py | 24 +-- tests/test_bind_interface.py | 10 +- tests/test_binding_clash.py | 24 +-- tests/test_binding_compression.py | 8 +- tests/test_class_destruction.py | 4 +- tests/test_component.py | 8 +- tests/test_dependency_loop.py | 2 +- tests/test_duplicated_types.py | 2 +- tests/test_eager_injection.py | 2 +- tests/test_injected_provider.py | 12 +- tests/test_injector.py | 50 ++++- tests/test_injector_unsafe_get.py | 2 +- tests/test_install.py | 199 +++++++++++++++++- ...est_install_component_swap_optimization.py | 2 +- tests/test_misc.py | 12 +- tests/test_multibindings_bind_instance.py | 4 +- tests/test_multibindings_bind_provider.py | 20 +- tests/test_multibindings_misc.py | 4 +- tests/test_normalized_component.py | 71 +++++-- tests/test_register_constructor.py | 14 +- tests/test_register_factory.py | 76 +++---- tests/test_register_instance.py | 14 +- tests/test_register_provider.py | 12 +- tests/test_required_types.py | 10 +- tests/test_semistatic_map_hash_selection.py | 2 +- tests/test_type_alignment.py | 2 +- tests/test_type_alignment_with_annotation.py | 2 +- 41 files changed, 570 insertions(+), 192 deletions(-) diff --git a/examples/annotated_injection/main.cpp b/examples/annotated_injection/main.cpp index 68c0248d..92e8d15d 100644 --- a/examples/annotated_injection/main.cpp +++ b/examples/annotated_injection/main.cpp @@ -19,7 +19,7 @@ using fruit::Injector; int main() { - Injector injector(getCarComponent()); + Injector injector(getCarComponent); Car* car(injector); car->brake(); diff --git a/examples/hello_world/main.cpp b/examples/hello_world/main.cpp index de1ac91f..5136f5d5 100644 --- a/examples/hello_world/main.cpp +++ b/examples/hello_world/main.cpp @@ -50,7 +50,7 @@ Component getGreeterComponent() { int main() { - Injector injector(getGreeterComponent()); + Injector injector(getGreeterComponent); Greeter* greeter = injector.get(); greeter->greet(); diff --git a/examples/multibindings/main.cpp b/examples/multibindings/main.cpp index b72224fb..845cf9a2 100644 --- a/examples/multibindings/main.cpp +++ b/examples/multibindings/main.cpp @@ -72,7 +72,7 @@ Component<> getListenersComponent() { } int main() { - Injector<> injector(getListenersComponent()); + Injector<> injector(getListenersComponent); std::vector listeners = injector.getMultibindings(); // The order of the returned listeners is unspecified, so the lines in output may have any order. diff --git a/examples/scaling_doubles/main.cpp b/examples/scaling_doubles/main.cpp index 189da5ee..c26e152d 100644 --- a/examples/scaling_doubles/main.cpp +++ b/examples/scaling_doubles/main.cpp @@ -21,7 +21,7 @@ using fruit::Injector; int main() { - Injector injector(getScalerComponent()); + Injector injector(getScalerComponent); ScalerFactory scalerFactory(injector); std::unique_ptr scaler = scalerFactory(12.1); diff --git a/examples/server/main.cpp b/examples/server/main.cpp index 633ab2e6..ba84b188 100644 --- a/examples/server/main.cpp +++ b/examples/server/main.cpp @@ -22,7 +22,7 @@ using namespace fruit; int main() { - Injector injector(getServerComponent()); + Injector injector(getServerComponent); Server* server(injector); server->run(getRequestDispatcherComponent); diff --git a/examples/server/server.cpp b/examples/server/server.cpp index 33f012f8..833acbbb 100644 --- a/examples/server/server.cpp +++ b/examples/server/server.cpp @@ -42,9 +42,9 @@ class ServerImpl : public Server { serverContext.startupTime = getTime(); const NormalizedComponent, RequestDispatcher> requestDispatcherNormalizedComponent( - createComponent() - .install(requestDispatcherComponent) - .bindInstance(serverContext)); + getRequestDispatcherNormalizedComponent, + requestDispatcherComponent, + &serverContext); cerr << "Server started." << endl; @@ -68,7 +68,7 @@ class ServerImpl : public Server { private: static void worker_thread_main(const NormalizedComponent, RequestDispatcher>& requestDispatcherNormalizedComponent, Request request) { - Injector injector(requestDispatcherNormalizedComponent, getRequestComponent(request)); + Injector injector(requestDispatcherNormalizedComponent, getRequestComponent, &request); RequestDispatcher* requestDispatcher(injector); requestDispatcher->handleRequest(); @@ -84,9 +84,17 @@ class ServerImpl : public Server { return result; } - static Component getRequestComponent(Request request) { + static Component getRequestComponent(Request* request) { return createComponent() - .bindInstance(request); + .bindInstance(*request); + } + + static Component, RequestDispatcher> getRequestDispatcherNormalizedComponent( + Component, RequestDispatcher>(*requestDispatcherComponent)(), + ServerContext* server_context) { + return createComponent() + .install(requestDispatcherComponent) + .bindInstance(*server_context); } }; diff --git a/examples/simple_injection/main.cpp b/examples/simple_injection/main.cpp index e366952c..0fa305a6 100644 --- a/examples/simple_injection/main.cpp +++ b/examples/simple_injection/main.cpp @@ -31,7 +31,7 @@ int main(int argc, const char* argv[]) { if (argc == 2 && std::string(argv[1]) == "--checked") checked = true; - Injector injector(getIncrementerComponent(checked)); + Injector injector(getIncrementerComponent, checked); Incrementer* incrementer(injector); int x; diff --git a/examples/simple_injection/main_v1.cpp b/examples/simple_injection/main_v1.cpp index 0c55d6a3..f887dd01 100644 --- a/examples/simple_injection/main_v1.cpp +++ b/examples/simple_injection/main_v1.cpp @@ -25,7 +25,7 @@ using fruit::Injector; // echo 2147483647 | ./incrementer int main() { - Injector injector(getSimpleIncrementerComponent()); + Injector injector(getSimpleIncrementerComponent); Incrementer* incrementer = injector.get(); int x; diff --git a/include/fruit/component.h b/include/fruit/component.h index ee93c4bf..8618ebf1 100644 --- a/include/fruit/component.h +++ b/include/fruit/component.h @@ -400,7 +400,7 @@ class PartialComponent { * * and then, e.g. in main(): * - * Injector(int)>> injector(getMyClassComponent()); + * Injector(int)>> injector(getMyClassComponent); * * std::function(int)> factory(injector); * std::unique_ptr x = factory(42); @@ -510,10 +510,10 @@ class PartialComponent { * As in the example, the template parameters for this method will be inferred by the compiler, it's not necessary to * specify them explicitly. */ - template + template PartialComponent, Bindings...> install( - OtherComponent(*)(Args...), - Args... args) &&; + OtherComponent(*)(FormalArgs...), + Args&&... args) &&; private: template diff --git a/include/fruit/impl/component.defn.h b/include/fruit/impl/component.defn.h index c79279b5..a10440fa 100644 --- a/include/fruit/impl/component.defn.h +++ b/include/fruit/impl/component.defn.h @@ -256,18 +256,18 @@ inline int checkAcceptableComponentInstallArg() { } template -template +template inline PartialComponent, Bindings...> PartialComponent::install( - OtherComponent(*f)(Args...), - Args... args) && { + OtherComponent(*f)(FormalArgs...), + Args&&... args) && { using IntCollector = int[]; - (void)(IntCollector{0, checkAcceptableComponentInstallArg()...}); + (void)(IntCollector{0, checkAcceptableComponentInstallArg()...}); using Op = OpFor>; (void)typename fruit::impl::meta::CheckIfError::type(); - OtherComponent component = f(std::move(args)...); + OtherComponent component = f(std::forward(args)...); storage.install(std::move(component.storage)); return {std::move(storage)}; diff --git a/include/fruit/impl/injector.defn.h b/include/fruit/impl/injector.defn.h index 32dc73a8..446000e3 100644 --- a/include/fruit/impl/injector.defn.h +++ b/include/fruit/impl/injector.defn.h @@ -25,10 +25,23 @@ namespace fruit { template -inline Injector::Injector(Component component) +inline FRUIT_DEPRECATED_DEFINITION(Injector::Injector(Component component)) : storage(new fruit::impl::InjectorStorage(std::move(component.storage), std::initializer_list{fruit::impl::getTypeId

()...})) { -}; +} + +template +template +inline Injector::Injector(Component(*getComponent)(FormalArgs...), Args&&... args) + : storage( + new fruit::impl::InjectorStorage( + std::move( + fruit::Component( + fruit::createComponent().install(getComponent, std::forward(args)...)) + .storage), + std::initializer_list{fruit::impl::getTypeId

()...})) { +} + namespace impl { namespace meta { @@ -75,8 +88,9 @@ struct InjectorImplHelper { template template -inline Injector::Injector(const NormalizedComponent& normalized_component, - Component component) +inline FRUIT_DEPRECATED_DEFINITION( + Injector::Injector(const NormalizedComponent& normalized_component, + Component component)) : storage(new fruit::impl::InjectorStorage(normalized_component.storage, std::move(component.storage), fruit::impl::getTypeIdsForList::Injector(const NormalizedComponent::type(); } +template +template +inline Injector::Injector(const NormalizedComponent& normalized_component, + Component(*getComponent)(FormalArgs...), Args&&... args) + : storage( + new fruit::impl::InjectorStorage( + normalized_component.storage, + std::move( + fruit::Component( + fruit::createComponent().install(getComponent, std::forward(args)...)) + .storage), + fruit::impl::getTypeIdsForList< + fruit::impl::meta::Eval< + fruit::impl::meta::ConcatVectors( + fruit::impl::meta::SetToVector(fruit::impl::meta::GetComponentPs(fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type...))), + fruit::impl::meta::SetToVector(fruit::impl::meta::GetComponentPs(fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type...)))) + >>())) { + + using NormalizedComp = fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type...); + using Comp = fruit::impl::meta::ConstructComponentImpl(fruit::impl::meta::Type...); + // We don't check whether the construction of NormalizedComp or Comp resulted in errors here; if they did, the instantiation + // of NormalizedComponent or Component would have resulted in an error already. + + using E = typename fruit::impl::meta::InjectorImplHelper::template CheckConstructionFromNormalizedComponent::type; + (void)typename fruit::impl::meta::CheckIfError::type(); +} + template template inline Injector::RemoveAnnotations Injector::get() { diff --git a/include/fruit/impl/normalized_component.defn.h b/include/fruit/impl/normalized_component.defn.h index 55a43692..d9047fdf 100644 --- a/include/fruit/impl/normalized_component.defn.h +++ b/include/fruit/impl/normalized_component.defn.h @@ -22,7 +22,8 @@ namespace fruit { template -inline NormalizedComponent::NormalizedComponent(Component&& component) +inline FRUIT_DEPRECATED_DEFINITION( + NormalizedComponent::NormalizedComponent(Component&& component)) : storage(std::move(component.storage), fruit::impl::getTypeIdsForList< typename fruit::impl::meta::Eval::NormalizedComponent(Component& >::Ps)>>()) { } +template +template +inline NormalizedComponent::NormalizedComponent(Component(*getComponent)(FormalArgs...), Args&&... args) + : storage( + std::move( + fruit::Component( + fruit::createComponent().install(getComponent, std::forward(args)...)) + .storage), + fruit::impl::getTypeIdsForList< + typename fruit::impl::meta::Eval...) + >::Ps)>>()) { +} + } // namespace fruit #endif // FRUIT_NORMALIZED_COMPONENT_INLINES_H diff --git a/include/fruit/injector.h b/include/fruit/injector.h index abe6b296..6330656c 100644 --- a/include/fruit/injector.h +++ b/include/fruit/injector.h @@ -34,7 +34,7 @@ namespace fruit { * * Example usage: * - * Injector injector(getFooBarComponent()); + * Injector injector(getFooBarComponent); * Foo* foo = injector.get(); * Bar* bar(injector); // Equivalent to: Bar* bar = injector.get(); */ @@ -58,11 +58,19 @@ class Injector { * * Example usage: * - * Injector injector(getFooBarComponent()); + * Injector injector(getFooBarComponent); * Foo* foo = injector.get(); * Bar* bar(injector); // Equivalent to: Bar* bar = injector.get(); */ - Injector(Component component); + FRUIT_DEPRECATED_DECLARATION(Injector(Component component)); + + /** + * Similar to the previous constructor, but takes a component function and arguments instead. + * This constructor replaces the previous in Fruit 3.x. + * The (formal) argument types have the same constraints as the ones for PartialComponent::install. + */ + template + Injector(Component(*)(FormalArgs...), Args&&... args); /** * Creation of an injector from a normalized component and a component. @@ -100,16 +108,37 @@ class Injector { * } */ template - Injector(const NormalizedComponent& normalized_component, Component component); + FRUIT_DEPRECATED_DECLARATION( + Injector( + const NormalizedComponent& normalized_component, + Component component) + ); + /** + * Similar to the previous constructor, but takes a component function and arguments instead. + * This constructor replaces the previous in Fruit 3.x. + * The (formal) argument types have the same constraints as the ones for PartialComponent::install. + */ + template + Injector(const NormalizedComponent& normalized_component, + Component(*)(FormalArgs...), Args&&... args); + /** * Deleted constructor, to ensure that constructing an Injector from a temporary NormalizedComponent doesn't compile. * The NormalizedComponent must remain valid during the lifetime of any Injector object constructed with it. */ template - Injector(NormalizedComponent&& normalized_component, + Injector(NormalizedComponent&& normalized_component, Component component) = delete; - + + /** + * Deleted constructor, to ensure that constructing an Injector from a temporary NormalizedComponent doesn't compile. + * The NormalizedComponent must remain valid during the lifetime of any Injector object constructed with it. + */ + template + Injector(NormalizedComponent&& normalized_component, + Component(*)(FormalArgs...), Args&&... args) = delete; + /** * Returns an instance of the specified type. For any class C in the Injector's template parameters, the following variations * are allowed: diff --git a/include/fruit/normalized_component.h b/include/fruit/normalized_component.h index cc2bf0e4..c475f8f6 100644 --- a/include/fruit/normalized_component.h +++ b/include/fruit/normalized_component.h @@ -56,7 +56,15 @@ class NormalizedComponent { public: // The Component used as parameter can have (and usually has) unsatisfied requirements, so it's usually of the form // Component, ...>. - NormalizedComponent(Component&& component); + FRUIT_DEPRECATED_DECLARATION(NormalizedComponent(Component&& component)); + + /** + * Similar to the previous constructor, but takes a component function and arguments instead. + * This constructor replaces the previous in Fruit 3.x. + * The (formal) argument types have the same constraints as the ones for PartialComponent::install. + */ + template + NormalizedComponent(Component(*)(FormalArgs...), Args&&... args); NormalizedComponent(NormalizedComponent&&) = default; NormalizedComponent(const NormalizedComponent&) = delete; diff --git a/tests/test_bind_instance.py b/tests/test_bind_instance.py index c61f0658..e98f8402 100755 --- a/tests/test_bind_instance.py +++ b/tests/test_bind_instance.py @@ -41,14 +41,14 @@ def test_success(): } }; - fruit::Component getComponent(X& x) { + fruit::Component getComponent(X* x) { return fruit::createComponent() - .bindInstance(x); + .bindInstance(*x); } int main() { X x(34); - fruit::Injector injector(getComponent(x)); + fruit::Injector injector(getComponent, &x); X& x1 = injector.get(); Assert(&x == &x1); } @@ -65,14 +65,14 @@ def test_success_annotated(): } }; - fruit::Component getComponent(X& x) { + fruit::Component getComponent(X* x) { return fruit::createComponent() - .bindInstance(x); + .bindInstance(*x); } int main() { X x(34); - fruit::Injector injector(getComponent(x)); + fruit::Injector injector(getComponent, &x); X& x1 = injector.get>(); Assert(&x == &x1); } @@ -93,14 +93,14 @@ def test_success_two_explicit_type_arguments(XAnnot, XRefAnnot): } }; - fruit::Component getComponent(X& x) { + fruit::Component getComponent(X* x) { return fruit::createComponent() - .bindInstance(x); + .bindInstance(*x); } int main() { X x(34); - fruit::Injector injector(getComponent(x)); + fruit::Injector injector(getComponent, &x); X& x1 = injector.get(); Assert(&x == &x1); } @@ -124,14 +124,14 @@ def test_bind_instance_to_subclass(BaseAnnot, BasePtrAnnot): } }; - fruit::Component getComponent(Derived& derived) { + fruit::Component getComponent(Derived* derived) { return fruit::createComponent() - .bindInstance(derived); + .bindInstance(*derived); } int main() { Derived derived; - fruit::Injector injector(getComponent(derived)); + fruit::Injector injector(getComponent, &derived); Base* base = injector.get(); base->f(); } diff --git a/tests/test_bind_interface.py b/tests/test_bind_interface.py index 3037b949..265ca7e5 100755 --- a/tests/test_bind_interface.py +++ b/tests/test_bind_interface.py @@ -101,7 +101,7 @@ def test_bound_chain_ok(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); X& x = injector.get(); x.f(); } @@ -135,7 +135,7 @@ def test_bind_factory_no_args(): } int main() { - fruit::Injector> injector(getComponent()); + fruit::Injector> injector(getComponent); Factory xFactory = injector.get>(); std::unique_ptr xPtr = xFactory(); xPtr->foo(); @@ -170,7 +170,7 @@ def test_bind_factory_no_args_invalid_unique_ptr(): } int main() { - fruit::Injector> injector(getComponent()); + fruit::Injector> injector(getComponent); Factory xFactory = injector.get>(); std::unique_ptr xPtr = xFactory(); Assert(xPtr.get() == nullptr); @@ -206,7 +206,7 @@ def test_bind_factory_1_arg(): } int main() { - fruit::Injector> injector(getComponent()); + fruit::Injector> injector(getComponent); Factory xFactory = injector.get>(); std::unique_ptr xPtr = xFactory('w'); xPtr->foo(); @@ -242,7 +242,7 @@ def test_bind_factory_2_arg(): } int main() { - fruit::Injector> injector(getComponent()); + fruit::Injector> injector(getComponent); Factory xFactory = injector.get>(); std::unique_ptr xPtr = xFactory('w', 3.2); xPtr->foo(); diff --git a/tests/test_binding_clash.py b/tests/test_binding_clash.py index 1edd373d..31307d1f 100755 --- a/tests/test_binding_clash.py +++ b/tests/test_binding_clash.py @@ -284,7 +284,7 @@ def test_no_clash_with_different_annotations(binding1_preparation, binding1, bin } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); injector.get(); } @@ -323,7 +323,7 @@ def test_no_clash_with_different_annotations_old_style_install(binding1_preparat } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); injector.get(); } @@ -347,8 +347,8 @@ def test_during_component_merge(XAnnot): } void f() { - fruit::NormalizedComponent nc(getComponent()); - fruit::Injector injector(nc, getComponent()); + fruit::NormalizedComponent nc(getComponent); + fruit::Injector injector(nc, getComponent); (void) injector; } ''' @@ -374,8 +374,8 @@ def test_during_component_merge_with_different_annotation_ok(): } int main() { - fruit::NormalizedComponent nc(getComponent1()); - fruit::Injector injector(nc, getComponent2()); + fruit::NormalizedComponent nc(getComponent1); + fruit::Injector injector(nc, getComponent2); injector.get(); injector.get(); } @@ -406,7 +406,7 @@ def test_bind_instance_and_bind_instance_runtime(XAnnot, XAnnotRegex): } int main() { - fruit::Injector injector(getComponentForInstance()); + fruit::Injector injector(getComponentForInstance); injector.get(); } ''' @@ -429,15 +429,15 @@ def test_bind_instance_and_binding_runtime(XAnnot, XAnnotRegex): .bindInstance(*x); } - fruit::Component getComponentForInstance(X& x) { + fruit::Component getComponentForInstance(X* x) { return fruit::createComponent() - .install(getComponentForInstanceHelper, &x) + .install(getComponentForInstanceHelper, x) .registerConstructor(); } int main() { X x; - fruit::Injector injector(getComponentForInstance(x)); + fruit::Injector injector(getComponentForInstance, &x); injector.get(); } ''' @@ -467,8 +467,8 @@ def test_during_component_merge_consistent_ok(XAnnot): } int main() { - fruit::NormalizedComponent<> normalizedComponent(getRootComponent()); - fruit::Injector injector(normalizedComponent, getComponent()); + fruit::NormalizedComponent<> normalizedComponent(getRootComponent); + fruit::Injector injector(normalizedComponent, getComponent); Assert(X::num_objects_constructed == 0); injector.get(); diff --git a/tests/test_binding_compression.py b/tests/test_binding_compression.py index 53c15737..b8206f3c 100755 --- a/tests/test_binding_compression.py +++ b/tests/test_binding_compression.py @@ -52,7 +52,7 @@ def test_provider_returning_value_success_with_annotation(IAnnot, XAnnot, WithAn } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); Assert((injector.get>() .value == 5)); Assert((injector.get>()->value == 5)); Assert((injector.get>() .value == 5)); @@ -89,7 +89,7 @@ def test_provider_returning_pointer_success_with_annotation(IAnnot, XAnnot, XPtr } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); Assert((injector.get>() .value == 5)); Assert((injector.get>()->value == 5)); Assert((injector.get>() .value == 5)); @@ -139,10 +139,10 @@ def test_compression_undone(): int main() { // Here the binding C2->I1->C1 is compressed into C2->C1. - fruit::NormalizedComponent normalizedComponent(getI2Component()); + fruit::NormalizedComponent normalizedComponent(getI2Component); // However the binding X->C1 prevents binding compression on I1->C1, the binding compression must be undone. - fruit::Injector injector(normalizedComponent, getXComponent()); + fruit::Injector injector(normalizedComponent, getXComponent); Assert(C1::num_objects_constructed == 0); injector.get(); diff --git a/tests/test_class_destruction.py b/tests/test_class_destruction.py index 7e190fbe..f36c83df 100644 --- a/tests/test_class_destruction.py +++ b/tests/test_class_destruction.py @@ -120,7 +120,7 @@ def test_injector_creation_no_injection( } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); (void)injector; } ''' @@ -153,7 +153,7 @@ def test_injector_creation_and_injection( } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); injector.get(); diff --git a/tests/test_component.py b/tests/test_component.py index 8669e3ac..e3aad12a 100755 --- a/tests/test_component.py +++ b/tests/test_component.py @@ -47,7 +47,7 @@ def test_component_conversion(XAnnot, XPtrAnnot): } int main() { - fruit::Injector injector(getXComponent()); + fruit::Injector injector(getXComponent); injector.get(); } ''' @@ -156,7 +156,7 @@ def test_move(XAnnot): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); } ''' @@ -182,7 +182,7 @@ def test_move_partial_component(XAnnot): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); } ''' @@ -279,7 +279,7 @@ def test_multiple_required_types_ok(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); } ''' diff --git a/tests/test_dependency_loop.py b/tests/test_dependency_loop.py index e9bc942a..7ca75f0a 100755 --- a/tests/test_dependency_loop.py +++ b/tests/test_dependency_loop.py @@ -106,7 +106,7 @@ def test_with_different_annotations_ok(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); } ''' diff --git a/tests/test_duplicated_types.py b/tests/test_duplicated_types.py index 00fa808c..58c628b3 100755 --- a/tests/test_duplicated_types.py +++ b/tests/test_duplicated_types.py @@ -60,7 +60,7 @@ def test_component_with_different_annotation_ok(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); injector.get(); } diff --git a/tests/test_eager_injection.py b/tests/test_eager_injection.py index 88887c1e..48120399 100644 --- a/tests/test_eager_injection.py +++ b/tests/test_eager_injection.py @@ -62,7 +62,7 @@ def test_eager_injection(): int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); Assert(!X::constructed); Assert(!Y::constructed); diff --git a/tests/test_injected_provider.py b/tests/test_injected_provider.py index 5bcda485..b5b6aaca 100755 --- a/tests/test_injected_provider.py +++ b/tests/test_injected_provider.py @@ -66,7 +66,7 @@ def test_get_ok(XAnnot, XProviderAnnot): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); fruit::Provider provider = injector.get(); Assert(X::num_objects_constructed == 0); @@ -117,7 +117,7 @@ def test_get_during_injection_ok(): } int main() { - fruit::Injector injector(getZComponent()); + fruit::Injector injector(getZComponent); fruit::Provider provider(injector); // During provider.get(), yProvider.get() is called, and during that xProvider.get() // is called. @@ -184,9 +184,13 @@ def test_lazy_injection_with_annotations(Y_PROVIDER_ANNOT): return fruit::createComponent(); } + fruit::Component<> getEmptyComponent() { + return fruit::createComponent(); + } + int main() { - fruit::NormalizedComponent<> normalizedComponent(fruit::createComponent()); - fruit::Injector injector(normalizedComponent, getComponent()); + fruit::NormalizedComponent<> normalizedComponent(getEmptyComponent); + fruit::Injector injector(normalizedComponent, getComponent); Assert(X::num_objects_constructed == 0); Assert(Y::num_objects_constructed == 0); diff --git a/tests/test_injector.py b/tests/test_injector.py index 0b009ba2..cc1a8942 100755 --- a/tests/test_injector.py +++ b/tests/test_injector.py @@ -35,13 +35,43 @@ def test_empty_injector(): } int main() { - fruit::Injector<> injector(getComponent()); + fruit::Injector<> injector(getComponent); } ''' expect_success( COMMON_DEFINITIONS, source) +def test_empty_injector_old_style_deprecated_error(): + source = ''' + fruit::Component<> getComponent() { + return fruit::createComponent(); + } + + int main() { + fruit::Injector<> injector(getComponent()); + } + ''' + expect_generic_compile_error( + 'deprecation|deprecated', + COMMON_DEFINITIONS, + source) + +def test_empty_injector_old_style_ok(): + source = ''' + fruit::Component<> getComponent() { + return fruit::createComponent(); + } + + int main() { + fruit::Injector<> injector(getComponent()); + } + ''' + expect_success( + COMMON_DEFINITIONS, + source, + ignore_deprecation_warnings=True) + @pytest.mark.parametrize('XAnnot', [ 'X', 'fruit::Annotated', @@ -55,10 +85,14 @@ def test_error_component_with_requirements(XAnnot): fruit::Component> getComponent() { return fruit::createComponent(); } + + fruit::Component<> getEmptyComponent() { + return fruit::createComponent(); + } int main() { - fruit::NormalizedComponent normalizedComponent(fruit::createComponent()); - fruit::Injector injector(normalizedComponent, getComponent()); + fruit::NormalizedComponent<> normalizedComponent(getEmptyComponent); + fruit::Injector injector(normalizedComponent, getComponent); } ''' expect_compile_error( @@ -78,9 +112,13 @@ def test_error_types_not_provided(XAnnot): using Inject = XAnnot(); }; + fruit::Component<> getEmptyComponent() { + return fruit::createComponent(); + } + int main() { - fruit::NormalizedComponent<> normalizedComponent(fruit::createComponent()); - fruit::Injector injector(normalizedComponent, fruit::Component<>(fruit::createComponent())); + fruit::NormalizedComponent<> normalizedComponent(getEmptyComponent); + fruit::Injector injector(normalizedComponent, getEmptyComponent); } ''' expect_compile_error( @@ -180,7 +218,7 @@ def test_error_type_not_provided_with_annotation(XAnnot, YAnnot): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); } ''' diff --git a/tests/test_injector_unsafe_get.py b/tests/test_injector_unsafe_get.py index 701c71aa..c39234f1 100755 --- a/tests/test_injector_unsafe_get.py +++ b/tests/test_injector_unsafe_get.py @@ -53,7 +53,7 @@ def test_success(XAnnot, YAnnot, ZAnnot): } int main() { - fruit::Injector<> injector(getRootComponent()); + fruit::Injector<> injector(getRootComponent); X* x = injector.unsafeGet(); Y* y = injector.unsafeGet(); Z* z = injector.unsafeGet(); diff --git a/tests/test_install.py b/tests/test_install.py index 0ab906bc..283b6a98 100755 --- a/tests/test_install.py +++ b/tests/test_install.py @@ -42,7 +42,7 @@ def test_success(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); X x = injector.get(); Assert(x.n == 5); } @@ -67,7 +67,7 @@ def test_success_old_style(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); X x = injector.get(); Assert(x.n == 5); } @@ -92,7 +92,7 @@ def test_old_style_deprecation_error(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); X x = injector.get(); Assert(x.n == 5); } @@ -128,7 +128,7 @@ def test_with_requirements_success(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); Y y = injector.get(); Assert(y.x.n == 5); } @@ -164,7 +164,7 @@ def test_with_requirements_success_old_style(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); Y y = injector.get(); Assert(y.x.n == 5); } @@ -238,6 +238,7 @@ def test_install_with_args_success(): }; struct Arg { + Arg(int) {} Arg() = default; Arg(const Arg&) = default; Arg(Arg&&) = default; @@ -258,18 +259,18 @@ def test_install_with_args_success(): }; } - fruit::Component getParentComponent(int, std::string, Arg) { + fruit::Component getParentComponent(int, std::string, Arg, Arg) { return fruit::createComponent() .registerProvider([]() { return X(5); }); } fruit::Component getComponent() { return fruit::createComponent() - .install(getParentComponent, 5, std::string("Hello"), Arg{}); + .install(getParentComponent, 5, std::string("Hello"), Arg{}, 15); } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); X x = injector.get(); Assert(x.n == 5); } @@ -314,6 +315,45 @@ def test_install_with_args_error_not_copy_constructible(): COMMON_DEFINITIONS, source) +def test_install_with_args_error_not_copy_constructible_with_conversion(): + source = ''' + struct X { + int n; + X(int n) : n(n) {} + }; + + struct Arg { + Arg(int) {} + Arg() = default; + Arg(const Arg&) = delete; + Arg(Arg&&) = default; + Arg& operator=(const Arg&) = default; + Arg& operator=(Arg&&) = default; + }; + + bool operator==(const Arg&, const Arg&); + + namespace std { + template <> + struct hash { + size_t operator()(const Arg&); + }; + } + + fruit::Component getParentComponent(int, std::string, Arg); + + fruit::Component getComponent() { + return fruit::createComponent() + .install(getParentComponent, 5, std::string("Hello"), 15); + } + ''' + expect_generic_compile_error( + 'error: use of deleted function .Arg::Arg\(const Arg&\).' + + '|error: call to deleted constructor of .Arg.' + + '|error C2280: .Arg::Arg\(const Arg &\).: attempting to reference a deleted function', + COMMON_DEFINITIONS, + source) + def test_install_with_args_error_not_move_assignable(): source = ''' struct Arg { @@ -347,6 +387,40 @@ def test_install_with_args_error_not_move_assignable(): COMMON_DEFINITIONS, source) +def test_install_with_args_error_not_move_assignable_with_conversion(): + source = ''' + struct Arg { + Arg(int) {} + Arg() = default; + Arg(const Arg&) = default; + Arg(Arg&&) = default; + Arg& operator=(const Arg&) = default; + Arg& operator=(Arg&&) = delete; + }; + + bool operator==(const Arg&, const Arg&); + + namespace std { + template <> + struct hash { + size_t operator()(const Arg&); + }; + } + + fruit::Component getParentComponent(int, std::string, Arg); + + fruit::Component getComponent() { + return fruit::createComponent() + .install(getParentComponent, 5, std::string("Hello"), 15); + } + ''' + expect_generic_compile_error( + 'error: use of deleted function .Arg& Arg::operator=\(Arg&&\).' + + '|error: overload resolution selected deleted operator .=.' + + '|error C2280: .Arg &Arg::operator =\(Arg &&\).: attempting to reference a deleted function', + COMMON_DEFINITIONS, + source) + def test_install_with_args_error_not_copy_assignable(): source = ''' struct X { @@ -385,6 +459,45 @@ def test_install_with_args_error_not_copy_assignable(): COMMON_DEFINITIONS, source) +def test_install_with_args_error_not_copy_assignable_with_conversion(): + source = ''' + struct X { + int n; + X(int n) : n(n) {} + }; + + struct Arg { + Arg(int) {} + Arg() = default; + Arg(const Arg&) = default; + Arg(Arg&&) = default; + Arg& operator=(const Arg&) = delete; + Arg& operator=(Arg&&) = default; + }; + + bool operator==(const Arg&, const Arg&); + + namespace std { + template <> + struct hash { + size_t operator()(const Arg&); + }; + } + + fruit::Component getParentComponent(int, std::string, Arg); + + fruit::Component getComponent() { + return fruit::createComponent() + .install(getParentComponent, 5, std::string("Hello"), 15); + } + ''' + expect_generic_compile_error( + 'error: use of deleted function .Arg& Arg::operator=\(const Arg&\).' + + '|error: overload resolution selected deleted operator .=.' + + '|error C2280: .Arg &Arg::operator =\(const Arg &\).: attempting to reference a deleted function', + COMMON_DEFINITIONS, + source) + def test_install_with_args_error_not_equality_comparable(): source = ''' struct X { @@ -421,6 +534,43 @@ def test_install_with_args_error_not_equality_comparable(): COMMON_DEFINITIONS, source) +def test_install_with_args_error_not_equality_comparable_with_conversion(): + source = ''' + struct X { + int n; + X(int n) : n(n) {} + }; + + struct Arg { + Arg(int) {} + Arg() = default; + Arg(const Arg&) = default; + Arg(Arg&&) = default; + Arg& operator=(const Arg&) = default; + Arg& operator=(Arg&&) = default; + }; + + namespace std { + template <> + struct hash { + size_t operator()(const Arg&); + }; + } + + fruit::Component getParentComponent(int, std::string, Arg); + + fruit::Component getComponent() { + return fruit::createComponent() + .install(getParentComponent, 5, std::string("Hello"), 15); + } + ''' + expect_generic_compile_error( + 'error: no match for .operator==. \(operand types are .const Arg. and .const Arg.\)' + + '|error: invalid operands to binary expression \(.const Arg. and .const Arg.\)' + + '|error C2676: binary .==.: .const Arg. does not define this operator', + COMMON_DEFINITIONS, + source) + def test_install_with_args_error_not_hashable(): source = ''' struct Arg { @@ -449,6 +599,35 @@ def test_install_with_args_error_not_hashable(): COMMON_DEFINITIONS, source) +def test_install_with_args_error_not_hashable_with_conversion(): + source = ''' + struct Arg { + Arg(int) {} + Arg() = default; + Arg(const Arg&) = default; + Arg(Arg&&) = default; + Arg& operator=(const Arg&) = default; + Arg& operator=(Arg&&) = default; + }; + + bool operator==(const Arg&, const Arg&); + + fruit::Component getParentComponent(int, std::string, Arg); + + fruit::Component getComponent() { + return fruit::createComponent() + .install(getParentComponent, 5, std::string("Hello"), 15); + } + ''' + expect_generic_compile_error( + 'error: use of deleted function .std::hash::hash\(\).' + + '|error: call to implicitly-deleted default constructor of .std::hash.' + + '|error: invalid use of incomplete type .struct std::hash.' + + '|error: implicit instantiation of undefined template .std::(__1::)?hash.' + + '|error C2338: The C\+\+ Standard doesn.t provide a hash for this type.', + COMMON_DEFINITIONS, + source) + @pytest.mark.parametrize('XAnnot', [ 'X', 'fruit::Annotated', @@ -481,7 +660,7 @@ def test_install_component_functions_different_args_not_deduped(XAnnot): } int main() { - fruit::Injector<> injector(getComponent4()); + fruit::Injector<> injector(getComponent4); // We test multibindings because the effect on other bindings is not user-visible (it only affects // performance). @@ -532,7 +711,7 @@ def test_install_component_functions_different_arguments_loop_not_reported(): } int main() { - fruit::Injector injector(getXComponent()); + fruit::Injector injector(getXComponent); injector.get(); } ''' diff --git a/tests/test_install_component_swap_optimization.py b/tests/test_install_component_swap_optimization.py index 12bd6437..2c7bfd62 100644 --- a/tests/test_install_component_swap_optimization.py +++ b/tests/test_install_component_swap_optimization.py @@ -53,7 +53,7 @@ def test_install_component_swap_optimization(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); return 0; diff --git a/tests/test_misc.py b/tests/test_misc.py index 7dacb0b7..abb69660 100644 --- a/tests/test_misc.py +++ b/tests/test_misc.py @@ -118,12 +118,16 @@ def test_misc(): .install(getParentComponent); } + fruit::Component)>> getAssistedMultiparamExampleComponent() { + return fruit::createComponent(); + } + int main() { fruit::Injector< Interface3, // XFactory, std::function - > oldInjector(getMyComponent()); + > oldInjector(getMyComponent); // The move is completely unnecessary, it's just to check that it works. fruit::Injector< @@ -150,9 +154,7 @@ def test_misc(): } std::cout << "Destroying injector" << std::endl; - fruit::Component)>> assistedMultiparamExampleComponent = - fruit::createComponent(); - fruit::Injector)>> assistedMultiparamExampleInjector(std::move(assistedMultiparamExampleComponent)); + fruit::Injector)>> assistedMultiparamExampleInjector(getAssistedMultiparamExampleComponent ); return 0; } @@ -253,7 +255,7 @@ def test_misc_old_style_install(): Interface3, // XFactory, std::function - > oldInjector(getMyComponent()); + > oldInjector(getMyComponent); // The move is completely unnecessary, it's just to check that it works. fruit::Injector< diff --git a/tests/test_multibindings_bind_instance.py b/tests/test_multibindings_bind_instance.py index d6c1fd47..f3a99d65 100755 --- a/tests/test_multibindings_bind_instance.py +++ b/tests/test_multibindings_bind_instance.py @@ -38,7 +38,7 @@ def test_simple(XAnnot): } int main() { - fruit::Injector<> injector(getComponent()); + fruit::Injector<> injector(getComponent); std::vector multibindings = injector.getMultibindings(); Assert(multibindings.size() == 1); @@ -66,7 +66,7 @@ def test_instance_vector_with_annotation(XAnnot): } int main() { - fruit::Injector<> injector(getComponent()); + fruit::Injector<> injector(getComponent); std::vector multibindings = injector.getMultibindings(); Assert(multibindings.size() == 2); diff --git a/tests/test_multibindings_bind_provider.py b/tests/test_multibindings_bind_provider.py index 468cd8e9..2d826311 100755 --- a/tests/test_multibindings_bind_provider.py +++ b/tests/test_multibindings_bind_provider.py @@ -35,7 +35,7 @@ def test_success_returning_value_implicit_signature(): } int main() { - fruit::Injector<> injector(getComponent()); + fruit::Injector<> injector(getComponent); Assert(X::num_objects_constructed == 0); Assert(injector.getMultibindings().size() == 1); @@ -66,7 +66,7 @@ def test_success_returning_pointer_implicit_signature(): } int main() { - fruit::Injector<> injector(getComponent()); + fruit::Injector<> injector(getComponent); Assert(!X::constructed); Assert(injector.getMultibindings().size() == 1); @@ -97,7 +97,7 @@ def test_success_returning_value(XAnnot): } int main() { - fruit::Injector<> injector(getComponent()); + fruit::Injector<> injector(getComponent); Assert(X::num_objects_constructed == 0); Assert(injector.getMultibindings().size() == 1); @@ -132,7 +132,7 @@ def test_success_returning_pointer(XAnnot, XPtrAnnot): } int main() { - fruit::Injector<> injector(getComponent()); + fruit::Injector<> injector(getComponent); Assert(!X::constructed); Assert(injector.getMultibindings().size() == 1); @@ -159,9 +159,13 @@ def test_success_returning_value_with_normalized_component(XAnnot): .addMultibindingProvider([](){return X();}); } + fruit::Component<> getEmptyComponent() { + return fruit::createComponent(); + } + int main() { - fruit::NormalizedComponent<> normalizedComponent(fruit::createComponent()); - fruit::Injector<> injector(normalizedComponent, getComponent()); + fruit::NormalizedComponent<> normalizedComponent(getEmptyComponent); + fruit::Injector<> injector(normalizedComponent, getComponent); Assert(X::num_objects_constructed == 0); const std::vector& bindings = injector.getMultibindings(); @@ -190,7 +194,7 @@ def test_multiple_providers(XAnnot, XPtrAnnot, intAnnot): } int main() { - fruit::Injector<> injector(getComponent()); + fruit::Injector<> injector(getComponent); std::vector multibindings = injector.getMultibindings(); Assert(multibindings.size() == 2); @@ -278,7 +282,7 @@ def test_provider_returns_nullptr_error(XAnnot, XPtrAnnot, XAnnotRegex): } int main() { - fruit::Injector<> injector(getComponent()); + fruit::Injector<> injector(getComponent); injector.getMultibindings(); } ''' diff --git a/tests/test_multibindings_misc.py b/tests/test_multibindings_misc.py index d6b6d5cf..04e9a9f2 100755 --- a/tests/test_multibindings_misc.py +++ b/tests/test_multibindings_misc.py @@ -33,7 +33,7 @@ def test_get_none(): } int main() { - fruit::Injector<> injector(getComponent()); + fruit::Injector<> injector(getComponent); std::vector multibindings = injector.getMultibindings(); (void) multibindings; @@ -130,7 +130,7 @@ def test_multiple_various_kinds(): } int main() { - fruit::Injector<> injector(getListenersComponent()); + fruit::Injector<> injector(getListenersComponent); std::vector listeners = injector.getMultibindings(); for (Listener* listener : listeners) { listener->notify(); diff --git a/tests/test_normalized_component.py b/tests/test_normalized_component.py index 0f0b9e2d..6a0ec8c6 100755 --- a/tests/test_normalized_component.py +++ b/tests/test_normalized_component.py @@ -44,17 +44,17 @@ def test_success_normalized_component_provides_unused(XAnnot, X_ANNOT, YAnnot): return fruit::createComponent(); } - fruit::Component getXComponent(X& x) { + fruit::Component getXComponent(X* x) { return fruit::createComponent() - .bindInstance(x); + .bindInstance(*x); } int main() { - fruit::NormalizedComponent, YAnnot> normalizedComponent(getComponent()); + fruit::NormalizedComponent, YAnnot> normalizedComponent(getComponent); X x{}; - fruit::Injector injector(normalizedComponent, getXComponent(x)); + fruit::Injector injector(normalizedComponent, getXComponent, &x); injector.get(); } ''' @@ -68,6 +68,41 @@ def test_success_normalized_component_provides_unused(XAnnot, X_ANNOT, YAnnot): ('fruit::Annotated', 'ANNOTATED(Annotation1, X)', 'fruit::Annotated'), ]) def test_success(XAnnot, X_ANNOT, YAnnot): + source = ''' + struct X {}; + + struct Y { + INJECT(Y(X_ANNOT)) {}; + }; + + fruit::Component, YAnnot> getComponent() { + return fruit::createComponent(); + } + + fruit::Component getXComponent(X* x) { + return fruit::createComponent() + .bindInstance(*x); + } + + int main() { + fruit::NormalizedComponent, YAnnot> normalizedComponent(getComponent); + + X x{}; + + fruit::Injector injector(normalizedComponent, getXComponent, &x); + injector.get(); + } + ''' + expect_success( + COMMON_DEFINITIONS, + source, + locals()) + +@pytest.mark.parametrize('XAnnot,X_ANNOT,YAnnot', [ + ('X', 'X', 'Y'), + ('fruit::Annotated', 'ANNOTATED(Annotation1, X)', 'fruit::Annotated'), +]) +def test_success_old_style_deprecated_error(XAnnot, X_ANNOT, YAnnot): source = ''' struct X {}; @@ -93,7 +128,8 @@ def test_success(XAnnot, X_ANNOT, YAnnot): injector.get(); } ''' - expect_success( + expect_generic_compile_error( + 'deprecation|deprecated', COMMON_DEFINITIONS, source, locals()) @@ -102,7 +138,7 @@ def test_success(XAnnot, X_ANNOT, YAnnot): ('X', 'X', 'Y'), ('fruit::Annotated', 'ANNOTATED(Annotation1, X)', 'fruit::Annotated'), ]) -def test_success_inline_component(XAnnot, X_ANNOT, YAnnot): +def test_success_old_style(XAnnot, X_ANNOT, YAnnot): source = ''' struct X {}; @@ -114,20 +150,25 @@ def test_success_inline_component(XAnnot, X_ANNOT, YAnnot): return fruit::createComponent(); } + fruit::Component getXComponent(X& x) { + return fruit::createComponent() + .bindInstance(x); + } + int main() { fruit::NormalizedComponent, YAnnot> normalizedComponent(getComponent()); X x{}; - fruit::Injector injector(normalizedComponent, - fruit::Component(fruit::createComponent().bindInstance(x))); + fruit::Injector injector(normalizedComponent, getXComponent(x)); injector.get(); } ''' expect_success( COMMON_DEFINITIONS, source, - locals()) + locals(), + ignore_deprecation_warnings=True) @pytest.mark.parametrize('XAnnot', [ 'X', @@ -143,9 +184,13 @@ def test_unsatisfied_requirements(XAnnot): return fruit::createComponent(); } + fruit::Component<> getEmptyComponent() { + return fruit::createComponent(); + } + int main() { - fruit::NormalizedComponent> normalizedComponent(getComponent()); - fruit::Injector<> injector(normalizedComponent, fruit::Component<>(fruit::createComponent())); + fruit::NormalizedComponent> normalizedComponent(getComponent); + fruit::Injector<> injector(normalizedComponent, getEmptyComponent); } ''' expect_compile_error( @@ -216,8 +261,8 @@ def test_multiple_required_types_ok(): } int main() { - fruit::NormalizedComponent> normalizedComponent(getEmptyComponent()); - fruit::Injector injector(normalizedComponent, getXYComponent()); + fruit::NormalizedComponent> normalizedComponent(getEmptyComponent); + fruit::Injector injector(normalizedComponent, getXYComponent); injector.get(); } ''' diff --git a/tests/test_register_constructor.py b/tests/test_register_constructor.py index b62ce0f3..e9aa91cc 100755 --- a/tests/test_register_constructor.py +++ b/tests/test_register_constructor.py @@ -42,7 +42,7 @@ def test_success_copyable_and_movable(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); } ''' @@ -63,7 +63,7 @@ def test_success_movable_only(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); } ''' @@ -84,7 +84,7 @@ def test_success_not_movable(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); } ''' @@ -115,9 +115,13 @@ def test_autoinject_with_annotation_success(XAnnot, YAnnot, ZAnnot): return fruit::createComponent(); } + fruit::Component<> getEmptyComponent() { + return fruit::createComponent(); + } + int main() { - fruit::NormalizedComponent<> normalizedComponent(fruit::createComponent()); - fruit::Injector injector(normalizedComponent, getComponent()); + fruit::NormalizedComponent<> normalizedComponent(getEmptyComponent); + fruit::Injector injector(normalizedComponent, getComponent); Assert(Y::num_objects_constructed == 0); injector.get(); diff --git a/tests/test_register_factory.py b/tests/test_register_factory.py index 0eac7adb..f7dcdd59 100755 --- a/tests/test_register_factory.py +++ b/tests/test_register_factory.py @@ -46,7 +46,7 @@ def test_success_no_params_autoinject(XFactoryAnnot): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get()(); } ''' @@ -69,7 +69,7 @@ def test_success_no_params_returning_value(XAnnot, XFactoryAnnot): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get()(); } ''' @@ -92,7 +92,7 @@ def test_success_no_params_returning_pointer(XAnnot, XPtrAnnot, XPtrFactoryAnnot } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get()(); } ''' @@ -129,7 +129,7 @@ def test_autoinject_success(): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory(injector); std::unique_ptr scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; @@ -173,7 +173,7 @@ def test_autoinject(ScalerAnnot, ScalerFactoryAnnot): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory = injector.get(); std::unique_ptr scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; @@ -211,7 +211,7 @@ def test_autoinject_returning_value(): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory(injector); Scaler scaler = scalerFactory(12.1); std::cout << scaler.scale(3) << std::endl; @@ -284,7 +284,7 @@ def test_autoinject_nonmovable_ok(): } int main() { - fruit::Injector injector(getIFactory()); + fruit::Injector injector(getIFactory); IFactory iFactory(injector); std::unique_ptr i = iFactory(); (void)i; @@ -314,7 +314,7 @@ def test_autoinject_2_assisted_params(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); FooFactory fooFactory(injector); Foo foo = fooFactory(1, 2.3f); (void)foo; @@ -344,7 +344,7 @@ def test_autoinject_2_assisted_params_returning_value(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); FooFactory fooFactory(injector); Foo foo = fooFactory(1, 2.3f); (void)foo; @@ -382,7 +382,7 @@ def test_autoinject_instances_bound_to_assisted_params(): int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); FooFactory fooFactory(injector); Foo foo = fooFactory(); (void)foo; @@ -420,7 +420,7 @@ def test_autoinject_2_assisted_params_plus_nonassisted_params(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); FooPtrFactory fooPtrFactory(injector); std::unique_ptr foo = fooPtrFactory(1, 3.4f); (void)foo; @@ -458,7 +458,7 @@ def test_autoinject_2_assisted_params_plus_nonassisted_params_returning_value(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); FooFactory fooFactory(injector); Foo foo = fooFactory(1, 3.4f); (void)foo; @@ -493,7 +493,7 @@ def test_autoinject_mixed_assisted_and_injected_params(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); FooFactory fooFactory(injector); Foo foo = fooFactory(1, 3.4f, 3.456); (void)foo; @@ -572,7 +572,7 @@ def test_autoinject_from_provider(): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory(injector); std::unique_ptr scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; @@ -630,7 +630,7 @@ def test_autoinject_from_provider(ScalerAnnot, ScalerFactoryAnnot, ScalerImplAnn } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory = injector.get(); std::unique_ptr scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; @@ -677,7 +677,7 @@ def test_autoinject_from_provider_returning_value(ScalerFactoryAnnot): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory = injector.get(); Scaler scaler = scalerFactory(12.1); std::cout << scaler.scale(3) << std::endl; @@ -725,7 +725,7 @@ def test_autoinject_with_binding(X_ANNOT): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory(injector); std::unique_ptr scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; @@ -768,7 +768,7 @@ def test_autoinject_with_binding_returning_value(X_ANNOT): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory(injector); Scaler scaler = scalerFactory(12.1); std::cout << scaler.scale(3) << std::endl; @@ -811,7 +811,7 @@ def test_autoinject_with_binding2(): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory(injector); std::unique_ptr scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; @@ -848,7 +848,7 @@ def test_autoinject_with_binding2_returning_value(): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory(injector); Scaler scaler = scalerFactory(12.1); std::cout << scaler.scale(3) << std::endl; @@ -895,7 +895,7 @@ def test_success(ScalerAnnot, ScalerImplAnnot, ScalerFactoryAnnot): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory = injector.get(); std::unique_ptr scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; @@ -934,7 +934,7 @@ def test_with_annotation_returning_value(): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory = injector.get(); Scaler scaler = scalerFactory(12.1); std::cout << scaler.scale(3) << std::endl; @@ -977,7 +977,7 @@ def test_with_different_annotation(): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory = injector.get(); std::unique_ptr scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; @@ -1017,7 +1017,7 @@ def test_with_different_annotation_error(): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory = injector.get(); std::unique_ptr scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; @@ -1063,7 +1063,7 @@ def test_dep_on_provider(): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory(injector); std::unique_ptr scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; @@ -1101,7 +1101,7 @@ def test_dep_on_provider_returning_value(): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory(injector); Scaler scaler = scalerFactory(12.1); std::cout << scaler.scale(3) << std::endl; @@ -1202,7 +1202,7 @@ def test_for_pointer(ScalerAnnot, ScalerImplAnnot, ScalerImplPtrAnnot, ScalerFac } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory = injector.get(); std::unique_ptr scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; @@ -1247,7 +1247,7 @@ def test_for_pointer_returning_value(ScalerPtrAnnot, ScalerFactoryAnnot, ScalerF } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory = injector.get(); Scaler scaler = scalerFactory(12.1); std::cout << scaler.scale(3) << std::endl; @@ -1302,7 +1302,7 @@ def test_for_unique_pointer(ScalerAnnot, ScalerImplAnnot, ScalerImplPtrAnnot, Sc } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory = injector.get(); std::unique_ptr scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; @@ -1346,7 +1346,7 @@ def test_for_unique_pointer_returning_value(ScalerAnnot, ScalerFactoryAnnot): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory = injector.get(); Scaler scaler = scalerFactory(12.1); std::cout << scaler.scale(3) << std::endl; @@ -1390,7 +1390,7 @@ def test_inconsistent_signature(ScalerImplAnnot): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory(injector); std::unique_ptr scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; @@ -1427,7 +1427,7 @@ def test_inconsistent_signature_returning_value(): } int main() { - fruit::Injector injector(getScalerComponent()); + fruit::Injector injector(getScalerComponent); ScalerFactory scalerFactory(injector); Scaler scaler = scalerFactory(12.1); std::cout << scaler.scale(3) << std::endl; @@ -1457,7 +1457,7 @@ def test_nonmovable_ok(): } int main() { - fruit::Injector injector(getCFactory()); + fruit::Injector injector(getCFactory); CFactory cFactory(injector); std::unique_ptr c = cFactory(); (void)c; @@ -1562,7 +1562,7 @@ def test_success_factory_movable_only_implicit(XFactoryAnnot): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get()(); } ''' @@ -1589,7 +1589,7 @@ def test_success_factory_movable_only_explicit_returning_value(XAnnot, XFactoryA } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get()(); } ''' @@ -1616,7 +1616,7 @@ def test_success_factory_movable_only_explicit_returning_pointer(XAnnot, XPtrAnn } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get()(); } ''' @@ -1642,7 +1642,7 @@ def test_success_factory_not_movable_implicit(XPtrFactoryAnnot): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get()(); } ''' @@ -1669,7 +1669,7 @@ def test_success_factory_not_movable_explicit_returning_pointer_with_annotation( } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get()(); } ''' diff --git a/tests/test_register_instance.py b/tests/test_register_instance.py index 83438119..c2dd7f8e 100755 --- a/tests/test_register_instance.py +++ b/tests/test_register_instance.py @@ -33,15 +33,15 @@ def test_success(intAnnot, intPtrAnnot): .bindInstance(*n); } - fruit::Component getComponentForInstance(int& n) { + fruit::Component getComponentForInstance(int* n) { return fruit::createComponent() - .install(getComponentForInstanceHelper, &n) - .bindInstance(n); + .install(getComponentForInstanceHelper, n) + .bindInstance(*n); } int main() { int n = 5; - fruit::Injector injector(getComponentForInstance(n)); + fruit::Injector injector(getComponentForInstance, &n); if (injector.get() != &n) abort(); } @@ -66,10 +66,10 @@ def test_abstract_class_ok(XAnnot): .bindInstance(*x); } - fruit::Component getComponentForInstance(X& x) { + fruit::Component getComponentForInstance(X* x) { return fruit::createComponent() - .install(getComponentForInstanceHelper, &x) - .bindInstance(x); + .install(getComponentForInstanceHelper, x) + .bindInstance(*x); } ''' expect_success( diff --git a/tests/test_register_provider.py b/tests/test_register_provider.py index cbea62b8..5c97ddba 100755 --- a/tests/test_register_provider.py +++ b/tests/test_register_provider.py @@ -45,7 +45,7 @@ def test_success_returning_value(XAnnot, WithAnnot): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); Assert((injector.get>(). value == 5)); Assert((injector.get>()->value == 5)); @@ -79,7 +79,7 @@ def test_success_returning_pointer(XAnnot, WithAnnot): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); Assert((injector.get>(). value == 5)); Assert((injector.get>()->value == 5)); Assert((injector.get>(). value == 5)); @@ -110,7 +110,7 @@ def test_success_not_copyable_returning_value(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); } ''' @@ -132,7 +132,7 @@ def test_success_not_copyable_returning_pointer(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); } ''' @@ -154,7 +154,7 @@ def test_success_not_movable_returning_pointer(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); } ''' @@ -217,7 +217,7 @@ def test_error_returned_nullptr(XAnnot, XPtrAnnot, XAnnotRegex): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); } ''' diff --git a/tests/test_required_types.py b/tests/test_required_types.py index 8ca8a603..ec07dd62 100755 --- a/tests/test_required_types.py +++ b/tests/test_required_types.py @@ -58,7 +58,7 @@ def test_required_success(): .install(getXFactoryComponent); } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); Y* y(injector); y->doStuff(); } @@ -99,7 +99,7 @@ def test_required_success_old_style_install(): .install(getXFactoryComponent()); } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); Y* y(injector); y->doStuff(); } @@ -141,7 +141,7 @@ def test_required_annotated_success(): .install(getXFactoryComponent); } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); Y* y(injector); y->doStuff(); } @@ -171,7 +171,7 @@ def test_required_forward_declared_success(): .install(getXFactoryComponent); } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); Y* y(injector); y->doStuff(); } @@ -218,7 +218,7 @@ def test_required_annotated_forward_declared_success(): .install(getXFactoryComponent); } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); Y* y(injector); y->doStuff(); } diff --git a/tests/test_semistatic_map_hash_selection.py b/tests/test_semistatic_map_hash_selection.py index c97097dc..6bf557ad 100644 --- a/tests/test_semistatic_map_hash_selection.py +++ b/tests/test_semistatic_map_hash_selection.py @@ -44,7 +44,7 @@ def test_semistatic_map_hash_selection(): // The component normalization generates a random hash. By looping 50 times it's very likely that we'll get at // least one hash with too many collisions (and we'll generate another). for (int i = 0; i < 50; i++) { - fruit::NormalizedComponent<> normalizedComponent(getComponent()); + fruit::NormalizedComponent<> normalizedComponent(getComponent); (void) normalizedComponent; } } diff --git a/tests/test_type_alignment.py b/tests/test_type_alignment.py index a47a5fb1..39d8193c 100644 --- a/tests/test_type_alignment.py +++ b/tests/test_type_alignment.py @@ -44,7 +44,7 @@ def test_everything(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get(); injector.get(); diff --git a/tests/test_type_alignment_with_annotation.py b/tests/test_type_alignment_with_annotation.py index 547ade67..c830c4d3 100644 --- a/tests/test_type_alignment_with_annotation.py +++ b/tests/test_type_alignment_with_annotation.py @@ -53,7 +53,7 @@ def test_type_alignment_with_annotation(): } int main() { - fruit::Injector injector(getComponent()); + fruit::Injector injector(getComponent); injector.get>(); injector.get>();