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