HELLO·Android
系统源代码
IT资讯
技术文章
我的收藏
注册
登录
-
我收藏的文章
创建代码块
我的代码块
我的账号
Android 10
|
10.0.0_r6
下载
查看原文件
收藏
根目录
external
google-fruit
tests
test_register_factory.py
#!/usr/bin/env python3 # Copyright 2016 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS-IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import pytest from fruit_test_common import * from fruit_test_config import CXX_COMPILER_NAME COMMON_DEFINITIONS = ''' #include "test_common.h" struct Scaler; struct ScalerImpl; struct Annotation1 {}; using ScalerAnnot1 = fruit::Annotated
; using ScalerImplAnnot1 = fruit::Annotated
; struct Annotation2 {}; using ScalerAnnot2 = fruit::Annotated
; using ScalerImplAnnot2 = fruit::Annotated
; template
using WithNoAnnotation = T; template
using WithAnnotation1 = fruit::Annotated
; ''' @pytest.mark.parametrize('XFactoryAnnot', [ 'std::function
', 'fruit::Annotated
>', ]) def test_register_factory_success_no_params_autoinject(XFactoryAnnot): source = ''' struct X { INJECT(X()) = default; }; fruit::Component
getComponent() { return fruit::createComponent(); } int main() { fruit::Injector
injector(getComponent); injector.get
()(); } ''' expect_success( COMMON_DEFINITIONS, source, locals()) @pytest.mark.parametrize('ConstructX,XPtrAnnot,XPtrFactoryAnnot', [ ('X()', 'X', 'std::function
'), ('X()', 'fruit::Annotated
', 'fruit::Annotated
>'), ('std::unique_ptr
()', 'std::unique_ptr
', 'std::function
()>'), ('std::unique_ptr
()', 'fruit::Annotated
>', 'fruit::Annotated
()>>'), ]) def test_register_factory_success_no_params(ConstructX, XPtrAnnot, XPtrFactoryAnnot): source = ''' struct X {}; fruit::Component
getComponent() { return fruit::createComponent() .registerFactory
([](){return ConstructX;}); } int main() { fruit::Injector
injector(getComponent); injector.get
()(); } ''' expect_success( COMMON_DEFINITIONS, source, locals()) @pytest.mark.parametrize('MaybeConst', [ '', 'const', ]) def test_register_factory_autoinject_success(MaybeConst): source = ''' struct Scaler { virtual double scale(double x) = 0; virtual ~Scaler() = default; }; struct ScalerImpl : public Scaler { private: double factor; public: INJECT(ScalerImpl(ASSISTED(double) factor)) : factor(factor) { } double scale(double x) override { return x * factor; } }; using ScalerFactory = std::function
(double)>; fruit::Component
getScalerComponent() { return fruit::createComponent() .bind
(); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory(injector); std::unique_ptr
scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source, locals()) def test_register_factory_autoinject_abstract_class_with_no_virtual_destructor_error(): source = ''' struct Scaler { virtual double scale(double x) = 0; }; struct ScalerImpl : public Scaler { public: INJECT(ScalerImpl(ASSISTED(double))) { } double scale(double x) override { return x; } }; using ScalerFactory = std::function
(double)>; fruit::Component
getScalerComponent() { return fruit::createComponent() .bind
(); } ''' expect_compile_error( 'FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorError
)?>\(double\)>,std::function
)?>\(double\)>>', 'Fruit was trying to bind BaseFactory to DerivedFactory but the return type of BaseFactory is a std::unique_ptr of a class with no virtual destructor', COMMON_DEFINITIONS, source, locals()) def test_register_factory_autoinject_non_abstract_class_with_no_virtual_destructor_error(): source = ''' struct Scaler { }; struct ScalerImpl : public Scaler { public: INJECT(ScalerImpl(ASSISTED(double))) { } }; using ScalerFactory = std::function
(double)>; fruit::Component
getScalerComponent() { return fruit::createComponent() .bind
(); } ''' expect_compile_error( 'FactoryBindingForUniquePtrOfClassWithNoVirtualDestructorError
)?>\(double\)>,std::function
)?>\(double\)>>', 'Fruit was trying to bind BaseFactory to DerivedFactory but the return type of BaseFactory is a std::unique_ptr of a class with no virtual destructor', COMMON_DEFINITIONS, source, locals()) @pytest.mark.parametrize('ScalerAnnot,ScalerFactoryAnnot,MaybeConstScalerFactoryAnnot', [ ('Scaler', 'std::function
(double)>', 'std::function
(double)>'), ('Scaler', 'std::function
(double)>', 'const std::function
(double)>'), ('fruit::Annotated
', 'fruit::Annotated
(double)>>', 'fruit::Annotated
(double)>>'), ('fruit::Annotated
', 'fruit::Annotated
(double)>>', 'fruit::Annotated
(double)>>'), ]) def test_autoinject(ScalerAnnot, ScalerFactoryAnnot, MaybeConstScalerFactoryAnnot): source = ''' struct Scaler { virtual double scale(double x) = 0; virtual ~Scaler() = default; }; struct ScalerImpl : public Scaler { private: double factor; public: INJECT(ScalerImpl(ASSISTED(double) factor)) : factor(factor) { } double scale(double x) override { return x * factor; } }; using ScalerFactory = std::function
(double)>; fruit::Component
getScalerComponent() { return fruit::createComponent() .bind
(); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory = injector.get
(); std::unique_ptr
scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source, locals()) @pytest.mark.parametrize('MaybeConst', [ '', 'const', ]) def test_autoinject_returning_value(MaybeConst): source = ''' struct X { INJECT(X()) = default; }; struct Scaler { private: double factor; public: INJECT(Scaler(ASSISTED(double) factor, X)) : factor(factor) { } double scale(double x) { return x * factor; } }; using ScalerFactory = std::function
; fruit::Component
getScalerComponent() { return fruit::createComponent(); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory(injector); Scaler scaler = scalerFactory(12.1); std::cout << scaler.scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source, locals()) @pytest.mark.parametrize('ScalerAnnot,ScalerImplAnnot,ScalerFactoryAnnot,ScalerImplFactoryAnnotRegex', [ ('Scaler', 'ScalerImpl', 'std::function
(double)>', 'std::function
)?>\(double\)>', ), ('fruit::Annotated
', 'fruit::Annotated
', 'fruit::Annotated
(double)>>', 'fruit::Annotated
)?>\(double\)>>', ), ]) def test_autoinject_error_abstract_class(ScalerAnnot, ScalerImplAnnot, ScalerFactoryAnnot, ScalerImplFactoryAnnotRegex): source = ''' struct Scaler { virtual double scale(double x) = 0; }; struct ScalerImpl : public Scaler { private: double factor; public: ScalerImpl(double factor) : factor(factor) { } // Note: here we "forgot" to implement scale() (on purpose, for this test) so ScalerImpl is an abstract class. }; fruit::Component
getScalerComponent() { return fruit::createComponent() .bind
(); } ''' expect_compile_error( 'NoBindingFoundForAbstractClassError
', 'No explicit binding was found for T, and note that C is an abstract class', COMMON_DEFINITIONS, source, locals()) def test_autoinject_nonmovable_ok(): source = ''' struct I { virtual ~I() = default; }; struct C : public I { INJECT(C()) = default; C(const C&) = delete; C(C&&) = delete; C& operator=(const C&) = delete; C& operator=(C&&) = delete; }; using IFactory = std::function
()>; fruit::Component
getIFactory() { return fruit::createComponent() .bind
(); } int main() { fruit::Injector
injector(getIFactory); IFactory iFactory(injector); std::unique_ptr
i = iFactory(); (void)i; } ''' expect_success( COMMON_DEFINITIONS, source) def test_autoinject_2_assisted_params(): source = ''' struct Foo { Foo(int x, float y) { (void)x; (void)y; } }; using FooFactory = std::function
; fruit::Component
getComponent() { return fruit::createComponent() .registerFactory
, fruit::Assisted
)>( [](int x, float y) { return Foo(x, y); }); } int main() { fruit::Injector
injector(getComponent); FooFactory fooFactory(injector); Foo foo = fooFactory(1, 2.3f); (void)foo; } ''' expect_success( COMMON_DEFINITIONS, source) def test_autoinject_2_assisted_params_returning_value(): source = ''' struct Foo { Foo(int x, float y) { (void)x; (void)y; } }; using FooFactory = std::function
; fruit::Component
getComponent() { return fruit::createComponent() .registerFactory
, fruit::Assisted
)>( [](int x, float y) { return Foo(x, y); }); } int main() { fruit::Injector
injector(getComponent); FooFactory fooFactory(injector); Foo foo = fooFactory(1, 2.3f); (void)foo; } ''' expect_success( COMMON_DEFINITIONS, source) def test_autoinject_instances_bound_to_assisted_params(): source = ''' struct X {}; struct Y {}; struct Foo { Foo(X x, Y y) { (void)x; (void)y; } }; using FooFactory = std::function
; fruit::Component
getComponent() { static X x = X(); static Y y = Y(); return fruit::createComponent() .bindInstance(x) .bindInstance(y) .registerFactory
( [](X x, Y y) { return Foo(x, y); }); } int main() { fruit::Injector
injector(getComponent); FooFactory fooFactory(injector); Foo foo = fooFactory(); (void)foo; } ''' expect_success( COMMON_DEFINITIONS, source) def test_autoinject_2_assisted_params_plus_nonassisted_params(): source = ''' struct X {}; struct Y {}; struct Z {}; struct Foo { Foo(X, Y, int, float, Z) { } }; using FooPtrFactory = std::function
(int, float)>; fruit::Component
getComponent() { static X x = X(); static Y y = Y(); static Z z = Z(); return fruit::createComponent() .bindInstance(x) .bindInstance(y) .bindInstance(z) .registerFactory
(X, Y, fruit::Assisted
, fruit::Assisted
, Z)>( [](X x, Y y, int n, float a, Z z) { return std::unique_ptr
(new Foo(x, y, n, a, z)); }); } int main() { fruit::Injector
injector(getComponent); FooPtrFactory fooPtrFactory(injector); std::unique_ptr
foo = fooPtrFactory(1, 3.4f); (void)foo; } ''' expect_success( COMMON_DEFINITIONS, source) def test_autoinject_2_assisted_params_plus_nonassisted_params_returning_value(): source = ''' struct X {}; struct Y {}; struct Z {}; struct Foo { Foo(X, Y, int, float, Z) { } }; using FooFactory = std::function
; fruit::Component
getComponent() { static X x = X(); static Y y = Y(); static Z z = Z(); return fruit::createComponent() .bindInstance(x) .bindInstance(y) .bindInstance(z) .registerFactory
, fruit::Assisted
, Z)>( [](X x, Y y, int n, float a, Z z) { return Foo(x, y, n, a, z); }); } int main() { fruit::Injector
injector(getComponent); FooFactory fooFactory(injector); Foo foo = fooFactory(1, 3.4f); (void)foo; } ''' expect_success( COMMON_DEFINITIONS, source) def test_autoinject_mixed_assisted_and_injected_params(): source = ''' struct X {}; struct Y {}; struct Foo { Foo(int, float, X, Y, double) { } }; using FooFactory = std::function
; fruit::Component
getComponent() { static X x = X(); static Y y = Y(); return fruit::createComponent() .bindInstance(x) .bindInstance(y) .registerFactory
, fruit::Assisted
, X, Y, fruit::Assisted
)>( [](int n, float a, X x, Y y, double d) { return Foo(n, a, x, y, d); }); } int main() { fruit::Injector
injector(getComponent); FooFactory fooFactory(injector); Foo foo = fooFactory(1, 3.4f, 3.456); (void)foo; } ''' expect_success( COMMON_DEFINITIONS, source) def test_autoinject_annotation_in_signature_return_type(): source = ''' struct X { using Inject = fruit::Annotated
(); }; fruit::Component
()>>> getComponent() { return fruit::createComponent(); } ''' expect_compile_error( 'InjectTypedefWithAnnotationError
', 'C::Inject is a signature that returns an annotated type', COMMON_DEFINITIONS, source) def test_autoinject_annotation_in_signature_return_type_returning_value(): source = ''' struct X { using Inject = fruit::Annotated
(); }; fruit::Component
>> getComponent() { return fruit::createComponent(); } ''' expect_compile_error( 'InjectTypedefWithAnnotationError
', 'C::Inject is a signature that returns an annotated type', COMMON_DEFINITIONS, source) def test_autoinject_from_provider_simple(): source = ''' struct X { INJECT(X()) = default; }; struct Scaler { virtual double scale(double x) = 0; virtual ~Scaler() = default; }; struct ScalerImpl : public Scaler { private: double factor; public: ScalerImpl(double factor, X) : factor(factor) { } double scale(double x) override { return x * factor; } }; using ScalerFactory = std::function
(double)>; fruit::Component
getScalerComponent() { return fruit::createComponent() .registerProvider([](X x) { return std::function
(double)>([x](double n){ return std::unique_ptr
(new ScalerImpl(n, x)); }); }) .bind
(); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory(injector); std::unique_ptr
scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source) @pytest.mark.parametrize('ScalerAnnot,ScalerFactoryAnnot,MaybeConstScalerFactoryAnnot,ScalerImplAnnot,ScalerImplFactoryAnnot', [ ('Scaler', 'std::function
(double)>', 'std::function
(double)>', 'ScalerImpl', 'std::function
(double)>'), ('Scaler', 'std::function
(double)>', 'const std::function
(double)>', 'ScalerImpl', 'std::function
(double)>'), ('fruit::Annotated
', 'fruit::Annotated
(double)>>', 'fruit::Annotated
(double)>>', 'fruit::Annotated
', 'fruit::Annotated
(double)>>'), ('fruit::Annotated
', 'fruit::Annotated
(double)>>', 'fruit::Annotated
(double)>>', 'fruit::Annotated
', 'fruit::Annotated
(double)>>'), ]) def test_autoinject_from_provider(ScalerAnnot, ScalerFactoryAnnot, MaybeConstScalerFactoryAnnot, ScalerImplAnnot, ScalerImplFactoryAnnot): source = ''' struct X { INJECT(X()) = default; }; struct Scaler { virtual double scale(double x) = 0; virtual ~Scaler() = default; }; struct ScalerImpl : public Scaler { private: double factor; public: ScalerImpl(double factor, X) : factor(factor) { } double scale(double x) override { return x * factor; } }; using ScalerFactory = std::function
(double)>; using ScalerImplFactory = std::function
(double)>; fruit::Component
getScalerComponent() { return fruit::createComponent() .registerProvider
([](X x) { return std::function
(double)>([x](double n){ return std::unique_ptr
(new ScalerImpl(n, x)); }); }) .bind
(); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory = injector.get
(); std::unique_ptr
scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source, locals()) @pytest.mark.parametrize('ScalerFactoryAnnot', [ 'ScalerFactory', 'fruit::Annotated
', ]) def test_autoinject_from_provider_returning_value(ScalerFactoryAnnot): source = ''' struct X { INJECT(X()) = default; }; struct Scaler { private: double factor; public: Scaler(double factor, X) : factor(factor) { } double scale(double x) { return x * factor; } }; using ScalerFactory = std::function
; fruit::Component
getScalerComponent() { return fruit::createComponent() .registerProvider
([](X x) { return std::function
([x](double n){ return Scaler(n, x); }); }); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory = injector.get
(); Scaler scaler = scalerFactory(12.1); std::cout << scaler.scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source, locals()) @pytest.mark.parametrize('MaybeConst', [ '', 'const', ]) @pytest.mark.parametrize('X_ANNOT', [ 'X', 'ANNOTATED(Annotation1, X)', ]) def test_autoinject_with_binding(MaybeConst, X_ANNOT): source = ''' struct X { using Inject = X(); }; struct Scaler { virtual double scale(double x) = 0; virtual ~Scaler() = default; }; struct ScalerImpl : public Scaler { private: double factor; public: INJECT(ScalerImpl(ASSISTED(double) factor, X_ANNOT x)) : factor(factor) { (void)x; } double scale(double x) override { return x * factor; } }; using ScalerFactory = std::function
(double)>; fruit::Component
getScalerComponent() { return fruit::createComponent() .bind
(); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory(injector); std::unique_ptr
scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source, locals()) @pytest.mark.parametrize('MaybeConst', [ '', 'const', ]) @pytest.mark.parametrize('X_ANNOT', [ 'X', 'ANNOTATED(Annotation1, X)', ]) def test_autoinject_with_binding_returning_value(MaybeConst, X_ANNOT): source = ''' struct X { using Inject = X(); }; struct Scaler { private: double factor; public: INJECT(Scaler(ASSISTED(double) factor, X_ANNOT x)) : factor(factor) { (void)x; } double scale(double x) { return x * factor; } }; using ScalerFactory = std::function
; fruit::Component
getScalerComponent() { return fruit::createComponent(); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory(injector); Scaler scaler = scalerFactory(12.1); std::cout << scaler.scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source, locals()) def test_autoinject_with_binding2(): source = ''' struct X { INJECT(X()) = default; }; struct Scaler { virtual double scale(double x) = 0; virtual ~Scaler() = default; }; struct ScalerImpl : public Scaler { private: double factor; public: INJECT(ScalerImpl(X, ASSISTED(double) factor)) : factor(factor) { } double scale(double x) override { return x * factor; } }; using ScalerFactory = std::function
(double)>; fruit::Component
getScalerComponent() { return fruit::createComponent() .bind
(); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory(injector); std::unique_ptr
scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source) def test_autoinject_with_binding2_returning_value(): source = ''' struct X { INJECT(X()) = default; }; struct Scaler { private: double factor; public: INJECT(Scaler(X, ASSISTED(double) factor)) : factor(factor) { } double scale(double x) { return x * factor; } }; using ScalerFactory = std::function
; fruit::Component
getScalerComponent() { return fruit::createComponent(); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory(injector); Scaler scaler = scalerFactory(12.1); std::cout << scaler.scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source) @pytest.mark.parametrize('ScalerAnnot,ScalerImplAnnot,ScalerFactoryAnnot', [ ('Scaler', 'ScalerImpl', 'std::function
(double)>'), ('fruit::Annotated
', 'fruit::Annotated
', 'fruit::Annotated
(double)>>'), ]) def test_register_factory_success(ScalerAnnot, ScalerImplAnnot, ScalerFactoryAnnot): source = ''' struct Scaler { virtual double scale(double x) = 0; virtual ~Scaler() = default; }; struct ScalerImpl : public Scaler { private: double factor; public: ScalerImpl(double factor) : factor(factor) { } double scale(double x) override { return x * factor; } }; using ScalerFactory = std::function
(double)>; fruit::Component
getScalerComponent() { return fruit::createComponent() .bind
() .registerFactory
)>([](double factor) { return ScalerImpl(factor); }); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory = injector.get
(); std::unique_ptr
scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source, locals()) def test_register_factory_with_annotation_returning_value(): source = ''' struct Scaler { private: double factor; public: Scaler(double factor) : factor(factor) { } double scale(double x) { return x * factor; } }; using ScalerFactory = std::function
; using ScalerFactoryAnnot1 = fruit::Annotated
; fruit::Component
getScalerComponent() { return fruit::createComponent() .registerFactory
)>( [](double factor) { return Scaler(factor); }); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory = injector.get
(); Scaler scaler = scalerFactory(12.1); std::cout << scaler.scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source) def test_register_factory_with_different_annotation(): source = ''' struct Scaler { virtual double scale(double x) = 0; virtual ~Scaler() = default; }; struct ScalerImpl : public Scaler { private: double factor; public: ScalerImpl(double factor) : factor(factor) { } double scale(double x) override { return x * factor; } }; using ScalerFactory = std::function
(double)>; using ScalerFactoryAnnot1 = fruit::Annotated
; fruit::Component
getScalerComponent() { return fruit::createComponent() .bind
() .registerFactory
)>( [](double factor) { return ScalerImpl(factor); }); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory = injector.get
(); std::unique_ptr
scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source) @pytest.mark.parametrize('ScalerAnnot,ScalerImplAnnot,ScalerFactoryAnnot', [ ('Scaler', 'ScalerImpl', 'std::function
(double, double)>'), ('fruit::Annotated
', 'fruit::Annotated
', 'fruit::Annotated
(double, double)>>'), ]) def test_register_factory_2arg_success(ScalerAnnot, ScalerImplAnnot, ScalerFactoryAnnot): source = ''' struct Scaler { virtual double scale(double x) = 0; virtual ~Scaler() = default; }; struct ScalerImpl : public Scaler { private: double factor; public: ScalerImpl(double factor) : factor(factor) { } double scale(double x) override { return x * factor; } }; using ScalerFactory = std::function
(double, double)>; fruit::Component
getScalerComponent() { return fruit::createComponent() .bind
() .registerFactory
, fruit::Assisted
)>( [](double factor, double) { return ScalerImpl(factor); }); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory = injector.get
(); std::unique_ptr
scaler = scalerFactory(12.1, 34.2); std::cout << scaler->scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source, locals()) def test_register_factory_with_different_annotation_error(): source = ''' struct Scaler { virtual double scale(double x) = 0; }; struct ScalerImpl : public Scaler { private: double factor; public: ScalerImpl(double factor) : factor(factor) { } double scale(double x) override { return x * factor; } }; using ScalerFactory = std::function
(double)>; using ScalerFactoryAnnot1 = fruit::Annotated
; fruit::Component
getScalerComponent() { return fruit::createComponent() .bind
() .registerFactory
)>([](double factor) { return ScalerImpl(factor); }); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory = injector.get
(); std::unique_ptr
scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; } ''' expect_compile_error( 'NoBindingFoundError
)?>\(double\)>>>', '', COMMON_DEFINITIONS, source) def test_register_factory_dep_on_provider(): source = ''' struct Scaler { virtual double scale(double x) = 0; virtual ~Scaler() = default; }; struct ScalerImpl : public Scaler { private: double factor; public: ScalerImpl(double factor) : factor(factor) { } double scale(double x) override { return x * factor; } }; using ScalerFactory = std::function
(double)>; fruit::Component
getScalerComponent() { return fruit::createComponent() .bind
() .registerProvider([](){return 23;}) .registerFactory
, fruit::Provider
)>( [](double factor, fruit::Provider
provider) { return ScalerImpl(factor * provider.get
()); }); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory(injector); std::unique_ptr
scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source) def test_register_factory_dep_on_provider_returning_value(): source = ''' struct Scaler { private: double factor; public: Scaler(double factor) : factor(factor) { } double scale(double x) { return x * factor; } }; using ScalerFactory = std::function
; fruit::Component
getScalerComponent() { return fruit::createComponent() .registerProvider([](){return 23;}) .registerFactory
, fruit::Provider
)>( [](double factor, fruit::Provider
provider) { return Scaler(factor * provider.get
()); }); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory(injector); Scaler scaler = scalerFactory(12.1); std::cout << scaler.scale(3) << std::endl; } ''' expect_success( COMMON_DEFINITIONS, source) def test_register_factory_error_abstract_class(): source = ''' struct Scaler { virtual double scale(double x) = 0; }; struct ScalerImpl : public Scaler { private: double factor; public: ScalerImpl(double factor) : factor(factor) { } // Note: here we "forgot" to implement scale() (on purpose, for this test) so ScalerImpl is an abstract class. }; using ScalerFactory = std::function
(double)>; fruit::Component
getScalerComponent() { return fruit::createComponent() .bind
() .registerFactory
(fruit::Assisted
)>([](double) { return (ScalerImpl*)nullptr; }); } ''' expect_compile_error( 'CannotConstructAbstractClassError
', 'The specified class can.t be constructed because it.s an abstract class.', COMMON_DEFINITIONS, source) def test_register_factory_error_not_function(): source = ''' struct X { X(int) {} }; fruit::Component
> getComponent() { int n = 3; return fruit::createComponent() .registerFactory
([=]{return X(n);}); } ''' expect_compile_error( 'LambdaWithCapturesError<.*>', 'Only lambdas with no captures are supported', COMMON_DEFINITIONS, source) @pytest.mark.parametrize('ScalerAnnot,ScalerImplAnnot,ScalerImplPtrAnnot,ScalerFactoryAnnot,ScalerImplFactorySignatureAnnotRegex', [ ('Scaler', 'ScalerImpl', 'ScalerImpl*', 'std::function
(double)>', 'ScalerImpl\*\(fruit::Assisted
\)'), ('fruit::Annotated
', 'fruit::Annotated
', 'fruit::Annotated
', 'fruit::Annotated
(double)>>', 'fruit::Annotated
\(fruit::Assisted
\)') ]) def test_register_factory_for_pointer(ScalerAnnot, ScalerImplAnnot, ScalerImplPtrAnnot, ScalerFactoryAnnot, ScalerImplFactorySignatureAnnotRegex): source = ''' struct Scaler { virtual double scale(double x) = 0; }; struct ScalerImpl : public Scaler { private: double factor; public: ScalerImpl(double factor) : factor(factor) { } double scale(double x) override { return x * factor; } }; using ScalerFactory = std::function
(double)>; fruit::Component
getScalerComponent() { return fruit::createComponent() .bind
() .registerFactory
)>([](double factor) { return new ScalerImpl(factor); }); } int main() { fruit::Injector
injector(getScalerComponent); ScalerFactory scalerFactory = injector.get
(); std::unique_ptr
scaler = scalerFactory(12.1); std::cout << scaler->scale(3) << std::endl; } ''' expect_compile_error( 'FactoryReturningPointerError