1 //===----- unittests/ErrorTest.cpp - Error.h tests ------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "llvm/Support/Error.h" 11 12 #include "llvm/ADT/Twine.h" 13 #include "llvm/Support/Errc.h" 14 #include "llvm/Support/ErrorHandling.h" 15 #include "llvm/Testing/Support/Error.h" 16 #include "gtest/gtest-spi.h" 17 #include "gtest/gtest.h" 18 #include <memory> 19 20 using namespace llvm; 21 22 namespace { 23 24 // Custom error class with a default base class and some random 'info' attached. 25 class CustomError : public ErrorInfo<CustomError> { 26 public: 27 // Create an error with some info attached. 28 CustomError(int Info) : Info(Info) {} 29 30 // Get the info attached to this error. 31 int getInfo() const { return Info; } 32 33 // Log this error to a stream. 34 void log(raw_ostream &OS) const override { 35 OS << "CustomError { " << getInfo() << "}"; 36 } 37 38 std::error_code convertToErrorCode() const override { 39 llvm_unreachable("CustomError doesn't support ECError conversion"); 40 } 41 42 // Used by ErrorInfo::classID. 43 static char ID; 44 45 protected: 46 // This error is subclassed below, but we can't use inheriting constructors 47 // yet, so we can't propagate the constructors through ErrorInfo. Instead 48 // we have to have a default constructor and have the subclass initialize all 49 // fields. 50 CustomError() : Info(0) {} 51 52 int Info; 53 }; 54 55 char CustomError::ID = 0; 56 57 // Custom error class with a custom base class and some additional random 58 // 'info'. 59 class CustomSubError : public ErrorInfo<CustomSubError, CustomError> { 60 public: 61 // Create a sub-error with some info attached. 62 CustomSubError(int Info, int ExtraInfo) : ExtraInfo(ExtraInfo) { 63 this->Info = Info; 64 } 65 66 // Get the extra info attached to this error. 67 int getExtraInfo() const { return ExtraInfo; } 68 69 // Log this error to a stream. 70 void log(raw_ostream &OS) const override { 71 OS << "CustomSubError { " << getInfo() << ", " << getExtraInfo() << "}"; 72 } 73 74 std::error_code convertToErrorCode() const override { 75 llvm_unreachable("CustomSubError doesn't support ECError conversion"); 76 } 77 78 // Used by ErrorInfo::classID. 79 static char ID; 80 81 protected: 82 int ExtraInfo; 83 }; 84 85 char CustomSubError::ID = 0; 86 87 static Error handleCustomError(const CustomError &CE) { 88 return Error::success(); 89 } 90 91 static void handleCustomErrorVoid(const CustomError &CE) {} 92 93 static Error handleCustomErrorUP(std::unique_ptr<CustomError> CE) { 94 return Error::success(); 95 } 96 97 static void handleCustomErrorUPVoid(std::unique_ptr<CustomError> CE) {} 98 99 // Test that success values implicitly convert to false, and don't cause crashes 100 // once they've been implicitly converted. 101 TEST(Error, CheckedSuccess) { 102 Error E = Error::success(); 103 EXPECT_FALSE(E) << "Unexpected error while testing Error 'Success'"; 104 } 105 106 // Test that unchecked succes values cause an abort. 107 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 108 TEST(Error, UncheckedSuccess) { 109 EXPECT_DEATH({ Error E = Error::success(); }, 110 "Program aborted due to an unhandled Error:") 111 << "Unchecked Error Succes value did not cause abort()"; 112 } 113 #endif 114 115 // ErrorAsOutParameter tester. 116 void errAsOutParamHelper(Error &Err) { 117 ErrorAsOutParameter ErrAsOutParam(&Err); 118 // Verify that checked flag is raised - assignment should not crash. 119 Err = Error::success(); 120 // Raise the checked bit manually - caller should still have to test the 121 // error. 122 (void)!!Err; 123 } 124 125 // Test that ErrorAsOutParameter sets the checked flag on construction. 126 TEST(Error, ErrorAsOutParameterChecked) { 127 Error E = Error::success(); 128 errAsOutParamHelper(E); 129 (void)!!E; 130 } 131 132 // Test that ErrorAsOutParameter clears the checked flag on destruction. 133 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 134 TEST(Error, ErrorAsOutParameterUnchecked) { 135 EXPECT_DEATH({ Error E = Error::success(); errAsOutParamHelper(E); }, 136 "Program aborted due to an unhandled Error:") 137 << "ErrorAsOutParameter did not clear the checked flag on destruction."; 138 } 139 #endif 140 141 // Check that we abort on unhandled failure cases. (Force conversion to bool 142 // to make sure that we don't accidentally treat checked errors as handled). 143 // Test runs in debug mode only. 144 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 145 TEST(Error, UncheckedError) { 146 auto DropUnhandledError = []() { 147 Error E = make_error<CustomError>(42); 148 (void)!E; 149 }; 150 EXPECT_DEATH(DropUnhandledError(), 151 "Program aborted due to an unhandled Error:") 152 << "Unhandled Error failure value did not cause abort()"; 153 } 154 #endif 155 156 // Check 'Error::isA<T>' method handling. 157 TEST(Error, IsAHandling) { 158 // Check 'isA' handling. 159 Error E = make_error<CustomError>(1); 160 Error F = make_error<CustomSubError>(1, 2); 161 Error G = Error::success(); 162 163 EXPECT_TRUE(E.isA<CustomError>()); 164 EXPECT_FALSE(E.isA<CustomSubError>()); 165 EXPECT_TRUE(F.isA<CustomError>()); 166 EXPECT_TRUE(F.isA<CustomSubError>()); 167 EXPECT_FALSE(G.isA<CustomError>()); 168 169 consumeError(std::move(E)); 170 consumeError(std::move(F)); 171 consumeError(std::move(G)); 172 } 173 174 // Check that we can handle a custom error. 175 TEST(Error, HandleCustomError) { 176 int CaughtErrorInfo = 0; 177 handleAllErrors(make_error<CustomError>(42), [&](const CustomError &CE) { 178 CaughtErrorInfo = CE.getInfo(); 179 }); 180 181 EXPECT_TRUE(CaughtErrorInfo == 42) << "Wrong result from CustomError handler"; 182 } 183 184 // Check that handler type deduction also works for handlers 185 // of the following types: 186 // void (const Err&) 187 // Error (const Err&) mutable 188 // void (const Err&) mutable 189 // Error (Err&) 190 // void (Err&) 191 // Error (Err&) mutable 192 // void (Err&) mutable 193 // Error (unique_ptr<Err>) 194 // void (unique_ptr<Err>) 195 // Error (unique_ptr<Err>) mutable 196 // void (unique_ptr<Err>) mutable 197 TEST(Error, HandlerTypeDeduction) { 198 199 handleAllErrors(make_error<CustomError>(42), [](const CustomError &CE) {}); 200 201 handleAllErrors( 202 make_error<CustomError>(42), 203 [](const CustomError &CE) mutable -> Error { return Error::success(); }); 204 205 handleAllErrors(make_error<CustomError>(42), 206 [](const CustomError &CE) mutable {}); 207 208 handleAllErrors(make_error<CustomError>(42), 209 [](CustomError &CE) -> Error { return Error::success(); }); 210 211 handleAllErrors(make_error<CustomError>(42), [](CustomError &CE) {}); 212 213 handleAllErrors(make_error<CustomError>(42), 214 [](CustomError &CE) mutable -> Error { return Error::success(); }); 215 216 handleAllErrors(make_error<CustomError>(42), [](CustomError &CE) mutable {}); 217 218 handleAllErrors( 219 make_error<CustomError>(42), 220 [](std::unique_ptr<CustomError> CE) -> Error { return Error::success(); }); 221 222 handleAllErrors(make_error<CustomError>(42), 223 [](std::unique_ptr<CustomError> CE) {}); 224 225 handleAllErrors( 226 make_error<CustomError>(42), 227 [](std::unique_ptr<CustomError> CE) mutable -> Error { return Error::success(); }); 228 229 handleAllErrors(make_error<CustomError>(42), 230 [](std::unique_ptr<CustomError> CE) mutable {}); 231 232 // Check that named handlers of type 'Error (const Err&)' work. 233 handleAllErrors(make_error<CustomError>(42), handleCustomError); 234 235 // Check that named handlers of type 'void (const Err&)' work. 236 handleAllErrors(make_error<CustomError>(42), handleCustomErrorVoid); 237 238 // Check that named handlers of type 'Error (std::unique_ptr<Err>)' work. 239 handleAllErrors(make_error<CustomError>(42), handleCustomErrorUP); 240 241 // Check that named handlers of type 'Error (std::unique_ptr<Err>)' work. 242 handleAllErrors(make_error<CustomError>(42), handleCustomErrorUPVoid); 243 } 244 245 // Test that we can handle errors with custom base classes. 246 TEST(Error, HandleCustomErrorWithCustomBaseClass) { 247 int CaughtErrorInfo = 0; 248 int CaughtErrorExtraInfo = 0; 249 handleAllErrors(make_error<CustomSubError>(42, 7), 250 [&](const CustomSubError &SE) { 251 CaughtErrorInfo = SE.getInfo(); 252 CaughtErrorExtraInfo = SE.getExtraInfo(); 253 }); 254 255 EXPECT_TRUE(CaughtErrorInfo == 42 && CaughtErrorExtraInfo == 7) 256 << "Wrong result from CustomSubError handler"; 257 } 258 259 // Check that we trigger only the first handler that applies. 260 TEST(Error, FirstHandlerOnly) { 261 int DummyInfo = 0; 262 int CaughtErrorInfo = 0; 263 int CaughtErrorExtraInfo = 0; 264 265 handleAllErrors(make_error<CustomSubError>(42, 7), 266 [&](const CustomSubError &SE) { 267 CaughtErrorInfo = SE.getInfo(); 268 CaughtErrorExtraInfo = SE.getExtraInfo(); 269 }, 270 [&](const CustomError &CE) { DummyInfo = CE.getInfo(); }); 271 272 EXPECT_TRUE(CaughtErrorInfo == 42 && CaughtErrorExtraInfo == 7 && 273 DummyInfo == 0) 274 << "Activated the wrong Error handler(s)"; 275 } 276 277 // Check that general handlers shadow specific ones. 278 TEST(Error, HandlerShadowing) { 279 int CaughtErrorInfo = 0; 280 int DummyInfo = 0; 281 int DummyExtraInfo = 0; 282 283 handleAllErrors( 284 make_error<CustomSubError>(42, 7), 285 [&](const CustomError &CE) { CaughtErrorInfo = CE.getInfo(); }, 286 [&](const CustomSubError &SE) { 287 DummyInfo = SE.getInfo(); 288 DummyExtraInfo = SE.getExtraInfo(); 289 }); 290 291 EXPECT_TRUE(CaughtErrorInfo == 42 && DummyInfo == 0 && DummyExtraInfo == 0) 292 << "General Error handler did not shadow specific handler"; 293 } 294 295 // Test joinErrors. 296 TEST(Error, CheckJoinErrors) { 297 int CustomErrorInfo1 = 0; 298 int CustomErrorInfo2 = 0; 299 int CustomErrorExtraInfo = 0; 300 Error E = 301 joinErrors(make_error<CustomError>(7), make_error<CustomSubError>(42, 7)); 302 303 handleAllErrors(std::move(E), 304 [&](const CustomSubError &SE) { 305 CustomErrorInfo2 = SE.getInfo(); 306 CustomErrorExtraInfo = SE.getExtraInfo(); 307 }, 308 [&](const CustomError &CE) { 309 // Assert that the CustomError instance above is handled 310 // before the 311 // CustomSubError - joinErrors should preserve error 312 // ordering. 313 EXPECT_EQ(CustomErrorInfo2, 0) 314 << "CustomErrorInfo2 should be 0 here. " 315 "joinErrors failed to preserve ordering.\n"; 316 CustomErrorInfo1 = CE.getInfo(); 317 }); 318 319 EXPECT_TRUE(CustomErrorInfo1 == 7 && CustomErrorInfo2 == 42 && 320 CustomErrorExtraInfo == 7) 321 << "Failed handling compound Error."; 322 323 // Test appending a single item to a list. 324 { 325 int Sum = 0; 326 handleAllErrors( 327 joinErrors( 328 joinErrors(make_error<CustomError>(7), 329 make_error<CustomError>(7)), 330 make_error<CustomError>(7)), 331 [&](const CustomError &CE) { 332 Sum += CE.getInfo(); 333 }); 334 EXPECT_EQ(Sum, 21) << "Failed to correctly append error to error list."; 335 } 336 337 // Test prepending a single item to a list. 338 { 339 int Sum = 0; 340 handleAllErrors( 341 joinErrors( 342 make_error<CustomError>(7), 343 joinErrors(make_error<CustomError>(7), 344 make_error<CustomError>(7))), 345 [&](const CustomError &CE) { 346 Sum += CE.getInfo(); 347 }); 348 EXPECT_EQ(Sum, 21) << "Failed to correctly prepend error to error list."; 349 } 350 351 // Test concatenating two error lists. 352 { 353 int Sum = 0; 354 handleAllErrors( 355 joinErrors( 356 joinErrors( 357 make_error<CustomError>(7), 358 make_error<CustomError>(7)), 359 joinErrors( 360 make_error<CustomError>(7), 361 make_error<CustomError>(7))), 362 [&](const CustomError &CE) { 363 Sum += CE.getInfo(); 364 }); 365 EXPECT_EQ(Sum, 28) << "Failed to correctly concatenate error lists."; 366 } 367 } 368 369 // Test that we can consume success values. 370 TEST(Error, ConsumeSuccess) { 371 Error E = Error::success(); 372 consumeError(std::move(E)); 373 } 374 375 TEST(Error, ConsumeError) { 376 Error E = make_error<CustomError>(7); 377 consumeError(std::move(E)); 378 } 379 380 // Test that handleAllUnhandledErrors crashes if an error is not caught. 381 // Test runs in debug mode only. 382 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 383 TEST(Error, FailureToHandle) { 384 auto FailToHandle = []() { 385 handleAllErrors(make_error<CustomError>(7), [&](const CustomSubError &SE) { 386 errs() << "This should never be called"; 387 exit(1); 388 }); 389 }; 390 391 EXPECT_DEATH(FailToHandle(), 392 "Failure value returned from cantFail wrapped call") 393 << "Unhandled Error in handleAllErrors call did not cause an " 394 "abort()"; 395 } 396 #endif 397 398 // Test that handleAllUnhandledErrors crashes if an error is returned from a 399 // handler. 400 // Test runs in debug mode only. 401 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 402 TEST(Error, FailureFromHandler) { 403 auto ReturnErrorFromHandler = []() { 404 handleAllErrors(make_error<CustomError>(7), 405 [&](std::unique_ptr<CustomSubError> SE) { 406 return Error(std::move(SE)); 407 }); 408 }; 409 410 EXPECT_DEATH(ReturnErrorFromHandler(), 411 "Failure value returned from cantFail wrapped call") 412 << " Error returned from handler in handleAllErrors call did not " 413 "cause abort()"; 414 } 415 #endif 416 417 // Test that we can return values from handleErrors. 418 TEST(Error, CatchErrorFromHandler) { 419 int ErrorInfo = 0; 420 421 Error E = handleErrors( 422 make_error<CustomError>(7), 423 [&](std::unique_ptr<CustomError> CE) { return Error(std::move(CE)); }); 424 425 handleAllErrors(std::move(E), 426 [&](const CustomError &CE) { ErrorInfo = CE.getInfo(); }); 427 428 EXPECT_EQ(ErrorInfo, 7) 429 << "Failed to handle Error returned from handleErrors."; 430 } 431 432 TEST(Error, StringError) { 433 std::string Msg; 434 raw_string_ostream S(Msg); 435 logAllUnhandledErrors(make_error<StringError>("foo" + Twine(42), 436 inconvertibleErrorCode()), 437 S, ""); 438 EXPECT_EQ(S.str(), "foo42\n") << "Unexpected StringError log result"; 439 440 auto EC = 441 errorToErrorCode(make_error<StringError>("", errc::invalid_argument)); 442 EXPECT_EQ(EC, errc::invalid_argument) 443 << "Failed to convert StringError to error_code."; 444 } 445 446 // Test that the ExitOnError utility works as expected. 447 TEST(Error, ExitOnError) { 448 ExitOnError ExitOnErr; 449 ExitOnErr.setBanner("Error in tool:"); 450 ExitOnErr.setExitCodeMapper([](const Error &E) { 451 if (E.isA<CustomSubError>()) 452 return 2; 453 return 1; 454 }); 455 456 // Make sure we don't bail on success. 457 ExitOnErr(Error::success()); 458 EXPECT_EQ(ExitOnErr(Expected<int>(7)), 7) 459 << "exitOnError returned an invalid value for Expected"; 460 461 int A = 7; 462 int &B = ExitOnErr(Expected<int&>(A)); 463 EXPECT_EQ(&A, &B) << "ExitOnError failed to propagate reference"; 464 465 // Exit tests. 466 EXPECT_EXIT(ExitOnErr(make_error<CustomError>(7)), 467 ::testing::ExitedWithCode(1), "Error in tool:") 468 << "exitOnError returned an unexpected error result"; 469 470 EXPECT_EXIT(ExitOnErr(Expected<int>(make_error<CustomSubError>(0, 0))), 471 ::testing::ExitedWithCode(2), "Error in tool:") 472 << "exitOnError returned an unexpected error result"; 473 } 474 475 // Test that the ExitOnError utility works as expected. 476 TEST(Error, CantFailSuccess) { 477 cantFail(Error::success()); 478 479 int X = cantFail(Expected<int>(42)); 480 EXPECT_EQ(X, 42) << "Expected value modified by cantFail"; 481 482 int Dummy = 42; 483 int &Y = cantFail(Expected<int&>(Dummy)); 484 EXPECT_EQ(&Dummy, &Y) << "Reference mangled by cantFail"; 485 } 486 487 // Test that cantFail results in a crash if you pass it a failure value. 488 #if LLVM_ENABLE_ABI_BREAKING_CHECKS && !defined(NDEBUG) 489 TEST(Error, CantFailDeath) { 490 EXPECT_DEATH( 491 cantFail(make_error<StringError>("foo", inconvertibleErrorCode()), 492 "Cantfail call failed"), 493 "Cantfail call failed") 494 << "cantFail(Error) did not cause an abort for failure value"; 495 496 EXPECT_DEATH( 497 { 498 auto IEC = inconvertibleErrorCode(); 499 int X = cantFail(Expected<int>(make_error<StringError>("foo", IEC))); 500 (void)X; 501 }, 502 "Failure value returned from cantFail wrapped call") 503 << "cantFail(Expected<int>) did not cause an abort for failure value"; 504 } 505 #endif 506 507 508 // Test Checked Expected<T> in success mode. 509 TEST(Error, CheckedExpectedInSuccessMode) { 510 Expected<int> A = 7; 511 EXPECT_TRUE(!!A) << "Expected with non-error value doesn't convert to 'true'"; 512 // Access is safe in second test, since we checked the error in the first. 513 EXPECT_EQ(*A, 7) << "Incorrect Expected non-error value"; 514 } 515 516 // Test Expected with reference type. 517 TEST(Error, ExpectedWithReferenceType) { 518 int A = 7; 519 Expected<int&> B = A; 520 // 'Check' B. 521 (void)!!B; 522 int &C = *B; 523 EXPECT_EQ(&A, &C) << "Expected failed to propagate reference"; 524 } 525 526 // Test Unchecked Expected<T> in success mode. 527 // We expect this to blow up the same way Error would. 528 // Test runs in debug mode only. 529 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 530 TEST(Error, UncheckedExpectedInSuccessModeDestruction) { 531 EXPECT_DEATH({ Expected<int> A = 7; }, 532 "Expected<T> must be checked before access or destruction.") 533 << "Unchecekd Expected<T> success value did not cause an abort()."; 534 } 535 #endif 536 537 // Test Unchecked Expected<T> in success mode. 538 // We expect this to blow up the same way Error would. 539 // Test runs in debug mode only. 540 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 541 TEST(Error, UncheckedExpectedInSuccessModeAccess) { 542 EXPECT_DEATH({ Expected<int> A = 7; *A; }, 543 "Expected<T> must be checked before access or destruction.") 544 << "Unchecekd Expected<T> success value did not cause an abort()."; 545 } 546 #endif 547 548 // Test Unchecked Expected<T> in success mode. 549 // We expect this to blow up the same way Error would. 550 // Test runs in debug mode only. 551 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 552 TEST(Error, UncheckedExpectedInSuccessModeAssignment) { 553 EXPECT_DEATH({ Expected<int> A = 7; A = 7; }, 554 "Expected<T> must be checked before access or destruction.") 555 << "Unchecekd Expected<T> success value did not cause an abort()."; 556 } 557 #endif 558 559 // Test Expected<T> in failure mode. 560 TEST(Error, ExpectedInFailureMode) { 561 Expected<int> A = make_error<CustomError>(42); 562 EXPECT_FALSE(!!A) << "Expected with error value doesn't convert to 'false'"; 563 Error E = A.takeError(); 564 EXPECT_TRUE(E.isA<CustomError>()) << "Incorrect Expected error value"; 565 consumeError(std::move(E)); 566 } 567 568 // Check that an Expected instance with an error value doesn't allow access to 569 // operator*. 570 // Test runs in debug mode only. 571 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 572 TEST(Error, AccessExpectedInFailureMode) { 573 Expected<int> A = make_error<CustomError>(42); 574 EXPECT_DEATH(*A, "Expected<T> must be checked before access or destruction.") 575 << "Incorrect Expected error value"; 576 consumeError(A.takeError()); 577 } 578 #endif 579 580 // Check that an Expected instance with an error triggers an abort if 581 // unhandled. 582 // Test runs in debug mode only. 583 #if LLVM_ENABLE_ABI_BREAKING_CHECKS 584 TEST(Error, UnhandledExpectedInFailureMode) { 585 EXPECT_DEATH({ Expected<int> A = make_error<CustomError>(42); }, 586 "Expected<T> must be checked before access or destruction.") 587 << "Unchecked Expected<T> failure value did not cause an abort()"; 588 } 589 #endif 590 591 // Test covariance of Expected. 592 TEST(Error, ExpectedCovariance) { 593 class B {}; 594 class D : public B {}; 595 596 Expected<B *> A1(Expected<D *>(nullptr)); 597 // Check A1 by converting to bool before assigning to it. 598 (void)!!A1; 599 A1 = Expected<D *>(nullptr); 600 // Check A1 again before destruction. 601 (void)!!A1; 602 603 Expected<std::unique_ptr<B>> A2(Expected<std::unique_ptr<D>>(nullptr)); 604 // Check A2 by converting to bool before assigning to it. 605 (void)!!A2; 606 A2 = Expected<std::unique_ptr<D>>(nullptr); 607 // Check A2 again before destruction. 608 (void)!!A2; 609 } 610 611 // Test that handleExpected just returns success values. 612 TEST(Error, HandleExpectedSuccess) { 613 auto ValOrErr = 614 handleExpected(Expected<int>(42), 615 []() { return Expected<int>(43); }); 616 EXPECT_TRUE(!!ValOrErr) 617 << "handleExpected should have returned a success value here"; 618 EXPECT_EQ(*ValOrErr, 42) 619 << "handleExpected should have returned the original success value here"; 620 } 621 622 enum FooStrategy { Aggressive, Conservative }; 623 624 static Expected<int> foo(FooStrategy S) { 625 if (S == Aggressive) 626 return make_error<CustomError>(7); 627 return 42; 628 } 629 630 // Test that handleExpected invokes the error path if errors are not handled. 631 TEST(Error, HandleExpectedUnhandledError) { 632 // foo(Aggressive) should return a CustomError which should pass through as 633 // there is no handler for CustomError. 634 auto ValOrErr = 635 handleExpected( 636 foo(Aggressive), 637 []() { return foo(Conservative); }); 638 639 EXPECT_FALSE(!!ValOrErr) 640 << "handleExpected should have returned an error here"; 641 auto Err = ValOrErr.takeError(); 642 EXPECT_TRUE(Err.isA<CustomError>()) 643 << "handleExpected should have returned the CustomError generated by " 644 "foo(Aggressive) here"; 645 consumeError(std::move(Err)); 646 } 647 648 // Test that handleExpected invokes the fallback path if errors are handled. 649 TEST(Error, HandleExpectedHandledError) { 650 // foo(Aggressive) should return a CustomError which should handle triggering 651 // the fallback path. 652 auto ValOrErr = 653 handleExpected( 654 foo(Aggressive), 655 []() { return foo(Conservative); }, 656 [](const CustomError&) { /* do nothing */ }); 657 658 EXPECT_TRUE(!!ValOrErr) 659 << "handleExpected should have returned a success value here"; 660 EXPECT_EQ(*ValOrErr, 42) 661 << "handleExpected returned the wrong success value"; 662 } 663 664 TEST(Error, ErrorCodeConversions) { 665 // Round-trip a success value to check that it converts correctly. 666 EXPECT_EQ(errorToErrorCode(errorCodeToError(std::error_code())), 667 std::error_code()) 668 << "std::error_code() should round-trip via Error conversions"; 669 670 // Round-trip an error value to check that it converts correctly. 671 EXPECT_EQ(errorToErrorCode(errorCodeToError(errc::invalid_argument)), 672 errc::invalid_argument) 673 << "std::error_code error value should round-trip via Error " 674 "conversions"; 675 676 // Round-trip a success value through ErrorOr/Expected to check that it 677 // converts correctly. 678 { 679 auto Orig = ErrorOr<int>(42); 680 auto RoundTripped = 681 expectedToErrorOr(errorOrToExpected(ErrorOr<int>(42))); 682 EXPECT_EQ(*Orig, *RoundTripped) 683 << "ErrorOr<T> success value should round-trip via Expected<T> " 684 "conversions."; 685 } 686 687 // Round-trip a failure value through ErrorOr/Expected to check that it 688 // converts correctly. 689 { 690 auto Orig = ErrorOr<int>(errc::invalid_argument); 691 auto RoundTripped = 692 expectedToErrorOr( 693 errorOrToExpected(ErrorOr<int>(errc::invalid_argument))); 694 EXPECT_EQ(Orig.getError(), RoundTripped.getError()) 695 << "ErrorOr<T> failure value should round-trip via Expected<T> " 696 "conversions."; 697 } 698 } 699 700 // Test that error messages work. 701 TEST(Error, ErrorMessage) { 702 EXPECT_EQ(toString(Error::success()).compare(""), 0); 703 704 Error E1 = make_error<CustomError>(0); 705 EXPECT_EQ(toString(std::move(E1)).compare("CustomError { 0}"), 0); 706 707 Error E2 = make_error<CustomError>(0); 708 handleAllErrors(std::move(E2), [](const CustomError &CE) { 709 EXPECT_EQ(CE.message().compare("CustomError { 0}"), 0); 710 }); 711 712 Error E3 = joinErrors(make_error<CustomError>(0), make_error<CustomError>(1)); 713 EXPECT_EQ(toString(std::move(E3)) 714 .compare("CustomError { 0}\n" 715 "CustomError { 1}"), 716 0); 717 } 718 719 TEST(Error, ErrorMatchers) { 720 EXPECT_THAT_ERROR(Error::success(), Succeeded()); 721 EXPECT_NONFATAL_FAILURE( 722 EXPECT_THAT_ERROR(make_error<CustomError>(0), Succeeded()), 723 "Expected: succeeded\n Actual: failed (CustomError { 0})"); 724 725 EXPECT_THAT_ERROR(make_error<CustomError>(0), Failed()); 726 EXPECT_NONFATAL_FAILURE(EXPECT_THAT_ERROR(Error::success(), Failed()), 727 "Expected: failed\n Actual: succeeded"); 728 729 EXPECT_THAT_EXPECTED(Expected<int>(0), Succeeded()); 730 EXPECT_NONFATAL_FAILURE( 731 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), 732 Succeeded()), 733 "Expected: succeeded\n Actual: failed (CustomError { 0})"); 734 735 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), Failed()); 736 EXPECT_NONFATAL_FAILURE( 737 EXPECT_THAT_EXPECTED(Expected<int>(0), Failed()), 738 "Expected: failed\n Actual: succeeded with value 0"); 739 740 EXPECT_THAT_EXPECTED(Expected<int>(0), HasValue(0)); 741 EXPECT_NONFATAL_FAILURE( 742 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), 743 HasValue(0)), 744 "Expected: succeeded with value (is equal to 0)\n" 745 " Actual: failed (CustomError { 0})"); 746 EXPECT_NONFATAL_FAILURE( 747 EXPECT_THAT_EXPECTED(Expected<int>(1), HasValue(0)), 748 "Expected: succeeded with value (is equal to 0)\n" 749 " Actual: succeeded with value 1, (isn't equal to 0)"); 750 751 EXPECT_THAT_EXPECTED(Expected<int &>(make_error<CustomError>(0)), Failed()); 752 int a = 1; 753 EXPECT_THAT_EXPECTED(Expected<int &>(a), Succeeded()); 754 EXPECT_THAT_EXPECTED(Expected<int &>(a), HasValue(testing::Eq(1))); 755 756 EXPECT_THAT_EXPECTED(Expected<int>(1), HasValue(testing::Gt(0))); 757 EXPECT_NONFATAL_FAILURE( 758 EXPECT_THAT_EXPECTED(Expected<int>(0), HasValue(testing::Gt(1))), 759 "Expected: succeeded with value (is > 1)\n" 760 " Actual: succeeded with value 0, (isn't > 1)"); 761 EXPECT_NONFATAL_FAILURE( 762 EXPECT_THAT_EXPECTED(Expected<int>(make_error<CustomError>(0)), 763 HasValue(testing::Gt(1))), 764 "Expected: succeeded with value (is > 1)\n" 765 " Actual: failed (CustomError { 0})"); 766 } 767 768 } // end anon namespace 769