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 absl.testing import parameterized 17from fruit_test_common import * 18 19COMMON_DEFINITIONS = ''' 20 #include "test_common.h" 21 22 template <typename T> 23 class V {}; 24 25 template <typename T> 26 class X { 27 private: 28 X() {} 29 30 public: 31 INJECT(X(ASSISTED(int))) { 32 } 33 }; 34 35 using XFactory = std::function<X<V<float>>(int)>; 36 ''' 37 38class TestMisc(parameterized.TestCase): 39 40 def test_misc(self): 41 source = ''' 42 fruit::Component<X<V<float>>> getXProvider2() { 43 return fruit::createComponent() 44 .registerProvider([](){return X<V<float>>(1);}); 45 } 46 47 struct AssistedMultiparamExample { 48 INJECT(AssistedMultiparamExample(ASSISTED(std::map<int, float>))) {} 49 }; 50 51 struct Implementation1 { 52 bool constructed = true; 53 54 Implementation1(V<int>&&, XFactory) { 55 std::cout << "Called Implementation1() for object " << this << std::endl; 56 } 57 58 Implementation1() = delete; 59 Implementation1(const Implementation1&) = delete; 60 61 Implementation1& operator=(const Implementation1&) = delete; 62 Implementation1& operator=(Implementation1&&) = delete; 63 64 Implementation1(Implementation1&&) { 65 std::cout << "Moving an Implementation1 into object" << this << std::endl; 66 } 67 68 ~Implementation1() { 69 std::cout << "Called ~Implementation1() for object " << this << std::endl; 70 constructed = 0; 71 } 72 73 int x; 74 }; 75 76 struct Interface2 { 77 virtual void f() = 0; 78 }; 79 80 struct Implementation2 : public Interface2 { 81 INJECT(Implementation2(std::function<Implementation1(int)>)) { 82 std::cout << "Called Implementation2()" << std::endl; 83 } 84 85 virtual ~Implementation2() {} 86 87 virtual void f() {}; 88 }; 89 90 fruit::Component<Interface2, XFactory, std::function<Implementation1(int)>> getParentComponent() { 91 return fruit::createComponent() 92 .registerFactory<Implementation1(fruit::Assisted<int>, XFactory)>( 93 [](int, XFactory xFactory) { 94 return Implementation1(V<int>(), xFactory); 95 }) 96 .bind<Interface2, Implementation2>(); 97 } 98 99 //************************************* 100 101 struct Interface3 { 102 virtual void f() = 0; 103 }; 104 105 struct Implementation3 : public Interface3 { 106 INJECT(Implementation3(Implementation2*, fruit::Provider<Implementation2> provider)) { 107 (void) provider.get(); 108 std::cout << "Called Implementation2()" << std::endl; 109 } 110 111 virtual ~Implementation3() {} 112 113 virtual void f() {}; 114 }; 115 116 fruit::Component<Interface3, std::function<Implementation1(int)>> getMyComponent() { 117 return fruit::createComponent() 118 // Must fail at runtime. 119 // .install(getXProvider2) 120 .bind<Interface3, Implementation3>() 121 .install(getParentComponent); 122 } 123 124 fruit::Component<std::function<AssistedMultiparamExample(std::map<int, float>)>> getAssistedMultiparamExampleComponent() { 125 return fruit::createComponent(); 126 } 127 128 int main() { 129 fruit::Injector< 130 Interface3, 131 // XFactory, 132 std::function<Implementation1(int)> 133 > oldInjector(getMyComponent); 134 135 // The move is completely unnecessary, it's just to check that it works. 136 fruit::Injector< 137 Interface3, 138 // XFactory, 139 std::function<Implementation1(int)> 140 > injector(std::move(oldInjector)); 141 142 std::cout << "Constructing an Interface3" << std::endl; 143 Interface3* interface3(injector); 144 std::cout << std::endl; 145 (void) interface3; 146 147 std::cout << "Constructing another Interface3" << std::endl; 148 Interface3* interface3_obj2 = injector.get<Interface3*>(); 149 std::cout << std::endl; 150 (void) interface3_obj2; 151 152 std::function<Implementation1(int)> implementation1Factory(injector); 153 { 154 std::cout << "Constructing another Implementation1" << std::endl; 155 Implementation1 implementation1 = implementation1Factory(12); 156 (void) implementation1; 157 } 158 std::cout << "Destroying injector" << std::endl; 159 160 fruit::Injector<std::function<AssistedMultiparamExample(std::map<int, float>)>> assistedMultiparamExampleInjector( 161 getAssistedMultiparamExampleComponent); 162 163 return 0; 164 } 165 ''' 166 expect_success( 167 COMMON_DEFINITIONS, 168 source, 169 locals()) 170 171if __name__ == '__main__': 172 absltest.main() 173