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 22def test_component_function_success(): 23 source = ''' 24 struct X { 25 int n; 26 X(int n) : n(n) {} 27 }; 28 29 struct Arg { 30 Arg(int) {} 31 Arg() = default; 32 Arg(const Arg&) = default; 33 Arg(Arg&&) = default; 34 Arg& operator=(const Arg&) = default; 35 Arg& operator=(Arg&&) = default; 36 }; 37 38 bool operator==(const Arg&, const Arg&) { 39 return true; 40 } 41 42 namespace std { 43 template <> 44 struct hash<Arg> { 45 size_t operator()(const Arg&) { 46 return 0; 47 } 48 }; 49 } 50 51 fruit::Component<X> getParentComponent(int, std::string, Arg, Arg) { 52 return fruit::createComponent() 53 .registerProvider([]() { return X(5); }); 54 } 55 56 fruit::Component<X> getComponent() { 57 return fruit::createComponent() 58 .installComponentFunctions(fruit::componentFunction(getParentComponent, 5, std::string("Hello"), Arg{}, 15)); 59 } 60 61 int main() { 62 fruit::Injector<X> injector(getComponent); 63 X x = injector.get<X>(); 64 Assert(x.n == 5); 65 } 66 ''' 67 expect_success(COMMON_DEFINITIONS, source) 68 69def test_component_function_no_args_success(): 70 source = ''' 71 struct X { 72 int n; 73 X(int n) : n(n) {} 74 }; 75 76 fruit::Component<X> getParentComponent() { 77 return fruit::createComponent() 78 .registerProvider([]() { return X(5); }); 79 } 80 81 fruit::Component<X> getComponent() { 82 return fruit::createComponent() 83 .installComponentFunctions(fruit::componentFunction(getParentComponent)); 84 } 85 86 int main() { 87 fruit::Injector<X> injector(getComponent); 88 X x = injector.get<X>(); 89 Assert(x.n == 5); 90 } 91 ''' 92 expect_success(COMMON_DEFINITIONS, source) 93 94def test_component_function_one_arg_success(): 95 source = ''' 96 struct X { 97 int n; 98 X(int n) : n(n) {} 99 }; 100 101 fruit::Component<X> getParentComponent(std::string) { 102 return fruit::createComponent() 103 .registerProvider([]() { return X(5); }); 104 } 105 106 fruit::Component<X> getComponent() { 107 return fruit::createComponent() 108 .installComponentFunctions(fruit::componentFunction(getParentComponent, std::string("Hello"))); 109 } 110 111 int main() { 112 fruit::Injector<X> injector(getComponent); 113 X x = injector.get<X>(); 114 Assert(x.n == 5); 115 } 116 ''' 117 expect_success(COMMON_DEFINITIONS, source) 118 119def test_component_function_error_not_move_constructible(): 120 source = ''' 121 struct X {}; 122 123 struct Arg { 124 Arg() = default; 125 Arg(const Arg&) = default; 126 Arg(Arg&&) = delete; 127 Arg& operator=(const Arg&) = default; 128 Arg& operator=(Arg&&) = default; 129 }; 130 131 bool operator==(const Arg&, const Arg&); 132 133 namespace std { 134 template <> 135 struct hash<Arg> { 136 size_t operator()(const Arg&); 137 }; 138 } 139 140 fruit::Component<X> getParentComponent(int, std::string, Arg); 141 142 fruit::Component<X> getComponent() { 143 return fruit::createComponent() 144 .installComponentFunctions(fruit::componentFunction(getParentComponent, 5, std::string("Hello"), Arg{})); 145 } 146 ''' 147 expect_generic_compile_error( 148 'error: use of deleted function .Arg::Arg\(Arg&&\).' 149 + '|error: call to deleted constructor of .Arg.' 150 + '|.Arg::Arg\(Arg &&\).: cannot convert argument 1 from .std::_Tuple_val<Arg>. to .const Arg &.' 151 + '|.Arg::Arg\(Arg &&\).: attempting to reference a deleted function', 152 COMMON_DEFINITIONS, 153 source) 154 155def test_component_function_error_not_move_constructible_with_conversion(): 156 source = ''' 157 struct X {}; 158 159 struct Arg { 160 Arg(int) {} 161 Arg() = default; 162 Arg(const Arg&) = default; 163 Arg(Arg&&) = delete; 164 Arg& operator=(const Arg&) = default; 165 Arg& operator=(Arg&&) = default; 166 }; 167 168 bool operator==(const Arg&, const Arg&); 169 170 namespace std { 171 template <> 172 struct hash<Arg> { 173 size_t operator()(const Arg&); 174 }; 175 } 176 177 fruit::Component<X> getParentComponent(int, std::string, Arg); 178 179 fruit::Component<X> getComponent() { 180 return fruit::createComponent() 181 .installComponentFunctions(fruit::componentFunction(getParentComponent, 5, std::string("Hello"), 15)); 182 } 183 ''' 184 expect_generic_compile_error( 185 'error: use of deleted function .Arg::Arg\(Arg&&\).' 186 + '|error: call to deleted constructor of .Arg.' 187 + '|.Arg::Arg\(Arg &&\).: cannot convert argument 1 from .std::_Tuple_val<Arg>. to .int.' 188 + '|error: copying parameter of type .Arg. invokes deleted constructor', 189 COMMON_DEFINITIONS, 190 source) 191 192def test_component_function_error_not_copy_constructible(): 193 source = ''' 194 struct X { 195 int n; 196 X(int n) : n(n) {} 197 }; 198 199 struct Arg { 200 Arg() = default; 201 Arg(const Arg&) = delete; 202 Arg(Arg&&) = default; 203 Arg& operator=(const Arg&) = default; 204 Arg& operator=(Arg&&) = default; 205 }; 206 207 bool operator==(const Arg&, const Arg&); 208 209 namespace std { 210 template <> 211 struct hash<Arg> { 212 size_t operator()(const Arg&); 213 }; 214 } 215 216 fruit::Component<X> getParentComponent(int, std::string, Arg); 217 218 fruit::Component<X> getComponent() { 219 return fruit::createComponent() 220 .installComponentFunctions(fruit::componentFunction(getParentComponent, 5, std::string("Hello"), Arg{})); 221 } 222 ''' 223 expect_generic_compile_error( 224 'error: use of deleted function .Arg::Arg\(const Arg&\).' 225 + '|error: call to deleted constructor of .Arg.' 226 + '|error C2280: .Arg::Arg\(const Arg &\).: attempting to reference a deleted function' 227 # This is the error printed by MSVC. It's not great but I couldn't find a way to have it print 228 # a more useful error. 229 + '|cannot convert argument 1 from .int. to .std::allocator_arg_t.', 230 COMMON_DEFINITIONS, 231 source) 232 233def test_component_function_error_not_copy_constructible_with_conversion(): 234 source = ''' 235 struct X { 236 int n; 237 X(int n) : n(n) {} 238 }; 239 240 struct Arg { 241 Arg(int) {} 242 Arg() = default; 243 Arg(const Arg&) = delete; 244 Arg(Arg&&) = default; 245 Arg& operator=(const Arg&) = default; 246 Arg& operator=(Arg&&) = default; 247 }; 248 249 bool operator==(const Arg&, const Arg&); 250 251 namespace std { 252 template <> 253 struct hash<Arg> { 254 size_t operator()(const Arg&); 255 }; 256 } 257 258 fruit::Component<X> getParentComponent(int, std::string, Arg); 259 260 fruit::Component<X> getComponent() { 261 return fruit::createComponent() 262 .installComponentFunctions(fruit::componentFunction(getParentComponent, 5, std::string("Hello"), 15)); 263 } 264 ''' 265 expect_generic_compile_error( 266 'error: use of deleted function .Arg::Arg\(const Arg&\).' 267 + '|error: call to deleted constructor of .Arg.' 268 + '|error C2280: .Arg::Arg\(const Arg &\).: attempting to reference a deleted function' 269 # This is the error printed by MSVC. It's not great but I couldn't find a way to have it print 270 # a more useful error. 271 + '|cannot convert argument 1 from .int. to .std::allocator_arg_t.', 272 COMMON_DEFINITIONS, 273 source) 274 275def test_component_function_error_not_move_assignable(): 276 source = ''' 277 struct X {}; 278 279 struct Arg { 280 Arg() = default; 281 Arg(const Arg&) = default; 282 Arg(Arg&&) = default; 283 Arg& operator=(const Arg&) = default; 284 Arg& operator=(Arg&&) = delete; 285 }; 286 287 bool operator==(const Arg&, const Arg&); 288 289 namespace std { 290 template <> 291 struct hash<Arg> { 292 size_t operator()(const Arg&); 293 }; 294 } 295 296 fruit::Component<X> getParentComponent(int, std::string, Arg); 297 298 fruit::Component<X> getComponent() { 299 return fruit::createComponent() 300 .installComponentFunctions(fruit::componentFunction(getParentComponent, 5, std::string("Hello"), Arg{})); 301 } 302 ''' 303 expect_generic_compile_error( 304 'error: use of deleted function .Arg& Arg::operator=\(Arg&&\).' 305 + '|error: overload resolution selected deleted operator .=.' 306 + '|error C2280: .Arg &Arg::operator =\(Arg &&\).: attempting to reference a deleted function', 307 COMMON_DEFINITIONS, 308 source) 309 310def test_component_function_error_not_move_assignable_with_conversion(): 311 source = ''' 312 struct X {}; 313 314 struct Arg { 315 Arg(int) {} 316 Arg() = default; 317 Arg(const Arg&) = default; 318 Arg(Arg&&) = default; 319 Arg& operator=(const Arg&) = default; 320 Arg& operator=(Arg&&) = delete; 321 }; 322 323 bool operator==(const Arg&, const Arg&); 324 325 namespace std { 326 template <> 327 struct hash<Arg> { 328 size_t operator()(const Arg&); 329 }; 330 } 331 332 fruit::Component<X> getParentComponent(int, std::string, Arg); 333 334 fruit::Component<X> getComponent() { 335 return fruit::createComponent() 336 .installComponentFunctions(fruit::componentFunction(getParentComponent, 5, std::string("Hello"), 15)); 337 } 338 ''' 339 expect_generic_compile_error( 340 'error: use of deleted function .Arg& Arg::operator=\(Arg&&\).' 341 + '|error: overload resolution selected deleted operator .=.' 342 + '|error C2280: .Arg &Arg::operator =\(Arg &&\).: attempting to reference a deleted function', 343 COMMON_DEFINITIONS, 344 source) 345 346def test_component_function_error_not_copy_assignable(): 347 source = ''' 348 struct X { 349 int n; 350 X(int n) : n(n) {} 351 }; 352 353 struct Arg { 354 Arg() = default; 355 Arg(const Arg&) = default; 356 Arg(Arg&&) = default; 357 Arg& operator=(const Arg&) = delete; 358 Arg& operator=(Arg&&) = default; 359 }; 360 361 bool operator==(const Arg&, const Arg&); 362 363 namespace std { 364 template <> 365 struct hash<Arg> { 366 size_t operator()(const Arg&); 367 }; 368 } 369 370 fruit::Component<X> getParentComponent(int, std::string, Arg); 371 372 fruit::Component<X> getComponent() { 373 return fruit::createComponent() 374 .installComponentFunctions(fruit::componentFunction(getParentComponent, 5, std::string("Hello"), Arg{})); 375 } 376 ''' 377 expect_generic_compile_error( 378 'error: use of deleted function .Arg& Arg::operator=\(const Arg&\).' 379 + '|error: overload resolution selected deleted operator .=.' 380 + '|error C2280: .Arg &Arg::operator =\(const Arg &\).: attempting to reference a deleted function', 381 COMMON_DEFINITIONS, 382 source) 383 384def test_component_function_error_not_copy_assignable_with_conversion(): 385 source = ''' 386 struct X { 387 int n; 388 X(int n) : n(n) {} 389 }; 390 391 struct Arg { 392 Arg(int) {} 393 Arg() = default; 394 Arg(const Arg&) = default; 395 Arg(Arg&&) = default; 396 Arg& operator=(const Arg&) = delete; 397 Arg& operator=(Arg&&) = default; 398 }; 399 400 bool operator==(const Arg&, const Arg&); 401 402 namespace std { 403 template <> 404 struct hash<Arg> { 405 size_t operator()(const Arg&); 406 }; 407 } 408 409 fruit::Component<X> getParentComponent(int, std::string, Arg); 410 411 fruit::Component<X> getComponent() { 412 return fruit::createComponent() 413 .installComponentFunctions(fruit::componentFunction(getParentComponent, 5, std::string("Hello"), 15)); 414 } 415 ''' 416 expect_generic_compile_error( 417 'error: use of deleted function .Arg& Arg::operator=\(const Arg&\).' 418 + '|error: overload resolution selected deleted operator .=.' 419 + '|error C2280: .Arg &Arg::operator =\(const Arg &\).: attempting to reference a deleted function', 420 COMMON_DEFINITIONS, 421 source) 422 423def test_component_function_error_not_equality_comparable(): 424 source = ''' 425 struct X { 426 int n; 427 X(int n) : n(n) {} 428 }; 429 430 struct Arg { 431 Arg() = default; 432 Arg(const Arg&) = default; 433 Arg(Arg&&) = default; 434 Arg& operator=(const Arg&) = default; 435 Arg& operator=(Arg&&) = default; 436 }; 437 438 namespace std { 439 template <> 440 struct hash<Arg> { 441 size_t operator()(const Arg&); 442 }; 443 } 444 445 fruit::Component<X> getParentComponent(int, std::string, Arg); 446 447 fruit::Component<X> getComponent() { 448 return fruit::createComponent() 449 .installComponentFunctions(fruit::componentFunction(getParentComponent, 5, std::string("Hello"), Arg{})); 450 } 451 ''' 452 expect_generic_compile_error( 453 'error: no match for .operator==. \(operand types are .const Arg. and .const Arg.\)' 454 + '|error: invalid operands to binary expression \(.const Arg. and .const Arg.\)' 455 + '|error C2676: binary .==.: .const Arg. does not define this operator', 456 COMMON_DEFINITIONS, 457 source) 458 459def test_component_function_error_not_equality_comparable_with_conversion(): 460 source = ''' 461 struct X { 462 int n; 463 X(int n) : n(n) {} 464 }; 465 466 struct Arg { 467 Arg(int) {} 468 Arg() = default; 469 Arg(const Arg&) = default; 470 Arg(Arg&&) = default; 471 Arg& operator=(const Arg&) = default; 472 Arg& operator=(Arg&&) = default; 473 }; 474 475 namespace std { 476 template <> 477 struct hash<Arg> { 478 size_t operator()(const Arg&); 479 }; 480 } 481 482 fruit::Component<X> getParentComponent(int, std::string, Arg); 483 484 fruit::Component<X> getComponent() { 485 return fruit::createComponent() 486 .installComponentFunctions(fruit::componentFunction(getParentComponent, 5, std::string("Hello"), 15)); 487 } 488 ''' 489 expect_generic_compile_error( 490 'error: no match for .operator==. \(operand types are .const Arg. and .const Arg.\)' 491 + '|error: invalid operands to binary expression \(.const Arg. and .const Arg.\)' 492 + '|error C2676: binary .==.: .const Arg. does not define this operator', 493 COMMON_DEFINITIONS, 494 source) 495 496def test_component_function_error_not_hashable(): 497 source = ''' 498 struct X {}; 499 500 struct Arg { 501 Arg() = default; 502 Arg(const Arg&) = default; 503 Arg(Arg&&) = default; 504 Arg& operator=(const Arg&) = default; 505 Arg& operator=(Arg&&) = default; 506 }; 507 508 bool operator==(const Arg&, const Arg&); 509 510 fruit::Component<X> getParentComponent(int, std::string, Arg); 511 512 fruit::Component<X> getComponent() { 513 return fruit::createComponent() 514 .installComponentFunctions(fruit::componentFunction(getParentComponent, 5, std::string("Hello"), Arg{})); 515 } 516 ''' 517 expect_generic_compile_error( 518 'error: use of deleted function .std::hash<Arg>::hash\(\).' 519 + '|error: call to implicitly-deleted default constructor of .std::hash<Arg>.' 520 + '|error: invalid use of incomplete type .struct std::hash<Arg>.' 521 + '|error: implicit instantiation of undefined template .std::(__1::)?hash<Arg>.' 522 + '|error C2338: The C\+\+ Standard doesn.t provide a hash for this type.' 523 + '|error C2064: term does not evaluate to a function taking 1 arguments', 524 COMMON_DEFINITIONS, 525 source) 526 527def test_component_function_error_not_hashable_with_conversion(): 528 source = ''' 529 struct X {}; 530 531 struct Arg { 532 Arg(int) {} 533 Arg() = default; 534 Arg(const Arg&) = default; 535 Arg(Arg&&) = default; 536 Arg& operator=(const Arg&) = default; 537 Arg& operator=(Arg&&) = default; 538 }; 539 540 bool operator==(const Arg&, const Arg&); 541 542 fruit::Component<X> getParentComponent(int, std::string, Arg); 543 544 fruit::Component<X> getComponent() { 545 return fruit::createComponent() 546 .installComponentFunctions(fruit::componentFunction(getParentComponent, 5, std::string("Hello"), 15)); 547 } 548 ''' 549 expect_generic_compile_error( 550 'error: use of deleted function .std::hash<Arg>::hash\(\).' 551 + '|error: call to implicitly-deleted default constructor of .std::hash<Arg>.' 552 + '|error: invalid use of incomplete type .struct std::hash<Arg>.' 553 + '|error: implicit instantiation of undefined template .std::(__1::)?hash<Arg>.' 554 + '|error C2338: The C\+\+ Standard doesn.t provide a hash for this type.' 555 + '|error C2064: term does not evaluate to a function taking 1 arguments', 556 COMMON_DEFINITIONS, 557 source) 558 559if __name__== '__main__': 560 main(__file__) 561