Bitcoin Core  31.0.0
P2P Digital Currency
util_expected_tests.cpp
Go to the documentation of this file.
1 // Copyright (c) The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or https://opensource.org/license/mit.
4 
6 #include <util/expected.h>
7 
8 #include <boost/test/unit_test.hpp>
9 
10 #include <memory>
11 #include <string>
12 #include <utility>
13 
14 
15 using namespace util;
16 
17 BOOST_AUTO_TEST_SUITE(util_expected_tests)
18 
19 BOOST_AUTO_TEST_CASE(expected_value)
20 {
21  struct Obj {
22  int x;
23  };
25  BOOST_CHECK_EQUAL(e.value().x, 0);
26 
27  e = Obj{42};
28 
29  BOOST_CHECK(e.has_value());
30  BOOST_CHECK(static_cast<bool>(e));
31  BOOST_CHECK_EQUAL(e.value().x, 42);
32  BOOST_CHECK_EQUAL((*e).x, 42);
33  BOOST_CHECK_EQUAL(e->x, 42);
34 
35  // modify value
36  e.value().x += 1;
37  (*e).x += 1;
38  e->x += 1;
39 
40  const auto& read{e};
41  BOOST_CHECK_EQUAL(read.value().x, 45);
42  BOOST_CHECK_EQUAL((*read).x, 45);
43  BOOST_CHECK_EQUAL(read->x, 45);
44 }
45 
46 BOOST_AUTO_TEST_CASE(expected_value_rvalue)
47 {
48  Expected<std::unique_ptr<int>, int> no_copy{std::make_unique<int>(5)};
49  const auto moved{std::move(no_copy).value()};
50  BOOST_CHECK_EQUAL(*moved, 5);
51 }
52 
53 BOOST_AUTO_TEST_CASE(expected_deref_rvalue)
54 {
55  Expected<std::unique_ptr<int>, int> no_copy{std::make_unique<int>(5)};
56  const auto moved{*std::move(no_copy)};
57  BOOST_CHECK_EQUAL(*moved, 5);
58 }
59 
60 BOOST_AUTO_TEST_CASE(expected_value_or)
61 {
62  Expected<std::unique_ptr<int>, int> no_copy{std::make_unique<int>(1)};
63  const int one{*std::move(no_copy).value_or(std::make_unique<int>(2))};
64  BOOST_CHECK_EQUAL(one, 1);
65 
66  const Expected<std::string, int> const_val{Unexpected{-1}};
67  BOOST_CHECK_EQUAL(const_val.value_or("fallback"), "fallback");
68 }
69 
70 BOOST_AUTO_TEST_CASE(expected_value_throws)
71 {
72  const Expected<int, std::string> e{Unexpected{"fail"}};
74 
75  const Expected<void, std::string> void_e{Unexpected{"fail"}};
76  BOOST_CHECK_THROW(void_e.value(), BadExpectedAccess);
77 }
78 
79 BOOST_AUTO_TEST_CASE(expected_error)
80 {
82  BOOST_CHECK(e.has_value());
83  [&]() -> void { return e.value(); }(); // check value returns void and does not throw
84  [&]() -> void { return *e; }();
85 
86  e = Unexpected{"fail"};
87  BOOST_CHECK(!e.has_value());
88  BOOST_CHECK(!static_cast<bool>(e));
89  BOOST_CHECK_EQUAL(e.error(), "fail");
90 
91  // modify error
92  e.error() += "1";
93 
94  const auto& read{e};
95  BOOST_CHECK_EQUAL(read.error(), "fail1");
96 }
97 
98 BOOST_AUTO_TEST_CASE(expected_error_rvalue)
99 {
100  {
101  Expected<int, std::unique_ptr<int>> nocopy_err{Unexpected{std::make_unique<int>(7)}};
102  const auto moved{std::move(nocopy_err).error()};
103  BOOST_CHECK_EQUAL(*moved, 7);
104  }
105  {
106  Expected<void, std::unique_ptr<int>> void_nocopy_err{Unexpected{std::make_unique<int>(9)}};
107  const auto moved{std::move(void_nocopy_err).error()};
108  BOOST_CHECK_EQUAL(*moved, 9);
109  }
110 }
111 
112 BOOST_AUTO_TEST_CASE(unexpected_error_accessors)
113 {
114  Unexpected u{std::make_unique<int>(-1)};
115  BOOST_CHECK_EQUAL(*u.error(), -1);
116 
117  *u.error() -= 1;
118  const auto& read{u};
119  BOOST_CHECK_EQUAL(*read.error(), -2);
120 
121  const auto moved{std::move(u).error()};
122  BOOST_CHECK_EQUAL(*moved, -2);
123 }
124 
125 BOOST_AUTO_TEST_CASE(expected_swap)
126 {
127  Expected<const char*, std::unique_ptr<int>> a{Unexpected{std::make_unique<int>(-1)}};
129  a.swap(b);
130  BOOST_CHECK_EQUAL(a.value(), "good");
131  BOOST_CHECK_EQUAL(*b.error(), -1);
132 }
133 
#define BOOST_CHECK_THROW(stmt, excMatch)
Definition: object.cpp:18
constexpr const T & value() const &LIFETIMEBOUND
Definition: expected.h:60
BOOST_AUTO_TEST_CASE(expected_value)
The util::Unexpected class represents an unexpected value stored in util::Expected.
Definition: expected.h:21
BOOST_AUTO_TEST_SUITE_END()
constexpr const E & error() const &noexcept LIFETIMEBOUND
Definition: expected.h:26
The util::Expected class provides a standard way for low-level functions to return either error value...
Definition: expected.h:44
#define BOOST_CHECK_EQUAL(v1, v2)
Definition: object.cpp:17
constexpr void swap(Expected &other) noexcept
Definition: expected.h:91
T value_or(U &&default_value) const &
Definition: expected.h:77
#define BOOST_CHECK(expr)
Definition: object.cpp:16