statusor_test.cc (59288B)
1 // Copyright 2020 The Abseil Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // https://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "absl/status/statusor.h" 16 17 #include <array> 18 #include <cstddef> 19 #include <initializer_list> 20 #include <map> 21 #include <memory> 22 #include <ostream> 23 #include <sstream> 24 #include <string> 25 #include <type_traits> 26 #include <utility> 27 #include <vector> 28 29 #include "gmock/gmock.h" 30 #include "gtest/gtest.h" 31 #include "absl/base/casts.h" 32 #include "absl/memory/memory.h" 33 #include "absl/status/status.h" 34 #include "absl/status/status_matchers.h" 35 #include "absl/strings/str_cat.h" 36 #include "absl/strings/string_view.h" 37 #include "absl/types/any.h" 38 #include "absl/types/variant.h" 39 #include "absl/utility/utility.h" 40 41 namespace { 42 43 using ::absl_testing::IsOk; 44 using ::absl_testing::IsOkAndHolds; 45 using ::testing::AllOf; 46 using ::testing::AnyOf; 47 using ::testing::AnyWith; 48 using ::testing::ElementsAre; 49 using ::testing::EndsWith; 50 using ::testing::Field; 51 using ::testing::HasSubstr; 52 using ::testing::Ne; 53 using ::testing::Not; 54 using ::testing::Pointee; 55 using ::testing::StartsWith; 56 using ::testing::VariantWith; 57 58 struct CopyDetector { 59 CopyDetector() = default; 60 explicit CopyDetector(int xx) : x(xx) {} 61 CopyDetector(CopyDetector&& d) noexcept 62 : x(d.x), copied(false), moved(true) {} 63 CopyDetector(const CopyDetector& d) : x(d.x), copied(true), moved(false) {} 64 CopyDetector& operator=(const CopyDetector& c) { 65 x = c.x; 66 copied = true; 67 moved = false; 68 return *this; 69 } 70 CopyDetector& operator=(CopyDetector&& c) noexcept { 71 x = c.x; 72 copied = false; 73 moved = true; 74 return *this; 75 } 76 int x = 0; 77 bool copied = false; 78 bool moved = false; 79 }; 80 81 testing::Matcher<const CopyDetector&> CopyDetectorHas(int a, bool b, bool c) { 82 return AllOf(Field(&CopyDetector::x, a), Field(&CopyDetector::moved, b), 83 Field(&CopyDetector::copied, c)); 84 } 85 86 class Base1 { 87 public: 88 virtual ~Base1() {} 89 int pad; 90 }; 91 92 class Base2 { 93 public: 94 virtual ~Base2() {} 95 int yetotherpad; 96 }; 97 98 class Derived : public Base1, public Base2 { 99 public: 100 virtual ~Derived() {} 101 int evenmorepad; 102 }; 103 104 class CopyNoAssign { 105 public: 106 explicit CopyNoAssign(int value) : foo(value) {} 107 CopyNoAssign(const CopyNoAssign& other) : foo(other.foo) {} 108 int foo; 109 110 private: 111 const CopyNoAssign& operator=(const CopyNoAssign&); 112 }; 113 114 absl::StatusOr<std::unique_ptr<int>> ReturnUniquePtr() { 115 // Uses implicit constructor from T&& 116 return absl::make_unique<int>(0); 117 } 118 119 TEST(StatusOr, ElementType) { 120 static_assert(std::is_same<absl::StatusOr<int>::value_type, int>(), ""); 121 static_assert(std::is_same<absl::StatusOr<char>::value_type, char>(), ""); 122 } 123 124 TEST(StatusOr, TestMoveOnlyInitialization) { 125 absl::StatusOr<std::unique_ptr<int>> thing(ReturnUniquePtr()); 126 ASSERT_TRUE(thing.ok()); 127 EXPECT_EQ(0, **thing); 128 int* previous = thing->get(); 129 130 thing = ReturnUniquePtr(); 131 EXPECT_TRUE(thing.ok()); 132 EXPECT_EQ(0, **thing); 133 EXPECT_NE(previous, thing->get()); 134 } 135 136 TEST(StatusOr, TestMoveOnlyValueExtraction) { 137 absl::StatusOr<std::unique_ptr<int>> thing(ReturnUniquePtr()); 138 ASSERT_TRUE(thing.ok()); 139 std::unique_ptr<int> ptr = *std::move(thing); 140 EXPECT_EQ(0, *ptr); 141 142 thing = std::move(ptr); 143 ptr = std::move(*thing); 144 EXPECT_EQ(0, *ptr); 145 } 146 147 TEST(StatusOr, TestMoveOnlyInitializationFromTemporaryByValueOrDie) { 148 std::unique_ptr<int> ptr(*ReturnUniquePtr()); 149 EXPECT_EQ(0, *ptr); 150 } 151 152 TEST(StatusOr, TestValueOrDieOverloadForConstTemporary) { 153 static_assert( 154 std::is_same< 155 const int&&, 156 decltype(std::declval<const absl::StatusOr<int>&&>().value())>(), 157 "value() for const temporaries should return const T&&"); 158 } 159 160 TEST(StatusOr, TestMoveOnlyConversion) { 161 absl::StatusOr<std::unique_ptr<const int>> const_thing(ReturnUniquePtr()); 162 EXPECT_TRUE(const_thing.ok()); 163 EXPECT_EQ(0, **const_thing); 164 165 // Test rvalue converting assignment 166 const int* const_previous = const_thing->get(); 167 const_thing = ReturnUniquePtr(); 168 EXPECT_TRUE(const_thing.ok()); 169 EXPECT_EQ(0, **const_thing); 170 EXPECT_NE(const_previous, const_thing->get()); 171 } 172 173 TEST(StatusOr, TestMoveOnlyVector) { 174 // Sanity check that absl::StatusOr<MoveOnly> works in vector. 175 std::vector<absl::StatusOr<std::unique_ptr<int>>> vec; 176 vec.push_back(ReturnUniquePtr()); 177 vec.resize(2); 178 auto another_vec = std::move(vec); 179 EXPECT_EQ(0, **another_vec[0]); 180 EXPECT_EQ(absl::UnknownError(""), another_vec[1].status()); 181 } 182 183 TEST(StatusOr, TestDefaultCtor) { 184 absl::StatusOr<int> thing; 185 EXPECT_FALSE(thing.ok()); 186 EXPECT_EQ(thing.status().code(), absl::StatusCode::kUnknown); 187 } 188 189 TEST(StatusOr, StatusCtorForwards) { 190 absl::Status status(absl::StatusCode::kInternal, "Some error"); 191 192 EXPECT_EQ(absl::StatusOr<int>(status).status().message(), "Some error"); 193 EXPECT_EQ(status.message(), "Some error"); 194 195 EXPECT_EQ(absl::StatusOr<int>(std::move(status)).status().message(), 196 "Some error"); 197 EXPECT_NE(status.message(), "Some error"); 198 } 199 200 TEST(BadStatusOrAccessTest, CopyConstructionWhatOk) { 201 absl::Status error = 202 absl::InternalError("some arbitrary message too big for the sso buffer"); 203 absl::BadStatusOrAccess e1{error}; 204 absl::BadStatusOrAccess e2{e1}; 205 EXPECT_THAT(e1.what(), HasSubstr(error.ToString())); 206 EXPECT_THAT(e2.what(), HasSubstr(error.ToString())); 207 } 208 209 TEST(BadStatusOrAccessTest, CopyAssignmentWhatOk) { 210 absl::Status error = 211 absl::InternalError("some arbitrary message too big for the sso buffer"); 212 absl::BadStatusOrAccess e1{error}; 213 absl::BadStatusOrAccess e2{absl::InternalError("other")}; 214 e2 = e1; 215 EXPECT_THAT(e1.what(), HasSubstr(error.ToString())); 216 EXPECT_THAT(e2.what(), HasSubstr(error.ToString())); 217 } 218 219 TEST(BadStatusOrAccessTest, MoveConstructionWhatOk) { 220 absl::Status error = 221 absl::InternalError("some arbitrary message too big for the sso buffer"); 222 absl::BadStatusOrAccess e1{error}; 223 absl::BadStatusOrAccess e2{std::move(e1)}; 224 EXPECT_THAT(e2.what(), HasSubstr(error.ToString())); 225 } 226 227 TEST(BadStatusOrAccessTest, MoveAssignmentWhatOk) { 228 absl::Status error = 229 absl::InternalError("some arbitrary message too big for the sso buffer"); 230 absl::BadStatusOrAccess e1{error}; 231 absl::BadStatusOrAccess e2{absl::InternalError("other")}; 232 e2 = std::move(e1); 233 EXPECT_THAT(e2.what(), HasSubstr(error.ToString())); 234 } 235 236 // Define `EXPECT_DEATH_OR_THROW` to test the behavior of `StatusOr::value`, 237 // which either throws `BadStatusOrAccess` or `LOG(FATAL)` based on whether 238 // exceptions are enabled. 239 #ifdef ABSL_HAVE_EXCEPTIONS 240 #define EXPECT_DEATH_OR_THROW(statement, status_) \ 241 EXPECT_THROW( \ 242 { \ 243 try { \ 244 statement; \ 245 } catch (const absl::BadStatusOrAccess& e) { \ 246 EXPECT_EQ(e.status(), status_); \ 247 EXPECT_THAT(e.what(), HasSubstr(e.status().ToString())); \ 248 throw; \ 249 } \ 250 }, \ 251 absl::BadStatusOrAccess); 252 #else // ABSL_HAVE_EXCEPTIONS 253 #define EXPECT_DEATH_OR_THROW(statement, status) \ 254 EXPECT_DEATH_IF_SUPPORTED(statement, status.ToString()); 255 #endif // ABSL_HAVE_EXCEPTIONS 256 257 TEST(StatusOrDeathTest, TestDefaultCtorValue) { 258 absl::StatusOr<int> thing; 259 EXPECT_DEATH_OR_THROW(thing.value(), absl::UnknownError("")); 260 const absl::StatusOr<int> thing2; 261 EXPECT_DEATH_OR_THROW(thing2.value(), absl::UnknownError("")); 262 } 263 264 TEST(StatusOrDeathTest, TestValueNotOk) { 265 absl::StatusOr<int> thing(absl::CancelledError()); 266 EXPECT_DEATH_OR_THROW(thing.value(), absl::CancelledError()); 267 } 268 269 TEST(StatusOrDeathTest, TestValueNotOkConst) { 270 const absl::StatusOr<int> thing(absl::UnknownError("")); 271 EXPECT_DEATH_OR_THROW(thing.value(), absl::UnknownError("")); 272 } 273 274 TEST(StatusOrDeathTest, TestPointerDefaultCtorValue) { 275 absl::StatusOr<int*> thing; 276 EXPECT_DEATH_OR_THROW(thing.value(), absl::UnknownError("")); 277 } 278 279 TEST(StatusOrDeathTest, TestPointerValueNotOk) { 280 absl::StatusOr<int*> thing(absl::CancelledError()); 281 EXPECT_DEATH_OR_THROW(thing.value(), absl::CancelledError()); 282 } 283 284 TEST(StatusOrDeathTest, TestPointerValueNotOkConst) { 285 const absl::StatusOr<int*> thing(absl::CancelledError()); 286 EXPECT_DEATH_OR_THROW(thing.value(), absl::CancelledError()); 287 } 288 289 #if GTEST_HAS_DEATH_TEST 290 TEST(StatusOrDeathTest, TestStatusCtorStatusOk) { 291 EXPECT_DEBUG_DEATH( 292 { 293 // This will DCHECK 294 absl::StatusOr<int> thing(absl::OkStatus()); 295 // In optimized mode, we are actually going to get error::INTERNAL for 296 // status here, rather than crashing, so check that. 297 EXPECT_FALSE(thing.ok()); 298 EXPECT_EQ(thing.status().code(), absl::StatusCode::kInternal); 299 }, 300 "An OK status is not a valid constructor argument"); 301 } 302 303 TEST(StatusOrDeathTest, TestPointerStatusCtorStatusOk) { 304 EXPECT_DEBUG_DEATH( 305 { 306 absl::StatusOr<int*> thing(absl::OkStatus()); 307 // In optimized mode, we are actually going to get error::INTERNAL for 308 // status here, rather than crashing, so check that. 309 EXPECT_FALSE(thing.ok()); 310 EXPECT_EQ(thing.status().code(), absl::StatusCode::kInternal); 311 }, 312 "An OK status is not a valid constructor argument"); 313 } 314 #endif 315 316 TEST(StatusOr, ValueAccessor) { 317 const int kIntValue = 110; 318 { 319 absl::StatusOr<int> status_or(kIntValue); 320 EXPECT_EQ(kIntValue, status_or.value()); 321 EXPECT_EQ(kIntValue, std::move(status_or).value()); 322 } 323 { 324 absl::StatusOr<CopyDetector> status_or(kIntValue); 325 EXPECT_THAT(status_or, 326 IsOkAndHolds(CopyDetectorHas(kIntValue, false, false))); 327 CopyDetector copy_detector = status_or.value(); 328 EXPECT_THAT(copy_detector, CopyDetectorHas(kIntValue, false, true)); 329 copy_detector = std::move(status_or).value(); 330 EXPECT_THAT(copy_detector, CopyDetectorHas(kIntValue, true, false)); 331 } 332 } 333 334 TEST(StatusOr, BadValueAccess) { 335 const absl::Status kError = absl::CancelledError("message"); 336 absl::StatusOr<int> status_or(kError); 337 EXPECT_DEATH_OR_THROW(status_or.value(), kError); 338 } 339 340 TEST(StatusOr, TestStatusCtor) { 341 absl::StatusOr<int> thing(absl::CancelledError()); 342 EXPECT_FALSE(thing.ok()); 343 EXPECT_EQ(thing.status().code(), absl::StatusCode::kCancelled); 344 } 345 346 TEST(StatusOr, TestValueCtor) { 347 const int kI = 4; 348 const absl::StatusOr<int> thing(kI); 349 EXPECT_TRUE(thing.ok()); 350 EXPECT_EQ(kI, *thing); 351 } 352 353 struct Foo { 354 const int x; 355 explicit Foo(int y) : x(y) {} 356 }; 357 358 TEST(StatusOr, InPlaceConstruction) { 359 EXPECT_THAT(absl::StatusOr<Foo>(absl::in_place, 10), 360 IsOkAndHolds(Field(&Foo::x, 10))); 361 } 362 363 struct InPlaceHelper { 364 InPlaceHelper(std::initializer_list<int> xs, std::unique_ptr<int> yy) 365 : x(xs), y(std::move(yy)) {} 366 const std::vector<int> x; 367 std::unique_ptr<int> y; 368 }; 369 370 TEST(StatusOr, InPlaceInitListConstruction) { 371 absl::StatusOr<InPlaceHelper> status_or(absl::in_place, {10, 11, 12}, 372 absl::make_unique<int>(13)); 373 EXPECT_THAT(status_or, IsOkAndHolds(AllOf( 374 Field(&InPlaceHelper::x, ElementsAre(10, 11, 12)), 375 Field(&InPlaceHelper::y, Pointee(13))))); 376 } 377 378 TEST(StatusOr, Emplace) { 379 absl::StatusOr<Foo> status_or_foo(10); 380 status_or_foo.emplace(20); 381 EXPECT_THAT(status_or_foo, IsOkAndHolds(Field(&Foo::x, 20))); 382 status_or_foo = absl::InvalidArgumentError("msg"); 383 EXPECT_FALSE(status_or_foo.ok()); 384 EXPECT_EQ(status_or_foo.status().code(), absl::StatusCode::kInvalidArgument); 385 EXPECT_EQ(status_or_foo.status().message(), "msg"); 386 status_or_foo.emplace(20); 387 EXPECT_THAT(status_or_foo, IsOkAndHolds(Field(&Foo::x, 20))); 388 } 389 390 TEST(StatusOr, EmplaceInitializerList) { 391 absl::StatusOr<InPlaceHelper> status_or(absl::in_place, {10, 11, 12}, 392 absl::make_unique<int>(13)); 393 status_or.emplace({1, 2, 3}, absl::make_unique<int>(4)); 394 EXPECT_THAT(status_or, 395 IsOkAndHolds(AllOf(Field(&InPlaceHelper::x, ElementsAre(1, 2, 3)), 396 Field(&InPlaceHelper::y, Pointee(4))))); 397 status_or = absl::InvalidArgumentError("msg"); 398 EXPECT_FALSE(status_or.ok()); 399 EXPECT_EQ(status_or.status().code(), absl::StatusCode::kInvalidArgument); 400 EXPECT_EQ(status_or.status().message(), "msg"); 401 status_or.emplace({1, 2, 3}, absl::make_unique<int>(4)); 402 EXPECT_THAT(status_or, 403 IsOkAndHolds(AllOf(Field(&InPlaceHelper::x, ElementsAre(1, 2, 3)), 404 Field(&InPlaceHelper::y, Pointee(4))))); 405 } 406 407 TEST(StatusOr, TestCopyCtorStatusOk) { 408 const int kI = 4; 409 const absl::StatusOr<int> original(kI); 410 const absl::StatusOr<int> copy(original); 411 EXPECT_THAT(copy.status(), IsOk()); 412 EXPECT_EQ(*original, *copy); 413 } 414 415 TEST(StatusOr, TestCopyCtorStatusNotOk) { 416 absl::StatusOr<int> original(absl::CancelledError()); 417 absl::StatusOr<int> copy(original); 418 EXPECT_EQ(copy.status().code(), absl::StatusCode::kCancelled); 419 } 420 421 TEST(StatusOr, TestCopyCtorNonAssignable) { 422 const int kI = 4; 423 CopyNoAssign value(kI); 424 absl::StatusOr<CopyNoAssign> original(value); 425 absl::StatusOr<CopyNoAssign> copy(original); 426 EXPECT_THAT(copy.status(), IsOk()); 427 EXPECT_EQ(original->foo, copy->foo); 428 } 429 430 TEST(StatusOr, TestCopyCtorStatusOKConverting) { 431 const int kI = 4; 432 absl::StatusOr<int> original(kI); 433 absl::StatusOr<double> copy(original); 434 EXPECT_THAT(copy.status(), IsOk()); 435 EXPECT_DOUBLE_EQ(*original, *copy); 436 } 437 438 TEST(StatusOr, TestCopyCtorStatusNotOkConverting) { 439 absl::StatusOr<int> original(absl::CancelledError()); 440 absl::StatusOr<double> copy(original); 441 EXPECT_EQ(copy.status(), original.status()); 442 } 443 444 TEST(StatusOr, TestAssignmentStatusOk) { 445 // Copy assignmment 446 { 447 const auto p = std::make_shared<int>(17); 448 absl::StatusOr<std::shared_ptr<int>> source(p); 449 450 absl::StatusOr<std::shared_ptr<int>> target; 451 target = source; 452 453 ASSERT_TRUE(target.ok()); 454 EXPECT_THAT(target.status(), IsOk()); 455 EXPECT_EQ(p, *target); 456 457 ASSERT_TRUE(source.ok()); 458 EXPECT_THAT(source.status(), IsOk()); 459 EXPECT_EQ(p, *source); 460 } 461 462 // Move asssignment 463 { 464 const auto p = std::make_shared<int>(17); 465 absl::StatusOr<std::shared_ptr<int>> source(p); 466 467 absl::StatusOr<std::shared_ptr<int>> target; 468 target = std::move(source); 469 470 ASSERT_TRUE(target.ok()); 471 EXPECT_THAT(target.status(), IsOk()); 472 EXPECT_EQ(p, *target); 473 474 ASSERT_TRUE(source.ok()); 475 EXPECT_THAT(source.status(), IsOk()); 476 EXPECT_EQ(nullptr, *source); 477 } 478 } 479 480 TEST(StatusOr, TestAssignmentStatusNotOk) { 481 // Copy assignment 482 { 483 const absl::Status expected = absl::CancelledError(); 484 absl::StatusOr<int> source(expected); 485 486 absl::StatusOr<int> target; 487 target = source; 488 489 EXPECT_FALSE(target.ok()); 490 EXPECT_EQ(expected, target.status()); 491 492 EXPECT_FALSE(source.ok()); 493 EXPECT_EQ(expected, source.status()); 494 } 495 496 // Move assignment 497 { 498 const absl::Status expected = absl::CancelledError(); 499 absl::StatusOr<int> source(expected); 500 501 absl::StatusOr<int> target; 502 target = std::move(source); 503 504 EXPECT_FALSE(target.ok()); 505 EXPECT_EQ(expected, target.status()); 506 507 EXPECT_FALSE(source.ok()); 508 EXPECT_EQ(source.status().code(), absl::StatusCode::kInternal); 509 } 510 } 511 512 TEST(StatusOr, TestAssignmentStatusOKConverting) { 513 // Copy assignment 514 { 515 const int kI = 4; 516 absl::StatusOr<int> source(kI); 517 518 absl::StatusOr<double> target; 519 target = source; 520 521 ASSERT_TRUE(target.ok()); 522 EXPECT_THAT(target.status(), IsOk()); 523 EXPECT_DOUBLE_EQ(kI, *target); 524 525 ASSERT_TRUE(source.ok()); 526 EXPECT_THAT(source.status(), IsOk()); 527 EXPECT_DOUBLE_EQ(kI, *source); 528 } 529 530 // Move assignment 531 { 532 const auto p = new int(17); 533 absl::StatusOr<std::unique_ptr<int>> source(absl::WrapUnique(p)); 534 535 absl::StatusOr<std::shared_ptr<int>> target; 536 target = std::move(source); 537 538 ASSERT_TRUE(target.ok()); 539 EXPECT_THAT(target.status(), IsOk()); 540 EXPECT_EQ(p, target->get()); 541 542 ASSERT_TRUE(source.ok()); 543 EXPECT_THAT(source.status(), IsOk()); 544 EXPECT_EQ(nullptr, source->get()); 545 } 546 } 547 548 struct A { 549 int x; 550 }; 551 552 struct ImplicitConstructibleFromA { 553 int x; 554 bool moved; 555 ImplicitConstructibleFromA(const A& a) // NOLINT 556 : x(a.x), moved(false) {} 557 ImplicitConstructibleFromA(A&& a) // NOLINT 558 : x(a.x), moved(true) {} 559 }; 560 561 TEST(StatusOr, ImplicitConvertingConstructor) { 562 EXPECT_THAT( 563 absl::implicit_cast<absl::StatusOr<ImplicitConstructibleFromA>>( 564 absl::StatusOr<A>(A{11})), 565 IsOkAndHolds(AllOf(Field(&ImplicitConstructibleFromA::x, 11), 566 Field(&ImplicitConstructibleFromA::moved, true)))); 567 absl::StatusOr<A> a(A{12}); 568 EXPECT_THAT( 569 absl::implicit_cast<absl::StatusOr<ImplicitConstructibleFromA>>(a), 570 IsOkAndHolds(AllOf(Field(&ImplicitConstructibleFromA::x, 12), 571 Field(&ImplicitConstructibleFromA::moved, false)))); 572 } 573 574 struct ExplicitConstructibleFromA { 575 int x; 576 bool moved; 577 explicit ExplicitConstructibleFromA(const A& a) : x(a.x), moved(false) {} 578 explicit ExplicitConstructibleFromA(A&& a) : x(a.x), moved(true) {} 579 }; 580 581 TEST(StatusOr, ExplicitConvertingConstructor) { 582 EXPECT_FALSE( 583 (std::is_convertible<const absl::StatusOr<A>&, 584 absl::StatusOr<ExplicitConstructibleFromA>>::value)); 585 EXPECT_FALSE( 586 (std::is_convertible<absl::StatusOr<A>&&, 587 absl::StatusOr<ExplicitConstructibleFromA>>::value)); 588 EXPECT_THAT( 589 absl::StatusOr<ExplicitConstructibleFromA>(absl::StatusOr<A>(A{11})), 590 IsOkAndHolds(AllOf(Field(&ExplicitConstructibleFromA::x, 11), 591 Field(&ExplicitConstructibleFromA::moved, true)))); 592 absl::StatusOr<A> a(A{12}); 593 EXPECT_THAT( 594 absl::StatusOr<ExplicitConstructibleFromA>(a), 595 IsOkAndHolds(AllOf(Field(&ExplicitConstructibleFromA::x, 12), 596 Field(&ExplicitConstructibleFromA::moved, false)))); 597 } 598 599 struct ImplicitConstructibleFromBool { 600 ImplicitConstructibleFromBool(bool y) : x(y) {} // NOLINT 601 bool x = false; 602 }; 603 604 struct ConvertibleToBool { 605 explicit ConvertibleToBool(bool y) : x(y) {} 606 operator bool() const { return x; } // NOLINT 607 bool x = false; 608 }; 609 610 TEST(StatusOr, ImplicitBooleanConstructionWithImplicitCasts) { 611 EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<ConvertibleToBool>(true)), 612 IsOkAndHolds(true)); 613 EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<ConvertibleToBool>(false)), 614 IsOkAndHolds(false)); 615 EXPECT_THAT( 616 absl::implicit_cast<absl::StatusOr<ImplicitConstructibleFromBool>>( 617 absl::StatusOr<bool>(false)), 618 IsOkAndHolds(Field(&ImplicitConstructibleFromBool::x, false))); 619 EXPECT_FALSE((std::is_convertible< 620 absl::StatusOr<ConvertibleToBool>, 621 absl::StatusOr<ImplicitConstructibleFromBool>>::value)); 622 } 623 624 TEST(StatusOr, BooleanConstructionWithImplicitCasts) { 625 EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<ConvertibleToBool>(true)), 626 IsOkAndHolds(true)); 627 EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<ConvertibleToBool>(false)), 628 IsOkAndHolds(false)); 629 EXPECT_THAT( 630 absl::StatusOr<ImplicitConstructibleFromBool>{ 631 absl::StatusOr<bool>(false)}, 632 IsOkAndHolds(Field(&ImplicitConstructibleFromBool::x, false))); 633 EXPECT_THAT( 634 absl::StatusOr<ImplicitConstructibleFromBool>{ 635 absl::StatusOr<bool>(absl::InvalidArgumentError(""))}, 636 Not(IsOk())); 637 638 EXPECT_THAT( 639 absl::StatusOr<ImplicitConstructibleFromBool>{ 640 absl::StatusOr<ConvertibleToBool>(ConvertibleToBool{false})}, 641 IsOkAndHolds(Field(&ImplicitConstructibleFromBool::x, false))); 642 EXPECT_THAT( 643 absl::StatusOr<ImplicitConstructibleFromBool>{ 644 absl::StatusOr<ConvertibleToBool>(absl::InvalidArgumentError(""))}, 645 Not(IsOk())); 646 } 647 648 TEST(StatusOr, ConstImplicitCast) { 649 EXPECT_THAT(absl::implicit_cast<absl::StatusOr<bool>>( 650 absl::StatusOr<const bool>(true)), 651 IsOkAndHolds(true)); 652 EXPECT_THAT(absl::implicit_cast<absl::StatusOr<bool>>( 653 absl::StatusOr<const bool>(false)), 654 IsOkAndHolds(false)); 655 EXPECT_THAT(absl::implicit_cast<absl::StatusOr<const bool>>( 656 absl::StatusOr<bool>(true)), 657 IsOkAndHolds(true)); 658 EXPECT_THAT(absl::implicit_cast<absl::StatusOr<const bool>>( 659 absl::StatusOr<bool>(false)), 660 IsOkAndHolds(false)); 661 EXPECT_THAT(absl::implicit_cast<absl::StatusOr<const std::string>>( 662 absl::StatusOr<std::string>("foo")), 663 IsOkAndHolds("foo")); 664 EXPECT_THAT(absl::implicit_cast<absl::StatusOr<std::string>>( 665 absl::StatusOr<const std::string>("foo")), 666 IsOkAndHolds("foo")); 667 EXPECT_THAT( 668 absl::implicit_cast<absl::StatusOr<std::shared_ptr<const std::string>>>( 669 absl::StatusOr<std::shared_ptr<std::string>>( 670 std::make_shared<std::string>("foo"))), 671 IsOkAndHolds(Pointee(std::string("foo")))); 672 } 673 674 TEST(StatusOr, ConstExplicitConstruction) { 675 EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<const bool>(true)), 676 IsOkAndHolds(true)); 677 EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<const bool>(false)), 678 IsOkAndHolds(false)); 679 EXPECT_THAT(absl::StatusOr<const bool>(absl::StatusOr<bool>(true)), 680 IsOkAndHolds(true)); 681 EXPECT_THAT(absl::StatusOr<const bool>(absl::StatusOr<bool>(false)), 682 IsOkAndHolds(false)); 683 } 684 685 struct ExplicitConstructibleFromInt { 686 int x; 687 explicit ExplicitConstructibleFromInt(int y) : x(y) {} 688 }; 689 690 TEST(StatusOr, ExplicitConstruction) { 691 EXPECT_THAT(absl::StatusOr<ExplicitConstructibleFromInt>(10), 692 IsOkAndHolds(Field(&ExplicitConstructibleFromInt::x, 10))); 693 } 694 695 TEST(StatusOr, ImplicitConstruction) { 696 // Check implicit casting works. 697 auto status_or = 698 absl::implicit_cast<absl::StatusOr<absl::variant<int, std::string>>>(10); 699 EXPECT_THAT(status_or, IsOkAndHolds(VariantWith<int>(10))); 700 } 701 702 TEST(StatusOr, ImplicitConstructionFromInitliazerList) { 703 // Note: dropping the explicit std::initializer_list<int> is not supported 704 // by absl::StatusOr or absl::optional. 705 auto status_or = 706 absl::implicit_cast<absl::StatusOr<std::vector<int>>>({{10, 20, 30}}); 707 EXPECT_THAT(status_or, IsOkAndHolds(ElementsAre(10, 20, 30))); 708 } 709 710 TEST(StatusOr, UniquePtrImplicitConstruction) { 711 auto status_or = absl::implicit_cast<absl::StatusOr<std::unique_ptr<Base1>>>( 712 absl::make_unique<Derived>()); 713 EXPECT_THAT(status_or, IsOkAndHolds(Ne(nullptr))); 714 } 715 716 TEST(StatusOr, NestedStatusOrCopyAndMoveConstructorTests) { 717 absl::StatusOr<absl::StatusOr<CopyDetector>> status_or = CopyDetector(10); 718 absl::StatusOr<absl::StatusOr<CopyDetector>> status_error = 719 absl::InvalidArgumentError("foo"); 720 EXPECT_THAT(status_or, 721 IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, true, false)))); 722 absl::StatusOr<absl::StatusOr<CopyDetector>> a = status_or; 723 EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true)))); 724 absl::StatusOr<absl::StatusOr<CopyDetector>> a_err = status_error; 725 EXPECT_THAT(a_err, Not(IsOk())); 726 727 const absl::StatusOr<absl::StatusOr<CopyDetector>>& cref = status_or; 728 absl::StatusOr<absl::StatusOr<CopyDetector>> b = cref; // NOLINT 729 EXPECT_THAT(b, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true)))); 730 const absl::StatusOr<absl::StatusOr<CopyDetector>>& cref_err = status_error; 731 absl::StatusOr<absl::StatusOr<CopyDetector>> b_err = cref_err; // NOLINT 732 EXPECT_THAT(b_err, Not(IsOk())); 733 734 absl::StatusOr<absl::StatusOr<CopyDetector>> c = std::move(status_or); 735 EXPECT_THAT(c, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, true, false)))); 736 absl::StatusOr<absl::StatusOr<CopyDetector>> c_err = std::move(status_error); 737 EXPECT_THAT(c_err, Not(IsOk())); 738 } 739 740 TEST(StatusOr, NestedStatusOrCopyAndMoveAssignment) { 741 absl::StatusOr<absl::StatusOr<CopyDetector>> status_or = CopyDetector(10); 742 absl::StatusOr<absl::StatusOr<CopyDetector>> status_error = 743 absl::InvalidArgumentError("foo"); 744 absl::StatusOr<absl::StatusOr<CopyDetector>> a; 745 a = status_or; 746 EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true)))); 747 a = status_error; 748 EXPECT_THAT(a, Not(IsOk())); 749 750 const absl::StatusOr<absl::StatusOr<CopyDetector>>& cref = status_or; 751 a = cref; 752 EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true)))); 753 const absl::StatusOr<absl::StatusOr<CopyDetector>>& cref_err = status_error; 754 a = cref_err; 755 EXPECT_THAT(a, Not(IsOk())); 756 a = std::move(status_or); 757 EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, true, false)))); 758 a = std::move(status_error); 759 EXPECT_THAT(a, Not(IsOk())); 760 } 761 762 struct Copyable { 763 Copyable() {} 764 Copyable(const Copyable&) {} 765 Copyable& operator=(const Copyable&) { return *this; } 766 }; 767 768 struct MoveOnly { 769 MoveOnly() {} 770 MoveOnly(MoveOnly&&) {} 771 MoveOnly& operator=(MoveOnly&&) { return *this; } 772 }; 773 774 struct NonMovable { 775 NonMovable() {} 776 NonMovable(const NonMovable&) = delete; 777 NonMovable(NonMovable&&) = delete; 778 NonMovable& operator=(const NonMovable&) = delete; 779 NonMovable& operator=(NonMovable&&) = delete; 780 }; 781 782 TEST(StatusOr, CopyAndMoveAbility) { 783 EXPECT_TRUE(std::is_copy_constructible<Copyable>::value); 784 EXPECT_TRUE(std::is_copy_assignable<Copyable>::value); 785 EXPECT_TRUE(std::is_move_constructible<Copyable>::value); 786 EXPECT_TRUE(std::is_move_assignable<Copyable>::value); 787 EXPECT_FALSE(std::is_copy_constructible<MoveOnly>::value); 788 EXPECT_FALSE(std::is_copy_assignable<MoveOnly>::value); 789 EXPECT_TRUE(std::is_move_constructible<MoveOnly>::value); 790 EXPECT_TRUE(std::is_move_assignable<MoveOnly>::value); 791 EXPECT_FALSE(std::is_copy_constructible<NonMovable>::value); 792 EXPECT_FALSE(std::is_copy_assignable<NonMovable>::value); 793 EXPECT_FALSE(std::is_move_constructible<NonMovable>::value); 794 EXPECT_FALSE(std::is_move_assignable<NonMovable>::value); 795 } 796 797 TEST(StatusOr, StatusOrAnyCopyAndMoveConstructorTests) { 798 absl::StatusOr<absl::any> status_or = CopyDetector(10); 799 absl::StatusOr<absl::any> status_error = absl::InvalidArgumentError("foo"); 800 EXPECT_THAT( 801 status_or, 802 IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, true, false)))); 803 absl::StatusOr<absl::any> a = status_or; 804 EXPECT_THAT( 805 a, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, false, true)))); 806 absl::StatusOr<absl::any> a_err = status_error; 807 EXPECT_THAT(a_err, Not(IsOk())); 808 809 const absl::StatusOr<absl::any>& cref = status_or; 810 // No lint for no-change copy. 811 absl::StatusOr<absl::any> b = cref; // NOLINT 812 EXPECT_THAT( 813 b, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, false, true)))); 814 const absl::StatusOr<absl::any>& cref_err = status_error; 815 // No lint for no-change copy. 816 absl::StatusOr<absl::any> b_err = cref_err; // NOLINT 817 EXPECT_THAT(b_err, Not(IsOk())); 818 819 absl::StatusOr<absl::any> c = std::move(status_or); 820 EXPECT_THAT( 821 c, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, true, false)))); 822 absl::StatusOr<absl::any> c_err = std::move(status_error); 823 EXPECT_THAT(c_err, Not(IsOk())); 824 } 825 826 TEST(StatusOr, StatusOrAnyCopyAndMoveAssignment) { 827 absl::StatusOr<absl::any> status_or = CopyDetector(10); 828 absl::StatusOr<absl::any> status_error = absl::InvalidArgumentError("foo"); 829 absl::StatusOr<absl::any> a; 830 a = status_or; 831 EXPECT_THAT( 832 a, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, false, true)))); 833 a = status_error; 834 EXPECT_THAT(a, Not(IsOk())); 835 836 const absl::StatusOr<absl::any>& cref = status_or; 837 a = cref; 838 EXPECT_THAT( 839 a, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, false, true)))); 840 const absl::StatusOr<absl::any>& cref_err = status_error; 841 a = cref_err; 842 EXPECT_THAT(a, Not(IsOk())); 843 a = std::move(status_or); 844 EXPECT_THAT( 845 a, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, true, false)))); 846 a = std::move(status_error); 847 EXPECT_THAT(a, Not(IsOk())); 848 } 849 850 TEST(StatusOr, StatusOrCopyAndMoveTestsConstructor) { 851 absl::StatusOr<CopyDetector> status_or(10); 852 ASSERT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(10, false, false))); 853 absl::StatusOr<CopyDetector> a(status_or); 854 EXPECT_THAT(a, IsOkAndHolds(CopyDetectorHas(10, false, true))); 855 const absl::StatusOr<CopyDetector>& cref = status_or; 856 absl::StatusOr<CopyDetector> b(cref); // NOLINT 857 EXPECT_THAT(b, IsOkAndHolds(CopyDetectorHas(10, false, true))); 858 absl::StatusOr<CopyDetector> c(std::move(status_or)); 859 EXPECT_THAT(c, IsOkAndHolds(CopyDetectorHas(10, true, false))); 860 } 861 862 TEST(StatusOr, StatusOrCopyAndMoveTestsAssignment) { 863 absl::StatusOr<CopyDetector> status_or(10); 864 ASSERT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(10, false, false))); 865 absl::StatusOr<CopyDetector> a; 866 a = status_or; 867 EXPECT_THAT(a, IsOkAndHolds(CopyDetectorHas(10, false, true))); 868 const absl::StatusOr<CopyDetector>& cref = status_or; 869 absl::StatusOr<CopyDetector> b; 870 b = cref; 871 EXPECT_THAT(b, IsOkAndHolds(CopyDetectorHas(10, false, true))); 872 absl::StatusOr<CopyDetector> c; 873 c = std::move(status_or); 874 EXPECT_THAT(c, IsOkAndHolds(CopyDetectorHas(10, true, false))); 875 } 876 877 TEST(StatusOr, AbslAnyAssignment) { 878 EXPECT_FALSE((std::is_assignable<absl::StatusOr<absl::any>, 879 absl::StatusOr<int>>::value)); 880 absl::StatusOr<absl::any> status_or; 881 status_or = absl::InvalidArgumentError("foo"); 882 EXPECT_THAT(status_or, Not(IsOk())); 883 } 884 885 TEST(StatusOr, ImplicitAssignment) { 886 absl::StatusOr<absl::variant<int, std::string>> status_or; 887 status_or = 10; 888 EXPECT_THAT(status_or, IsOkAndHolds(VariantWith<int>(10))); 889 } 890 891 TEST(StatusOr, SelfDirectInitAssignment) { 892 absl::StatusOr<std::vector<int>> status_or = {{10, 20, 30}}; 893 status_or = *status_or; 894 EXPECT_THAT(status_or, IsOkAndHolds(ElementsAre(10, 20, 30))); 895 } 896 897 TEST(StatusOr, ImplicitCastFromInitializerList) { 898 absl::StatusOr<std::vector<int>> status_or = {{10, 20, 30}}; 899 EXPECT_THAT(status_or, IsOkAndHolds(ElementsAre(10, 20, 30))); 900 } 901 902 TEST(StatusOr, UniquePtrImplicitAssignment) { 903 absl::StatusOr<std::unique_ptr<Base1>> status_or; 904 status_or = absl::make_unique<Derived>(); 905 EXPECT_THAT(status_or, IsOkAndHolds(Ne(nullptr))); 906 } 907 908 TEST(StatusOr, Pointer) { 909 struct A {}; 910 struct B : public A {}; 911 struct C : private A {}; 912 913 EXPECT_TRUE((std::is_constructible<absl::StatusOr<A*>, B*>::value)); 914 EXPECT_TRUE((std::is_convertible<B*, absl::StatusOr<A*>>::value)); 915 EXPECT_FALSE((std::is_constructible<absl::StatusOr<A*>, C*>::value)); 916 EXPECT_FALSE((std::is_convertible<C*, absl::StatusOr<A*>>::value)); 917 } 918 919 TEST(StatusOr, TestAssignmentStatusNotOkConverting) { 920 // Copy assignment 921 { 922 const absl::Status expected = absl::CancelledError(); 923 absl::StatusOr<int> source(expected); 924 925 absl::StatusOr<double> target; 926 target = source; 927 928 EXPECT_FALSE(target.ok()); 929 EXPECT_EQ(expected, target.status()); 930 931 EXPECT_FALSE(source.ok()); 932 EXPECT_EQ(expected, source.status()); 933 } 934 935 // Move assignment 936 { 937 const absl::Status expected = absl::CancelledError(); 938 absl::StatusOr<int> source(expected); 939 940 absl::StatusOr<double> target; 941 target = std::move(source); 942 943 EXPECT_FALSE(target.ok()); 944 EXPECT_EQ(expected, target.status()); 945 946 EXPECT_FALSE(source.ok()); 947 EXPECT_EQ(source.status().code(), absl::StatusCode::kInternal); 948 } 949 } 950 951 TEST(StatusOr, SelfAssignment) { 952 // Copy-assignment, status OK 953 { 954 // A string long enough that it's likely to defeat any inline representation 955 // optimization. 956 const std::string long_str(128, 'a'); 957 958 absl::StatusOr<std::string> so = long_str; 959 so = *&so; 960 961 ASSERT_TRUE(so.ok()); 962 EXPECT_THAT(so.status(), IsOk()); 963 EXPECT_EQ(long_str, *so); 964 } 965 966 // Copy-assignment, error status 967 { 968 absl::StatusOr<int> so = absl::NotFoundError("taco"); 969 so = *&so; 970 971 EXPECT_FALSE(so.ok()); 972 EXPECT_EQ(so.status().code(), absl::StatusCode::kNotFound); 973 EXPECT_EQ(so.status().message(), "taco"); 974 } 975 976 // Move-assignment with copyable type, status OK 977 { 978 absl::StatusOr<int> so = 17; 979 980 // Fool the compiler, which otherwise complains. 981 auto& same = so; 982 so = std::move(same); 983 984 ASSERT_TRUE(so.ok()); 985 EXPECT_THAT(so.status(), IsOk()); 986 EXPECT_EQ(17, *so); 987 } 988 989 // Move-assignment with copyable type, error status 990 { 991 absl::StatusOr<int> so = absl::NotFoundError("taco"); 992 993 // Fool the compiler, which otherwise complains. 994 auto& same = so; 995 so = std::move(same); 996 997 EXPECT_FALSE(so.ok()); 998 EXPECT_EQ(so.status().code(), absl::StatusCode::kNotFound); 999 EXPECT_EQ(so.status().message(), "taco"); 1000 } 1001 1002 // Move-assignment with non-copyable type, status OK 1003 { 1004 const auto raw = new int(17); 1005 absl::StatusOr<std::unique_ptr<int>> so = absl::WrapUnique(raw); 1006 1007 // Fool the compiler, which otherwise complains. 1008 auto& same = so; 1009 so = std::move(same); 1010 1011 ASSERT_TRUE(so.ok()); 1012 EXPECT_THAT(so.status(), IsOk()); 1013 EXPECT_EQ(raw, so->get()); 1014 } 1015 1016 // Move-assignment with non-copyable type, error status 1017 { 1018 absl::StatusOr<std::unique_ptr<int>> so = absl::NotFoundError("taco"); 1019 1020 // Fool the compiler, which otherwise complains. 1021 auto& same = so; 1022 so = std::move(same); 1023 1024 EXPECT_FALSE(so.ok()); 1025 EXPECT_EQ(so.status().code(), absl::StatusCode::kNotFound); 1026 EXPECT_EQ(so.status().message(), "taco"); 1027 } 1028 } 1029 1030 // These types form the overload sets of the constructors and the assignment 1031 // operators of `MockValue`. They distinguish construction from assignment, 1032 // lvalue from rvalue. 1033 struct FromConstructibleAssignableLvalue {}; 1034 struct FromConstructibleAssignableRvalue {}; 1035 struct FromImplicitConstructibleOnly {}; 1036 struct FromAssignableOnly {}; 1037 1038 // This class is for testing the forwarding value assignments of `StatusOr`. 1039 // `from_rvalue` indicates whether the constructor or the assignment taking 1040 // rvalue reference is called. `from_assignment` indicates whether any 1041 // assignment is called. 1042 struct MockValue { 1043 // Constructs `MockValue` from `FromConstructibleAssignableLvalue`. 1044 MockValue(const FromConstructibleAssignableLvalue&) // NOLINT 1045 : from_rvalue(false), assigned(false) {} 1046 // Constructs `MockValue` from `FromConstructibleAssignableRvalue`. 1047 MockValue(FromConstructibleAssignableRvalue&&) // NOLINT 1048 : from_rvalue(true), assigned(false) {} 1049 // Constructs `MockValue` from `FromImplicitConstructibleOnly`. 1050 // `MockValue` is not assignable from `FromImplicitConstructibleOnly`. 1051 MockValue(const FromImplicitConstructibleOnly&) // NOLINT 1052 : from_rvalue(false), assigned(false) {} 1053 // Assigns `FromConstructibleAssignableLvalue`. 1054 MockValue& operator=(const FromConstructibleAssignableLvalue&) { 1055 from_rvalue = false; 1056 assigned = true; 1057 return *this; 1058 } 1059 // Assigns `FromConstructibleAssignableRvalue` (rvalue only). 1060 MockValue& operator=(FromConstructibleAssignableRvalue&&) { 1061 from_rvalue = true; 1062 assigned = true; 1063 return *this; 1064 } 1065 // Assigns `FromAssignableOnly`, but not constructible from 1066 // `FromAssignableOnly`. 1067 MockValue& operator=(const FromAssignableOnly&) { 1068 from_rvalue = false; 1069 assigned = true; 1070 return *this; 1071 } 1072 bool from_rvalue; 1073 bool assigned; 1074 }; 1075 1076 // operator=(U&&) 1077 TEST(StatusOr, PerfectForwardingAssignment) { 1078 // U == T 1079 constexpr int kValue1 = 10, kValue2 = 20; 1080 absl::StatusOr<CopyDetector> status_or; 1081 CopyDetector lvalue(kValue1); 1082 status_or = lvalue; 1083 EXPECT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(kValue1, false, true))); 1084 status_or = CopyDetector(kValue2); 1085 EXPECT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(kValue2, true, false))); 1086 1087 // U != T 1088 EXPECT_TRUE( 1089 (std::is_assignable<absl::StatusOr<MockValue>&, 1090 const FromConstructibleAssignableLvalue&>::value)); 1091 EXPECT_TRUE((std::is_assignable<absl::StatusOr<MockValue>&, 1092 FromConstructibleAssignableLvalue&&>::value)); 1093 EXPECT_FALSE( 1094 (std::is_assignable<absl::StatusOr<MockValue>&, 1095 const FromConstructibleAssignableRvalue&>::value)); 1096 EXPECT_TRUE((std::is_assignable<absl::StatusOr<MockValue>&, 1097 FromConstructibleAssignableRvalue&&>::value)); 1098 EXPECT_TRUE( 1099 (std::is_assignable<absl::StatusOr<MockValue>&, 1100 const FromImplicitConstructibleOnly&>::value)); 1101 EXPECT_FALSE((std::is_assignable<absl::StatusOr<MockValue>&, 1102 const FromAssignableOnly&>::value)); 1103 1104 absl::StatusOr<MockValue> from_lvalue(FromConstructibleAssignableLvalue{}); 1105 EXPECT_FALSE(from_lvalue->from_rvalue); 1106 EXPECT_FALSE(from_lvalue->assigned); 1107 from_lvalue = FromConstructibleAssignableLvalue{}; 1108 EXPECT_FALSE(from_lvalue->from_rvalue); 1109 EXPECT_TRUE(from_lvalue->assigned); 1110 1111 absl::StatusOr<MockValue> from_rvalue(FromConstructibleAssignableRvalue{}); 1112 EXPECT_TRUE(from_rvalue->from_rvalue); 1113 EXPECT_FALSE(from_rvalue->assigned); 1114 from_rvalue = FromConstructibleAssignableRvalue{}; 1115 EXPECT_TRUE(from_rvalue->from_rvalue); 1116 EXPECT_TRUE(from_rvalue->assigned); 1117 1118 absl::StatusOr<MockValue> from_implicit_constructible( 1119 FromImplicitConstructibleOnly{}); 1120 EXPECT_FALSE(from_implicit_constructible->from_rvalue); 1121 EXPECT_FALSE(from_implicit_constructible->assigned); 1122 // construct a temporary `StatusOr` object and invoke the `StatusOr` move 1123 // assignment operator. 1124 from_implicit_constructible = FromImplicitConstructibleOnly{}; 1125 EXPECT_FALSE(from_implicit_constructible->from_rvalue); 1126 EXPECT_FALSE(from_implicit_constructible->assigned); 1127 } 1128 1129 TEST(StatusOr, TestStatus) { 1130 absl::StatusOr<int> good(4); 1131 EXPECT_TRUE(good.ok()); 1132 absl::StatusOr<int> bad(absl::CancelledError()); 1133 EXPECT_FALSE(bad.ok()); 1134 EXPECT_EQ(bad.status().code(), absl::StatusCode::kCancelled); 1135 } 1136 1137 TEST(StatusOr, OperatorStarRefQualifiers) { 1138 static_assert( 1139 std::is_same<const int&, 1140 decltype(*std::declval<const absl::StatusOr<int>&>())>(), 1141 "Unexpected ref-qualifiers"); 1142 static_assert( 1143 std::is_same<int&, decltype(*std::declval<absl::StatusOr<int>&>())>(), 1144 "Unexpected ref-qualifiers"); 1145 static_assert( 1146 std::is_same<const int&&, 1147 decltype(*std::declval<const absl::StatusOr<int>&&>())>(), 1148 "Unexpected ref-qualifiers"); 1149 static_assert( 1150 std::is_same<int&&, decltype(*std::declval<absl::StatusOr<int>&&>())>(), 1151 "Unexpected ref-qualifiers"); 1152 } 1153 1154 TEST(StatusOr, OperatorStar) { 1155 const absl::StatusOr<std::string> const_lvalue("hello"); 1156 EXPECT_EQ("hello", *const_lvalue); 1157 1158 absl::StatusOr<std::string> lvalue("hello"); 1159 EXPECT_EQ("hello", *lvalue); 1160 1161 // Note: Recall that std::move() is equivalent to a static_cast to an rvalue 1162 // reference type. 1163 const absl::StatusOr<std::string> const_rvalue("hello"); 1164 EXPECT_EQ("hello", *std::move(const_rvalue)); // NOLINT 1165 1166 absl::StatusOr<std::string> rvalue("hello"); 1167 EXPECT_EQ("hello", *std::move(rvalue)); 1168 } 1169 1170 TEST(StatusOr, OperatorArrowQualifiers) { 1171 static_assert( 1172 std::is_same< 1173 const int*, 1174 decltype(std::declval<const absl::StatusOr<int>&>().operator->())>(), 1175 "Unexpected qualifiers"); 1176 static_assert( 1177 std::is_same< 1178 int*, decltype(std::declval<absl::StatusOr<int>&>().operator->())>(), 1179 "Unexpected qualifiers"); 1180 static_assert( 1181 std::is_same< 1182 const int*, 1183 decltype(std::declval<const absl::StatusOr<int>&&>().operator->())>(), 1184 "Unexpected qualifiers"); 1185 static_assert( 1186 std::is_same< 1187 int*, decltype(std::declval<absl::StatusOr<int>&&>().operator->())>(), 1188 "Unexpected qualifiers"); 1189 } 1190 1191 TEST(StatusOr, OperatorArrow) { 1192 const absl::StatusOr<std::string> const_lvalue("hello"); 1193 EXPECT_EQ(std::string("hello"), const_lvalue->c_str()); 1194 1195 absl::StatusOr<std::string> lvalue("hello"); 1196 EXPECT_EQ(std::string("hello"), lvalue->c_str()); 1197 } 1198 1199 TEST(StatusOr, RValueStatus) { 1200 absl::StatusOr<int> so(absl::NotFoundError("taco")); 1201 const absl::Status s = std::move(so).status(); 1202 1203 EXPECT_EQ(s.code(), absl::StatusCode::kNotFound); 1204 EXPECT_EQ(s.message(), "taco"); 1205 1206 // Check that !ok() still implies !status().ok(), even after moving out of the 1207 // object. See the note on the rvalue ref-qualified status method. 1208 EXPECT_FALSE(so.ok()); // NOLINT 1209 EXPECT_FALSE(so.status().ok()); 1210 EXPECT_EQ(so.status().code(), absl::StatusCode::kInternal); 1211 EXPECT_EQ(so.status().message(), "Status accessed after move."); 1212 } 1213 1214 TEST(StatusOr, TestValue) { 1215 const int kI = 4; 1216 absl::StatusOr<int> thing(kI); 1217 EXPECT_EQ(kI, *thing); 1218 } 1219 1220 TEST(StatusOr, TestValueConst) { 1221 const int kI = 4; 1222 const absl::StatusOr<int> thing(kI); 1223 EXPECT_EQ(kI, *thing); 1224 } 1225 1226 TEST(StatusOr, TestPointerDefaultCtor) { 1227 absl::StatusOr<int*> thing; 1228 EXPECT_FALSE(thing.ok()); 1229 EXPECT_EQ(thing.status().code(), absl::StatusCode::kUnknown); 1230 } 1231 1232 TEST(StatusOr, TestPointerStatusCtor) { 1233 absl::StatusOr<int*> thing(absl::CancelledError()); 1234 EXPECT_FALSE(thing.ok()); 1235 EXPECT_EQ(thing.status().code(), absl::StatusCode::kCancelled); 1236 } 1237 1238 TEST(StatusOr, TestPointerValueCtor) { 1239 const int kI = 4; 1240 1241 // Construction from a non-null pointer 1242 { 1243 absl::StatusOr<const int*> so(&kI); 1244 EXPECT_TRUE(so.ok()); 1245 EXPECT_THAT(so.status(), IsOk()); 1246 EXPECT_EQ(&kI, *so); 1247 } 1248 1249 // Construction from a null pointer constant 1250 { 1251 absl::StatusOr<const int*> so(nullptr); 1252 EXPECT_TRUE(so.ok()); 1253 EXPECT_THAT(so.status(), IsOk()); 1254 EXPECT_EQ(nullptr, *so); 1255 } 1256 1257 // Construction from a non-literal null pointer 1258 { 1259 const int* const p = nullptr; 1260 1261 absl::StatusOr<const int*> so(p); 1262 EXPECT_TRUE(so.ok()); 1263 EXPECT_THAT(so.status(), IsOk()); 1264 EXPECT_EQ(nullptr, *so); 1265 } 1266 } 1267 1268 TEST(StatusOr, TestPointerCopyCtorStatusOk) { 1269 const int kI = 0; 1270 absl::StatusOr<const int*> original(&kI); 1271 absl::StatusOr<const int*> copy(original); 1272 EXPECT_THAT(copy.status(), IsOk()); 1273 EXPECT_EQ(*original, *copy); 1274 } 1275 1276 TEST(StatusOr, TestPointerCopyCtorStatusNotOk) { 1277 absl::StatusOr<int*> original(absl::CancelledError()); 1278 absl::StatusOr<int*> copy(original); 1279 EXPECT_EQ(copy.status().code(), absl::StatusCode::kCancelled); 1280 } 1281 1282 TEST(StatusOr, TestPointerCopyCtorStatusOKConverting) { 1283 Derived derived; 1284 absl::StatusOr<Derived*> original(&derived); 1285 absl::StatusOr<Base2*> copy(original); 1286 EXPECT_THAT(copy.status(), IsOk()); 1287 EXPECT_EQ(static_cast<const Base2*>(*original), *copy); 1288 } 1289 1290 TEST(StatusOr, TestPointerCopyCtorStatusNotOkConverting) { 1291 absl::StatusOr<Derived*> original(absl::CancelledError()); 1292 absl::StatusOr<Base2*> copy(original); 1293 EXPECT_EQ(copy.status().code(), absl::StatusCode::kCancelled); 1294 } 1295 1296 TEST(StatusOr, TestPointerAssignmentStatusOk) { 1297 const int kI = 0; 1298 absl::StatusOr<const int*> source(&kI); 1299 absl::StatusOr<const int*> target; 1300 target = source; 1301 EXPECT_THAT(target.status(), IsOk()); 1302 EXPECT_EQ(*source, *target); 1303 } 1304 1305 TEST(StatusOr, TestPointerAssignmentStatusNotOk) { 1306 absl::StatusOr<int*> source(absl::CancelledError()); 1307 absl::StatusOr<int*> target; 1308 target = source; 1309 EXPECT_EQ(target.status().code(), absl::StatusCode::kCancelled); 1310 } 1311 1312 TEST(StatusOr, TestPointerAssignmentStatusOKConverting) { 1313 Derived derived; 1314 absl::StatusOr<Derived*> source(&derived); 1315 absl::StatusOr<Base2*> target; 1316 target = source; 1317 EXPECT_THAT(target.status(), IsOk()); 1318 EXPECT_EQ(static_cast<const Base2*>(*source), *target); 1319 } 1320 1321 TEST(StatusOr, TestPointerAssignmentStatusNotOkConverting) { 1322 absl::StatusOr<Derived*> source(absl::CancelledError()); 1323 absl::StatusOr<Base2*> target; 1324 target = source; 1325 EXPECT_EQ(target.status(), source.status()); 1326 } 1327 1328 TEST(StatusOr, TestPointerStatus) { 1329 const int kI = 0; 1330 absl::StatusOr<const int*> good(&kI); 1331 EXPECT_TRUE(good.ok()); 1332 absl::StatusOr<const int*> bad(absl::CancelledError()); 1333 EXPECT_EQ(bad.status().code(), absl::StatusCode::kCancelled); 1334 } 1335 1336 TEST(StatusOr, TestPointerValue) { 1337 const int kI = 0; 1338 absl::StatusOr<const int*> thing(&kI); 1339 EXPECT_EQ(&kI, *thing); 1340 } 1341 1342 TEST(StatusOr, TestPointerValueConst) { 1343 const int kI = 0; 1344 const absl::StatusOr<const int*> thing(&kI); 1345 EXPECT_EQ(&kI, *thing); 1346 } 1347 1348 TEST(StatusOr, StatusOrVectorOfUniquePointerCanReserveAndResize) { 1349 using EvilType = std::vector<std::unique_ptr<int>>; 1350 static_assert(std::is_copy_constructible<EvilType>::value, ""); 1351 std::vector<::absl::StatusOr<EvilType>> v(5); 1352 v.reserve(v.capacity() + 10); 1353 v.resize(v.capacity() + 10); 1354 } 1355 1356 TEST(StatusOr, ConstPayload) { 1357 // A reduced version of a problematic type found in the wild. All of the 1358 // operations below should compile. 1359 absl::StatusOr<const int> a; 1360 1361 // Copy-construction 1362 absl::StatusOr<const int> b(a); 1363 1364 // Copy-assignment 1365 EXPECT_FALSE(std::is_copy_assignable<absl::StatusOr<const int>>::value); 1366 1367 // Move-construction 1368 absl::StatusOr<const int> c(std::move(a)); 1369 1370 // Move-assignment 1371 EXPECT_FALSE(std::is_move_assignable<absl::StatusOr<const int>>::value); 1372 } 1373 1374 TEST(StatusOr, MapToStatusOrUniquePtr) { 1375 // A reduced version of a problematic type found in the wild. All of the 1376 // operations below should compile. 1377 using MapType = std::map<std::string, absl::StatusOr<std::unique_ptr<int>>>; 1378 1379 MapType a; 1380 1381 // Move-construction 1382 MapType b(std::move(a)); 1383 1384 // Move-assignment 1385 a = std::move(b); 1386 } 1387 1388 TEST(StatusOr, ValueOrOk) { 1389 const absl::StatusOr<int> status_or = 0; 1390 EXPECT_EQ(status_or.value_or(-1), 0); 1391 } 1392 1393 TEST(StatusOr, ValueOrDefault) { 1394 const absl::StatusOr<int> status_or = absl::CancelledError(); 1395 EXPECT_EQ(status_or.value_or(-1), -1); 1396 } 1397 1398 TEST(StatusOr, MoveOnlyValueOrOk) { 1399 EXPECT_THAT(absl::StatusOr<std::unique_ptr<int>>(absl::make_unique<int>(0)) 1400 .value_or(absl::make_unique<int>(-1)), 1401 Pointee(0)); 1402 } 1403 1404 TEST(StatusOr, MoveOnlyValueOrDefault) { 1405 EXPECT_THAT(absl::StatusOr<std::unique_ptr<int>>(absl::CancelledError()) 1406 .value_or(absl::make_unique<int>(-1)), 1407 Pointee(-1)); 1408 } 1409 1410 static absl::StatusOr<int> MakeStatus() { return 100; } 1411 1412 TEST(StatusOr, TestIgnoreError) { MakeStatus().IgnoreError(); } 1413 1414 TEST(StatusOr, EqualityOperator) { 1415 constexpr size_t kNumCases = 4; 1416 std::array<absl::StatusOr<int>, kNumCases> group1 = { 1417 absl::StatusOr<int>(1), absl::StatusOr<int>(2), 1418 absl::StatusOr<int>(absl::InvalidArgumentError("msg")), 1419 absl::StatusOr<int>(absl::InternalError("msg"))}; 1420 std::array<absl::StatusOr<int>, kNumCases> group2 = { 1421 absl::StatusOr<int>(1), absl::StatusOr<int>(2), 1422 absl::StatusOr<int>(absl::InvalidArgumentError("msg")), 1423 absl::StatusOr<int>(absl::InternalError("msg"))}; 1424 for (size_t i = 0; i < kNumCases; ++i) { 1425 for (size_t j = 0; j < kNumCases; ++j) { 1426 if (i == j) { 1427 EXPECT_TRUE(group1[i] == group2[j]); 1428 EXPECT_FALSE(group1[i] != group2[j]); 1429 } else { 1430 EXPECT_FALSE(group1[i] == group2[j]); 1431 EXPECT_TRUE(group1[i] != group2[j]); 1432 } 1433 } 1434 } 1435 } 1436 1437 struct MyType { 1438 bool operator==(const MyType&) const { return true; } 1439 }; 1440 1441 enum class ConvTraits { kNone = 0, kImplicit = 1, kExplicit = 2 }; 1442 1443 // This class has conversion operator to `StatusOr<T>` based on value of 1444 // `conv_traits`. 1445 template <typename T, ConvTraits conv_traits = ConvTraits::kNone> 1446 struct StatusOrConversionBase {}; 1447 1448 template <typename T> 1449 struct StatusOrConversionBase<T, ConvTraits::kImplicit> { 1450 operator absl::StatusOr<T>() const& { // NOLINT 1451 return absl::InvalidArgumentError("conversion to absl::StatusOr"); 1452 } 1453 operator absl::StatusOr<T>() && { // NOLINT 1454 return absl::InvalidArgumentError("conversion to absl::StatusOr"); 1455 } 1456 }; 1457 1458 template <typename T> 1459 struct StatusOrConversionBase<T, ConvTraits::kExplicit> { 1460 explicit operator absl::StatusOr<T>() const& { 1461 return absl::InvalidArgumentError("conversion to absl::StatusOr"); 1462 } 1463 explicit operator absl::StatusOr<T>() && { 1464 return absl::InvalidArgumentError("conversion to absl::StatusOr"); 1465 } 1466 }; 1467 1468 // This class has conversion operator to `T` based on the value of 1469 // `conv_traits`. 1470 template <typename T, ConvTraits conv_traits = ConvTraits::kNone> 1471 struct ConversionBase {}; 1472 1473 template <typename T> 1474 struct ConversionBase<T, ConvTraits::kImplicit> { 1475 operator T() const& { return t; } // NOLINT 1476 operator T() && { return std::move(t); } // NOLINT 1477 T t; 1478 }; 1479 1480 template <typename T> 1481 struct ConversionBase<T, ConvTraits::kExplicit> { 1482 explicit operator T() const& { return t; } 1483 explicit operator T() && { return std::move(t); } 1484 T t; 1485 }; 1486 1487 // This class has conversion operator to `absl::Status` based on the value of 1488 // `conv_traits`. 1489 template <ConvTraits conv_traits = ConvTraits::kNone> 1490 struct StatusConversionBase {}; 1491 1492 template <> 1493 struct StatusConversionBase<ConvTraits::kImplicit> { 1494 operator absl::Status() const& { // NOLINT 1495 return absl::InternalError("conversion to Status"); 1496 } 1497 operator absl::Status() && { // NOLINT 1498 return absl::InternalError("conversion to Status"); 1499 } 1500 }; 1501 1502 template <> 1503 struct StatusConversionBase<ConvTraits::kExplicit> { 1504 explicit operator absl::Status() const& { // NOLINT 1505 return absl::InternalError("conversion to Status"); 1506 } 1507 explicit operator absl::Status() && { // NOLINT 1508 return absl::InternalError("conversion to Status"); 1509 } 1510 }; 1511 1512 static constexpr int kConvToStatus = 1; 1513 static constexpr int kConvToStatusOr = 2; 1514 static constexpr int kConvToT = 4; 1515 static constexpr int kConvExplicit = 8; 1516 1517 constexpr ConvTraits GetConvTraits(int bit, int config) { 1518 return (config & bit) == 0 1519 ? ConvTraits::kNone 1520 : ((config & kConvExplicit) == 0 ? ConvTraits::kImplicit 1521 : ConvTraits::kExplicit); 1522 } 1523 1524 // This class conditionally has conversion operator to `absl::Status`, `T`, 1525 // `StatusOr<T>`, based on values of the template parameters. 1526 template <typename T, int config> 1527 struct CustomType 1528 : StatusOrConversionBase<T, GetConvTraits(kConvToStatusOr, config)>, 1529 ConversionBase<T, GetConvTraits(kConvToT, config)>, 1530 StatusConversionBase<GetConvTraits(kConvToStatus, config)> {}; 1531 1532 struct ConvertibleToAnyStatusOr { 1533 template <typename T> 1534 operator absl::StatusOr<T>() const { // NOLINT 1535 return absl::InvalidArgumentError("Conversion to absl::StatusOr"); 1536 } 1537 }; 1538 1539 // Test the rank of overload resolution for `StatusOr<T>` constructor and 1540 // assignment, from highest to lowest: 1541 // 1. T/Status 1542 // 2. U that has conversion operator to absl::StatusOr<T> 1543 // 3. U that is convertible to Status 1544 // 4. U that is convertible to T 1545 TEST(StatusOr, ConstructionFromT) { 1546 // Construct absl::StatusOr<T> from T when T is convertible to 1547 // absl::StatusOr<T> 1548 { 1549 ConvertibleToAnyStatusOr v; 1550 absl::StatusOr<ConvertibleToAnyStatusOr> statusor(v); 1551 EXPECT_TRUE(statusor.ok()); 1552 } 1553 { 1554 ConvertibleToAnyStatusOr v; 1555 absl::StatusOr<ConvertibleToAnyStatusOr> statusor = v; 1556 EXPECT_TRUE(statusor.ok()); 1557 } 1558 // Construct absl::StatusOr<T> from T when T is explicitly convertible to 1559 // Status 1560 { 1561 CustomType<MyType, kConvToStatus | kConvExplicit> v; 1562 absl::StatusOr<CustomType<MyType, kConvToStatus | kConvExplicit>> statusor( 1563 v); 1564 EXPECT_TRUE(statusor.ok()); 1565 } 1566 { 1567 CustomType<MyType, kConvToStatus | kConvExplicit> v; 1568 absl::StatusOr<CustomType<MyType, kConvToStatus | kConvExplicit>> statusor = 1569 v; 1570 EXPECT_TRUE(statusor.ok()); 1571 } 1572 } 1573 1574 // Construct absl::StatusOr<T> from U when U is explicitly convertible to T 1575 TEST(StatusOr, ConstructionFromTypeConvertibleToT) { 1576 { 1577 CustomType<MyType, kConvToT | kConvExplicit> v; 1578 absl::StatusOr<MyType> statusor(v); 1579 EXPECT_TRUE(statusor.ok()); 1580 } 1581 { 1582 CustomType<MyType, kConvToT> v; 1583 absl::StatusOr<MyType> statusor = v; 1584 EXPECT_TRUE(statusor.ok()); 1585 } 1586 } 1587 1588 // Construct absl::StatusOr<T> from U when U has explicit conversion operator to 1589 // absl::StatusOr<T> 1590 TEST(StatusOr, ConstructionFromTypeWithConversionOperatorToStatusOrT) { 1591 { 1592 CustomType<MyType, kConvToStatusOr | kConvExplicit> v; 1593 absl::StatusOr<MyType> statusor(v); 1594 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>()); 1595 } 1596 { 1597 CustomType<MyType, kConvToT | kConvToStatusOr | kConvExplicit> v; 1598 absl::StatusOr<MyType> statusor(v); 1599 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>()); 1600 } 1601 { 1602 CustomType<MyType, kConvToStatusOr | kConvToStatus | kConvExplicit> v; 1603 absl::StatusOr<MyType> statusor(v); 1604 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>()); 1605 } 1606 { 1607 CustomType<MyType, 1608 kConvToT | kConvToStatusOr | kConvToStatus | kConvExplicit> 1609 v; 1610 absl::StatusOr<MyType> statusor(v); 1611 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>()); 1612 } 1613 { 1614 CustomType<MyType, kConvToStatusOr> v; 1615 absl::StatusOr<MyType> statusor = v; 1616 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>()); 1617 } 1618 { 1619 CustomType<MyType, kConvToT | kConvToStatusOr> v; 1620 absl::StatusOr<MyType> statusor = v; 1621 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>()); 1622 } 1623 { 1624 CustomType<MyType, kConvToStatusOr | kConvToStatus> v; 1625 absl::StatusOr<MyType> statusor = v; 1626 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>()); 1627 } 1628 { 1629 CustomType<MyType, kConvToT | kConvToStatusOr | kConvToStatus> v; 1630 absl::StatusOr<MyType> statusor = v; 1631 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>()); 1632 } 1633 } 1634 1635 TEST(StatusOr, ConstructionFromTypeConvertibleToStatus) { 1636 // Construction fails because conversion to `Status` is explicit. 1637 { 1638 CustomType<MyType, kConvToStatus | kConvExplicit> v; 1639 absl::StatusOr<MyType> statusor(v); 1640 EXPECT_FALSE(statusor.ok()); 1641 EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v)); 1642 } 1643 { 1644 CustomType<MyType, kConvToT | kConvToStatus | kConvExplicit> v; 1645 absl::StatusOr<MyType> statusor(v); 1646 EXPECT_FALSE(statusor.ok()); 1647 EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v)); 1648 } 1649 { 1650 CustomType<MyType, kConvToStatus> v; 1651 absl::StatusOr<MyType> statusor = v; 1652 EXPECT_FALSE(statusor.ok()); 1653 EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v)); 1654 } 1655 { 1656 CustomType<MyType, kConvToT | kConvToStatus> v; 1657 absl::StatusOr<MyType> statusor = v; 1658 EXPECT_FALSE(statusor.ok()); 1659 EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v)); 1660 } 1661 } 1662 1663 TEST(StatusOr, AssignmentFromT) { 1664 // Assign to absl::StatusOr<T> from T when T is convertible to 1665 // absl::StatusOr<T> 1666 { 1667 ConvertibleToAnyStatusOr v; 1668 absl::StatusOr<ConvertibleToAnyStatusOr> statusor; 1669 statusor = v; 1670 EXPECT_TRUE(statusor.ok()); 1671 } 1672 // Assign to absl::StatusOr<T> from T when T is convertible to Status 1673 { 1674 CustomType<MyType, kConvToStatus> v; 1675 absl::StatusOr<CustomType<MyType, kConvToStatus>> statusor; 1676 statusor = v; 1677 EXPECT_TRUE(statusor.ok()); 1678 } 1679 } 1680 1681 TEST(StatusOr, AssignmentFromTypeConvertibleToT) { 1682 // Assign to absl::StatusOr<T> from U when U is convertible to T 1683 { 1684 CustomType<MyType, kConvToT> v; 1685 absl::StatusOr<MyType> statusor; 1686 statusor = v; 1687 EXPECT_TRUE(statusor.ok()); 1688 } 1689 } 1690 1691 TEST(StatusOr, AssignmentFromTypeWithConversionOperatortoStatusOrT) { 1692 // Assign to absl::StatusOr<T> from U when U has conversion operator to 1693 // absl::StatusOr<T> 1694 { 1695 CustomType<MyType, kConvToStatusOr> v; 1696 absl::StatusOr<MyType> statusor; 1697 statusor = v; 1698 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>()); 1699 } 1700 { 1701 CustomType<MyType, kConvToT | kConvToStatusOr> v; 1702 absl::StatusOr<MyType> statusor; 1703 statusor = v; 1704 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>()); 1705 } 1706 { 1707 CustomType<MyType, kConvToStatusOr | kConvToStatus> v; 1708 absl::StatusOr<MyType> statusor; 1709 statusor = v; 1710 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>()); 1711 } 1712 { 1713 CustomType<MyType, kConvToT | kConvToStatusOr | kConvToStatus> v; 1714 absl::StatusOr<MyType> statusor; 1715 statusor = v; 1716 EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>()); 1717 } 1718 } 1719 1720 TEST(StatusOr, AssignmentFromTypeConvertibleToStatus) { 1721 // Assign to absl::StatusOr<T> from U when U is convertible to Status 1722 { 1723 CustomType<MyType, kConvToStatus> v; 1724 absl::StatusOr<MyType> statusor; 1725 statusor = v; 1726 EXPECT_FALSE(statusor.ok()); 1727 EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v)); 1728 } 1729 { 1730 CustomType<MyType, kConvToT | kConvToStatus> v; 1731 absl::StatusOr<MyType> statusor; 1732 statusor = v; 1733 EXPECT_FALSE(statusor.ok()); 1734 EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v)); 1735 } 1736 } 1737 1738 TEST(StatusOr, StatusAssignmentFromStatusError) { 1739 absl::StatusOr<absl::Status> statusor; 1740 statusor.AssignStatus(absl::CancelledError()); 1741 1742 EXPECT_FALSE(statusor.ok()); 1743 EXPECT_EQ(statusor.status(), absl::CancelledError()); 1744 } 1745 1746 #if GTEST_HAS_DEATH_TEST 1747 TEST(StatusOr, StatusAssignmentFromStatusOk) { 1748 EXPECT_DEBUG_DEATH( 1749 { 1750 absl::StatusOr<absl::Status> statusor; 1751 // This will DCHECK. 1752 statusor.AssignStatus(absl::OkStatus()); 1753 // In optimized mode, we are actually going to get error::INTERNAL for 1754 // status here, rather than crashing, so check that. 1755 EXPECT_FALSE(statusor.ok()); 1756 EXPECT_EQ(statusor.status().code(), absl::StatusCode::kInternal); 1757 }, 1758 "An OK status is not a valid constructor argument to StatusOr<T>"); 1759 } 1760 #endif 1761 1762 TEST(StatusOr, StatusAssignmentFromTypeConvertibleToStatus) { 1763 CustomType<MyType, kConvToStatus> v; 1764 absl::StatusOr<MyType> statusor; 1765 statusor.AssignStatus(v); 1766 1767 EXPECT_FALSE(statusor.ok()); 1768 EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v)); 1769 } 1770 1771 struct PrintTestStruct { 1772 friend std::ostream& operator<<(std::ostream& os, const PrintTestStruct&) { 1773 return os << "ostream"; 1774 } 1775 1776 template <typename Sink> 1777 friend void AbslStringify(Sink& sink, const PrintTestStruct&) { 1778 sink.Append("stringify"); 1779 } 1780 }; 1781 1782 TEST(StatusOr, OkPrinting) { 1783 absl::StatusOr<PrintTestStruct> print_me = PrintTestStruct{}; 1784 std::stringstream stream; 1785 stream << print_me; 1786 EXPECT_EQ(stream.str(), "ostream"); 1787 EXPECT_EQ(absl::StrCat(print_me), "stringify"); 1788 } 1789 1790 TEST(StatusOr, ErrorPrinting) { 1791 absl::StatusOr<PrintTestStruct> print_me = absl::UnknownError("error"); 1792 std::stringstream stream; 1793 stream << print_me; 1794 const auto error_matcher = 1795 AllOf(HasSubstr("UNKNOWN"), HasSubstr("error"), 1796 AnyOf(AllOf(StartsWith("("), EndsWith(")")), 1797 AllOf(StartsWith("["), EndsWith("]")))); 1798 EXPECT_THAT(stream.str(), error_matcher); 1799 EXPECT_THAT(absl::StrCat(print_me), error_matcher); 1800 } 1801 1802 } // namespace