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