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 // The shared_ptr objects below ensure (since these tests are run under Valgrind) that deletion occurs, and only once. 23 24 struct I1 { 25 std::shared_ptr<int> x = std::make_shared<int>(3); 26 virtual ~I1() {} 27 }; 28 29 struct I2 { 30 std::shared_ptr<int> x = std::make_shared<int>(3); 31 }; 32 33 struct I3 { 34 std::shared_ptr<int> x = std::make_shared<int>(3); 35 }; 36 37 struct I4 { 38 std::shared_ptr<int> x = std::make_shared<int>(3); 39 }; 40 41 struct X1 : I1 { 42 INJECT(X1()) = default; 43 std::shared_ptr<int> x = std::make_shared<int>(3); 44 }; 45 46 struct X2 : I2 { 47 // Taking an X1 here prevents binding compression. 48 INJECT(X2(X1)) {} 49 std::shared_ptr<int> x = std::make_shared<int>(3); 50 }; 51 52 struct X3 : public I3 { 53 std::shared_ptr<int> x = std::make_shared<int>(3); 54 }; 55 56 struct X4 : public I4 { 57 // Taking an X3 here prevents binding compression. 58 X4(X3) {}; 59 std::shared_ptr<int> x = std::make_shared<int>(3); 60 }; 61 62 struct X5 { 63 std::shared_ptr<int> x = std::make_shared<int>(3); 64 }; 65 66 struct X6 : public I1 { 67 INJECT(X6()) = default; 68 std::shared_ptr<int> x = std::make_shared<int>(3); 69 }; 70 71 struct X7 : public I1 { 72 std::shared_ptr<int> x = std::make_shared<int>(3); 73 }; 74 75 struct X8 : public I1 { 76 std::shared_ptr<int> x = std::make_shared<int>(3); 77 virtual ~X8() {} 78 }; 79 80 struct Annotation {}; 81 82 using I1Annot = fruit::Annotated<Annotation, I1>; 83 using I2Annot = fruit::Annotated<Annotation, I2>; 84 using I3Annot = fruit::Annotated<Annotation, I3>; 85 using I4Annot = fruit::Annotated<Annotation, I4>; 86 87 using X1Annot = fruit::Annotated<Annotation, X1>; 88 using X2Annot = fruit::Annotated<Annotation, X2>; 89 using X3Annot = fruit::Annotated<Annotation, X3>; 90 using X4Annot = fruit::Annotated<Annotation, X4>; 91 using X5Annot = fruit::Annotated<Annotation, X5>; 92 using X6Annot = fruit::Annotated<Annotation, X6>; 93 using X7Annot = fruit::Annotated<Annotation, X7>; 94 using X8Annot = fruit::Annotated<Annotation, X8>; 95 96 using X1PtrAnnot = fruit::Annotated<Annotation, X1*>; 97 ''' 98 99class TestClassDestruction(parameterized.TestCase): 100 @parameterized.parameters([ 101 ('I1', 'I2', 'I3', 'I4', 'X1', 'X2', 'X3', 'X4', 'X5', 'X6', 'X7', 'X8', 'X1*', 'bindInstance(x5)', 'addInstanceMultibinding(*x7)'), 102 ('I1Annot', 'I2Annot', 'I3Annot', 'I4Annot', 'X1Annot', 'X2Annot', 'X3Annot', 'X4Annot', 'X5Annot', 'X6Annot', 'X7Annot', 'X8Annot', 'X1PtrAnnot', 'bindInstance<X5Annot>(x5)', 'addInstanceMultibinding<X7Annot>(*x7)'), 103 ]) 104 def test_injector_creation_no_injection(self, 105 I1Annot, I2Annot, I3Annot, I4Annot, X1Annot, X2Annot, X3Annot, X4Annot, X5Annot, X6Annot, X7Annot, X8Annot, X1PtrAnnot, bindX5Instance, addX7InstanceMultibinding): 106 source = ''' 107 fruit::Component<I1Annot, I2Annot, I3Annot, I4Annot, X5Annot> getComponent() { 108 static X5 x5; 109 static std::unique_ptr<X7> x7(new X7()); 110 return fruit::createComponent() 111 .bind<I1Annot, X1Annot>() 112 .bind<I2Annot, X2Annot>() 113 .bind<I3Annot, X3Annot>() 114 .bind<I4Annot, X4Annot>() 115 .registerProvider<X3Annot()>([]() { return X3(); }) 116 .registerProvider<X4Annot(X3Annot)>([](X3 x3) { return X4(x3); }) 117 .bindX5Instance 118 .addMultibinding<I1Annot, X6Annot>() 119 .addX7InstanceMultibinding 120 .addMultibindingProvider<X1PtrAnnot()>([]() { return (X1*) new X8(); }); 121 } 122 123 int main() { 124 fruit::Injector<I1Annot, I2Annot, I3Annot, I4Annot, X5Annot> injector(getComponent); 125 (void)injector; 126 } 127 ''' 128 expect_success( 129 COMMON_DEFINITIONS, 130 source, 131 locals()) 132 133 @parameterized.parameters([ 134 ('I1', 'I2', 'I3', 'I4', 'X1', 'X2', 'X3', 'X4', 'X5', 'X6', 'X7', 'X8', 'X1*', 'bindInstance(x5)', 'addInstanceMultibinding(*x7)'), 135 ('I1Annot', 'I2Annot', 'I3Annot', 'I4Annot', 'X1Annot', 'X2Annot', 'X3Annot', 'X4Annot', 'X5Annot', 'X6Annot', 'X7Annot', 'X8Annot', 'X1PtrAnnot', 'bindInstance<X5Annot>(x5)', 'addInstanceMultibinding<X7Annot>(*x7)'), 136 ]) 137 def test_injector_creation_and_injection(self, 138 I1Annot, I2Annot, I3Annot, I4Annot, X1Annot, X2Annot, X3Annot, X4Annot, X5Annot, X6Annot, X7Annot, X8Annot, X1PtrAnnot, bindX5Instance, addX7InstanceMultibinding): 139 source = ''' 140 fruit::Component<I1Annot, I2Annot, I3Annot, I4Annot, X5Annot> getComponent() { 141 static X5 x5; 142 static std::unique_ptr<X7> x7(new X7()); 143 return fruit::createComponent() 144 .bind<I1Annot, X1Annot>() 145 .bind<I2Annot, X2Annot>() 146 .bind<I3Annot, X3Annot>() 147 .bind<I4Annot, X4Annot>() 148 .registerProvider<X3Annot()>([]() { return X3(); }) 149 .registerProvider<X4Annot(X3Annot)>([](X3 x3) { return X4(x3); }) 150 .bindX5Instance 151 .addMultibinding<I1Annot, X6Annot>() 152 .addX7InstanceMultibinding 153 .addMultibindingProvider<X1PtrAnnot()>([]() { return (X1*) new X8(); }); 154 } 155 156 int main() { 157 fruit::Injector<I1Annot, I2Annot, I3Annot, I4Annot, X5Annot> injector(getComponent); 158 159 injector.get<I1Annot>(); 160 injector.get<I2Annot>(); 161 injector.get<I3Annot>(); 162 injector.get<I4Annot>(); 163 injector.get<X5Annot>(); 164 165 injector.getMultibindings<I1Annot>(); 166 } 167 ''' 168 expect_success( 169 COMMON_DEFINITIONS, 170 source, 171 locals()) 172 173if __name__ == '__main__': 174 absltest.main() 175