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