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 struct X; 22 23 struct Annotation1 {}; 24 using XAnnot1 = fruit::Annotated<Annotation1, X>; 25 ''' 26 27def test_install_component_functions_deduped_against_previous_install_no_args(): 28 source = ''' 29 int num_executions = 0; 30 31 fruit::Component<int> getChildComponent() { 32 static int n = 5; 33 ++num_executions; 34 return fruit::createComponent() 35 .bindInstance(n); 36 } 37 38 fruit::Component<> getMiddleComponent() { 39 return fruit::createComponent() 40 .install(getChildComponent); 41 } 42 43 fruit::Component<int> getMainComponent() { 44 return fruit::createComponent() 45 .install(getMiddleComponent) 46 .installComponentFunctions(fruit::componentFunction(getChildComponent)); 47 } 48 49 int main() { 50 fruit::Injector<int> injector(getMainComponent); 51 int n = injector.get<int>(); 52 Assert(n == 5); 53 Assert(num_executions == 1); 54 } 55 ''' 56 expect_success( 57 COMMON_DEFINITIONS, 58 source, 59 locals()) 60 61def test_install_component_functions_deduped_against_following_install_no_args(): 62 source = ''' 63 int num_executions = 0; 64 65 fruit::Component<int> getChildComponent() { 66 static int n = 5; 67 ++num_executions; 68 return fruit::createComponent() 69 .bindInstance(n); 70 } 71 72 fruit::Component<> getMiddleComponent() { 73 return fruit::createComponent() 74 .installComponentFunctions(fruit::componentFunction(getChildComponent)); 75 } 76 77 fruit::Component<int> getMainComponent() { 78 return fruit::createComponent() 79 .install(getMiddleComponent) 80 .install(getChildComponent); 81 } 82 83 int main() { 84 fruit::Injector<int> injector(getMainComponent); 85 int n = injector.get<int>(); 86 Assert(n == 5); 87 Assert(num_executions == 1); 88 } 89 ''' 90 expect_success( 91 COMMON_DEFINITIONS, 92 source, 93 locals()) 94 95def test_install_component_functions_deduped_against_previous_install_with_args(): 96 source = ''' 97 int num_executions = 0; 98 99 fruit::Component<int> getChildComponent(int) { 100 static int n = 5; 101 ++num_executions; 102 return fruit::createComponent() 103 .bindInstance(n); 104 } 105 106 fruit::Component<> getMiddleComponent() { 107 return fruit::createComponent() 108 .install(getChildComponent, 42); 109 } 110 111 fruit::Component<int> getMainComponent() { 112 return fruit::createComponent() 113 .install(getMiddleComponent) 114 .installComponentFunctions(fruit::componentFunction(getChildComponent, 42)); 115 } 116 117 int main() { 118 fruit::Injector<int> injector(getMainComponent); 119 int n = injector.get<int>(); 120 Assert(n == 5); 121 Assert(num_executions == 1); 122 } 123 ''' 124 expect_success( 125 COMMON_DEFINITIONS, 126 source, 127 locals()) 128 129def test_install_component_functions_deduped_against_following_install_with_args(): 130 source = ''' 131 int num_executions = 0; 132 133 fruit::Component<int> getChildComponent(int) { 134 static int n = 5; 135 ++num_executions; 136 return fruit::createComponent() 137 .bindInstance(n); 138 } 139 140 fruit::Component<> getMiddleComponent() { 141 return fruit::createComponent() 142 .installComponentFunctions(fruit::componentFunction(getChildComponent, 42)); 143 } 144 145 fruit::Component<int> getMainComponent() { 146 return fruit::createComponent() 147 .install(getMiddleComponent) 148 .install(getChildComponent, 42); 149 } 150 151 int main() { 152 fruit::Injector<int> injector(getMainComponent); 153 int n = injector.get<int>(); 154 Assert(n == 5); 155 Assert(num_executions == 1); 156 } 157 ''' 158 expect_success( 159 COMMON_DEFINITIONS, 160 source, 161 locals()) 162 163def test_install_component_functions_same_as_with_previous_install_with_different_args(): 164 source = ''' 165 int num_executions = 0; 166 167 fruit::Component<int> getChildComponent(int) { 168 static int n = 5; 169 ++num_executions; 170 return fruit::createComponent() 171 .bindInstance(n); 172 } 173 174 fruit::Component<> getMiddleComponent() { 175 return fruit::createComponent() 176 .install(getChildComponent, 42); 177 } 178 179 fruit::Component<int> getMainComponent() { 180 return fruit::createComponent() 181 .install(getMiddleComponent) 182 .installComponentFunctions(fruit::componentFunction(getChildComponent, 2)); 183 } 184 185 int main() { 186 fruit::Injector<int> injector(getMainComponent); 187 int n = injector.get<int>(); 188 Assert(n == 5); 189 Assert(num_executions == 2); 190 } 191 ''' 192 expect_success( 193 COMMON_DEFINITIONS, 194 source, 195 locals()) 196 197def test_install_component_functions_same_as_following_install_with_different_args(): 198 source = ''' 199 int num_executions = 0; 200 201 fruit::Component<int> getChildComponent(int) { 202 static int n = 5; 203 ++num_executions; 204 return fruit::createComponent() 205 .bindInstance(n); 206 } 207 208 fruit::Component<> getMiddleComponent() { 209 return fruit::createComponent() 210 .installComponentFunctions(fruit::componentFunction(getChildComponent, 42)); 211 } 212 213 fruit::Component<int> getMainComponent() { 214 return fruit::createComponent() 215 .install(getMiddleComponent) 216 .install(getChildComponent, 2); 217 } 218 219 int main() { 220 fruit::Injector<int> injector(getMainComponent); 221 (void)injector; 222 Assert(num_executions == 2); 223 } 224 ''' 225 expect_success( 226 COMMON_DEFINITIONS, 227 source, 228 locals()) 229 230def test_install_component_functions_no_component_functions(): 231 source = ''' 232 fruit::Component<> getComponent() { 233 return fruit::createComponent() 234 .installComponentFunctions(); 235 } 236 237 int main() { 238 fruit::Injector<> injector(getComponent); 239 (void)injector; 240 } 241 ''' 242 expect_success(COMMON_DEFINITIONS, source) 243 244def test_install_component_functions_one_component_function(): 245 source = ''' 246 struct X { 247 int n; 248 X(int n) : n(n) {} 249 }; 250 251 fruit::Component<X> getParentComponent(std::string) { 252 return fruit::createComponent() 253 .registerProvider([]() { return X(5); }); 254 } 255 256 fruit::Component<X> getComponent() { 257 return fruit::createComponent() 258 .installComponentFunctions(fruit::componentFunction(getParentComponent, std::string("Hello"))); 259 } 260 261 int main() { 262 fruit::Injector<X> injector(getComponent); 263 X x = injector.get<X>(); 264 Assert(x.n == 5); 265 } 266 ''' 267 expect_success(COMMON_DEFINITIONS, source) 268 269def test_install_component_functions_two_component_functions(): 270 source = ''' 271 struct X { 272 int n; 273 X(int n) : n(n) {} 274 }; 275 276 struct Y { 277 int n; 278 Y(int n) : n(n) {} 279 }; 280 281 fruit::Component<X> getParentComponent1(std::string) { 282 return fruit::createComponent() 283 .registerProvider([]() { return X(5); }); 284 } 285 286 fruit::Component<Y> getParentComponent2(std::string) { 287 return fruit::createComponent() 288 .registerProvider([]() { return Y(42); }); 289 } 290 291 fruit::Component<X, Y> getComponent() { 292 return fruit::createComponent() 293 .installComponentFunctions( 294 fruit::componentFunction(getParentComponent1, std::string("Hello")), 295 fruit::componentFunction(getParentComponent2, std::string("World"))); 296 } 297 298 int main() { 299 fruit::Injector<X, Y> injector(getComponent); 300 X x = injector.get<X>(); 301 Y y = injector.get<Y>(); 302 Assert(x.n == 5); 303 Assert(y.n == 42); 304 } 305 ''' 306 expect_success(COMMON_DEFINITIONS, source) 307 308def test_install_component_functions_with_template_parameter_pack_unpacking(): 309 source = ''' 310 template <typename T> 311 struct GetComponentHolder; 312 313 struct X { 314 int n; 315 X(int n) : n(n) {} 316 }; 317 318 struct Y { 319 int n; 320 Y(int n) : n(n) {} 321 }; 322 323 template <> 324 struct GetComponentHolder<X> { 325 static fruit::Component<X> getComponent(std::string) { 326 return fruit::createComponent() 327 .registerProvider([]() { return X(5); }); 328 } 329 }; 330 331 template <> 332 struct GetComponentHolder<Y> { 333 static fruit::Component<Y> getComponent(std::string) { 334 return fruit::createComponent() 335 .registerProvider([]() { return Y(42); }); 336 } 337 }; 338 339 template <typename... Ts> 340 fruit::Component<Ts...> getComponent() { 341 return fruit::createComponent() 342 .installComponentFunctions( 343 fruit::componentFunction(GetComponentHolder<Ts>::getComponent, std::string("Hello"))...); 344 } 345 346 int main() { 347 fruit::Injector<X, Y> injector(getComponent<X, Y>); 348 X x = injector.get<X>(); 349 Y y = injector.get<Y>(); 350 Assert(x.n == 5); 351 Assert(y.n == 42); 352 } 353 ''' 354 expect_success(COMMON_DEFINITIONS, source) 355 356def test_install_component_functions_wrong_argument_type(): 357 source = ''' 358 fruit::Component<> getMainComponent() { 359 return fruit::createComponent() 360 .installComponentFunctions(42); 361 } 362 ''' 363 expect_compile_error( 364 'IncorrectArgTypePassedToInstallComponentFuntionsError<int>', 365 'All arguments passed to installComponentFunctions.. must be fruit::ComponentFunction<...> objects but an ' 366 'argument with type Arg was passed instead.', 367 COMMON_DEFINITIONS, 368 source, 369 locals()) 370 371if __name__== '__main__': 372 main(__file__) 373