xref: /aosp_15_r20/system/libbase/result_test.cpp (revision 8f0ba417480079999ba552f1087ae592091b9d02)
1*8f0ba417SAndroid Build Coastguard Worker /*
2*8f0ba417SAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*8f0ba417SAndroid Build Coastguard Worker  *
4*8f0ba417SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*8f0ba417SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*8f0ba417SAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*8f0ba417SAndroid Build Coastguard Worker  *
8*8f0ba417SAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*8f0ba417SAndroid Build Coastguard Worker  *
10*8f0ba417SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*8f0ba417SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*8f0ba417SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*8f0ba417SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*8f0ba417SAndroid Build Coastguard Worker  * limitations under the License.
15*8f0ba417SAndroid Build Coastguard Worker  */
16*8f0ba417SAndroid Build Coastguard Worker 
17*8f0ba417SAndroid Build Coastguard Worker #include "android-base/result.h"
18*8f0ba417SAndroid Build Coastguard Worker #include <utils/ErrorsMacros.h>
19*8f0ba417SAndroid Build Coastguard Worker #include "android-base/errors.h"
20*8f0ba417SAndroid Build Coastguard Worker #include "errno.h"
21*8f0ba417SAndroid Build Coastguard Worker 
22*8f0ba417SAndroid Build Coastguard Worker #include <istream>
23*8f0ba417SAndroid Build Coastguard Worker #include <memory>
24*8f0ba417SAndroid Build Coastguard Worker #include <string>
25*8f0ba417SAndroid Build Coastguard Worker #include <type_traits>
26*8f0ba417SAndroid Build Coastguard Worker 
27*8f0ba417SAndroid Build Coastguard Worker #include <gmock/gmock.h>
28*8f0ba417SAndroid Build Coastguard Worker #include <gtest/gtest.h>
29*8f0ba417SAndroid Build Coastguard Worker 
30*8f0ba417SAndroid Build Coastguard Worker #include "android-base/result-gmock.h"
31*8f0ba417SAndroid Build Coastguard Worker 
32*8f0ba417SAndroid Build Coastguard Worker using namespace std::string_literals;
33*8f0ba417SAndroid Build Coastguard Worker using ::testing::Eq;
34*8f0ba417SAndroid Build Coastguard Worker using ::testing::ExplainMatchResult;
35*8f0ba417SAndroid Build Coastguard Worker using ::testing::HasSubstr;
36*8f0ba417SAndroid Build Coastguard Worker using ::testing::Not;
37*8f0ba417SAndroid Build Coastguard Worker using ::testing::StartsWith;
38*8f0ba417SAndroid Build Coastguard Worker 
39*8f0ba417SAndroid Build Coastguard Worker namespace android {
40*8f0ba417SAndroid Build Coastguard Worker namespace base {
41*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,result_accessors)42*8f0ba417SAndroid Build Coastguard Worker TEST(result, result_accessors) {
43*8f0ba417SAndroid Build Coastguard Worker   Result<std::string> result = "success";
44*8f0ba417SAndroid Build Coastguard Worker   ASSERT_RESULT_OK(result);
45*8f0ba417SAndroid Build Coastguard Worker   ASSERT_TRUE(result.has_value());
46*8f0ba417SAndroid Build Coastguard Worker 
47*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("success", *result);
48*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("success", result.value());
49*8f0ba417SAndroid Build Coastguard Worker 
50*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ('s', result->data()[0]);
51*8f0ba417SAndroid Build Coastguard Worker }
52*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,result_accessors_rvalue)53*8f0ba417SAndroid Build Coastguard Worker TEST(result, result_accessors_rvalue) {
54*8f0ba417SAndroid Build Coastguard Worker   ASSERT_TRUE(Result<std::string>("success").ok());
55*8f0ba417SAndroid Build Coastguard Worker   ASSERT_TRUE(Result<std::string>("success").has_value());
56*8f0ba417SAndroid Build Coastguard Worker 
57*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("success", *Result<std::string>("success"));
58*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("success", Result<std::string>("success").value());
59*8f0ba417SAndroid Build Coastguard Worker 
60*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ('s', Result<std::string>("success")->data()[0]);
61*8f0ba417SAndroid Build Coastguard Worker }
62*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,result_void)63*8f0ba417SAndroid Build Coastguard Worker TEST(result, result_void) {
64*8f0ba417SAndroid Build Coastguard Worker   Result<void> ok = {};
65*8f0ba417SAndroid Build Coastguard Worker   EXPECT_RESULT_OK(ok);
66*8f0ba417SAndroid Build Coastguard Worker   ok.value();  // should not crash
67*8f0ba417SAndroid Build Coastguard Worker   ASSERT_DEATH(ok.error(), "");
68*8f0ba417SAndroid Build Coastguard Worker 
69*8f0ba417SAndroid Build Coastguard Worker   Result<void> fail = Error() << "failure" << 1;
70*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(fail.ok());
71*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("failure1", fail.error().message());
72*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0, fail.error().code());
73*8f0ba417SAndroid Build Coastguard Worker   EXPECT_TRUE(ok != fail);
74*8f0ba417SAndroid Build Coastguard Worker   ASSERT_DEATH(fail.value(), "");
75*8f0ba417SAndroid Build Coastguard Worker 
76*8f0ba417SAndroid Build Coastguard Worker   auto test = [](bool ok) -> Result<void> {
77*8f0ba417SAndroid Build Coastguard Worker     if (ok) return {};
78*8f0ba417SAndroid Build Coastguard Worker     else return Error() << "failure" << 1;
79*8f0ba417SAndroid Build Coastguard Worker   };
80*8f0ba417SAndroid Build Coastguard Worker   EXPECT_TRUE(test(true).ok());
81*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(test(false).ok());
82*8f0ba417SAndroid Build Coastguard Worker   test(true).value();  // should not crash
83*8f0ba417SAndroid Build Coastguard Worker   ASSERT_DEATH(test(true).error(), "");
84*8f0ba417SAndroid Build Coastguard Worker   ASSERT_DEATH(test(false).value(), "");
85*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("failure1", test(false).error().message());
86*8f0ba417SAndroid Build Coastguard Worker }
87*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,result_error)88*8f0ba417SAndroid Build Coastguard Worker TEST(result, result_error) {
89*8f0ba417SAndroid Build Coastguard Worker   Result<void> result = Error() << "failure" << 1;
90*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result.ok());
91*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result.has_value());
92*8f0ba417SAndroid Build Coastguard Worker 
93*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0, result.error().code());
94*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("failure1", result.error().message());
95*8f0ba417SAndroid Build Coastguard Worker }
96*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,result_error_empty)97*8f0ba417SAndroid Build Coastguard Worker TEST(result, result_error_empty) {
98*8f0ba417SAndroid Build Coastguard Worker   Result<void> result = Error();
99*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result.ok());
100*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result.has_value());
101*8f0ba417SAndroid Build Coastguard Worker 
102*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0, result.error().code());
103*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("", result.error().message());
104*8f0ba417SAndroid Build Coastguard Worker }
105*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,result_error_rvalue)106*8f0ba417SAndroid Build Coastguard Worker TEST(result, result_error_rvalue) {
107*8f0ba417SAndroid Build Coastguard Worker   // Error() and ErrnoError() aren't actually used to create a Result<T> object.
108*8f0ba417SAndroid Build Coastguard Worker   // Under the hood, they are an intermediate class that can be implicitly constructed into a
109*8f0ba417SAndroid Build Coastguard Worker   // Result<T>.  This is needed both to create the ostream and because Error() itself, by
110*8f0ba417SAndroid Build Coastguard Worker   // definition will not know what the type, T, of the underlying Result<T> object that it would
111*8f0ba417SAndroid Build Coastguard Worker   // create is.
112*8f0ba417SAndroid Build Coastguard Worker 
113*8f0ba417SAndroid Build Coastguard Worker   auto MakeRvalueErrorResult = []() -> Result<void> { return Error() << "failure" << 1; };
114*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(MakeRvalueErrorResult().ok());
115*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(MakeRvalueErrorResult().has_value());
116*8f0ba417SAndroid Build Coastguard Worker 
117*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0, MakeRvalueErrorResult().error().code());
118*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("failure1", MakeRvalueErrorResult().error().message());
119*8f0ba417SAndroid Build Coastguard Worker }
120*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,result_errno_error)121*8f0ba417SAndroid Build Coastguard Worker TEST(result, result_errno_error) {
122*8f0ba417SAndroid Build Coastguard Worker   constexpr int test_errno = 6;
123*8f0ba417SAndroid Build Coastguard Worker   errno = test_errno;
124*8f0ba417SAndroid Build Coastguard Worker   Result<void> result = ErrnoError() << "failure" << 1;
125*8f0ba417SAndroid Build Coastguard Worker 
126*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result.ok());
127*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result.has_value());
128*8f0ba417SAndroid Build Coastguard Worker 
129*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(test_errno, result.error().code());
130*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("failure1: "s + strerror(test_errno), result.error().message());
131*8f0ba417SAndroid Build Coastguard Worker }
132*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,result_errno_error_no_text)133*8f0ba417SAndroid Build Coastguard Worker TEST(result, result_errno_error_no_text) {
134*8f0ba417SAndroid Build Coastguard Worker   constexpr int test_errno = 6;
135*8f0ba417SAndroid Build Coastguard Worker   errno = test_errno;
136*8f0ba417SAndroid Build Coastguard Worker   Result<void> result = ErrnoError();
137*8f0ba417SAndroid Build Coastguard Worker 
138*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result.ok());
139*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result.has_value());
140*8f0ba417SAndroid Build Coastguard Worker 
141*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(test_errno, result.error().code());
142*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(strerror(test_errno), result.error().message());
143*8f0ba417SAndroid Build Coastguard Worker }
144*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,result_error_from_other_result)145*8f0ba417SAndroid Build Coastguard Worker TEST(result, result_error_from_other_result) {
146*8f0ba417SAndroid Build Coastguard Worker   auto error_text = "test error"s;
147*8f0ba417SAndroid Build Coastguard Worker   Result<void> result = Error() << error_text;
148*8f0ba417SAndroid Build Coastguard Worker 
149*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result.ok());
150*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result.has_value());
151*8f0ba417SAndroid Build Coastguard Worker 
152*8f0ba417SAndroid Build Coastguard Worker   Result<std::string> result2 = result.error();
153*8f0ba417SAndroid Build Coastguard Worker 
154*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result2.ok());
155*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result2.has_value());
156*8f0ba417SAndroid Build Coastguard Worker 
157*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0, result2.error().code());
158*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(error_text, result2.error().message());
159*8f0ba417SAndroid Build Coastguard Worker }
160*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,result_error_through_ostream)161*8f0ba417SAndroid Build Coastguard Worker TEST(result, result_error_through_ostream) {
162*8f0ba417SAndroid Build Coastguard Worker   auto error_text = "test error"s;
163*8f0ba417SAndroid Build Coastguard Worker   Result<void> result = Error() << error_text;
164*8f0ba417SAndroid Build Coastguard Worker 
165*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result.ok());
166*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result.has_value());
167*8f0ba417SAndroid Build Coastguard Worker 
168*8f0ba417SAndroid Build Coastguard Worker   Result<std::string> result2 = Error() << result.error();
169*8f0ba417SAndroid Build Coastguard Worker 
170*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result2.ok());
171*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result2.has_value());
172*8f0ba417SAndroid Build Coastguard Worker 
173*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0, result2.error().code());
174*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(error_text, result2.error().message());
175*8f0ba417SAndroid Build Coastguard Worker }
176*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,result_errno_error_through_ostream)177*8f0ba417SAndroid Build Coastguard Worker TEST(result, result_errno_error_through_ostream) {
178*8f0ba417SAndroid Build Coastguard Worker   auto error_text = "test error"s;
179*8f0ba417SAndroid Build Coastguard Worker   constexpr int test_errno = 6;
180*8f0ba417SAndroid Build Coastguard Worker   errno = 6;
181*8f0ba417SAndroid Build Coastguard Worker   Result<void> result = ErrnoError() << error_text;
182*8f0ba417SAndroid Build Coastguard Worker 
183*8f0ba417SAndroid Build Coastguard Worker   errno = 0;
184*8f0ba417SAndroid Build Coastguard Worker 
185*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result.ok());
186*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result.has_value());
187*8f0ba417SAndroid Build Coastguard Worker 
188*8f0ba417SAndroid Build Coastguard Worker   Result<std::string> result2 = Error() << result.error();
189*8f0ba417SAndroid Build Coastguard Worker 
190*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result2.ok());
191*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result2.has_value());
192*8f0ba417SAndroid Build Coastguard Worker 
193*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(test_errno, result2.error().code());
194*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(error_text + ": " + strerror(test_errno), result2.error().message());
195*8f0ba417SAndroid Build Coastguard Worker }
196*8f0ba417SAndroid Build Coastguard Worker 
197*8f0ba417SAndroid Build Coastguard Worker enum class CustomError { A, B };
198*8f0ba417SAndroid Build Coastguard Worker 
199*8f0ba417SAndroid Build Coastguard Worker struct CustomErrorWrapper {
CustomErrorWrapperandroid::base::CustomErrorWrapper200*8f0ba417SAndroid Build Coastguard Worker   CustomErrorWrapper() : val_(CustomError::A) {}
CustomErrorWrapperandroid::base::CustomErrorWrapper201*8f0ba417SAndroid Build Coastguard Worker   CustomErrorWrapper(const CustomError& e) : val_(e) {}
valueandroid::base::CustomErrorWrapper202*8f0ba417SAndroid Build Coastguard Worker   CustomError value() const { return val_; }
operator CustomErrorandroid::base::CustomErrorWrapper203*8f0ba417SAndroid Build Coastguard Worker   operator CustomError() const { return value(); }
printandroid::base::CustomErrorWrapper204*8f0ba417SAndroid Build Coastguard Worker   std::string print() const {
205*8f0ba417SAndroid Build Coastguard Worker     switch (val_) {
206*8f0ba417SAndroid Build Coastguard Worker       case CustomError::A:
207*8f0ba417SAndroid Build Coastguard Worker         return "A";
208*8f0ba417SAndroid Build Coastguard Worker       case CustomError::B:
209*8f0ba417SAndroid Build Coastguard Worker         return "B";
210*8f0ba417SAndroid Build Coastguard Worker     }
211*8f0ba417SAndroid Build Coastguard Worker   }
212*8f0ba417SAndroid Build Coastguard Worker   CustomError val_;
213*8f0ba417SAndroid Build Coastguard Worker };
214*8f0ba417SAndroid Build Coastguard Worker 
215*8f0ba417SAndroid Build Coastguard Worker #define NewCustomError(e) Error<CustomErrorWrapper>(CustomError::e)
216*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,result_with_custom_errorcode)217*8f0ba417SAndroid Build Coastguard Worker TEST(result, result_with_custom_errorcode) {
218*8f0ba417SAndroid Build Coastguard Worker   Result<void, CustomError> ok = {};
219*8f0ba417SAndroid Build Coastguard Worker   EXPECT_RESULT_OK(ok);
220*8f0ba417SAndroid Build Coastguard Worker   ok.value();  // should not crash
221*8f0ba417SAndroid Build Coastguard Worker   EXPECT_DEATH(ok.error(), "");
222*8f0ba417SAndroid Build Coastguard Worker 
223*8f0ba417SAndroid Build Coastguard Worker   auto error_text = "test error"s;
224*8f0ba417SAndroid Build Coastguard Worker   Result<void, CustomError> err = NewCustomError(A) << error_text;
225*8f0ba417SAndroid Build Coastguard Worker 
226*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(err.ok());
227*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(err.has_value());
228*8f0ba417SAndroid Build Coastguard Worker 
229*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(CustomError::A, err.error().code());
230*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(error_text + ": A", err.error().message());
231*8f0ba417SAndroid Build Coastguard Worker }
232*8f0ba417SAndroid Build Coastguard Worker 
success_or_fail(bool success)233*8f0ba417SAndroid Build Coastguard Worker Result<std::string, CustomError> success_or_fail(bool success) {
234*8f0ba417SAndroid Build Coastguard Worker   if (success)
235*8f0ba417SAndroid Build Coastguard Worker     return "success";
236*8f0ba417SAndroid Build Coastguard Worker   else
237*8f0ba417SAndroid Build Coastguard Worker     return NewCustomError(A) << "fail";
238*8f0ba417SAndroid Build Coastguard Worker }
239*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,constructor_forwarding)240*8f0ba417SAndroid Build Coastguard Worker TEST(result, constructor_forwarding) {
241*8f0ba417SAndroid Build Coastguard Worker   auto result = Result<std::string>(std::in_place, 5, 'a');
242*8f0ba417SAndroid Build Coastguard Worker 
243*8f0ba417SAndroid Build Coastguard Worker   ASSERT_RESULT_OK(result);
244*8f0ba417SAndroid Build Coastguard Worker   ASSERT_TRUE(result.has_value());
245*8f0ba417SAndroid Build Coastguard Worker 
246*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("aaaaa", *result);
247*8f0ba417SAndroid Build Coastguard Worker }
248*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,unwrap_or_do)249*8f0ba417SAndroid Build Coastguard Worker TEST(result, unwrap_or_do) {
250*8f0ba417SAndroid Build Coastguard Worker   bool v = UNWRAP_OR_DO(res, Result<bool>(false), FAIL() << "Should not be reached");
251*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(v);
252*8f0ba417SAndroid Build Coastguard Worker 
253*8f0ba417SAndroid Build Coastguard Worker   []() -> void {
254*8f0ba417SAndroid Build Coastguard Worker     UNWRAP_OR_DO(res, Result<bool>(ResultError("foo", 17)), {
255*8f0ba417SAndroid Build Coastguard Worker       EXPECT_EQ(res.error().message(), "foo");
256*8f0ba417SAndroid Build Coastguard Worker       EXPECT_EQ(res.error().code(), 17);
257*8f0ba417SAndroid Build Coastguard Worker       return;
258*8f0ba417SAndroid Build Coastguard Worker     });
259*8f0ba417SAndroid Build Coastguard Worker     FAIL() << "Should not be reached";
260*8f0ba417SAndroid Build Coastguard Worker   }();
261*8f0ba417SAndroid Build Coastguard Worker }
262*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,unwrap_or_assert_fail)263*8f0ba417SAndroid Build Coastguard Worker TEST(result, unwrap_or_assert_fail) {
264*8f0ba417SAndroid Build Coastguard Worker   bool s = OR_ASSERT_FAIL(Result<bool>(true));
265*8f0ba417SAndroid Build Coastguard Worker   EXPECT_TRUE(s);
266*8f0ba417SAndroid Build Coastguard Worker   // NB: There's no (stable) way to test that an assertion failed, so cannot test the error case.
267*8f0ba417SAndroid Build Coastguard Worker }
268*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,unwrap_or_return)269*8f0ba417SAndroid Build Coastguard Worker TEST(result, unwrap_or_return) {
270*8f0ba417SAndroid Build Coastguard Worker   auto f = [](bool success) -> Result<size_t, CustomError> {
271*8f0ba417SAndroid Build Coastguard Worker     return OR_RETURN(success_or_fail(success)).size();
272*8f0ba417SAndroid Build Coastguard Worker   };
273*8f0ba417SAndroid Build Coastguard Worker 
274*8f0ba417SAndroid Build Coastguard Worker   auto r = f(true);
275*8f0ba417SAndroid Build Coastguard Worker   EXPECT_TRUE(r.ok());
276*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(strlen("success"), *r);
277*8f0ba417SAndroid Build Coastguard Worker 
278*8f0ba417SAndroid Build Coastguard Worker   auto s = f(false);
279*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(s.ok());
280*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(CustomError::A, s.error().code());
281*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("fail: A", s.error().message());
282*8f0ba417SAndroid Build Coastguard Worker }
283*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,unwrap_or_return_errorcode)284*8f0ba417SAndroid Build Coastguard Worker TEST(result, unwrap_or_return_errorcode) {
285*8f0ba417SAndroid Build Coastguard Worker   auto f = [](bool success) -> CustomError {
286*8f0ba417SAndroid Build Coastguard Worker     // Note that we use the same OR_RETURN macro for different return types: Result<U, CustomError>
287*8f0ba417SAndroid Build Coastguard Worker     // and CustomError.
288*8f0ba417SAndroid Build Coastguard Worker     std::string val = OR_RETURN(success_or_fail(success));
289*8f0ba417SAndroid Build Coastguard Worker     EXPECT_EQ("success", val);
290*8f0ba417SAndroid Build Coastguard Worker     return CustomError::B;
291*8f0ba417SAndroid Build Coastguard Worker   };
292*8f0ba417SAndroid Build Coastguard Worker 
293*8f0ba417SAndroid Build Coastguard Worker   auto r = f(true);
294*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(CustomError::B, r);
295*8f0ba417SAndroid Build Coastguard Worker 
296*8f0ba417SAndroid Build Coastguard Worker   auto s = f(false);
297*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(CustomError::A, s);
298*8f0ba417SAndroid Build Coastguard Worker }
299*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,unwrap_or_fatal)300*8f0ba417SAndroid Build Coastguard Worker TEST(result, unwrap_or_fatal) {
301*8f0ba417SAndroid Build Coastguard Worker   auto r = OR_FATAL(success_or_fail(true));
302*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("success", r);
303*8f0ba417SAndroid Build Coastguard Worker 
304*8f0ba417SAndroid Build Coastguard Worker   EXPECT_DEATH(OR_FATAL(success_or_fail(false)), "fail: A");
305*8f0ba417SAndroid Build Coastguard Worker }
306*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,unwrap_ambiguous_int)307*8f0ba417SAndroid Build Coastguard Worker TEST(result, unwrap_ambiguous_int) {
308*8f0ba417SAndroid Build Coastguard Worker   const std::string firstSuccess{"a"};
309*8f0ba417SAndroid Build Coastguard Worker   constexpr int secondSuccess = 5;
310*8f0ba417SAndroid Build Coastguard Worker   auto enum_success_or_fail = [&](bool success) -> Result<std::string, StatusT> {
311*8f0ba417SAndroid Build Coastguard Worker     if (success) return firstSuccess;
312*8f0ba417SAndroid Build Coastguard Worker     return ResultError<StatusT>("Fail", 10);
313*8f0ba417SAndroid Build Coastguard Worker   };
314*8f0ba417SAndroid Build Coastguard Worker   auto f = [&](bool success) -> Result<int, StatusT> {
315*8f0ba417SAndroid Build Coastguard Worker     auto val = OR_RETURN(enum_success_or_fail(success));
316*8f0ba417SAndroid Build Coastguard Worker     EXPECT_EQ(firstSuccess, val);
317*8f0ba417SAndroid Build Coastguard Worker     return secondSuccess;
318*8f0ba417SAndroid Build Coastguard Worker   };
319*8f0ba417SAndroid Build Coastguard Worker 
320*8f0ba417SAndroid Build Coastguard Worker   auto r = f(true);
321*8f0ba417SAndroid Build Coastguard Worker   ASSERT_TRUE(r.ok());
322*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(r.value(), secondSuccess);
323*8f0ba417SAndroid Build Coastguard Worker   auto s = f(false);
324*8f0ba417SAndroid Build Coastguard Worker   ASSERT_TRUE(!s.ok());
325*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(s.error().code(), 10);
326*8f0ba417SAndroid Build Coastguard Worker }
327*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,unwrap_ambiguous_uint_conv)328*8f0ba417SAndroid Build Coastguard Worker TEST(result, unwrap_ambiguous_uint_conv) {
329*8f0ba417SAndroid Build Coastguard Worker   const std::string firstSuccess{"a"};
330*8f0ba417SAndroid Build Coastguard Worker   constexpr size_t secondSuccess = 5ull;
331*8f0ba417SAndroid Build Coastguard Worker   auto enum_success_or_fail = [&](bool success) -> Result<std::string, StatusT> {
332*8f0ba417SAndroid Build Coastguard Worker     if (success) return firstSuccess;
333*8f0ba417SAndroid Build Coastguard Worker     return ResultError<StatusT>("Fail", 10);
334*8f0ba417SAndroid Build Coastguard Worker   };
335*8f0ba417SAndroid Build Coastguard Worker 
336*8f0ba417SAndroid Build Coastguard Worker   auto f = [&](bool success) -> Result<size_t, StatusT> {
337*8f0ba417SAndroid Build Coastguard Worker     auto val = OR_RETURN(enum_success_or_fail(success));
338*8f0ba417SAndroid Build Coastguard Worker     EXPECT_EQ(firstSuccess, val);
339*8f0ba417SAndroid Build Coastguard Worker     return secondSuccess;
340*8f0ba417SAndroid Build Coastguard Worker   };
341*8f0ba417SAndroid Build Coastguard Worker 
342*8f0ba417SAndroid Build Coastguard Worker   auto r = f(true);
343*8f0ba417SAndroid Build Coastguard Worker   ASSERT_TRUE(r.ok());
344*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(r.value(), secondSuccess);
345*8f0ba417SAndroid Build Coastguard Worker   auto s = f(false);
346*8f0ba417SAndroid Build Coastguard Worker   ASSERT_TRUE(!s.ok());
347*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(s.error().code(), 10);
348*8f0ba417SAndroid Build Coastguard Worker }
349*8f0ba417SAndroid Build Coastguard Worker 
350*8f0ba417SAndroid Build Coastguard Worker struct IntConst {
351*8f0ba417SAndroid Build Coastguard Worker     int val_;
352*8f0ba417SAndroid Build Coastguard Worker     template <typename T, typename = std::enable_if_t<std::is_convertible_v<T, int>>>
IntConstandroid::base::IntConst353*8f0ba417SAndroid Build Coastguard Worker     IntConst(T&& val) : val_(val) {}
operator status_tandroid::base::IntConst354*8f0ba417SAndroid Build Coastguard Worker     operator status_t() {return val_;}
355*8f0ba417SAndroid Build Coastguard Worker };
356*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,unwrap_ambiguous_constructible)357*8f0ba417SAndroid Build Coastguard Worker TEST(result, unwrap_ambiguous_constructible) {
358*8f0ba417SAndroid Build Coastguard Worker   constexpr int firstSuccess = 5;
359*8f0ba417SAndroid Build Coastguard Worker   constexpr int secondSuccess = 7;
360*8f0ba417SAndroid Build Coastguard Worker   struct A {
361*8f0ba417SAndroid Build Coastguard Worker     A (int val) : val_(val) {}
362*8f0ba417SAndroid Build Coastguard Worker     operator status_t() { return 0; }
363*8f0ba417SAndroid Build Coastguard Worker     int val_;
364*8f0ba417SAndroid Build Coastguard Worker   };
365*8f0ba417SAndroid Build Coastguard Worker   // If this returns Result<A, ...> instead of Result<IntConst, ...>,
366*8f0ba417SAndroid Build Coastguard Worker   // compilation fails unless we compile with c++20
367*8f0ba417SAndroid Build Coastguard Worker   auto enum_success_or_fail = [&](bool success) -> Result<IntConst, StatusT, false> {
368*8f0ba417SAndroid Build Coastguard Worker     if (success) return firstSuccess;
369*8f0ba417SAndroid Build Coastguard Worker     return ResultError<StatusT, false>(10);
370*8f0ba417SAndroid Build Coastguard Worker   };
371*8f0ba417SAndroid Build Coastguard Worker   auto f = [&](bool success) -> Result<IntConst, StatusT, false> {
372*8f0ba417SAndroid Build Coastguard Worker     auto val = OR_RETURN(enum_success_or_fail(success));
373*8f0ba417SAndroid Build Coastguard Worker     EXPECT_EQ(firstSuccess, val.val_);
374*8f0ba417SAndroid Build Coastguard Worker     return secondSuccess;
375*8f0ba417SAndroid Build Coastguard Worker   };
376*8f0ba417SAndroid Build Coastguard Worker   auto r = f(true);
377*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(r.value().val_, secondSuccess);
378*8f0ba417SAndroid Build Coastguard Worker   auto s = f(false);
379*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(s.error().code(), 10);
380*8f0ba417SAndroid Build Coastguard Worker }
381*8f0ba417SAndroid Build Coastguard Worker 
382*8f0ba417SAndroid Build Coastguard Worker struct Dangerous {};
383*8f0ba417SAndroid Build Coastguard Worker struct ImplicitFromDangerous {
384*8f0ba417SAndroid Build Coastguard Worker   ImplicitFromDangerous(Dangerous);
385*8f0ba417SAndroid Build Coastguard Worker };
386*8f0ba417SAndroid Build Coastguard Worker template <typename U>
387*8f0ba417SAndroid Build Coastguard Worker struct Templated {
388*8f0ba417SAndroid Build Coastguard Worker     U val_;
389*8f0ba417SAndroid Build Coastguard Worker     template <typename T, typename=std::enable_if_t<std::is_convertible_v<T, U>>>
Templatedandroid::base::Templated390*8f0ba417SAndroid Build Coastguard Worker     Templated(T val) : val_(val) {}
391*8f0ba417SAndroid Build Coastguard Worker };
392*8f0ba417SAndroid Build Coastguard Worker 
393*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,dangerous_result_conversion)394*8f0ba417SAndroid Build Coastguard Worker TEST(result, dangerous_result_conversion) {
395*8f0ba417SAndroid Build Coastguard Worker   ResultError<Dangerous, false> error {Dangerous{}};
396*8f0ba417SAndroid Build Coastguard Worker   Result<Templated<Dangerous>, Dangerous, false> surprise {error};
397*8f0ba417SAndroid Build Coastguard Worker   EXPECT_TRUE(!surprise.ok());
398*8f0ba417SAndroid Build Coastguard Worker   Result<Templated<ImplicitFromDangerous>, Dangerous, false> surprise2 {error};
399*8f0ba417SAndroid Build Coastguard Worker   EXPECT_TRUE(!surprise2.ok());
400*8f0ba417SAndroid Build Coastguard Worker }
401*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,generic_convertible)402*8f0ba417SAndroid Build Coastguard Worker TEST(result, generic_convertible) {
403*8f0ba417SAndroid Build Coastguard Worker   const std::string firstSuccess{"a"};
404*8f0ba417SAndroid Build Coastguard Worker   struct A {};
405*8f0ba417SAndroid Build Coastguard Worker   struct B {
406*8f0ba417SAndroid Build Coastguard Worker     operator A() {return A{};}
407*8f0ba417SAndroid Build Coastguard Worker   };
408*8f0ba417SAndroid Build Coastguard Worker 
409*8f0ba417SAndroid Build Coastguard Worker   auto enum_success_or_fail = [&](bool success) -> Result<std::string, B> {
410*8f0ba417SAndroid Build Coastguard Worker     if (success) return firstSuccess;
411*8f0ba417SAndroid Build Coastguard Worker     return ResultError<B>("Fail", B{});
412*8f0ba417SAndroid Build Coastguard Worker   };
413*8f0ba417SAndroid Build Coastguard Worker   auto f = [&](bool success) -> Result<A, B> {
414*8f0ba417SAndroid Build Coastguard Worker     auto val = OR_RETURN(enum_success_or_fail(success));
415*8f0ba417SAndroid Build Coastguard Worker     EXPECT_EQ(firstSuccess, val);
416*8f0ba417SAndroid Build Coastguard Worker     return A{};
417*8f0ba417SAndroid Build Coastguard Worker   };
418*8f0ba417SAndroid Build Coastguard Worker 
419*8f0ba417SAndroid Build Coastguard Worker   auto r = f(true);
420*8f0ba417SAndroid Build Coastguard Worker   EXPECT_TRUE(r.ok());
421*8f0ba417SAndroid Build Coastguard Worker   auto s = f(false);
422*8f0ba417SAndroid Build Coastguard Worker   EXPECT_TRUE(!s.ok());
423*8f0ba417SAndroid Build Coastguard Worker }
424*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,generic_exact)425*8f0ba417SAndroid Build Coastguard Worker TEST(result, generic_exact) {
426*8f0ba417SAndroid Build Coastguard Worker   const std::string firstSuccess{"a"};
427*8f0ba417SAndroid Build Coastguard Worker   struct A {};
428*8f0ba417SAndroid Build Coastguard Worker   auto enum_success_or_fail = [&](bool success) -> Result<std::string, A> {
429*8f0ba417SAndroid Build Coastguard Worker     if (success) return firstSuccess;
430*8f0ba417SAndroid Build Coastguard Worker     return ResultError<A>("Fail", A{});
431*8f0ba417SAndroid Build Coastguard Worker   };
432*8f0ba417SAndroid Build Coastguard Worker   auto f = [&](bool success) -> Result<A, A> {
433*8f0ba417SAndroid Build Coastguard Worker     auto val = OR_RETURN(enum_success_or_fail(success));
434*8f0ba417SAndroid Build Coastguard Worker     EXPECT_EQ(firstSuccess, val);
435*8f0ba417SAndroid Build Coastguard Worker     return A{};
436*8f0ba417SAndroid Build Coastguard Worker   };
437*8f0ba417SAndroid Build Coastguard Worker 
438*8f0ba417SAndroid Build Coastguard Worker   auto r = f(true);
439*8f0ba417SAndroid Build Coastguard Worker   EXPECT_TRUE(r.ok());
440*8f0ba417SAndroid Build Coastguard Worker   auto s = f(false);
441*8f0ba417SAndroid Build Coastguard Worker   EXPECT_TRUE(!s.ok());
442*8f0ba417SAndroid Build Coastguard Worker }
443*8f0ba417SAndroid Build Coastguard Worker 
444*8f0ba417SAndroid Build Coastguard Worker struct MyData {
445*8f0ba417SAndroid Build Coastguard Worker   const int data;
446*8f0ba417SAndroid Build Coastguard Worker   static int copy_constructed;
447*8f0ba417SAndroid Build Coastguard Worker   static int move_constructed;
MyDataandroid::base::MyData448*8f0ba417SAndroid Build Coastguard Worker   explicit MyData(int d) : data(d) {}
MyDataandroid::base::MyData449*8f0ba417SAndroid Build Coastguard Worker   MyData(const MyData& other) : data(other.data) { copy_constructed++; }
MyDataandroid::base::MyData450*8f0ba417SAndroid Build Coastguard Worker   MyData(MyData&& other) : data(other.data) { move_constructed++; }
451*8f0ba417SAndroid Build Coastguard Worker   MyData& operator=(const MyData&) = delete;
452*8f0ba417SAndroid Build Coastguard Worker   MyData& operator=(MyData&&) = delete;
453*8f0ba417SAndroid Build Coastguard Worker };
454*8f0ba417SAndroid Build Coastguard Worker 
455*8f0ba417SAndroid Build Coastguard Worker int MyData::copy_constructed = 0;
456*8f0ba417SAndroid Build Coastguard Worker int MyData::move_constructed = 0;
457*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,unwrap_does_not_incur_additional_copying)458*8f0ba417SAndroid Build Coastguard Worker TEST(result, unwrap_does_not_incur_additional_copying) {
459*8f0ba417SAndroid Build Coastguard Worker   MyData::copy_constructed = 0;
460*8f0ba417SAndroid Build Coastguard Worker   MyData::move_constructed = 0;
461*8f0ba417SAndroid Build Coastguard Worker   auto f = []() -> Result<MyData> { return MyData{10}; };
462*8f0ba417SAndroid Build Coastguard Worker 
463*8f0ba417SAndroid Build Coastguard Worker   [&]() -> Result<void> {
464*8f0ba417SAndroid Build Coastguard Worker     int data = OR_RETURN(f()).data;
465*8f0ba417SAndroid Build Coastguard Worker     EXPECT_EQ(10, data);
466*8f0ba417SAndroid Build Coastguard Worker     EXPECT_EQ(0, MyData::copy_constructed);
467*8f0ba417SAndroid Build Coastguard Worker     // Moved once when MyData{10} is returned as Result<MyData> in the lambda f.
468*8f0ba417SAndroid Build Coastguard Worker     // Moved once again when the variable d is constructed from OR_RETURN.
469*8f0ba417SAndroid Build Coastguard Worker     EXPECT_EQ(2, MyData::move_constructed);
470*8f0ba417SAndroid Build Coastguard Worker     return {};
471*8f0ba417SAndroid Build Coastguard Worker   }();
472*8f0ba417SAndroid Build Coastguard Worker }
473*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,supports_move_only_type)474*8f0ba417SAndroid Build Coastguard Worker TEST(result, supports_move_only_type) {
475*8f0ba417SAndroid Build Coastguard Worker   auto f = [](bool success) -> Result<std::unique_ptr<std::string>> {
476*8f0ba417SAndroid Build Coastguard Worker     if (success) return std::make_unique<std::string>("hello");
477*8f0ba417SAndroid Build Coastguard Worker     return Error() << "error";
478*8f0ba417SAndroid Build Coastguard Worker   };
479*8f0ba417SAndroid Build Coastguard Worker 
480*8f0ba417SAndroid Build Coastguard Worker   auto g = [&](bool success) -> Result<std::unique_ptr<std::string>> {
481*8f0ba417SAndroid Build Coastguard Worker     auto r = OR_RETURN(f(success));
482*8f0ba417SAndroid Build Coastguard Worker     EXPECT_EQ("hello", *(r.get()));
483*8f0ba417SAndroid Build Coastguard Worker     return std::make_unique<std::string>("world");
484*8f0ba417SAndroid Build Coastguard Worker   };
485*8f0ba417SAndroid Build Coastguard Worker 
486*8f0ba417SAndroid Build Coastguard Worker   auto s = g(true);
487*8f0ba417SAndroid Build Coastguard Worker   EXPECT_RESULT_OK(s);
488*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("world", *(s->get()));
489*8f0ba417SAndroid Build Coastguard Worker 
490*8f0ba417SAndroid Build Coastguard Worker   auto t = g(false);
491*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(t.ok());
492*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("error", t.error().message());
493*8f0ba417SAndroid Build Coastguard Worker }
494*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,unique_ptr)495*8f0ba417SAndroid Build Coastguard Worker TEST(result, unique_ptr) {
496*8f0ba417SAndroid Build Coastguard Worker   using testing::Ok;
497*8f0ba417SAndroid Build Coastguard Worker 
498*8f0ba417SAndroid Build Coastguard Worker   auto return_unique_ptr = [](bool success) -> Result<std::unique_ptr<int>> {
499*8f0ba417SAndroid Build Coastguard Worker     auto result = OR_RETURN(Result<std::unique_ptr<int>>(std::make_unique<int>(3)));
500*8f0ba417SAndroid Build Coastguard Worker     if (!success) {
501*8f0ba417SAndroid Build Coastguard Worker       return Error() << __func__ << " failed.";
502*8f0ba417SAndroid Build Coastguard Worker     }
503*8f0ba417SAndroid Build Coastguard Worker     return result;
504*8f0ba417SAndroid Build Coastguard Worker   };
505*8f0ba417SAndroid Build Coastguard Worker   Result<std::unique_ptr<int>> result1 = return_unique_ptr(false);
506*8f0ba417SAndroid Build Coastguard Worker   ASSERT_THAT(result1, Not(Ok()));
507*8f0ba417SAndroid Build Coastguard Worker   Result<std::unique_ptr<int>> result2 = return_unique_ptr(true);
508*8f0ba417SAndroid Build Coastguard Worker   ASSERT_THAT(result2, Ok());
509*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(**result2, 3);
510*8f0ba417SAndroid Build Coastguard Worker }
511*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,void)512*8f0ba417SAndroid Build Coastguard Worker TEST(result, void) {
513*8f0ba417SAndroid Build Coastguard Worker   using testing::Ok;
514*8f0ba417SAndroid Build Coastguard Worker 
515*8f0ba417SAndroid Build Coastguard Worker   auto return_void = []() -> Result<void> {
516*8f0ba417SAndroid Build Coastguard Worker     OR_RETURN(Result<void>());
517*8f0ba417SAndroid Build Coastguard Worker     return {};
518*8f0ba417SAndroid Build Coastguard Worker   };
519*8f0ba417SAndroid Build Coastguard Worker 
520*8f0ba417SAndroid Build Coastguard Worker   ASSERT_THAT(return_void(), Ok());
521*8f0ba417SAndroid Build Coastguard Worker }
522*8f0ba417SAndroid Build Coastguard Worker 
523*8f0ba417SAndroid Build Coastguard Worker struct ConstructorTracker {
524*8f0ba417SAndroid Build Coastguard Worker   static size_t constructor_called;
525*8f0ba417SAndroid Build Coastguard Worker   static size_t copy_constructor_called;
526*8f0ba417SAndroid Build Coastguard Worker   static size_t move_constructor_called;
527*8f0ba417SAndroid Build Coastguard Worker   static size_t copy_assignment_called;
528*8f0ba417SAndroid Build Coastguard Worker   static size_t move_assignment_called;
529*8f0ba417SAndroid Build Coastguard Worker 
530*8f0ba417SAndroid Build Coastguard Worker   template <typename T>
ConstructorTrackerandroid::base::ConstructorTracker531*8f0ba417SAndroid Build Coastguard Worker   ConstructorTracker(T&& string) : string(string) {
532*8f0ba417SAndroid Build Coastguard Worker     ++constructor_called;
533*8f0ba417SAndroid Build Coastguard Worker   }
534*8f0ba417SAndroid Build Coastguard Worker 
ConstructorTrackerandroid::base::ConstructorTracker535*8f0ba417SAndroid Build Coastguard Worker   ConstructorTracker(const ConstructorTracker& ct) {
536*8f0ba417SAndroid Build Coastguard Worker     ++copy_constructor_called;
537*8f0ba417SAndroid Build Coastguard Worker     string = ct.string;
538*8f0ba417SAndroid Build Coastguard Worker   }
ConstructorTrackerandroid::base::ConstructorTracker539*8f0ba417SAndroid Build Coastguard Worker   ConstructorTracker(ConstructorTracker&& ct) noexcept {
540*8f0ba417SAndroid Build Coastguard Worker     ++move_constructor_called;
541*8f0ba417SAndroid Build Coastguard Worker     string = std::move(ct.string);
542*8f0ba417SAndroid Build Coastguard Worker   }
operator =android::base::ConstructorTracker543*8f0ba417SAndroid Build Coastguard Worker   ConstructorTracker& operator=(const ConstructorTracker& ct) {
544*8f0ba417SAndroid Build Coastguard Worker     ++copy_assignment_called;
545*8f0ba417SAndroid Build Coastguard Worker     string = ct.string;
546*8f0ba417SAndroid Build Coastguard Worker     return *this;
547*8f0ba417SAndroid Build Coastguard Worker   }
operator =android::base::ConstructorTracker548*8f0ba417SAndroid Build Coastguard Worker   ConstructorTracker& operator=(ConstructorTracker&& ct) noexcept {
549*8f0ba417SAndroid Build Coastguard Worker     ++move_assignment_called;
550*8f0ba417SAndroid Build Coastguard Worker     string = std::move(ct.string);
551*8f0ba417SAndroid Build Coastguard Worker     return *this;
552*8f0ba417SAndroid Build Coastguard Worker   }
553*8f0ba417SAndroid Build Coastguard Worker 
554*8f0ba417SAndroid Build Coastguard Worker   std::string string;
555*8f0ba417SAndroid Build Coastguard Worker };
556*8f0ba417SAndroid Build Coastguard Worker 
557*8f0ba417SAndroid Build Coastguard Worker size_t ConstructorTracker::constructor_called = 0;
558*8f0ba417SAndroid Build Coastguard Worker size_t ConstructorTracker::copy_constructor_called = 0;
559*8f0ba417SAndroid Build Coastguard Worker size_t ConstructorTracker::move_constructor_called = 0;
560*8f0ba417SAndroid Build Coastguard Worker size_t ConstructorTracker::copy_assignment_called = 0;
561*8f0ba417SAndroid Build Coastguard Worker size_t ConstructorTracker::move_assignment_called = 0;
562*8f0ba417SAndroid Build Coastguard Worker 
ReturnConstructorTracker(const std::string & in)563*8f0ba417SAndroid Build Coastguard Worker Result<ConstructorTracker> ReturnConstructorTracker(const std::string& in) {
564*8f0ba417SAndroid Build Coastguard Worker   if (in.empty()) {
565*8f0ba417SAndroid Build Coastguard Worker     return "literal string";
566*8f0ba417SAndroid Build Coastguard Worker   }
567*8f0ba417SAndroid Build Coastguard Worker   if (in == "test2") {
568*8f0ba417SAndroid Build Coastguard Worker     return ConstructorTracker(in + in + "2");
569*8f0ba417SAndroid Build Coastguard Worker   }
570*8f0ba417SAndroid Build Coastguard Worker   ConstructorTracker result(in + " " + in);
571*8f0ba417SAndroid Build Coastguard Worker   return result;
572*8f0ba417SAndroid Build Coastguard Worker };
573*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,no_copy_on_return)574*8f0ba417SAndroid Build Coastguard Worker TEST(result, no_copy_on_return) {
575*8f0ba417SAndroid Build Coastguard Worker   // If returning parameters that may be used to implicitly construct the type T of Result<T>,
576*8f0ba417SAndroid Build Coastguard Worker   // then those parameters are forwarded to the construction of Result<T>.
577*8f0ba417SAndroid Build Coastguard Worker 
578*8f0ba417SAndroid Build Coastguard Worker   // If returning an prvalue or xvalue, it will be move constructed during the construction of
579*8f0ba417SAndroid Build Coastguard Worker   // Result<T>.
580*8f0ba417SAndroid Build Coastguard Worker 
581*8f0ba417SAndroid Build Coastguard Worker   // This check ensures that that is the case, and particularly that no copy constructors
582*8f0ba417SAndroid Build Coastguard Worker   // are called.
583*8f0ba417SAndroid Build Coastguard Worker 
584*8f0ba417SAndroid Build Coastguard Worker   auto result1 = ReturnConstructorTracker("");
585*8f0ba417SAndroid Build Coastguard Worker   ASSERT_RESULT_OK(result1);
586*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("literal string", result1->string);
587*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(1U, ConstructorTracker::constructor_called);
588*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
589*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
590*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
591*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
592*8f0ba417SAndroid Build Coastguard Worker 
593*8f0ba417SAndroid Build Coastguard Worker   auto result2 = ReturnConstructorTracker("test2");
594*8f0ba417SAndroid Build Coastguard Worker   ASSERT_RESULT_OK(result2);
595*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("test2test22", result2->string);
596*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(2U, ConstructorTracker::constructor_called);
597*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
598*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
599*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
600*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
601*8f0ba417SAndroid Build Coastguard Worker 
602*8f0ba417SAndroid Build Coastguard Worker   auto result3 = ReturnConstructorTracker("test3");
603*8f0ba417SAndroid Build Coastguard Worker   ASSERT_RESULT_OK(result3);
604*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("test3 test3", result3->string);
605*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(3U, ConstructorTracker::constructor_called);
606*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
607*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(2U, ConstructorTracker::move_constructor_called);
608*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
609*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
610*8f0ba417SAndroid Build Coastguard Worker }
611*8f0ba417SAndroid Build Coastguard Worker 
612*8f0ba417SAndroid Build Coastguard Worker // Below two tests require that we do not hide the move constructor with our forwarding reference
613*8f0ba417SAndroid Build Coastguard Worker // constructor.  This is done with by disabling the forwarding reference constructor if its first
614*8f0ba417SAndroid Build Coastguard Worker // and only type is Result<T>.
TEST(result,result_result_with_success)615*8f0ba417SAndroid Build Coastguard Worker TEST(result, result_result_with_success) {
616*8f0ba417SAndroid Build Coastguard Worker   auto return_result_result_with_success = []() -> Result<Result<void>> { return Result<void>(); };
617*8f0ba417SAndroid Build Coastguard Worker   auto result = return_result_result_with_success();
618*8f0ba417SAndroid Build Coastguard Worker   ASSERT_RESULT_OK(result);
619*8f0ba417SAndroid Build Coastguard Worker   ASSERT_RESULT_OK(*result);
620*8f0ba417SAndroid Build Coastguard Worker 
621*8f0ba417SAndroid Build Coastguard Worker   auto inner_result = result.value();
622*8f0ba417SAndroid Build Coastguard Worker   ASSERT_RESULT_OK(inner_result);
623*8f0ba417SAndroid Build Coastguard Worker }
624*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,result_result_with_failure)625*8f0ba417SAndroid Build Coastguard Worker TEST(result, result_result_with_failure) {
626*8f0ba417SAndroid Build Coastguard Worker   auto return_result_result_with_error = []() -> Result<Result<void>> {
627*8f0ba417SAndroid Build Coastguard Worker     return Result<void>(ResultError("failure string", 6));
628*8f0ba417SAndroid Build Coastguard Worker   };
629*8f0ba417SAndroid Build Coastguard Worker   auto result = return_result_result_with_error();
630*8f0ba417SAndroid Build Coastguard Worker   ASSERT_RESULT_OK(result);
631*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result->ok());
632*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("failure string", (*result).error().message());
633*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(6, (*result).error().code());
634*8f0ba417SAndroid Build Coastguard Worker }
635*8f0ba417SAndroid Build Coastguard Worker 
636*8f0ba417SAndroid Build Coastguard Worker // This test requires that we disable the forwarding reference constructor if Result<T> is the
637*8f0ba417SAndroid Build Coastguard Worker // *only* type that we are forwarding.  In otherwords, if we are forwarding Result<T>, int to
638*8f0ba417SAndroid Build Coastguard Worker // construct a Result<T>, then we still need the constructor.
TEST(result,result_two_parameter_constructor_same_type)639*8f0ba417SAndroid Build Coastguard Worker TEST(result, result_two_parameter_constructor_same_type) {
640*8f0ba417SAndroid Build Coastguard Worker   struct TestStruct {
641*8f0ba417SAndroid Build Coastguard Worker     TestStruct(int value) : value_(value) {}
642*8f0ba417SAndroid Build Coastguard Worker     TestStruct(Result<TestStruct> result, int value) : value_(result->value_ * value) {}
643*8f0ba417SAndroid Build Coastguard Worker     int value_;
644*8f0ba417SAndroid Build Coastguard Worker   };
645*8f0ba417SAndroid Build Coastguard Worker 
646*8f0ba417SAndroid Build Coastguard Worker   auto return_test_struct = []() -> Result<TestStruct> {
647*8f0ba417SAndroid Build Coastguard Worker     return Result<TestStruct>(std::in_place, Result<TestStruct>(std::in_place, 6), 6);
648*8f0ba417SAndroid Build Coastguard Worker   };
649*8f0ba417SAndroid Build Coastguard Worker 
650*8f0ba417SAndroid Build Coastguard Worker   auto result = return_test_struct();
651*8f0ba417SAndroid Build Coastguard Worker   ASSERT_RESULT_OK(result);
652*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(36, result->value_);
653*8f0ba417SAndroid Build Coastguard Worker }
654*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,die_on_access_failed_result)655*8f0ba417SAndroid Build Coastguard Worker TEST(result, die_on_access_failed_result) {
656*8f0ba417SAndroid Build Coastguard Worker   Result<std::string> result = Error();
657*8f0ba417SAndroid Build Coastguard Worker   ASSERT_DEATH(*result, "");
658*8f0ba417SAndroid Build Coastguard Worker }
659*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,die_on_get_error_succesful_result)660*8f0ba417SAndroid Build Coastguard Worker TEST(result, die_on_get_error_succesful_result) {
661*8f0ba417SAndroid Build Coastguard Worker   Result<std::string> result = "success";
662*8f0ba417SAndroid Build Coastguard Worker   ASSERT_DEATH(result.error(), "");
663*8f0ba417SAndroid Build Coastguard Worker }
664*8f0ba417SAndroid Build Coastguard Worker 
665*8f0ba417SAndroid Build Coastguard Worker template <class CharT>
SetErrnoToTwo(std::basic_ostream<CharT> & ss)666*8f0ba417SAndroid Build Coastguard Worker std::basic_ostream<CharT>& SetErrnoToTwo(std::basic_ostream<CharT>& ss) {
667*8f0ba417SAndroid Build Coastguard Worker   errno = 2;
668*8f0ba417SAndroid Build Coastguard Worker   return ss;
669*8f0ba417SAndroid Build Coastguard Worker }
670*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,preserve_errno)671*8f0ba417SAndroid Build Coastguard Worker TEST(result, preserve_errno) {
672*8f0ba417SAndroid Build Coastguard Worker   errno = 1;
673*8f0ba417SAndroid Build Coastguard Worker   int old_errno = errno;
674*8f0ba417SAndroid Build Coastguard Worker   Result<int> result = Error() << "Failed" << SetErrnoToTwo<char>;
675*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result.ok());
676*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(old_errno, errno);
677*8f0ba417SAndroid Build Coastguard Worker 
678*8f0ba417SAndroid Build Coastguard Worker   errno = 1;
679*8f0ba417SAndroid Build Coastguard Worker   old_errno = errno;
680*8f0ba417SAndroid Build Coastguard Worker   Result<int> result2 = ErrnoError() << "Failed" << SetErrnoToTwo<char>;
681*8f0ba417SAndroid Build Coastguard Worker   ASSERT_FALSE(result2.ok());
682*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(old_errno, errno);
683*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(old_errno, result2.error().code());
684*8f0ba417SAndroid Build Coastguard Worker }
685*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,error_with_fmt)686*8f0ba417SAndroid Build Coastguard Worker TEST(result, error_with_fmt) {
687*8f0ba417SAndroid Build Coastguard Worker   Result<int> result = Errorf("{} {}!", "hello", "world");
688*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("hello world!", result.error().message());
689*8f0ba417SAndroid Build Coastguard Worker 
690*8f0ba417SAndroid Build Coastguard Worker   result = Errorf("{} {}!", std::string("hello"), std::string("world"));
691*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("hello world!", result.error().message());
692*8f0ba417SAndroid Build Coastguard Worker 
693*8f0ba417SAndroid Build Coastguard Worker   result = Errorf("{1} {0}!", "world", "hello");
694*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("hello world!", result.error().message());
695*8f0ba417SAndroid Build Coastguard Worker 
696*8f0ba417SAndroid Build Coastguard Worker   result = Errorf("hello world!");
697*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("hello world!", result.error().message());
698*8f0ba417SAndroid Build Coastguard Worker 
699*8f0ba417SAndroid Build Coastguard Worker   Result<int> result2 = Errorf("error occurred with {}", result.error());
700*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("error occurred with hello world!", result2.error().message());
701*8f0ba417SAndroid Build Coastguard Worker 
702*8f0ba417SAndroid Build Coastguard Worker   constexpr int test_errno = 6;
703*8f0ba417SAndroid Build Coastguard Worker   errno = test_errno;
704*8f0ba417SAndroid Build Coastguard Worker   result = ErrnoErrorf("{} {}!", "hello", "world");
705*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(test_errno, result.error().code());
706*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("hello world!: "s + strerror(test_errno), result.error().message());
707*8f0ba417SAndroid Build Coastguard Worker }
708*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,error_with_fmt_carries_errno)709*8f0ba417SAndroid Build Coastguard Worker TEST(result, error_with_fmt_carries_errno) {
710*8f0ba417SAndroid Build Coastguard Worker   constexpr int inner_errno = 6;
711*8f0ba417SAndroid Build Coastguard Worker   errno = inner_errno;
712*8f0ba417SAndroid Build Coastguard Worker   Result<int> inner_result = ErrnoErrorf("inner failure");
713*8f0ba417SAndroid Build Coastguard Worker   errno = 0;
714*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(inner_errno, inner_result.error().code());
715*8f0ba417SAndroid Build Coastguard Worker 
716*8f0ba417SAndroid Build Coastguard Worker   // outer_result is created with Errorf, but its error code is got from inner_result.
717*8f0ba417SAndroid Build Coastguard Worker   Result<int> outer_result = Errorf("outer failure caused by {}", inner_result.error());
718*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(inner_errno, outer_result.error().code());
719*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("outer failure caused by inner failure: "s + strerror(inner_errno),
720*8f0ba417SAndroid Build Coastguard Worker             outer_result.error().message());
721*8f0ba417SAndroid Build Coastguard Worker 
722*8f0ba417SAndroid Build Coastguard Worker   // now both result objects are created with ErrnoErrorf. errno from the inner_result
723*8f0ba417SAndroid Build Coastguard Worker   // is not passed to outer_result.
724*8f0ba417SAndroid Build Coastguard Worker   constexpr int outer_errno = 10;
725*8f0ba417SAndroid Build Coastguard Worker   errno = outer_errno;
726*8f0ba417SAndroid Build Coastguard Worker   outer_result = ErrnoErrorf("outer failure caused by {}", inner_result.error());
727*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(outer_errno, outer_result.error().code());
728*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("outer failure caused by inner failure: "s + strerror(inner_errno) + ": "s +
729*8f0ba417SAndroid Build Coastguard Worker                 strerror(outer_errno),
730*8f0ba417SAndroid Build Coastguard Worker             outer_result.error().message());
731*8f0ba417SAndroid Build Coastguard Worker }
732*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,errno_chaining_multiple)733*8f0ba417SAndroid Build Coastguard Worker TEST(result, errno_chaining_multiple) {
734*8f0ba417SAndroid Build Coastguard Worker   constexpr int errno1 = 6;
735*8f0ba417SAndroid Build Coastguard Worker   errno = errno1;
736*8f0ba417SAndroid Build Coastguard Worker   Result<int> inner1 = ErrnoErrorf("error1");
737*8f0ba417SAndroid Build Coastguard Worker 
738*8f0ba417SAndroid Build Coastguard Worker   constexpr int errno2 = 10;
739*8f0ba417SAndroid Build Coastguard Worker   errno = errno2;
740*8f0ba417SAndroid Build Coastguard Worker   Result<int> inner2 = ErrnoErrorf("error2");
741*8f0ba417SAndroid Build Coastguard Worker 
742*8f0ba417SAndroid Build Coastguard Worker   // takes the error code of inner2 since its the last one.
743*8f0ba417SAndroid Build Coastguard Worker   Result<int> outer = Errorf("two errors: {}, {}", inner1.error(), inner2.error());
744*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(errno2, outer.error().code());
745*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ("two errors: error1: "s + strerror(errno1) + ", error2: "s + strerror(errno2),
746*8f0ba417SAndroid Build Coastguard Worker             outer.error().message());
747*8f0ba417SAndroid Build Coastguard Worker }
748*8f0ba417SAndroid Build Coastguard Worker 
TEST(result,error_without_message)749*8f0ba417SAndroid Build Coastguard Worker TEST(result, error_without_message) {
750*8f0ba417SAndroid Build Coastguard Worker   constexpr bool include_message = false;
751*8f0ba417SAndroid Build Coastguard Worker   Result<void, Errno, include_message> res = Error<Errno, include_message>(10);
752*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(res.ok());
753*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(10, res.error().code());
754*8f0ba417SAndroid Build Coastguard Worker   EXPECT_EQ(sizeof(int), sizeof(res.error()));
755*8f0ba417SAndroid Build Coastguard Worker }
756*8f0ba417SAndroid Build Coastguard Worker 
757*8f0ba417SAndroid Build Coastguard Worker namespace testing {
758*8f0ba417SAndroid Build Coastguard Worker 
759*8f0ba417SAndroid Build Coastguard Worker class Listener : public ::testing::MatchResultListener {
760*8f0ba417SAndroid Build Coastguard Worker  public:
Listener()761*8f0ba417SAndroid Build Coastguard Worker   Listener() : MatchResultListener(&ss_) {}
762*8f0ba417SAndroid Build Coastguard Worker   ~Listener() = default;
message() const763*8f0ba417SAndroid Build Coastguard Worker   std::string message() const { return ss_.str(); }
764*8f0ba417SAndroid Build Coastguard Worker 
765*8f0ba417SAndroid Build Coastguard Worker  private:
766*8f0ba417SAndroid Build Coastguard Worker   std::stringstream ss_;
767*8f0ba417SAndroid Build Coastguard Worker };
768*8f0ba417SAndroid Build Coastguard Worker 
769*8f0ba417SAndroid Build Coastguard Worker class ResultMatchers : public ::testing::Test {
770*8f0ba417SAndroid Build Coastguard Worker  public:
771*8f0ba417SAndroid Build Coastguard Worker   Result<int> result = 1;
772*8f0ba417SAndroid Build Coastguard Worker   Result<int> error = Error(EBADF) << "error message";
773*8f0ba417SAndroid Build Coastguard Worker   Listener listener;
774*8f0ba417SAndroid Build Coastguard Worker };
775*8f0ba417SAndroid Build Coastguard Worker 
TEST_F(ResultMatchers,ok_result)776*8f0ba417SAndroid Build Coastguard Worker TEST_F(ResultMatchers, ok_result) {
777*8f0ba417SAndroid Build Coastguard Worker   EXPECT_TRUE(ExplainMatchResult(Ok(), result, &listener));
778*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), Eq("result is OK"));
779*8f0ba417SAndroid Build Coastguard Worker }
780*8f0ba417SAndroid Build Coastguard Worker 
TEST_F(ResultMatchers,ok_error)781*8f0ba417SAndroid Build Coastguard Worker TEST_F(ResultMatchers, ok_error) {
782*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(ExplainMatchResult(Ok(), error, &listener));
783*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), StartsWith("error is"));
784*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), HasSubstr(error.error().message()));
785*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), HasSubstr(strerror(error.error().code())));
786*8f0ba417SAndroid Build Coastguard Worker }
787*8f0ba417SAndroid Build Coastguard Worker 
TEST_F(ResultMatchers,not_ok_result)788*8f0ba417SAndroid Build Coastguard Worker TEST_F(ResultMatchers, not_ok_result) {
789*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(ExplainMatchResult(Not(Ok()), result, &listener));
790*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), Eq("result is OK"));
791*8f0ba417SAndroid Build Coastguard Worker }
792*8f0ba417SAndroid Build Coastguard Worker 
TEST_F(ResultMatchers,not_ok_error)793*8f0ba417SAndroid Build Coastguard Worker TEST_F(ResultMatchers, not_ok_error) {
794*8f0ba417SAndroid Build Coastguard Worker   EXPECT_TRUE(ExplainMatchResult(Not(Ok()), error, &listener));
795*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), StartsWith("error is"));
796*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), HasSubstr(error.error().message()));
797*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), HasSubstr(strerror(error.error().code())));
798*8f0ba417SAndroid Build Coastguard Worker }
799*8f0ba417SAndroid Build Coastguard Worker 
TEST_F(ResultMatchers,has_value_result)800*8f0ba417SAndroid Build Coastguard Worker TEST_F(ResultMatchers, has_value_result) {
801*8f0ba417SAndroid Build Coastguard Worker   EXPECT_TRUE(ExplainMatchResult(HasValue(*result), result, &listener));
802*8f0ba417SAndroid Build Coastguard Worker }
803*8f0ba417SAndroid Build Coastguard Worker 
TEST_F(ResultMatchers,has_value_wrong_result)804*8f0ba417SAndroid Build Coastguard Worker TEST_F(ResultMatchers, has_value_wrong_result) {
805*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(ExplainMatchResult(HasValue(*result + 1), result, &listener));
806*8f0ba417SAndroid Build Coastguard Worker }
807*8f0ba417SAndroid Build Coastguard Worker 
TEST_F(ResultMatchers,has_value_error)808*8f0ba417SAndroid Build Coastguard Worker TEST_F(ResultMatchers, has_value_error) {
809*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(ExplainMatchResult(HasValue(*result), error, &listener));
810*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), StartsWith("error is"));
811*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), HasSubstr(error.error().message()));
812*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), HasSubstr(strerror(error.error().code())));
813*8f0ba417SAndroid Build Coastguard Worker }
814*8f0ba417SAndroid Build Coastguard Worker 
TEST_F(ResultMatchers,has_error_code_result)815*8f0ba417SAndroid Build Coastguard Worker TEST_F(ResultMatchers, has_error_code_result) {
816*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(ExplainMatchResult(HasError(WithCode(error.error().code())), result, &listener));
817*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), Eq("result is OK"));
818*8f0ba417SAndroid Build Coastguard Worker }
819*8f0ba417SAndroid Build Coastguard Worker 
TEST_F(ResultMatchers,has_error_code_wrong_code)820*8f0ba417SAndroid Build Coastguard Worker TEST_F(ResultMatchers, has_error_code_wrong_code) {
821*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(ExplainMatchResult(HasError(WithCode(error.error().code() + 1)), error, &listener));
822*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), StartsWith("actual error is"));
823*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), HasSubstr(strerror(error.error().code())));
824*8f0ba417SAndroid Build Coastguard Worker }
825*8f0ba417SAndroid Build Coastguard Worker 
TEST_F(ResultMatchers,has_error_code_correct_code)826*8f0ba417SAndroid Build Coastguard Worker TEST_F(ResultMatchers, has_error_code_correct_code) {
827*8f0ba417SAndroid Build Coastguard Worker   EXPECT_TRUE(ExplainMatchResult(HasError(WithCode(error.error().code())), error, &listener));
828*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), StartsWith("actual error is"));
829*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), HasSubstr(strerror(error.error().code())));
830*8f0ba417SAndroid Build Coastguard Worker }
831*8f0ba417SAndroid Build Coastguard Worker 
TEST_F(ResultMatchers,has_error_message_result)832*8f0ba417SAndroid Build Coastguard Worker TEST_F(ResultMatchers, has_error_message_result) {
833*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(
834*8f0ba417SAndroid Build Coastguard Worker       ExplainMatchResult(HasError(WithMessage(error.error().message())), result, &listener));
835*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), Eq("result is OK"));
836*8f0ba417SAndroid Build Coastguard Worker }
837*8f0ba417SAndroid Build Coastguard Worker 
TEST_F(ResultMatchers,has_error_message_wrong_message)838*8f0ba417SAndroid Build Coastguard Worker TEST_F(ResultMatchers, has_error_message_wrong_message) {
839*8f0ba417SAndroid Build Coastguard Worker   EXPECT_FALSE(ExplainMatchResult(HasError(WithMessage("foo")), error, &listener));
840*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), StartsWith("actual error is"));
841*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), HasSubstr(error.error().message()));
842*8f0ba417SAndroid Build Coastguard Worker }
843*8f0ba417SAndroid Build Coastguard Worker 
TEST_F(ResultMatchers,has_error_message_correct_message)844*8f0ba417SAndroid Build Coastguard Worker TEST_F(ResultMatchers, has_error_message_correct_message) {
845*8f0ba417SAndroid Build Coastguard Worker   EXPECT_TRUE(ExplainMatchResult(HasError(WithMessage(error.error().message())), error, &listener));
846*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), StartsWith("actual error is"));
847*8f0ba417SAndroid Build Coastguard Worker   EXPECT_THAT(listener.message(), HasSubstr(error.error().message()));
848*8f0ba417SAndroid Build Coastguard Worker }
849*8f0ba417SAndroid Build Coastguard Worker 
850*8f0ba417SAndroid Build Coastguard Worker }  // namespace testing
851*8f0ba417SAndroid Build Coastguard Worker }  // namespace base
852*8f0ba417SAndroid Build Coastguard Worker }  // namespace android
853