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