12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847 |
- // Copyright 2020 The Abseil Authors.
- //
- // Licensed under the Apache License, Version 2.0 (the "License");
- // you may not use this file except in compliance with the License.
- // You may obtain a copy of the License at
- //
- // https://www.apache.org/licenses/LICENSE-2.0
- //
- // Unless required by applicable law or agreed to in writing, software
- // distributed under the License is distributed on an "AS IS" BASIS,
- // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- // See the License for the specific language governing permissions and
- // limitations under the License.
- #include "absl/status/statusor.h"
- #include <array>
- #include <initializer_list>
- #include <memory>
- #include <string>
- #include <type_traits>
- #include <utility>
- #include "gmock/gmock.h"
- #include "gtest/gtest.h"
- #include "absl/base/casts.h"
- #include "absl/memory/memory.h"
- #include "absl/status/status.h"
- #include "absl/strings/string_view.h"
- #include "absl/types/any.h"
- #include "absl/utility/utility.h"
- namespace {
- using ::testing::AllOf;
- using ::testing::AnyWith;
- using ::testing::ElementsAre;
- using ::testing::Field;
- using ::testing::HasSubstr;
- using ::testing::Ne;
- using ::testing::Not;
- using ::testing::Pointee;
- using ::testing::VariantWith;
- #ifdef GTEST_HAS_STATUS_MATCHERS
- using ::testing::status::IsOk;
- using ::testing::status::IsOkAndHolds;
- #else // GTEST_HAS_STATUS_MATCHERS
- inline const ::absl::Status& GetStatus(const ::absl::Status& status) {
- return status;
- }
- template <typename T>
- inline const ::absl::Status& GetStatus(const ::absl::StatusOr<T>& status) {
- return status.status();
- }
- // Monomorphic implementation of matcher IsOkAndHolds(m). StatusOrType is a
- // reference to StatusOr<T>.
- template <typename StatusOrType>
- class IsOkAndHoldsMatcherImpl
- : public ::testing::MatcherInterface<StatusOrType> {
- public:
- typedef
- typename std::remove_reference<StatusOrType>::type::value_type value_type;
- template <typename InnerMatcher>
- explicit IsOkAndHoldsMatcherImpl(InnerMatcher&& inner_matcher)
- : inner_matcher_(::testing::SafeMatcherCast<const value_type&>(
- std::forward<InnerMatcher>(inner_matcher))) {}
- void DescribeTo(std::ostream* os) const override {
- *os << "is OK and has a value that ";
- inner_matcher_.DescribeTo(os);
- }
- void DescribeNegationTo(std::ostream* os) const override {
- *os << "isn't OK or has a value that ";
- inner_matcher_.DescribeNegationTo(os);
- }
- bool MatchAndExplain(
- StatusOrType actual_value,
- ::testing::MatchResultListener* result_listener) const override {
- if (!actual_value.ok()) {
- *result_listener << "which has status " << actual_value.status();
- return false;
- }
- ::testing::StringMatchResultListener inner_listener;
- const bool matches =
- inner_matcher_.MatchAndExplain(*actual_value, &inner_listener);
- const std::string inner_explanation = inner_listener.str();
- if (!inner_explanation.empty()) {
- *result_listener << "which contains value "
- << ::testing::PrintToString(*actual_value) << ", "
- << inner_explanation;
- }
- return matches;
- }
- private:
- const ::testing::Matcher<const value_type&> inner_matcher_;
- };
- // Implements IsOkAndHolds(m) as a polymorphic matcher.
- template <typename InnerMatcher>
- class IsOkAndHoldsMatcher {
- public:
- explicit IsOkAndHoldsMatcher(InnerMatcher inner_matcher)
- : inner_matcher_(std::move(inner_matcher)) {}
- // Converts this polymorphic matcher to a monomorphic matcher of the
- // given type. StatusOrType can be either StatusOr<T> or a
- // reference to StatusOr<T>.
- template <typename StatusOrType>
- operator ::testing::Matcher<StatusOrType>() const { // NOLINT
- return ::testing::Matcher<StatusOrType>(
- new IsOkAndHoldsMatcherImpl<const StatusOrType&>(inner_matcher_));
- }
- private:
- const InnerMatcher inner_matcher_;
- };
- // Monomorphic implementation of matcher IsOk() for a given type T.
- // T can be Status, StatusOr<>, or a reference to either of them.
- template <typename T>
- class MonoIsOkMatcherImpl : public ::testing::MatcherInterface<T> {
- public:
- void DescribeTo(std::ostream* os) const override { *os << "is OK"; }
- void DescribeNegationTo(std::ostream* os) const override {
- *os << "is not OK";
- }
- bool MatchAndExplain(T actual_value,
- ::testing::MatchResultListener*) const override {
- return GetStatus(actual_value).ok();
- }
- };
- // Implements IsOk() as a polymorphic matcher.
- class IsOkMatcher {
- public:
- template <typename T>
- operator ::testing::Matcher<T>() const { // NOLINT
- return ::testing::Matcher<T>(new MonoIsOkMatcherImpl<T>());
- }
- };
- // Macros for testing the results of functions that return absl::Status or
- // absl::StatusOr<T> (for any type T).
- #define EXPECT_OK(expression) EXPECT_THAT(expression, IsOk())
- // Returns a gMock matcher that matches a StatusOr<> whose status is
- // OK and whose value matches the inner matcher.
- template <typename InnerMatcher>
- IsOkAndHoldsMatcher<typename std::decay<InnerMatcher>::type> IsOkAndHolds(
- InnerMatcher&& inner_matcher) {
- return IsOkAndHoldsMatcher<typename std::decay<InnerMatcher>::type>(
- std::forward<InnerMatcher>(inner_matcher));
- }
- // Returns a gMock matcher that matches a Status or StatusOr<> which is OK.
- inline IsOkMatcher IsOk() { return IsOkMatcher(); }
- #endif // GTEST_HAS_STATUS_MATCHERS
- struct CopyDetector {
- CopyDetector() = default;
- explicit CopyDetector(int xx) : x(xx) {}
- CopyDetector(CopyDetector&& d) noexcept
- : x(d.x), copied(false), moved(true) {}
- CopyDetector(const CopyDetector& d) : x(d.x), copied(true), moved(false) {}
- CopyDetector& operator=(const CopyDetector& c) {
- x = c.x;
- copied = true;
- moved = false;
- return *this;
- }
- CopyDetector& operator=(CopyDetector&& c) noexcept {
- x = c.x;
- copied = false;
- moved = true;
- return *this;
- }
- int x = 0;
- bool copied = false;
- bool moved = false;
- };
- testing::Matcher<const CopyDetector&> CopyDetectorHas(int a, bool b, bool c) {
- return AllOf(Field(&CopyDetector::x, a), Field(&CopyDetector::moved, b),
- Field(&CopyDetector::copied, c));
- }
- class Base1 {
- public:
- virtual ~Base1() {}
- int pad;
- };
- class Base2 {
- public:
- virtual ~Base2() {}
- int yetotherpad;
- };
- class Derived : public Base1, public Base2 {
- public:
- virtual ~Derived() {}
- int evenmorepad;
- };
- class CopyNoAssign {
- public:
- explicit CopyNoAssign(int value) : foo(value) {}
- CopyNoAssign(const CopyNoAssign& other) : foo(other.foo) {}
- int foo;
- private:
- const CopyNoAssign& operator=(const CopyNoAssign&);
- };
- absl::StatusOr<std::unique_ptr<int>> ReturnUniquePtr() {
- // Uses implicit constructor from T&&
- return absl::make_unique<int>(0);
- }
- TEST(StatusOr, ElementType) {
- static_assert(std::is_same<absl::StatusOr<int>::value_type, int>(), "");
- static_assert(std::is_same<absl::StatusOr<char>::value_type, char>(), "");
- }
- TEST(StatusOr, TestMoveOnlyInitialization) {
- absl::StatusOr<std::unique_ptr<int>> thing(ReturnUniquePtr());
- ASSERT_TRUE(thing.ok());
- EXPECT_EQ(0, **thing);
- int* previous = thing->get();
- thing = ReturnUniquePtr();
- EXPECT_TRUE(thing.ok());
- EXPECT_EQ(0, **thing);
- EXPECT_NE(previous, thing->get());
- }
- TEST(StatusOr, TestMoveOnlyValueExtraction) {
- absl::StatusOr<std::unique_ptr<int>> thing(ReturnUniquePtr());
- ASSERT_TRUE(thing.ok());
- std::unique_ptr<int> ptr = *std::move(thing);
- EXPECT_EQ(0, *ptr);
- thing = std::move(ptr);
- ptr = std::move(*thing);
- EXPECT_EQ(0, *ptr);
- }
- TEST(StatusOr, TestMoveOnlyInitializationFromTemporaryByValueOrDie) {
- std::unique_ptr<int> ptr(*ReturnUniquePtr());
- EXPECT_EQ(0, *ptr);
- }
- TEST(StatusOr, TestValueOrDieOverloadForConstTemporary) {
- static_assert(
- std::is_same<
- const int&&,
- decltype(std::declval<const absl::StatusOr<int>&&>().value())>(),
- "value() for const temporaries should return const T&&");
- }
- TEST(StatusOr, TestMoveOnlyConversion) {
- absl::StatusOr<std::unique_ptr<const int>> const_thing(ReturnUniquePtr());
- EXPECT_TRUE(const_thing.ok());
- EXPECT_EQ(0, **const_thing);
- // Test rvalue converting assignment
- const int* const_previous = const_thing->get();
- const_thing = ReturnUniquePtr();
- EXPECT_TRUE(const_thing.ok());
- EXPECT_EQ(0, **const_thing);
- EXPECT_NE(const_previous, const_thing->get());
- }
- TEST(StatusOr, TestMoveOnlyVector) {
- // Sanity check that absl::StatusOr<MoveOnly> works in vector.
- std::vector<absl::StatusOr<std::unique_ptr<int>>> vec;
- vec.push_back(ReturnUniquePtr());
- vec.resize(2);
- auto another_vec = std::move(vec);
- EXPECT_EQ(0, **another_vec[0]);
- EXPECT_EQ(absl::UnknownError(""), another_vec[1].status());
- }
- TEST(StatusOr, TestDefaultCtor) {
- absl::StatusOr<int> thing;
- EXPECT_FALSE(thing.ok());
- EXPECT_EQ(thing.status().code(), absl::StatusCode::kUnknown);
- }
- TEST(StatusOr, StatusCtorForwards) {
- absl::Status status(absl::StatusCode::kInternal, "Some error");
- EXPECT_EQ(absl::StatusOr<int>(status).status().message(), "Some error");
- EXPECT_EQ(status.message(), "Some error");
- EXPECT_EQ(absl::StatusOr<int>(std::move(status)).status().message(),
- "Some error");
- EXPECT_NE(status.message(), "Some error");
- }
- TEST(BadStatusOrAccessTest, CopyConstructionWhatOk) {
- absl::Status error =
- absl::InternalError("some arbitrary message too big for the sso buffer");
- absl::BadStatusOrAccess e1{error};
- absl::BadStatusOrAccess e2{e1};
- EXPECT_THAT(e1.what(), HasSubstr(error.ToString()));
- EXPECT_THAT(e2.what(), HasSubstr(error.ToString()));
- }
- TEST(BadStatusOrAccessTest, CopyAssignmentWhatOk) {
- absl::Status error =
- absl::InternalError("some arbitrary message too big for the sso buffer");
- absl::BadStatusOrAccess e1{error};
- absl::BadStatusOrAccess e2{absl::InternalError("other")};
- e2 = e1;
- EXPECT_THAT(e1.what(), HasSubstr(error.ToString()));
- EXPECT_THAT(e2.what(), HasSubstr(error.ToString()));
- }
- TEST(BadStatusOrAccessTest, MoveConstructionWhatOk) {
- absl::Status error =
- absl::InternalError("some arbitrary message too big for the sso buffer");
- absl::BadStatusOrAccess e1{error};
- absl::BadStatusOrAccess e2{std::move(e1)};
- EXPECT_THAT(e2.what(), HasSubstr(error.ToString()));
- }
- TEST(BadStatusOrAccessTest, MoveAssignmentWhatOk) {
- absl::Status error =
- absl::InternalError("some arbitrary message too big for the sso buffer");
- absl::BadStatusOrAccess e1{error};
- absl::BadStatusOrAccess e2{absl::InternalError("other")};
- e2 = std::move(e1);
- EXPECT_THAT(e2.what(), HasSubstr(error.ToString()));
- }
- // Define `EXPECT_DEATH_OR_THROW` to test the behavior of `StatusOr::value`,
- // which either throws `BadStatusOrAccess` or `LOG(FATAL)` based on whether
- // exceptions are enabled.
- #ifdef ABSL_HAVE_EXCEPTIONS
- #define EXPECT_DEATH_OR_THROW(statement, status_) \
- EXPECT_THROW( \
- { \
- try { \
- statement; \
- } catch (const absl::BadStatusOrAccess& e) { \
- EXPECT_EQ(e.status(), status_); \
- EXPECT_THAT(e.what(), HasSubstr(e.status().ToString())); \
- throw; \
- } \
- }, \
- absl::BadStatusOrAccess);
- #else // ABSL_HAVE_EXCEPTIONS
- #define EXPECT_DEATH_OR_THROW(statement, status) \
- EXPECT_DEATH_IF_SUPPORTED(statement, status.ToString());
- #endif // ABSL_HAVE_EXCEPTIONS
- TEST(StatusOrDeathTest, TestDefaultCtorValue) {
- absl::StatusOr<int> thing;
- EXPECT_DEATH_OR_THROW(thing.value(), absl::UnknownError(""));
- const absl::StatusOr<int> thing2;
- EXPECT_DEATH_OR_THROW(thing2.value(), absl::UnknownError(""));
- }
- TEST(StatusOrDeathTest, TestValueNotOk) {
- absl::StatusOr<int> thing(absl::CancelledError());
- EXPECT_DEATH_OR_THROW(thing.value(), absl::CancelledError());
- }
- TEST(StatusOrDeathTest, TestValueNotOkConst) {
- const absl::StatusOr<int> thing(absl::UnknownError(""));
- EXPECT_DEATH_OR_THROW(thing.value(), absl::UnknownError(""));
- }
- TEST(StatusOrDeathTest, TestPointerDefaultCtorValue) {
- absl::StatusOr<int*> thing;
- EXPECT_DEATH_OR_THROW(thing.value(), absl::UnknownError(""));
- }
- TEST(StatusOrDeathTest, TestPointerValueNotOk) {
- absl::StatusOr<int*> thing(absl::CancelledError());
- EXPECT_DEATH_OR_THROW(thing.value(), absl::CancelledError());
- }
- TEST(StatusOrDeathTest, TestPointerValueNotOkConst) {
- const absl::StatusOr<int*> thing(absl::CancelledError());
- EXPECT_DEATH_OR_THROW(thing.value(), absl::CancelledError());
- }
- #if GTEST_HAS_DEATH_TEST
- TEST(StatusOrDeathTest, TestStatusCtorStatusOk) {
- EXPECT_DEBUG_DEATH(
- {
- // This will DCHECK
- absl::StatusOr<int> thing(absl::OkStatus());
- // In optimized mode, we are actually going to get error::INTERNAL for
- // status here, rather than crashing, so check that.
- EXPECT_FALSE(thing.ok());
- EXPECT_EQ(thing.status().code(), absl::StatusCode::kInternal);
- },
- "An OK status is not a valid constructor argument");
- }
- TEST(StatusOrDeathTest, TestPointerStatusCtorStatusOk) {
- EXPECT_DEBUG_DEATH(
- {
- absl::StatusOr<int*> thing(absl::OkStatus());
- // In optimized mode, we are actually going to get error::INTERNAL for
- // status here, rather than crashing, so check that.
- EXPECT_FALSE(thing.ok());
- EXPECT_EQ(thing.status().code(), absl::StatusCode::kInternal);
- },
- "An OK status is not a valid constructor argument");
- }
- #endif
- TEST(StatusOr, ValueAccessor) {
- const int kIntValue = 110;
- {
- absl::StatusOr<int> status_or(kIntValue);
- EXPECT_EQ(kIntValue, status_or.value());
- EXPECT_EQ(kIntValue, std::move(status_or).value());
- }
- {
- absl::StatusOr<CopyDetector> status_or(kIntValue);
- EXPECT_THAT(status_or,
- IsOkAndHolds(CopyDetectorHas(kIntValue, false, false)));
- CopyDetector copy_detector = status_or.value();
- EXPECT_THAT(copy_detector, CopyDetectorHas(kIntValue, false, true));
- copy_detector = std::move(status_or).value();
- EXPECT_THAT(copy_detector, CopyDetectorHas(kIntValue, true, false));
- }
- }
- TEST(StatusOr, BadValueAccess) {
- const absl::Status kError = absl::CancelledError("message");
- absl::StatusOr<int> status_or(kError);
- EXPECT_DEATH_OR_THROW(status_or.value(), kError);
- }
- TEST(StatusOr, TestStatusCtor) {
- absl::StatusOr<int> thing(absl::CancelledError());
- EXPECT_FALSE(thing.ok());
- EXPECT_EQ(thing.status().code(), absl::StatusCode::kCancelled);
- }
- TEST(StatusOr, TestValueCtor) {
- const int kI = 4;
- const absl::StatusOr<int> thing(kI);
- EXPECT_TRUE(thing.ok());
- EXPECT_EQ(kI, *thing);
- }
- struct Foo {
- const int x;
- explicit Foo(int y) : x(y) {}
- };
- TEST(StatusOr, InPlaceConstruction) {
- EXPECT_THAT(absl::StatusOr<Foo>(absl::in_place, 10),
- IsOkAndHolds(Field(&Foo::x, 10)));
- }
- struct InPlaceHelper {
- InPlaceHelper(std::initializer_list<int> xs, std::unique_ptr<int> yy)
- : x(xs), y(std::move(yy)) {}
- const std::vector<int> x;
- std::unique_ptr<int> y;
- };
- TEST(StatusOr, InPlaceInitListConstruction) {
- absl::StatusOr<InPlaceHelper> status_or(absl::in_place, {10, 11, 12},
- absl::make_unique<int>(13));
- EXPECT_THAT(status_or, IsOkAndHolds(AllOf(
- Field(&InPlaceHelper::x, ElementsAre(10, 11, 12)),
- Field(&InPlaceHelper::y, Pointee(13)))));
- }
- TEST(StatusOr, Emplace) {
- absl::StatusOr<Foo> status_or_foo(10);
- status_or_foo.emplace(20);
- EXPECT_THAT(status_or_foo, IsOkAndHolds(Field(&Foo::x, 20)));
- status_or_foo = absl::InvalidArgumentError("msg");
- EXPECT_FALSE(status_or_foo.ok());
- EXPECT_EQ(status_or_foo.status().code(), absl::StatusCode::kInvalidArgument);
- EXPECT_EQ(status_or_foo.status().message(), "msg");
- status_or_foo.emplace(20);
- EXPECT_THAT(status_or_foo, IsOkAndHolds(Field(&Foo::x, 20)));
- }
- TEST(StatusOr, EmplaceInitializerList) {
- absl::StatusOr<InPlaceHelper> status_or(absl::in_place, {10, 11, 12},
- absl::make_unique<int>(13));
- status_or.emplace({1, 2, 3}, absl::make_unique<int>(4));
- EXPECT_THAT(status_or,
- IsOkAndHolds(AllOf(Field(&InPlaceHelper::x, ElementsAre(1, 2, 3)),
- Field(&InPlaceHelper::y, Pointee(4)))));
- status_or = absl::InvalidArgumentError("msg");
- EXPECT_FALSE(status_or.ok());
- EXPECT_EQ(status_or.status().code(), absl::StatusCode::kInvalidArgument);
- EXPECT_EQ(status_or.status().message(), "msg");
- status_or.emplace({1, 2, 3}, absl::make_unique<int>(4));
- EXPECT_THAT(status_or,
- IsOkAndHolds(AllOf(Field(&InPlaceHelper::x, ElementsAre(1, 2, 3)),
- Field(&InPlaceHelper::y, Pointee(4)))));
- }
- TEST(StatusOr, TestCopyCtorStatusOk) {
- const int kI = 4;
- const absl::StatusOr<int> original(kI);
- const absl::StatusOr<int> copy(original);
- EXPECT_OK(copy.status());
- EXPECT_EQ(*original, *copy);
- }
- TEST(StatusOr, TestCopyCtorStatusNotOk) {
- absl::StatusOr<int> original(absl::CancelledError());
- absl::StatusOr<int> copy(original);
- EXPECT_EQ(copy.status().code(), absl::StatusCode::kCancelled);
- }
- TEST(StatusOr, TestCopyCtorNonAssignable) {
- const int kI = 4;
- CopyNoAssign value(kI);
- absl::StatusOr<CopyNoAssign> original(value);
- absl::StatusOr<CopyNoAssign> copy(original);
- EXPECT_OK(copy.status());
- EXPECT_EQ(original->foo, copy->foo);
- }
- TEST(StatusOr, TestCopyCtorStatusOKConverting) {
- const int kI = 4;
- absl::StatusOr<int> original(kI);
- absl::StatusOr<double> copy(original);
- EXPECT_OK(copy.status());
- EXPECT_DOUBLE_EQ(*original, *copy);
- }
- TEST(StatusOr, TestCopyCtorStatusNotOkConverting) {
- absl::StatusOr<int> original(absl::CancelledError());
- absl::StatusOr<double> copy(original);
- EXPECT_EQ(copy.status(), original.status());
- }
- TEST(StatusOr, TestAssignmentStatusOk) {
- // Copy assignmment
- {
- const auto p = std::make_shared<int>(17);
- absl::StatusOr<std::shared_ptr<int>> source(p);
- absl::StatusOr<std::shared_ptr<int>> target;
- target = source;
- ASSERT_TRUE(target.ok());
- EXPECT_OK(target.status());
- EXPECT_EQ(p, *target);
- ASSERT_TRUE(source.ok());
- EXPECT_OK(source.status());
- EXPECT_EQ(p, *source);
- }
- // Move asssignment
- {
- const auto p = std::make_shared<int>(17);
- absl::StatusOr<std::shared_ptr<int>> source(p);
- absl::StatusOr<std::shared_ptr<int>> target;
- target = std::move(source);
- ASSERT_TRUE(target.ok());
- EXPECT_OK(target.status());
- EXPECT_EQ(p, *target);
- ASSERT_TRUE(source.ok());
- EXPECT_OK(source.status());
- EXPECT_EQ(nullptr, *source);
- }
- }
- TEST(StatusOr, TestAssignmentStatusNotOk) {
- // Copy assignment
- {
- const absl::Status expected = absl::CancelledError();
- absl::StatusOr<int> source(expected);
- absl::StatusOr<int> target;
- target = source;
- EXPECT_FALSE(target.ok());
- EXPECT_EQ(expected, target.status());
- EXPECT_FALSE(source.ok());
- EXPECT_EQ(expected, source.status());
- }
- // Move assignment
- {
- const absl::Status expected = absl::CancelledError();
- absl::StatusOr<int> source(expected);
- absl::StatusOr<int> target;
- target = std::move(source);
- EXPECT_FALSE(target.ok());
- EXPECT_EQ(expected, target.status());
- EXPECT_FALSE(source.ok());
- EXPECT_EQ(source.status().code(), absl::StatusCode::kInternal);
- }
- }
- TEST(StatusOr, TestAssignmentStatusOKConverting) {
- // Copy assignment
- {
- const int kI = 4;
- absl::StatusOr<int> source(kI);
- absl::StatusOr<double> target;
- target = source;
- ASSERT_TRUE(target.ok());
- EXPECT_OK(target.status());
- EXPECT_DOUBLE_EQ(kI, *target);
- ASSERT_TRUE(source.ok());
- EXPECT_OK(source.status());
- EXPECT_DOUBLE_EQ(kI, *source);
- }
- // Move assignment
- {
- const auto p = new int(17);
- absl::StatusOr<std::unique_ptr<int>> source(absl::WrapUnique(p));
- absl::StatusOr<std::shared_ptr<int>> target;
- target = std::move(source);
- ASSERT_TRUE(target.ok());
- EXPECT_OK(target.status());
- EXPECT_EQ(p, target->get());
- ASSERT_TRUE(source.ok());
- EXPECT_OK(source.status());
- EXPECT_EQ(nullptr, source->get());
- }
- }
- struct A {
- int x;
- };
- struct ImplicitConstructibleFromA {
- int x;
- bool moved;
- ImplicitConstructibleFromA(const A& a) // NOLINT
- : x(a.x), moved(false) {}
- ImplicitConstructibleFromA(A&& a) // NOLINT
- : x(a.x), moved(true) {}
- };
- TEST(StatusOr, ImplicitConvertingConstructor) {
- EXPECT_THAT(
- absl::implicit_cast<absl::StatusOr<ImplicitConstructibleFromA>>(
- absl::StatusOr<A>(A{11})),
- IsOkAndHolds(AllOf(Field(&ImplicitConstructibleFromA::x, 11),
- Field(&ImplicitConstructibleFromA::moved, true))));
- absl::StatusOr<A> a(A{12});
- EXPECT_THAT(
- absl::implicit_cast<absl::StatusOr<ImplicitConstructibleFromA>>(a),
- IsOkAndHolds(AllOf(Field(&ImplicitConstructibleFromA::x, 12),
- Field(&ImplicitConstructibleFromA::moved, false))));
- }
- struct ExplicitConstructibleFromA {
- int x;
- bool moved;
- explicit ExplicitConstructibleFromA(const A& a) : x(a.x), moved(false) {}
- explicit ExplicitConstructibleFromA(A&& a) : x(a.x), moved(true) {}
- };
- TEST(StatusOr, ExplicitConvertingConstructor) {
- EXPECT_FALSE(
- (std::is_convertible<const absl::StatusOr<A>&,
- absl::StatusOr<ExplicitConstructibleFromA>>::value));
- EXPECT_FALSE(
- (std::is_convertible<absl::StatusOr<A>&&,
- absl::StatusOr<ExplicitConstructibleFromA>>::value));
- EXPECT_THAT(
- absl::StatusOr<ExplicitConstructibleFromA>(absl::StatusOr<A>(A{11})),
- IsOkAndHolds(AllOf(Field(&ExplicitConstructibleFromA::x, 11),
- Field(&ExplicitConstructibleFromA::moved, true))));
- absl::StatusOr<A> a(A{12});
- EXPECT_THAT(
- absl::StatusOr<ExplicitConstructibleFromA>(a),
- IsOkAndHolds(AllOf(Field(&ExplicitConstructibleFromA::x, 12),
- Field(&ExplicitConstructibleFromA::moved, false))));
- }
- struct ImplicitConstructibleFromBool {
- ImplicitConstructibleFromBool(bool y) : x(y) {} // NOLINT
- bool x = false;
- };
- struct ConvertibleToBool {
- explicit ConvertibleToBool(bool y) : x(y) {}
- operator bool() const { return x; } // NOLINT
- bool x = false;
- };
- TEST(StatusOr, ImplicitBooleanConstructionWithImplicitCasts) {
- EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<ConvertibleToBool>(true)),
- IsOkAndHolds(true));
- EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<ConvertibleToBool>(false)),
- IsOkAndHolds(false));
- EXPECT_THAT(
- absl::implicit_cast<absl::StatusOr<ImplicitConstructibleFromBool>>(
- absl::StatusOr<bool>(false)),
- IsOkAndHolds(Field(&ImplicitConstructibleFromBool::x, false)));
- EXPECT_FALSE((std::is_convertible<
- absl::StatusOr<ConvertibleToBool>,
- absl::StatusOr<ImplicitConstructibleFromBool>>::value));
- }
- TEST(StatusOr, BooleanConstructionWithImplicitCasts) {
- EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<ConvertibleToBool>(true)),
- IsOkAndHolds(true));
- EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<ConvertibleToBool>(false)),
- IsOkAndHolds(false));
- EXPECT_THAT(
- absl::StatusOr<ImplicitConstructibleFromBool>{
- absl::StatusOr<bool>(false)},
- IsOkAndHolds(Field(&ImplicitConstructibleFromBool::x, false)));
- EXPECT_THAT(
- absl::StatusOr<ImplicitConstructibleFromBool>{
- absl::StatusOr<bool>(absl::InvalidArgumentError(""))},
- Not(IsOk()));
- EXPECT_THAT(
- absl::StatusOr<ImplicitConstructibleFromBool>{
- absl::StatusOr<ConvertibleToBool>(ConvertibleToBool{false})},
- IsOkAndHolds(Field(&ImplicitConstructibleFromBool::x, false)));
- EXPECT_THAT(
- absl::StatusOr<ImplicitConstructibleFromBool>{
- absl::StatusOr<ConvertibleToBool>(absl::InvalidArgumentError(""))},
- Not(IsOk()));
- }
- TEST(StatusOr, ConstImplicitCast) {
- EXPECT_THAT(absl::implicit_cast<absl::StatusOr<bool>>(
- absl::StatusOr<const bool>(true)),
- IsOkAndHolds(true));
- EXPECT_THAT(absl::implicit_cast<absl::StatusOr<bool>>(
- absl::StatusOr<const bool>(false)),
- IsOkAndHolds(false));
- EXPECT_THAT(absl::implicit_cast<absl::StatusOr<const bool>>(
- absl::StatusOr<bool>(true)),
- IsOkAndHolds(true));
- EXPECT_THAT(absl::implicit_cast<absl::StatusOr<const bool>>(
- absl::StatusOr<bool>(false)),
- IsOkAndHolds(false));
- EXPECT_THAT(absl::implicit_cast<absl::StatusOr<const std::string>>(
- absl::StatusOr<std::string>("foo")),
- IsOkAndHolds("foo"));
- EXPECT_THAT(absl::implicit_cast<absl::StatusOr<std::string>>(
- absl::StatusOr<const std::string>("foo")),
- IsOkAndHolds("foo"));
- EXPECT_THAT(
- absl::implicit_cast<absl::StatusOr<std::shared_ptr<const std::string>>>(
- absl::StatusOr<std::shared_ptr<std::string>>(
- std::make_shared<std::string>("foo"))),
- IsOkAndHolds(Pointee(std::string("foo"))));
- }
- TEST(StatusOr, ConstExplicitConstruction) {
- EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<const bool>(true)),
- IsOkAndHolds(true));
- EXPECT_THAT(absl::StatusOr<bool>(absl::StatusOr<const bool>(false)),
- IsOkAndHolds(false));
- EXPECT_THAT(absl::StatusOr<const bool>(absl::StatusOr<bool>(true)),
- IsOkAndHolds(true));
- EXPECT_THAT(absl::StatusOr<const bool>(absl::StatusOr<bool>(false)),
- IsOkAndHolds(false));
- }
- struct ExplicitConstructibleFromInt {
- int x;
- explicit ExplicitConstructibleFromInt(int y) : x(y) {}
- };
- TEST(StatusOr, ExplicitConstruction) {
- EXPECT_THAT(absl::StatusOr<ExplicitConstructibleFromInt>(10),
- IsOkAndHolds(Field(&ExplicitConstructibleFromInt::x, 10)));
- }
- TEST(StatusOr, ImplicitConstruction) {
- // Check implicit casting works.
- auto status_or =
- absl::implicit_cast<absl::StatusOr<absl::variant<int, std::string>>>(10);
- EXPECT_THAT(status_or, IsOkAndHolds(VariantWith<int>(10)));
- }
- TEST(StatusOr, ImplicitConstructionFromInitliazerList) {
- // Note: dropping the explicit std::initializer_list<int> is not supported
- // by absl::StatusOr or absl::optional.
- auto status_or =
- absl::implicit_cast<absl::StatusOr<std::vector<int>>>({{10, 20, 30}});
- EXPECT_THAT(status_or, IsOkAndHolds(ElementsAre(10, 20, 30)));
- }
- TEST(StatusOr, UniquePtrImplicitConstruction) {
- auto status_or = absl::implicit_cast<absl::StatusOr<std::unique_ptr<Base1>>>(
- absl::make_unique<Derived>());
- EXPECT_THAT(status_or, IsOkAndHolds(Ne(nullptr)));
- }
- TEST(StatusOr, NestedStatusOrCopyAndMoveConstructorTests) {
- absl::StatusOr<absl::StatusOr<CopyDetector>> status_or = CopyDetector(10);
- absl::StatusOr<absl::StatusOr<CopyDetector>> status_error =
- absl::InvalidArgumentError("foo");
- EXPECT_THAT(status_or,
- IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, true, false))));
- absl::StatusOr<absl::StatusOr<CopyDetector>> a = status_or;
- EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true))));
- absl::StatusOr<absl::StatusOr<CopyDetector>> a_err = status_error;
- EXPECT_THAT(a_err, Not(IsOk()));
- const absl::StatusOr<absl::StatusOr<CopyDetector>>& cref = status_or;
- absl::StatusOr<absl::StatusOr<CopyDetector>> b = cref; // NOLINT
- EXPECT_THAT(b, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true))));
- const absl::StatusOr<absl::StatusOr<CopyDetector>>& cref_err = status_error;
- absl::StatusOr<absl::StatusOr<CopyDetector>> b_err = cref_err; // NOLINT
- EXPECT_THAT(b_err, Not(IsOk()));
- absl::StatusOr<absl::StatusOr<CopyDetector>> c = std::move(status_or);
- EXPECT_THAT(c, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, true, false))));
- absl::StatusOr<absl::StatusOr<CopyDetector>> c_err = std::move(status_error);
- EXPECT_THAT(c_err, Not(IsOk()));
- }
- TEST(StatusOr, NestedStatusOrCopyAndMoveAssignment) {
- absl::StatusOr<absl::StatusOr<CopyDetector>> status_or = CopyDetector(10);
- absl::StatusOr<absl::StatusOr<CopyDetector>> status_error =
- absl::InvalidArgumentError("foo");
- absl::StatusOr<absl::StatusOr<CopyDetector>> a;
- a = status_or;
- EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true))));
- a = status_error;
- EXPECT_THAT(a, Not(IsOk()));
- const absl::StatusOr<absl::StatusOr<CopyDetector>>& cref = status_or;
- a = cref;
- EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, false, true))));
- const absl::StatusOr<absl::StatusOr<CopyDetector>>& cref_err = status_error;
- a = cref_err;
- EXPECT_THAT(a, Not(IsOk()));
- a = std::move(status_or);
- EXPECT_THAT(a, IsOkAndHolds(IsOkAndHolds(CopyDetectorHas(10, true, false))));
- a = std::move(status_error);
- EXPECT_THAT(a, Not(IsOk()));
- }
- struct Copyable {
- Copyable() {}
- Copyable(const Copyable&) {}
- Copyable& operator=(const Copyable&) { return *this; }
- };
- struct MoveOnly {
- MoveOnly() {}
- MoveOnly(MoveOnly&&) {}
- MoveOnly& operator=(MoveOnly&&) { return *this; }
- };
- struct NonMovable {
- NonMovable() {}
- NonMovable(const NonMovable&) = delete;
- NonMovable(NonMovable&&) = delete;
- NonMovable& operator=(const NonMovable&) = delete;
- NonMovable& operator=(NonMovable&&) = delete;
- };
- TEST(StatusOr, CopyAndMoveAbility) {
- EXPECT_TRUE(std::is_copy_constructible<Copyable>::value);
- EXPECT_TRUE(std::is_copy_assignable<Copyable>::value);
- EXPECT_TRUE(std::is_move_constructible<Copyable>::value);
- EXPECT_TRUE(std::is_move_assignable<Copyable>::value);
- EXPECT_FALSE(std::is_copy_constructible<MoveOnly>::value);
- EXPECT_FALSE(std::is_copy_assignable<MoveOnly>::value);
- EXPECT_TRUE(std::is_move_constructible<MoveOnly>::value);
- EXPECT_TRUE(std::is_move_assignable<MoveOnly>::value);
- EXPECT_FALSE(std::is_copy_constructible<NonMovable>::value);
- EXPECT_FALSE(std::is_copy_assignable<NonMovable>::value);
- EXPECT_FALSE(std::is_move_constructible<NonMovable>::value);
- EXPECT_FALSE(std::is_move_assignable<NonMovable>::value);
- }
- TEST(StatusOr, StatusOrAnyCopyAndMoveConstructorTests) {
- absl::StatusOr<absl::any> status_or = CopyDetector(10);
- absl::StatusOr<absl::any> status_error = absl::InvalidArgumentError("foo");
- EXPECT_THAT(
- status_or,
- IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, true, false))));
- absl::StatusOr<absl::any> a = status_or;
- EXPECT_THAT(
- a, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, false, true))));
- absl::StatusOr<absl::any> a_err = status_error;
- EXPECT_THAT(a_err, Not(IsOk()));
- const absl::StatusOr<absl::any>& cref = status_or;
- // No lint for no-change copy.
- absl::StatusOr<absl::any> b = cref; // NOLINT
- EXPECT_THAT(
- b, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, false, true))));
- const absl::StatusOr<absl::any>& cref_err = status_error;
- // No lint for no-change copy.
- absl::StatusOr<absl::any> b_err = cref_err; // NOLINT
- EXPECT_THAT(b_err, Not(IsOk()));
- absl::StatusOr<absl::any> c = std::move(status_or);
- EXPECT_THAT(
- c, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, true, false))));
- absl::StatusOr<absl::any> c_err = std::move(status_error);
- EXPECT_THAT(c_err, Not(IsOk()));
- }
- TEST(StatusOr, StatusOrAnyCopyAndMoveAssignment) {
- absl::StatusOr<absl::any> status_or = CopyDetector(10);
- absl::StatusOr<absl::any> status_error = absl::InvalidArgumentError("foo");
- absl::StatusOr<absl::any> a;
- a = status_or;
- EXPECT_THAT(
- a, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, false, true))));
- a = status_error;
- EXPECT_THAT(a, Not(IsOk()));
- const absl::StatusOr<absl::any>& cref = status_or;
- a = cref;
- EXPECT_THAT(
- a, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, false, true))));
- const absl::StatusOr<absl::any>& cref_err = status_error;
- a = cref_err;
- EXPECT_THAT(a, Not(IsOk()));
- a = std::move(status_or);
- EXPECT_THAT(
- a, IsOkAndHolds(AnyWith<CopyDetector>(CopyDetectorHas(10, true, false))));
- a = std::move(status_error);
- EXPECT_THAT(a, Not(IsOk()));
- }
- TEST(StatusOr, StatusOrCopyAndMoveTestsConstructor) {
- absl::StatusOr<CopyDetector> status_or(10);
- ASSERT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(10, false, false)));
- absl::StatusOr<CopyDetector> a(status_or);
- EXPECT_THAT(a, IsOkAndHolds(CopyDetectorHas(10, false, true)));
- const absl::StatusOr<CopyDetector>& cref = status_or;
- absl::StatusOr<CopyDetector> b(cref); // NOLINT
- EXPECT_THAT(b, IsOkAndHolds(CopyDetectorHas(10, false, true)));
- absl::StatusOr<CopyDetector> c(std::move(status_or));
- EXPECT_THAT(c, IsOkAndHolds(CopyDetectorHas(10, true, false)));
- }
- TEST(StatusOr, StatusOrCopyAndMoveTestsAssignment) {
- absl::StatusOr<CopyDetector> status_or(10);
- ASSERT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(10, false, false)));
- absl::StatusOr<CopyDetector> a;
- a = status_or;
- EXPECT_THAT(a, IsOkAndHolds(CopyDetectorHas(10, false, true)));
- const absl::StatusOr<CopyDetector>& cref = status_or;
- absl::StatusOr<CopyDetector> b;
- b = cref;
- EXPECT_THAT(b, IsOkAndHolds(CopyDetectorHas(10, false, true)));
- absl::StatusOr<CopyDetector> c;
- c = std::move(status_or);
- EXPECT_THAT(c, IsOkAndHolds(CopyDetectorHas(10, true, false)));
- }
- TEST(StatusOr, AbslAnyAssignment) {
- EXPECT_FALSE((std::is_assignable<absl::StatusOr<absl::any>,
- absl::StatusOr<int>>::value));
- absl::StatusOr<absl::any> status_or;
- status_or = absl::InvalidArgumentError("foo");
- EXPECT_THAT(status_or, Not(IsOk()));
- }
- TEST(StatusOr, ImplicitAssignment) {
- absl::StatusOr<absl::variant<int, std::string>> status_or;
- status_or = 10;
- EXPECT_THAT(status_or, IsOkAndHolds(VariantWith<int>(10)));
- }
- TEST(StatusOr, SelfDirectInitAssignment) {
- absl::StatusOr<std::vector<int>> status_or = {{10, 20, 30}};
- status_or = *status_or;
- EXPECT_THAT(status_or, IsOkAndHolds(ElementsAre(10, 20, 30)));
- }
- TEST(StatusOr, ImplicitCastFromInitializerList) {
- absl::StatusOr<std::vector<int>> status_or = {{10, 20, 30}};
- EXPECT_THAT(status_or, IsOkAndHolds(ElementsAre(10, 20, 30)));
- }
- TEST(StatusOr, UniquePtrImplicitAssignment) {
- absl::StatusOr<std::unique_ptr<Base1>> status_or;
- status_or = absl::make_unique<Derived>();
- EXPECT_THAT(status_or, IsOkAndHolds(Ne(nullptr)));
- }
- TEST(StatusOr, Pointer) {
- struct A {};
- struct B : public A {};
- struct C : private A {};
- EXPECT_TRUE((std::is_constructible<absl::StatusOr<A*>, B*>::value));
- EXPECT_TRUE((std::is_convertible<B*, absl::StatusOr<A*>>::value));
- EXPECT_FALSE((std::is_constructible<absl::StatusOr<A*>, C*>::value));
- EXPECT_FALSE((std::is_convertible<C*, absl::StatusOr<A*>>::value));
- }
- TEST(StatusOr, TestAssignmentStatusNotOkConverting) {
- // Copy assignment
- {
- const absl::Status expected = absl::CancelledError();
- absl::StatusOr<int> source(expected);
- absl::StatusOr<double> target;
- target = source;
- EXPECT_FALSE(target.ok());
- EXPECT_EQ(expected, target.status());
- EXPECT_FALSE(source.ok());
- EXPECT_EQ(expected, source.status());
- }
- // Move assignment
- {
- const absl::Status expected = absl::CancelledError();
- absl::StatusOr<int> source(expected);
- absl::StatusOr<double> target;
- target = std::move(source);
- EXPECT_FALSE(target.ok());
- EXPECT_EQ(expected, target.status());
- EXPECT_FALSE(source.ok());
- EXPECT_EQ(source.status().code(), absl::StatusCode::kInternal);
- }
- }
- TEST(StatusOr, SelfAssignment) {
- // Copy-assignment, status OK
- {
- // A string long enough that it's likely to defeat any inline representation
- // optimization.
- const std::string long_str(128, 'a');
- absl::StatusOr<std::string> so = long_str;
- so = *&so;
- ASSERT_TRUE(so.ok());
- EXPECT_OK(so.status());
- EXPECT_EQ(long_str, *so);
- }
- // Copy-assignment, error status
- {
- absl::StatusOr<int> so = absl::NotFoundError("taco");
- so = *&so;
- EXPECT_FALSE(so.ok());
- EXPECT_EQ(so.status().code(), absl::StatusCode::kNotFound);
- EXPECT_EQ(so.status().message(), "taco");
- }
- // Move-assignment with copyable type, status OK
- {
- absl::StatusOr<int> so = 17;
- // Fool the compiler, which otherwise complains.
- auto& same = so;
- so = std::move(same);
- ASSERT_TRUE(so.ok());
- EXPECT_OK(so.status());
- EXPECT_EQ(17, *so);
- }
- // Move-assignment with copyable type, error status
- {
- absl::StatusOr<int> so = absl::NotFoundError("taco");
- // Fool the compiler, which otherwise complains.
- auto& same = so;
- so = std::move(same);
- EXPECT_FALSE(so.ok());
- EXPECT_EQ(so.status().code(), absl::StatusCode::kNotFound);
- EXPECT_EQ(so.status().message(), "taco");
- }
- // Move-assignment with non-copyable type, status OK
- {
- const auto raw = new int(17);
- absl::StatusOr<std::unique_ptr<int>> so = absl::WrapUnique(raw);
- // Fool the compiler, which otherwise complains.
- auto& same = so;
- so = std::move(same);
- ASSERT_TRUE(so.ok());
- EXPECT_OK(so.status());
- EXPECT_EQ(raw, so->get());
- }
- // Move-assignment with non-copyable type, error status
- {
- absl::StatusOr<std::unique_ptr<int>> so = absl::NotFoundError("taco");
- // Fool the compiler, which otherwise complains.
- auto& same = so;
- so = std::move(same);
- EXPECT_FALSE(so.ok());
- EXPECT_EQ(so.status().code(), absl::StatusCode::kNotFound);
- EXPECT_EQ(so.status().message(), "taco");
- }
- }
- // These types form the overload sets of the constructors and the assignment
- // operators of `MockValue`. They distinguish construction from assignment,
- // lvalue from rvalue.
- struct FromConstructibleAssignableLvalue {};
- struct FromConstructibleAssignableRvalue {};
- struct FromImplicitConstructibleOnly {};
- struct FromAssignableOnly {};
- // This class is for testing the forwarding value assignments of `StatusOr`.
- // `from_rvalue` indicates whether the constructor or the assignment taking
- // rvalue reference is called. `from_assignment` indicates whether any
- // assignment is called.
- struct MockValue {
- // Constructs `MockValue` from `FromConstructibleAssignableLvalue`.
- MockValue(const FromConstructibleAssignableLvalue&) // NOLINT
- : from_rvalue(false), assigned(false) {}
- // Constructs `MockValue` from `FromConstructibleAssignableRvalue`.
- MockValue(FromConstructibleAssignableRvalue&&) // NOLINT
- : from_rvalue(true), assigned(false) {}
- // Constructs `MockValue` from `FromImplicitConstructibleOnly`.
- // `MockValue` is not assignable from `FromImplicitConstructibleOnly`.
- MockValue(const FromImplicitConstructibleOnly&) // NOLINT
- : from_rvalue(false), assigned(false) {}
- // Assigns `FromConstructibleAssignableLvalue`.
- MockValue& operator=(const FromConstructibleAssignableLvalue&) {
- from_rvalue = false;
- assigned = true;
- return *this;
- }
- // Assigns `FromConstructibleAssignableRvalue` (rvalue only).
- MockValue& operator=(FromConstructibleAssignableRvalue&&) {
- from_rvalue = true;
- assigned = true;
- return *this;
- }
- // Assigns `FromAssignableOnly`, but not constructible from
- // `FromAssignableOnly`.
- MockValue& operator=(const FromAssignableOnly&) {
- from_rvalue = false;
- assigned = true;
- return *this;
- }
- bool from_rvalue;
- bool assigned;
- };
- // operator=(U&&)
- TEST(StatusOr, PerfectForwardingAssignment) {
- // U == T
- constexpr int kValue1 = 10, kValue2 = 20;
- absl::StatusOr<CopyDetector> status_or;
- CopyDetector lvalue(kValue1);
- status_or = lvalue;
- EXPECT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(kValue1, false, true)));
- status_or = CopyDetector(kValue2);
- EXPECT_THAT(status_or, IsOkAndHolds(CopyDetectorHas(kValue2, true, false)));
- // U != T
- EXPECT_TRUE(
- (std::is_assignable<absl::StatusOr<MockValue>&,
- const FromConstructibleAssignableLvalue&>::value));
- EXPECT_TRUE((std::is_assignable<absl::StatusOr<MockValue>&,
- FromConstructibleAssignableLvalue&&>::value));
- EXPECT_FALSE(
- (std::is_assignable<absl::StatusOr<MockValue>&,
- const FromConstructibleAssignableRvalue&>::value));
- EXPECT_TRUE((std::is_assignable<absl::StatusOr<MockValue>&,
- FromConstructibleAssignableRvalue&&>::value));
- EXPECT_TRUE(
- (std::is_assignable<absl::StatusOr<MockValue>&,
- const FromImplicitConstructibleOnly&>::value));
- EXPECT_FALSE((std::is_assignable<absl::StatusOr<MockValue>&,
- const FromAssignableOnly&>::value));
- absl::StatusOr<MockValue> from_lvalue(FromConstructibleAssignableLvalue{});
- EXPECT_FALSE(from_lvalue->from_rvalue);
- EXPECT_FALSE(from_lvalue->assigned);
- from_lvalue = FromConstructibleAssignableLvalue{};
- EXPECT_FALSE(from_lvalue->from_rvalue);
- EXPECT_TRUE(from_lvalue->assigned);
- absl::StatusOr<MockValue> from_rvalue(FromConstructibleAssignableRvalue{});
- EXPECT_TRUE(from_rvalue->from_rvalue);
- EXPECT_FALSE(from_rvalue->assigned);
- from_rvalue = FromConstructibleAssignableRvalue{};
- EXPECT_TRUE(from_rvalue->from_rvalue);
- EXPECT_TRUE(from_rvalue->assigned);
- absl::StatusOr<MockValue> from_implicit_constructible(
- FromImplicitConstructibleOnly{});
- EXPECT_FALSE(from_implicit_constructible->from_rvalue);
- EXPECT_FALSE(from_implicit_constructible->assigned);
- // construct a temporary `StatusOr` object and invoke the `StatusOr` move
- // assignment operator.
- from_implicit_constructible = FromImplicitConstructibleOnly{};
- EXPECT_FALSE(from_implicit_constructible->from_rvalue);
- EXPECT_FALSE(from_implicit_constructible->assigned);
- }
- TEST(StatusOr, TestStatus) {
- absl::StatusOr<int> good(4);
- EXPECT_TRUE(good.ok());
- absl::StatusOr<int> bad(absl::CancelledError());
- EXPECT_FALSE(bad.ok());
- EXPECT_EQ(bad.status().code(), absl::StatusCode::kCancelled);
- }
- TEST(StatusOr, OperatorStarRefQualifiers) {
- static_assert(
- std::is_same<const int&,
- decltype(*std::declval<const absl::StatusOr<int>&>())>(),
- "Unexpected ref-qualifiers");
- static_assert(
- std::is_same<int&, decltype(*std::declval<absl::StatusOr<int>&>())>(),
- "Unexpected ref-qualifiers");
- static_assert(
- std::is_same<const int&&,
- decltype(*std::declval<const absl::StatusOr<int>&&>())>(),
- "Unexpected ref-qualifiers");
- static_assert(
- std::is_same<int&&, decltype(*std::declval<absl::StatusOr<int>&&>())>(),
- "Unexpected ref-qualifiers");
- }
- TEST(StatusOr, OperatorStar) {
- const absl::StatusOr<std::string> const_lvalue("hello");
- EXPECT_EQ("hello", *const_lvalue);
- absl::StatusOr<std::string> lvalue("hello");
- EXPECT_EQ("hello", *lvalue);
- // Note: Recall that std::move() is equivalent to a static_cast to an rvalue
- // reference type.
- const absl::StatusOr<std::string> const_rvalue("hello");
- EXPECT_EQ("hello", *std::move(const_rvalue)); // NOLINT
- absl::StatusOr<std::string> rvalue("hello");
- EXPECT_EQ("hello", *std::move(rvalue));
- }
- TEST(StatusOr, OperatorArrowQualifiers) {
- static_assert(
- std::is_same<
- const int*,
- decltype(std::declval<const absl::StatusOr<int>&>().operator->())>(),
- "Unexpected qualifiers");
- static_assert(
- std::is_same<
- int*, decltype(std::declval<absl::StatusOr<int>&>().operator->())>(),
- "Unexpected qualifiers");
- static_assert(
- std::is_same<
- const int*,
- decltype(std::declval<const absl::StatusOr<int>&&>().operator->())>(),
- "Unexpected qualifiers");
- static_assert(
- std::is_same<
- int*, decltype(std::declval<absl::StatusOr<int>&&>().operator->())>(),
- "Unexpected qualifiers");
- }
- TEST(StatusOr, OperatorArrow) {
- const absl::StatusOr<std::string> const_lvalue("hello");
- EXPECT_EQ(std::string("hello"), const_lvalue->c_str());
- absl::StatusOr<std::string> lvalue("hello");
- EXPECT_EQ(std::string("hello"), lvalue->c_str());
- }
- TEST(StatusOr, RValueStatus) {
- absl::StatusOr<int> so(absl::NotFoundError("taco"));
- const absl::Status s = std::move(so).status();
- EXPECT_EQ(s.code(), absl::StatusCode::kNotFound);
- EXPECT_EQ(s.message(), "taco");
- // Check that !ok() still implies !status().ok(), even after moving out of the
- // object. See the note on the rvalue ref-qualified status method.
- EXPECT_FALSE(so.ok()); // NOLINT
- EXPECT_FALSE(so.status().ok());
- EXPECT_EQ(so.status().code(), absl::StatusCode::kInternal);
- EXPECT_EQ(so.status().message(), "Status accessed after move.");
- }
- TEST(StatusOr, TestValue) {
- const int kI = 4;
- absl::StatusOr<int> thing(kI);
- EXPECT_EQ(kI, *thing);
- }
- TEST(StatusOr, TestValueConst) {
- const int kI = 4;
- const absl::StatusOr<int> thing(kI);
- EXPECT_EQ(kI, *thing);
- }
- TEST(StatusOr, TestPointerDefaultCtor) {
- absl::StatusOr<int*> thing;
- EXPECT_FALSE(thing.ok());
- EXPECT_EQ(thing.status().code(), absl::StatusCode::kUnknown);
- }
- TEST(StatusOr, TestPointerStatusCtor) {
- absl::StatusOr<int*> thing(absl::CancelledError());
- EXPECT_FALSE(thing.ok());
- EXPECT_EQ(thing.status().code(), absl::StatusCode::kCancelled);
- }
- TEST(StatusOr, TestPointerValueCtor) {
- const int kI = 4;
- // Construction from a non-null pointer
- {
- absl::StatusOr<const int*> so(&kI);
- EXPECT_TRUE(so.ok());
- EXPECT_OK(so.status());
- EXPECT_EQ(&kI, *so);
- }
- // Construction from a null pointer constant
- {
- absl::StatusOr<const int*> so(nullptr);
- EXPECT_TRUE(so.ok());
- EXPECT_OK(so.status());
- EXPECT_EQ(nullptr, *so);
- }
- // Construction from a non-literal null pointer
- {
- const int* const p = nullptr;
- absl::StatusOr<const int*> so(p);
- EXPECT_TRUE(so.ok());
- EXPECT_OK(so.status());
- EXPECT_EQ(nullptr, *so);
- }
- }
- TEST(StatusOr, TestPointerCopyCtorStatusOk) {
- const int kI = 0;
- absl::StatusOr<const int*> original(&kI);
- absl::StatusOr<const int*> copy(original);
- EXPECT_OK(copy.status());
- EXPECT_EQ(*original, *copy);
- }
- TEST(StatusOr, TestPointerCopyCtorStatusNotOk) {
- absl::StatusOr<int*> original(absl::CancelledError());
- absl::StatusOr<int*> copy(original);
- EXPECT_EQ(copy.status().code(), absl::StatusCode::kCancelled);
- }
- TEST(StatusOr, TestPointerCopyCtorStatusOKConverting) {
- Derived derived;
- absl::StatusOr<Derived*> original(&derived);
- absl::StatusOr<Base2*> copy(original);
- EXPECT_OK(copy.status());
- EXPECT_EQ(static_cast<const Base2*>(*original), *copy);
- }
- TEST(StatusOr, TestPointerCopyCtorStatusNotOkConverting) {
- absl::StatusOr<Derived*> original(absl::CancelledError());
- absl::StatusOr<Base2*> copy(original);
- EXPECT_EQ(copy.status().code(), absl::StatusCode::kCancelled);
- }
- TEST(StatusOr, TestPointerAssignmentStatusOk) {
- const int kI = 0;
- absl::StatusOr<const int*> source(&kI);
- absl::StatusOr<const int*> target;
- target = source;
- EXPECT_OK(target.status());
- EXPECT_EQ(*source, *target);
- }
- TEST(StatusOr, TestPointerAssignmentStatusNotOk) {
- absl::StatusOr<int*> source(absl::CancelledError());
- absl::StatusOr<int*> target;
- target = source;
- EXPECT_EQ(target.status().code(), absl::StatusCode::kCancelled);
- }
- TEST(StatusOr, TestPointerAssignmentStatusOKConverting) {
- Derived derived;
- absl::StatusOr<Derived*> source(&derived);
- absl::StatusOr<Base2*> target;
- target = source;
- EXPECT_OK(target.status());
- EXPECT_EQ(static_cast<const Base2*>(*source), *target);
- }
- TEST(StatusOr, TestPointerAssignmentStatusNotOkConverting) {
- absl::StatusOr<Derived*> source(absl::CancelledError());
- absl::StatusOr<Base2*> target;
- target = source;
- EXPECT_EQ(target.status(), source.status());
- }
- TEST(StatusOr, TestPointerStatus) {
- const int kI = 0;
- absl::StatusOr<const int*> good(&kI);
- EXPECT_TRUE(good.ok());
- absl::StatusOr<const int*> bad(absl::CancelledError());
- EXPECT_EQ(bad.status().code(), absl::StatusCode::kCancelled);
- }
- TEST(StatusOr, TestPointerValue) {
- const int kI = 0;
- absl::StatusOr<const int*> thing(&kI);
- EXPECT_EQ(&kI, *thing);
- }
- TEST(StatusOr, TestPointerValueConst) {
- const int kI = 0;
- const absl::StatusOr<const int*> thing(&kI);
- EXPECT_EQ(&kI, *thing);
- }
- TEST(StatusOr, StatusOrVectorOfUniquePointerCanReserveAndResize) {
- using EvilType = std::vector<std::unique_ptr<int>>;
- static_assert(std::is_copy_constructible<EvilType>::value, "");
- std::vector<::absl::StatusOr<EvilType>> v(5);
- v.reserve(v.capacity() + 10);
- v.resize(v.capacity() + 10);
- }
- TEST(StatusOr, ConstPayload) {
- // A reduced version of a problematic type found in the wild. All of the
- // operations below should compile.
- absl::StatusOr<const int> a;
- // Copy-construction
- absl::StatusOr<const int> b(a);
- // Copy-assignment
- EXPECT_FALSE(std::is_copy_assignable<absl::StatusOr<const int>>::value);
- // Move-construction
- absl::StatusOr<const int> c(std::move(a));
- // Move-assignment
- EXPECT_FALSE(std::is_move_assignable<absl::StatusOr<const int>>::value);
- }
- TEST(StatusOr, MapToStatusOrUniquePtr) {
- // A reduced version of a problematic type found in the wild. All of the
- // operations below should compile.
- using MapType = std::map<std::string, absl::StatusOr<std::unique_ptr<int>>>;
- MapType a;
- // Move-construction
- MapType b(std::move(a));
- // Move-assignment
- a = std::move(b);
- }
- TEST(StatusOr, ValueOrOk) {
- const absl::StatusOr<int> status_or = 0;
- EXPECT_EQ(status_or.value_or(-1), 0);
- }
- TEST(StatusOr, ValueOrDefault) {
- const absl::StatusOr<int> status_or = absl::CancelledError();
- EXPECT_EQ(status_or.value_or(-1), -1);
- }
- TEST(StatusOr, MoveOnlyValueOrOk) {
- EXPECT_THAT(absl::StatusOr<std::unique_ptr<int>>(absl::make_unique<int>(0))
- .value_or(absl::make_unique<int>(-1)),
- Pointee(0));
- }
- TEST(StatusOr, MoveOnlyValueOrDefault) {
- EXPECT_THAT(absl::StatusOr<std::unique_ptr<int>>(absl::CancelledError())
- .value_or(absl::make_unique<int>(-1)),
- Pointee(-1));
- }
- static absl::StatusOr<int> MakeStatus() { return 100; }
- TEST(StatusOr, TestIgnoreError) { MakeStatus().IgnoreError(); }
- TEST(StatusOr, EqualityOperator) {
- constexpr int kNumCases = 4;
- std::array<absl::StatusOr<int>, kNumCases> group1 = {
- absl::StatusOr<int>(1), absl::StatusOr<int>(2),
- absl::StatusOr<int>(absl::InvalidArgumentError("msg")),
- absl::StatusOr<int>(absl::InternalError("msg"))};
- std::array<absl::StatusOr<int>, kNumCases> group2 = {
- absl::StatusOr<int>(1), absl::StatusOr<int>(2),
- absl::StatusOr<int>(absl::InvalidArgumentError("msg")),
- absl::StatusOr<int>(absl::InternalError("msg"))};
- for (int i = 0; i < kNumCases; ++i) {
- for (int j = 0; j < kNumCases; ++j) {
- if (i == j) {
- EXPECT_TRUE(group1[i] == group2[j]);
- EXPECT_FALSE(group1[i] != group2[j]);
- } else {
- EXPECT_FALSE(group1[i] == group2[j]);
- EXPECT_TRUE(group1[i] != group2[j]);
- }
- }
- }
- }
- struct MyType {
- bool operator==(const MyType&) const { return true; }
- };
- enum class ConvTraits { kNone = 0, kImplicit = 1, kExplicit = 2 };
- // This class has conversion operator to `StatusOr<T>` based on value of
- // `conv_traits`.
- template <typename T, ConvTraits conv_traits = ConvTraits::kNone>
- struct StatusOrConversionBase {};
- template <typename T>
- struct StatusOrConversionBase<T, ConvTraits::kImplicit> {
- operator absl::StatusOr<T>() const& { // NOLINT
- return absl::InvalidArgumentError("conversion to absl::StatusOr");
- }
- operator absl::StatusOr<T>() && { // NOLINT
- return absl::InvalidArgumentError("conversion to absl::StatusOr");
- }
- };
- template <typename T>
- struct StatusOrConversionBase<T, ConvTraits::kExplicit> {
- explicit operator absl::StatusOr<T>() const& {
- return absl::InvalidArgumentError("conversion to absl::StatusOr");
- }
- explicit operator absl::StatusOr<T>() && {
- return absl::InvalidArgumentError("conversion to absl::StatusOr");
- }
- };
- // This class has conversion operator to `T` based on the value of
- // `conv_traits`.
- template <typename T, ConvTraits conv_traits = ConvTraits::kNone>
- struct ConversionBase {};
- template <typename T>
- struct ConversionBase<T, ConvTraits::kImplicit> {
- operator T() const& { return t; } // NOLINT
- operator T() && { return std::move(t); } // NOLINT
- T t;
- };
- template <typename T>
- struct ConversionBase<T, ConvTraits::kExplicit> {
- explicit operator T() const& { return t; }
- explicit operator T() && { return std::move(t); }
- T t;
- };
- // This class has conversion operator to `absl::Status` based on the value of
- // `conv_traits`.
- template <ConvTraits conv_traits = ConvTraits::kNone>
- struct StatusConversionBase {};
- template <>
- struct StatusConversionBase<ConvTraits::kImplicit> {
- operator absl::Status() const& { // NOLINT
- return absl::InternalError("conversion to Status");
- }
- operator absl::Status() && { // NOLINT
- return absl::InternalError("conversion to Status");
- }
- };
- template <>
- struct StatusConversionBase<ConvTraits::kExplicit> {
- explicit operator absl::Status() const& { // NOLINT
- return absl::InternalError("conversion to Status");
- }
- explicit operator absl::Status() && { // NOLINT
- return absl::InternalError("conversion to Status");
- }
- };
- static constexpr int kConvToStatus = 1;
- static constexpr int kConvToStatusOr = 2;
- static constexpr int kConvToT = 4;
- static constexpr int kConvExplicit = 8;
- constexpr ConvTraits GetConvTraits(int bit, int config) {
- return (config & bit) == 0
- ? ConvTraits::kNone
- : ((config & kConvExplicit) == 0 ? ConvTraits::kImplicit
- : ConvTraits::kExplicit);
- }
- // This class conditionally has conversion operator to `absl::Status`, `T`,
- // `StatusOr<T>`, based on values of the template parameters.
- template <typename T, int config>
- struct CustomType
- : StatusOrConversionBase<T, GetConvTraits(kConvToStatusOr, config)>,
- ConversionBase<T, GetConvTraits(kConvToT, config)>,
- StatusConversionBase<GetConvTraits(kConvToStatus, config)> {};
- struct ConvertibleToAnyStatusOr {
- template <typename T>
- operator absl::StatusOr<T>() const { // NOLINT
- return absl::InvalidArgumentError("Conversion to absl::StatusOr");
- }
- };
- // Test the rank of overload resolution for `StatusOr<T>` constructor and
- // assignment, from highest to lowest:
- // 1. T/Status
- // 2. U that has conversion operator to absl::StatusOr<T>
- // 3. U that is convertible to Status
- // 4. U that is convertible to T
- TEST(StatusOr, ConstructionFromT) {
- // Construct absl::StatusOr<T> from T when T is convertible to
- // absl::StatusOr<T>
- {
- ConvertibleToAnyStatusOr v;
- absl::StatusOr<ConvertibleToAnyStatusOr> statusor(v);
- EXPECT_TRUE(statusor.ok());
- }
- {
- ConvertibleToAnyStatusOr v;
- absl::StatusOr<ConvertibleToAnyStatusOr> statusor = v;
- EXPECT_TRUE(statusor.ok());
- }
- // Construct absl::StatusOr<T> from T when T is explicitly convertible to
- // Status
- {
- CustomType<MyType, kConvToStatus | kConvExplicit> v;
- absl::StatusOr<CustomType<MyType, kConvToStatus | kConvExplicit>> statusor(
- v);
- EXPECT_TRUE(statusor.ok());
- }
- {
- CustomType<MyType, kConvToStatus | kConvExplicit> v;
- absl::StatusOr<CustomType<MyType, kConvToStatus | kConvExplicit>> statusor =
- v;
- EXPECT_TRUE(statusor.ok());
- }
- }
- // Construct absl::StatusOr<T> from U when U is explicitly convertible to T
- TEST(StatusOr, ConstructionFromTypeConvertibleToT) {
- {
- CustomType<MyType, kConvToT | kConvExplicit> v;
- absl::StatusOr<MyType> statusor(v);
- EXPECT_TRUE(statusor.ok());
- }
- {
- CustomType<MyType, kConvToT> v;
- absl::StatusOr<MyType> statusor = v;
- EXPECT_TRUE(statusor.ok());
- }
- }
- // Construct absl::StatusOr<T> from U when U has explicit conversion operator to
- // absl::StatusOr<T>
- TEST(StatusOr, ConstructionFromTypeWithConversionOperatorToStatusOrT) {
- {
- CustomType<MyType, kConvToStatusOr | kConvExplicit> v;
- absl::StatusOr<MyType> statusor(v);
- EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
- }
- {
- CustomType<MyType, kConvToT | kConvToStatusOr | kConvExplicit> v;
- absl::StatusOr<MyType> statusor(v);
- EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
- }
- {
- CustomType<MyType, kConvToStatusOr | kConvToStatus | kConvExplicit> v;
- absl::StatusOr<MyType> statusor(v);
- EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
- }
- {
- CustomType<MyType,
- kConvToT | kConvToStatusOr | kConvToStatus | kConvExplicit>
- v;
- absl::StatusOr<MyType> statusor(v);
- EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
- }
- {
- CustomType<MyType, kConvToStatusOr> v;
- absl::StatusOr<MyType> statusor = v;
- EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
- }
- {
- CustomType<MyType, kConvToT | kConvToStatusOr> v;
- absl::StatusOr<MyType> statusor = v;
- EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
- }
- {
- CustomType<MyType, kConvToStatusOr | kConvToStatus> v;
- absl::StatusOr<MyType> statusor = v;
- EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
- }
- {
- CustomType<MyType, kConvToT | kConvToStatusOr | kConvToStatus> v;
- absl::StatusOr<MyType> statusor = v;
- EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
- }
- }
- TEST(StatusOr, ConstructionFromTypeConvertibleToStatus) {
- // Construction fails because conversion to `Status` is explicit.
- {
- CustomType<MyType, kConvToStatus | kConvExplicit> v;
- absl::StatusOr<MyType> statusor(v);
- EXPECT_FALSE(statusor.ok());
- EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v));
- }
- {
- CustomType<MyType, kConvToT | kConvToStatus | kConvExplicit> v;
- absl::StatusOr<MyType> statusor(v);
- EXPECT_FALSE(statusor.ok());
- EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v));
- }
- {
- CustomType<MyType, kConvToStatus> v;
- absl::StatusOr<MyType> statusor = v;
- EXPECT_FALSE(statusor.ok());
- EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v));
- }
- {
- CustomType<MyType, kConvToT | kConvToStatus> v;
- absl::StatusOr<MyType> statusor = v;
- EXPECT_FALSE(statusor.ok());
- EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v));
- }
- }
- TEST(StatusOr, AssignmentFromT) {
- // Assign to absl::StatusOr<T> from T when T is convertible to
- // absl::StatusOr<T>
- {
- ConvertibleToAnyStatusOr v;
- absl::StatusOr<ConvertibleToAnyStatusOr> statusor;
- statusor = v;
- EXPECT_TRUE(statusor.ok());
- }
- // Assign to absl::StatusOr<T> from T when T is convertible to Status
- {
- CustomType<MyType, kConvToStatus> v;
- absl::StatusOr<CustomType<MyType, kConvToStatus>> statusor;
- statusor = v;
- EXPECT_TRUE(statusor.ok());
- }
- }
- TEST(StatusOr, AssignmentFromTypeConvertibleToT) {
- // Assign to absl::StatusOr<T> from U when U is convertible to T
- {
- CustomType<MyType, kConvToT> v;
- absl::StatusOr<MyType> statusor;
- statusor = v;
- EXPECT_TRUE(statusor.ok());
- }
- }
- TEST(StatusOr, AssignmentFromTypeWithConversionOperatortoStatusOrT) {
- // Assign to absl::StatusOr<T> from U when U has conversion operator to
- // absl::StatusOr<T>
- {
- CustomType<MyType, kConvToStatusOr> v;
- absl::StatusOr<MyType> statusor;
- statusor = v;
- EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
- }
- {
- CustomType<MyType, kConvToT | kConvToStatusOr> v;
- absl::StatusOr<MyType> statusor;
- statusor = v;
- EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
- }
- {
- CustomType<MyType, kConvToStatusOr | kConvToStatus> v;
- absl::StatusOr<MyType> statusor;
- statusor = v;
- EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
- }
- {
- CustomType<MyType, kConvToT | kConvToStatusOr | kConvToStatus> v;
- absl::StatusOr<MyType> statusor;
- statusor = v;
- EXPECT_EQ(statusor, v.operator absl::StatusOr<MyType>());
- }
- }
- TEST(StatusOr, AssignmentFromTypeConvertibleToStatus) {
- // Assign to absl::StatusOr<T> from U when U is convertible to Status
- {
- CustomType<MyType, kConvToStatus> v;
- absl::StatusOr<MyType> statusor;
- statusor = v;
- EXPECT_FALSE(statusor.ok());
- EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v));
- }
- {
- CustomType<MyType, kConvToT | kConvToStatus> v;
- absl::StatusOr<MyType> statusor;
- statusor = v;
- EXPECT_FALSE(statusor.ok());
- EXPECT_EQ(statusor.status(), static_cast<absl::Status>(v));
- }
- }
- } // namespace
|