1 // Copyright 2022 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 // https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14
15 // pw::Result is derived from absl::StatusOr, but has some small differences.
16 // This test covers basic pw::Result functionality and as well as the features
17 // supported by pw::Result that are not supported by absl::StatusOr (constexpr
18 // use in particular).
19 //
20 // The complete, thorough pw::Result tests are in statusor_test.cc, which is
21 // derived from Abseil's tests for absl::StatusOr.
22
23 #include "pw_result/result.h"
24
25 #include <type_traits>
26
27 #include "pw_status/status.h"
28 #include "pw_status/try.h"
29 #include "pw_unit_test/framework.h"
30
31 namespace pw {
32 namespace {
33
TEST(Result,CreateOk)34 TEST(Result, CreateOk) {
35 Result<const char*> res("hello");
36 EXPECT_TRUE(res.ok());
37 EXPECT_EQ(res.status(), OkStatus());
38 EXPECT_EQ(res.value(), "hello");
39 }
40
TEST(Result,CreateOkTypeDeduction)41 TEST(Result, CreateOkTypeDeduction) {
42 auto res = Result("hello");
43 static_assert(std::is_same_v<decltype(res), Result<const char*>>);
44 EXPECT_TRUE(res.ok());
45 EXPECT_EQ(res.status(), OkStatus());
46 EXPECT_STREQ(res.value(), "hello");
47 }
48
TEST(Result,CreateNotOk)49 TEST(Result, CreateNotOk) {
50 Result<int> res(Status::DataLoss());
51 EXPECT_FALSE(res.ok());
52 EXPECT_EQ(res.status(), Status::DataLoss());
53 }
54
TEST(Result,ValueOr)55 TEST(Result, ValueOr) {
56 Result<int> good(3);
57 Result<int> bad(Status::DataLoss());
58 EXPECT_EQ(good.value_or(42), 3);
59 EXPECT_EQ(bad.value_or(42), 42);
60 }
61
TEST(Result,Deref)62 TEST(Result, Deref) {
63 struct Tester {
64 constexpr bool True() { return true; }
65 constexpr bool False() { return false; }
66 };
67
68 auto tester = Result<Tester>(Tester());
69 EXPECT_TRUE(tester.ok());
70 EXPECT_TRUE(tester->True());
71 EXPECT_FALSE(tester->False());
72 EXPECT_TRUE((*tester).True());
73 EXPECT_FALSE((*tester).False());
74 EXPECT_EQ(tester.value().True(), tester->True());
75 EXPECT_EQ(tester.value().False(), tester->False());
76 }
77
TEST(Result,ConstDeref)78 TEST(Result, ConstDeref) {
79 struct Tester {
80 constexpr bool True() const { return true; }
81 constexpr bool False() const { return false; }
82 };
83
84 const auto tester = Result<Tester>(Tester());
85 EXPECT_TRUE(tester.ok());
86 EXPECT_TRUE(tester->True());
87 EXPECT_FALSE(tester->False());
88 EXPECT_TRUE((*tester).True());
89 EXPECT_FALSE((*tester).False());
90 EXPECT_EQ(tester.value().True(), tester->True());
91 EXPECT_EQ(tester.value().False(), tester->False());
92 }
93
TEST(Result,ConstructType)94 TEST(Result, ConstructType) {
95 struct Point {
96 Point(int a, int b) : x(a), y(b) {}
97
98 int x;
99 int y;
100 };
101
102 Result<Point> origin{std::in_place, 0, 0};
103 ASSERT_TRUE(origin.ok());
104 ASSERT_EQ(origin.value().x, 0);
105 ASSERT_EQ(origin.value().y, 0);
106 }
107
Divide(float a,float b)108 Result<float> Divide(float a, float b) {
109 if (b == 0) {
110 return Status::InvalidArgument();
111 }
112 return a / b;
113 }
114
TEST(Divide,ReturnOk)115 TEST(Divide, ReturnOk) {
116 Result<float> res = Divide(10, 5);
117 ASSERT_TRUE(res.ok());
118 EXPECT_EQ(res.value(), 2.0f);
119 }
120
TEST(Divide,ReturnNotOk)121 TEST(Divide, ReturnNotOk) {
122 Result<float> res = Divide(10, 0);
123 EXPECT_FALSE(res.ok());
124 EXPECT_EQ(res.status(), Status::InvalidArgument());
125 }
126
ReturnResult(Result<bool> result)127 Result<bool> ReturnResult(Result<bool> result) { return result; }
128
TryResultAssign(Result<bool> result)129 Status TryResultAssign(Result<bool> result) {
130 PW_TRY_ASSIGN(const bool value, ReturnResult(result));
131
132 // Any status other than OK should have already returned.
133 EXPECT_EQ(result.status(), OkStatus());
134 EXPECT_EQ(value, result.value());
135 return result.status();
136 }
137
TEST(Result,TryAssign)138 TEST(Result, TryAssign) {
139 EXPECT_EQ(TryResultAssign(Status::Cancelled()), Status::Cancelled());
140 EXPECT_EQ(TryResultAssign(Status::DataLoss()), Status::DataLoss());
141 EXPECT_EQ(TryResultAssign(Status::Unimplemented()), Status::Unimplemented());
142 EXPECT_EQ(TryResultAssign(false), OkStatus());
143 EXPECT_EQ(TryResultAssign(true), OkStatus());
144 }
145
146 constexpr int kExpectedVal = 5;
147
148 class Immovable {
149 public:
150 Immovable() = delete;
Immovable(int val)151 explicit Immovable(int val) : val_(val) {}
152 Immovable(const Immovable&) = delete;
153 Immovable& operator=(const Immovable&) = delete;
154 Immovable(Immovable&&) = delete;
155 Immovable& operator=(Immovable&&) = delete;
val()156 int val() { return val_; }
157
158 private:
159 int val_;
160 };
161
MakeImmovable()162 Result<Immovable> MakeImmovable() { return Result<Immovable>(kExpectedVal); }
163
TryResultAssignImmovable()164 Result<int> TryResultAssignImmovable() {
165 PW_TRY_ASSIGN(auto&& thingy, MakeImmovable());
166 return thingy.val();
167 }
168
TEST(Result,TryAssignImmovable)169 TEST(Result, TryAssignImmovable) {
170 EXPECT_EQ(TryResultAssignImmovable(), Result<int>(kExpectedVal));
171 }
172
173 struct Value {
174 int number;
175 };
176
TEST(Result,ConstexprOk)177 TEST(Result, ConstexprOk) {
178 static constexpr pw::Result<Value> kResult(Value{123});
179
180 static_assert(kResult.status() == pw::OkStatus());
181 static_assert(kResult.ok());
182
183 static_assert((*kResult).number == 123);
184 static_assert((*std::move(kResult)).number == 123);
185
186 static_assert(kResult->number == 123);
187 static_assert(std::move(kResult)->number == 123);
188
189 static_assert(kResult.value().number == 123);
190 static_assert(std::move(kResult).value().number == 123);
191
192 static_assert(kResult.value_or(Value{99}).number == 123);
193 static_assert(std::move(kResult).value_or(Value{99}).number == 123);
194 }
195
TEST(Result,ConstexprNotOk)196 TEST(Result, ConstexprNotOk) {
197 static constexpr pw::Result<Value> kResult(pw::Status::NotFound());
198
199 static_assert(kResult.status() == pw::Status::NotFound());
200 static_assert(!kResult.ok());
201
202 static_assert(kResult.value_or(Value{99}).number == 99);
203 static_assert(std::move(kResult).value_or(Value{99}).number == 99);
204 }
205
TEST(Result,ConstexprNotOkCopy)206 TEST(Result, ConstexprNotOkCopy) {
207 static constexpr pw::Result<Value> kResult(pw::Status::NotFound());
208 constexpr pw::Result<Value> kResultCopy(kResult);
209
210 static_assert(kResultCopy.status() == pw::Status::NotFound());
211 static_assert(!kResultCopy.ok());
212
213 static_assert(kResultCopy.value_or(Value{99}).number == 99);
214 static_assert(std::move(kResultCopy).value_or(Value{99}).number == 99);
215 }
216
__anon829849410202(int x) 217 auto multiply = [](int x) -> Result<int> { return x * 2; };
__anon829849410302(int x) 218 auto add_two = [](int x) -> Result<int> { return x + 2; };
__anon829849410402(int) 219 auto fail_unknown = [](int) -> Result<int> { return Status::Unknown(); };
220
TEST(Result,AndThenNonConstLValueRefInvokeSuccess)221 TEST(Result, AndThenNonConstLValueRefInvokeSuccess) {
222 Result<int> r = 32;
223 auto ret = r.and_then(multiply);
224 ASSERT_TRUE(ret.ok());
225 EXPECT_EQ(*ret, 64);
226 }
227
TEST(Result,AndThenNonConstLValueRefInvokeFail)228 TEST(Result, AndThenNonConstLValueRefInvokeFail) {
229 Result<int> r = 32;
230 auto ret = r.and_then(fail_unknown);
231 ASSERT_FALSE(ret.ok());
232 EXPECT_EQ(ret.status(), Status::Unknown());
233 }
234
TEST(Result,AndThenNonConstLValueRefSkips)235 TEST(Result, AndThenNonConstLValueRefSkips) {
236 Result<int> r = Status::NotFound();
237 auto ret = r.and_then(multiply);
238 ASSERT_FALSE(ret.ok());
239 EXPECT_EQ(ret.status(), Status::NotFound());
240 }
241
TEST(Result,AndThenNonConstRvalueRefInvokeSuccess)242 TEST(Result, AndThenNonConstRvalueRefInvokeSuccess) {
243 Result<int> r = 32;
244 auto ret = std::move(r).and_then(multiply);
245 ASSERT_TRUE(ret.ok());
246 EXPECT_EQ(*ret, 64);
247 }
248
TEST(Result,AndThenNonConstRvalueRefInvokeFails)249 TEST(Result, AndThenNonConstRvalueRefInvokeFails) {
250 Result<int> r = 64;
251 auto ret = std::move(r).and_then(fail_unknown);
252 ASSERT_FALSE(ret.ok());
253 EXPECT_EQ(ret.status(), Status::Unknown());
254 }
255
TEST(Result,AndThenNonConstRvalueRefSkips)256 TEST(Result, AndThenNonConstRvalueRefSkips) {
257 Result<int> r = Status::NotFound();
258 auto ret = std::move(r).and_then(multiply);
259 ASSERT_FALSE(ret.ok());
260 EXPECT_EQ(ret.status(), Status::NotFound());
261 }
262
TEST(Result,AndThenConstLValueRefInvokeSuccess)263 TEST(Result, AndThenConstLValueRefInvokeSuccess) {
264 const Result<int> r = 32;
265 auto ret = r.and_then(multiply);
266 ASSERT_TRUE(ret.ok());
267 EXPECT_EQ(*ret, 64);
268 }
269
TEST(Result,AndThenConstLValueRefInvokeFail)270 TEST(Result, AndThenConstLValueRefInvokeFail) {
271 const Result<int> r = 32;
272 auto ret = r.and_then(fail_unknown);
273 ASSERT_FALSE(ret.ok());
274 EXPECT_EQ(ret.status(), Status::Unknown());
275 }
276
TEST(Result,AndThenConstLValueRefSkips)277 TEST(Result, AndThenConstLValueRefSkips) {
278 const Result<int> r = Status::NotFound();
279 auto ret = r.and_then(multiply);
280 ASSERT_FALSE(ret.ok());
281 EXPECT_EQ(ret.status(), Status::NotFound());
282 }
283
TEST(Result,AndThenConstRValueRefInvokeSuccess)284 TEST(Result, AndThenConstRValueRefInvokeSuccess) {
285 const Result<int> r = 32;
286 auto ret = std::move(r).and_then(multiply);
287 ASSERT_TRUE(ret.ok());
288 EXPECT_EQ(*ret, 64);
289 }
290
TEST(Result,AndThenConstRValueRefInvokeFail)291 TEST(Result, AndThenConstRValueRefInvokeFail) {
292 const Result<int> r = 32;
293 auto ret = std::move(r).and_then(fail_unknown);
294 ASSERT_FALSE(ret.ok());
295 EXPECT_EQ(ret.status(), Status::Unknown());
296 }
297
TEST(Result,AndThenConstRValueRefSkips)298 TEST(Result, AndThenConstRValueRefSkips) {
299 const Result<int> r = Status::NotFound();
300 auto ret = std::move(r).and_then(multiply);
301 ASSERT_FALSE(ret.ok());
302 EXPECT_EQ(ret.status(), Status::NotFound());
303 }
304
TEST(Result,AndThenMultipleChained)305 TEST(Result, AndThenMultipleChained) {
306 Result<int> r = 32;
307 auto ret = r.and_then(multiply).and_then(add_two).and_then(multiply);
308 ASSERT_TRUE(ret.ok());
309 EXPECT_EQ(*ret, 132);
310 }
311
__anon829849410502(Status) 312 auto return_status = [](Status) { return Status::Unknown(); };
__anon829849410602(Status) 313 auto return_result = [](Status) { return Result<int>(Status::Internal()); };
314
TEST(Result,OrElseNonConstLValueRefSkips)315 TEST(Result, OrElseNonConstLValueRefSkips) {
316 Result<int> r = 32;
317 auto ret = r.or_else(return_status);
318 ASSERT_TRUE(ret.ok());
319 EXPECT_EQ(*ret, 32);
320 }
321
TEST(Result,OrElseNonConstLValueRefStatusInvokes)322 TEST(Result, OrElseNonConstLValueRefStatusInvokes) {
323 Result<int> r = Status::NotFound();
324 auto ret = r.or_else(return_status);
325 ASSERT_FALSE(ret.ok());
326 EXPECT_EQ(ret.status(), Status::Unknown());
327 }
328
TEST(Result,OrElseNonConstLValueRefResultInvokes)329 TEST(Result, OrElseNonConstLValueRefResultInvokes) {
330 Result<int> r = Status::NotFound();
331 auto ret = r.or_else(return_result);
332 ASSERT_FALSE(ret.ok());
333 EXPECT_EQ(ret.status(), Status::Internal());
334 }
335
TEST(Result,OrElseNonConstLValueRefVoidSkips)336 TEST(Result, OrElseNonConstLValueRefVoidSkips) {
337 Result<int> r = 32;
338 bool invoked = false;
339 auto ret = r.or_else([&invoked](Status) { invoked = true; });
340 EXPECT_FALSE(invoked);
341 ASSERT_TRUE(ret.ok());
342 EXPECT_EQ(*ret, 32);
343 }
344
TEST(Result,OrElseNonConstLValueRefVoidInvokes)345 TEST(Result, OrElseNonConstLValueRefVoidInvokes) {
346 Result<int> r = Status::NotFound();
347 bool invoked = false;
348 auto ret = r.or_else([&invoked](Status) { invoked = true; });
349 EXPECT_TRUE(invoked);
350 ASSERT_FALSE(ret.ok());
351 EXPECT_EQ(ret.status(), Status::NotFound());
352 }
353
TEST(Result,OrElseNonConstRValueRefSkips)354 TEST(Result, OrElseNonConstRValueRefSkips) {
355 Result<int> r = 32;
356 auto ret = std::move(r).or_else(return_status);
357 ASSERT_TRUE(ret.ok());
358 EXPECT_EQ(*ret, 32);
359 }
360
TEST(Result,OrElseNonConstRValueRefStatusInvokes)361 TEST(Result, OrElseNonConstRValueRefStatusInvokes) {
362 Result<int> r = Status::NotFound();
363 auto ret = std::move(r).or_else(return_status);
364 ASSERT_FALSE(ret.ok());
365 EXPECT_EQ(ret.status(), Status::Unknown());
366 }
367
TEST(Result,OrElseNonConstRValueRefResultInvokes)368 TEST(Result, OrElseNonConstRValueRefResultInvokes) {
369 Result<int> r = Status::NotFound();
370 auto ret = std::move(r).or_else(return_result);
371 ASSERT_FALSE(ret.ok());
372 EXPECT_EQ(ret.status(), Status::Internal());
373 }
374
TEST(Result,OrElseNonConstRValueRefVoidSkips)375 TEST(Result, OrElseNonConstRValueRefVoidSkips) {
376 Result<int> r = 32;
377 bool invoked = false;
378 auto ret = std::move(r).or_else([&invoked](Status) { invoked = true; });
379 EXPECT_FALSE(invoked);
380 ASSERT_TRUE(ret.ok());
381 EXPECT_EQ(*ret, 32);
382 }
383
TEST(Result,OrElseNonConstRValueRefVoidInvokes)384 TEST(Result, OrElseNonConstRValueRefVoidInvokes) {
385 Result<int> r = Status::NotFound();
386 bool invoked = false;
387 auto ret = std::move(r).or_else([&invoked](Status) { invoked = true; });
388 EXPECT_TRUE(invoked);
389 ASSERT_FALSE(ret.ok());
390 EXPECT_EQ(ret.status(), Status::NotFound());
391 }
392
TEST(Result,OrElseConstLValueRefSkips)393 TEST(Result, OrElseConstLValueRefSkips) {
394 const Result<int> r = 32;
395 auto ret = r.or_else(return_status);
396 ASSERT_TRUE(ret.ok());
397 EXPECT_EQ(*ret, 32);
398 }
399
TEST(Result,OrElseConstLValueRefStatusInvokes)400 TEST(Result, OrElseConstLValueRefStatusInvokes) {
401 const Result<int> r = Status::NotFound();
402 auto ret = r.or_else(return_status);
403 ASSERT_FALSE(ret.ok());
404 EXPECT_EQ(ret.status(), Status::Unknown());
405 }
406
TEST(Result,OrElseConstLValueRefResultInvokes)407 TEST(Result, OrElseConstLValueRefResultInvokes) {
408 const Result<int> r = Status::NotFound();
409 auto ret = r.or_else(return_result);
410 ASSERT_FALSE(ret.ok());
411 EXPECT_EQ(ret.status(), Status::Internal());
412 }
413
TEST(Result,OrElseConstLValueRefVoidSkips)414 TEST(Result, OrElseConstLValueRefVoidSkips) {
415 const Result<int> r = 32;
416 bool invoked = false;
417 auto ret = r.or_else([&invoked](Status) { invoked = true; });
418 EXPECT_FALSE(invoked);
419 ASSERT_TRUE(ret.ok());
420 EXPECT_EQ(*ret, 32);
421 }
422
TEST(Result,OrElseConstLValueRefVoidInvokes)423 TEST(Result, OrElseConstLValueRefVoidInvokes) {
424 const Result<int> r = Status::NotFound();
425 bool invoked = false;
426 auto ret = r.or_else([&invoked](Status) { invoked = true; });
427 EXPECT_TRUE(invoked);
428 ASSERT_FALSE(ret.ok());
429 EXPECT_EQ(ret.status(), Status::NotFound());
430 }
431
TEST(Result,OrElseConstRValueRefSkips)432 TEST(Result, OrElseConstRValueRefSkips) {
433 const Result<int> r = 32;
434 auto ret = std::move(r).or_else(return_status);
435 ASSERT_TRUE(ret.ok());
436 EXPECT_EQ(*ret, 32);
437 }
438
TEST(Result,OrElseConstRValueRefStatusInvokes)439 TEST(Result, OrElseConstRValueRefStatusInvokes) {
440 const Result<int> r = Status::NotFound();
441 auto ret = std::move(r).or_else(return_status);
442 ASSERT_FALSE(ret.ok());
443 EXPECT_EQ(ret.status(), Status::Unknown());
444 }
445
TEST(Result,OrElseConstRValueRefResultInvokes)446 TEST(Result, OrElseConstRValueRefResultInvokes) {
447 const Result<int> r = Status::NotFound();
448 auto ret = std::move(r).or_else(return_result);
449 ASSERT_FALSE(ret.ok());
450 EXPECT_EQ(ret.status(), Status::Internal());
451 }
452
TEST(Result,OrElseConstRValueRefVoidSkips)453 TEST(Result, OrElseConstRValueRefVoidSkips) {
454 const Result<int> r = 32;
455 bool invoked = false;
456 auto ret = std::move(r).or_else([&invoked](Status) { invoked = true; });
457 EXPECT_FALSE(invoked);
458 ASSERT_TRUE(ret.ok());
459 EXPECT_EQ(*ret, 32);
460 }
461
TEST(Result,OrElseConstRValueRefVoidInvokes)462 TEST(Result, OrElseConstRValueRefVoidInvokes) {
463 const Result<int> r = Status::NotFound();
464 bool invoked = false;
465 auto ret = std::move(r).or_else([&invoked](Status) { invoked = true; });
466 EXPECT_TRUE(invoked);
467 ASSERT_FALSE(ret.ok());
468 EXPECT_EQ(ret.status(), Status::NotFound());
469 }
470
TEST(Result,OrElseMultipleChained)471 TEST(Result, OrElseMultipleChained) {
472 Result<int> r = Status::NotFound();
473 bool invoked = false;
474 auto ret =
475 r.or_else(return_result).or_else([&invoked](Status) { invoked = true; });
476 EXPECT_TRUE(invoked);
477 ASSERT_FALSE(ret.ok());
478 EXPECT_EQ(ret.status(), Status::Internal());
479 }
480
__anon829849411002(int x) 481 auto multiply_int = [](int x) { return x * 2; };
__anon829849411102(int x) 482 auto add_two_int = [](int x) { return x + 2; };
__anon829849411202(int x) 483 auto make_value = [](int x) { return Value{.number = x}; };
484
TEST(Result,TransformNonConstLValueRefInvokeSuccess)485 TEST(Result, TransformNonConstLValueRefInvokeSuccess) {
486 Result<int> r = 32;
487 auto ret = r.transform(multiply_int);
488 ASSERT_TRUE(ret.ok());
489 EXPECT_EQ(*ret, 64);
490 }
491
TEST(Result,TransformNonConstLValueRefInvokeDifferentType)492 TEST(Result, TransformNonConstLValueRefInvokeDifferentType) {
493 Result<int> r = 32;
494 auto ret = r.transform(make_value);
495 ASSERT_TRUE(ret.ok());
496 EXPECT_EQ(ret->number, 32);
497 }
498
TEST(Result,TransformNonConstLValueRefSkips)499 TEST(Result, TransformNonConstLValueRefSkips) {
500 Result<int> r = Status::NotFound();
501 auto ret = r.transform(multiply_int);
502 ASSERT_FALSE(ret.ok());
503 EXPECT_EQ(ret.status(), Status::NotFound());
504 }
505
TEST(Result,TransformNonConstRValueRefInvokeSuccess)506 TEST(Result, TransformNonConstRValueRefInvokeSuccess) {
507 Result<int> r = 32;
508 auto ret = std::move(r).transform(multiply_int);
509 ASSERT_TRUE(ret.ok());
510 EXPECT_EQ(*ret, 64);
511 }
512
TEST(Result,TransformNonConstRValueRefInvokeDifferentType)513 TEST(Result, TransformNonConstRValueRefInvokeDifferentType) {
514 Result<int> r = 32;
515 auto ret = std::move(r).transform(make_value);
516 ASSERT_TRUE(ret.ok());
517 EXPECT_EQ(ret->number, 32);
518 }
519
TEST(Result,TransformNonConstRValueRefSkips)520 TEST(Result, TransformNonConstRValueRefSkips) {
521 Result<int> r = Status::NotFound();
522 auto ret = std::move(r).transform(multiply_int);
523 ASSERT_FALSE(ret.ok());
524 EXPECT_EQ(ret.status(), Status::NotFound());
525 }
526
TEST(Result,TransformConstLValueRefInvokeSuccess)527 TEST(Result, TransformConstLValueRefInvokeSuccess) {
528 const Result<int> r = 32;
529 auto ret = r.transform(multiply_int);
530 ASSERT_TRUE(ret.ok());
531 EXPECT_EQ(*ret, 64);
532 }
533
TEST(Result,TransformConstLValueRefInvokeDifferentType)534 TEST(Result, TransformConstLValueRefInvokeDifferentType) {
535 const Result<int> r = 32;
536 auto ret = r.transform(make_value);
537 ASSERT_TRUE(ret.ok());
538 EXPECT_EQ(ret->number, 32);
539 }
540
TEST(Result,TransformConstLValueRefSkips)541 TEST(Result, TransformConstLValueRefSkips) {
542 const Result<int> r = Status::NotFound();
543 auto ret = r.transform(multiply_int);
544 ASSERT_FALSE(ret.ok());
545 EXPECT_EQ(ret.status(), Status::NotFound());
546 }
547
TEST(Result,TransformConstRValueRefInvokeSuccess)548 TEST(Result, TransformConstRValueRefInvokeSuccess) {
549 const Result<int> r = 32;
550 auto ret = std::move(r).transform(multiply_int);
551 ASSERT_TRUE(ret.ok());
552 EXPECT_EQ(*ret, 64);
553 }
554
TEST(Result,TransformConstRValueRefInvokeDifferentType)555 TEST(Result, TransformConstRValueRefInvokeDifferentType) {
556 const Result<int> r = 32;
557 auto ret = std::move(r).transform(make_value);
558 ASSERT_TRUE(ret.ok());
559 EXPECT_EQ(ret->number, 32);
560 }
561
TEST(Result,TransformConstRValueRefSkips)562 TEST(Result, TransformConstRValueRefSkips) {
563 const Result<int> r = Status::NotFound();
564 auto ret = std::move(r).transform(multiply_int);
565 ASSERT_FALSE(ret.ok());
566 EXPECT_EQ(ret.status(), Status::NotFound());
567 }
568
TEST(Result,TransformMultipleChained)569 TEST(Result, TransformMultipleChained) {
570 Result<int> r = 32;
571 auto ret = r.transform(multiply_int)
572 .transform(add_two_int)
573 .transform(multiply_int)
574 .transform(make_value);
575 ASSERT_TRUE(ret.ok());
576 EXPECT_EQ(ret->number, 132);
577 }
578
579 } // namespace
580 } // namespace pw
581