1#!/usr/bin/env python3 2# Copyright 2016 Google Inc. All Rights Reserved. 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS-IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16from fruit_test_common import * 17 18COMMON_DEFINITIONS = ''' 19 #include "test_common.h" 20 21 template <typename T> 22 class V {}; 23 24 template <typename T> 25 class X { 26 private: 27 X() {} 28 29 public: 30 INJECT(X(ASSISTED(int))) { 31 } 32 }; 33 34 using XFactory = std::function<X<V<float>>(int)>; 35 ''' 36 37def test_misc(): 38 source = ''' 39 fruit::Component<X<V<float>>> getXProvider2() { 40 return fruit::createComponent() 41 .registerProvider([](){return X<V<float>>(1);}); 42 } 43 44 struct AssistedMultiparamExample { 45 INJECT(AssistedMultiparamExample(ASSISTED(std::map<int, float>))) {} 46 }; 47 48 struct Implementation1 { 49 bool constructed = true; 50 51 Implementation1(V<int>&&, XFactory) { 52 std::cout << "Called Implementation1() for object " << this << std::endl; 53 } 54 55 Implementation1() = delete; 56 Implementation1(const Implementation1&) = delete; 57 58 Implementation1& operator=(const Implementation1&) = delete; 59 Implementation1& operator=(Implementation1&&) = delete; 60 61 Implementation1(Implementation1&&) { 62 std::cout << "Moving an Implementation1 into object" << this << std::endl; 63 } 64 65 ~Implementation1() { 66 std::cout << "Called ~Implementation1() for object " << this << std::endl; 67 constructed = 0; 68 } 69 70 int x; 71 }; 72 73 struct Interface2 { 74 virtual void f() = 0; 75 }; 76 77 struct Implementation2 : public Interface2 { 78 INJECT(Implementation2(std::function<Implementation1(int)>)) { 79 std::cout << "Called Implementation2()" << std::endl; 80 } 81 82 virtual ~Implementation2() {} 83 84 virtual void f() {}; 85 }; 86 87 fruit::Component<Interface2, XFactory, std::function<Implementation1(int)>> getParentComponent() { 88 return fruit::createComponent() 89 .registerFactory<Implementation1(fruit::Assisted<int>, XFactory)>( 90 [](int, XFactory xFactory) { 91 return Implementation1(V<int>(), xFactory); 92 }) 93 .bind<Interface2, Implementation2>(); 94 } 95 96 //************************************* 97 98 struct Interface3 { 99 virtual void f() = 0; 100 }; 101 102 struct Implementation3 : public Interface3 { 103 INJECT(Implementation3(Implementation2*, fruit::Provider<Implementation2> provider)) { 104 (void) provider.get(); 105 std::cout << "Called Implementation2()" << std::endl; 106 } 107 108 virtual ~Implementation3() {} 109 110 virtual void f() {}; 111 }; 112 113 fruit::Component<Interface3, std::function<Implementation1(int)>> getMyComponent() { 114 return fruit::createComponent() 115 // Must fail at runtime. 116 // .install(getXProvider2) 117 .bind<Interface3, Implementation3>() 118 .install(getParentComponent); 119 } 120 121 fruit::Component<std::function<AssistedMultiparamExample(std::map<int, float>)>> getAssistedMultiparamExampleComponent() { 122 return fruit::createComponent(); 123 } 124 125 int main() { 126 fruit::Injector< 127 Interface3, 128 // XFactory, 129 std::function<Implementation1(int)> 130 > oldInjector(getMyComponent); 131 132 // The move is completely unnecessary, it's just to check that it works. 133 fruit::Injector< 134 Interface3, 135 // XFactory, 136 std::function<Implementation1(int)> 137 > injector(std::move(oldInjector)); 138 139 std::cout << "Constructing an Interface3" << std::endl; 140 Interface3* interface3(injector); 141 std::cout << std::endl; 142 (void) interface3; 143 144 std::cout << "Constructing another Interface3" << std::endl; 145 Interface3* interface3_obj2 = injector.get<Interface3*>(); 146 std::cout << std::endl; 147 (void) interface3_obj2; 148 149 std::function<Implementation1(int)> implementation1Factory(injector); 150 { 151 std::cout << "Constructing another Implementation1" << std::endl; 152 Implementation1 implementation1 = implementation1Factory(12); 153 (void) implementation1; 154 } 155 std::cout << "Destroying injector" << std::endl; 156 157 fruit::Injector<std::function<AssistedMultiparamExample(std::map<int, float>)>> assistedMultiparamExampleInjector( 158 getAssistedMultiparamExampleComponent); 159 160 return 0; 161 } 162 ''' 163 expect_success( 164 COMMON_DEFINITIONS, 165 source, 166 locals()) 167 168if __name__== '__main__': 169 main(__file__) 170