Branch data Line data Source code
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 : :
5 : : #include <test/util/setup_common.h>
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 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(expected_value)
+ - + - -
+ + - + -
+ - + - +
- - + + -
+ - + - +
- + - - +
+ - + - +
- + - + -
- + + - +
- + - + -
+ - - + +
- ]
20 : : {
21 : 1 : struct Obj {
22 : : int x;
23 : : };
24 : 1 : Expected<Obj, int> e{};
25 [ + - ]: 1 : BOOST_CHECK_EQUAL(e.value().x, 0);
26 : :
27 : 1 : e = Obj{42};
28 : :
29 [ + - ]: 2 : BOOST_CHECK(e.has_value());
30 [ + - ]: 2 : BOOST_CHECK(static_cast<bool>(e));
31 [ + - ]: 1 : BOOST_CHECK_EQUAL(e.value().x, 42);
32 [ + - ]: 1 : BOOST_CHECK_EQUAL((*e).x, 42);
33 [ + - ]: 1 : BOOST_CHECK_EQUAL(e->x, 42);
34 : :
35 : : // modify value
36 : 1 : e.value().x += 1;
37 : 1 : (*e).x += 1;
38 : 1 : e->x += 1;
39 : :
40 : 1 : const auto& read{e};
41 [ + - ]: 1 : BOOST_CHECK_EQUAL(read.value().x, 45);
42 [ + - ]: 1 : BOOST_CHECK_EQUAL((*read).x, 45);
43 [ + - ]: 1 : BOOST_CHECK_EQUAL(read->x, 45);
44 : 1 : }
45 : :
46 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(expected_value_rvalue)
+ - + - -
+ + - + -
+ - + - +
- - + + -
+ - + - +
- + - - +
+ - + - +
- + - + -
- + + - +
- + - + -
+ - - + +
- ]
47 : : {
48 : 1 : Expected<std::unique_ptr<int>, int> no_copy{std::make_unique<int>(5)};
49 [ + - + - ]: 1 : const auto moved{std::move(no_copy).value()};
50 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(*moved, 5);
51 : 1 : }
52 : :
53 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(expected_deref_rvalue)
+ - + - -
+ + - + -
+ - + - +
- - + + -
+ - + - +
- + - - +
+ - + - +
- + - + -
- + + - +
- + - + -
+ - - + +
- ]
54 : : {
55 : 1 : Expected<std::unique_ptr<int>, int> no_copy{std::make_unique<int>(5)};
56 [ + - ]: 1 : const auto moved{*std::move(no_copy)};
57 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(*moved, 5);
58 : 1 : }
59 : :
60 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(expected_value_or)
+ - + - -
+ + - + -
+ - + - +
- - + + -
+ - + - +
- + - - +
+ - + - +
- + - + -
- + + - +
- + - + -
+ - - + +
- ]
61 : : {
62 : 1 : Expected<std::unique_ptr<int>, int> no_copy{std::make_unique<int>(1)};
63 [ + - + - ]: 1 : const int one{*std::move(no_copy).value_or(std::make_unique<int>(2))};
64 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(one, 1);
65 : :
66 : 1 : const Expected<std::string, int> const_val{Unexpected{-1}};
67 [ + - + - : 1 : BOOST_CHECK_EQUAL(const_val.value_or("fallback"), "fallback");
+ - ]
68 : 1 : }
69 : :
70 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(expected_value_throws)
+ - + - -
+ + - + -
+ - + - +
- - + + -
+ - + - +
- + - - +
+ - + - +
- + - + -
- + + - +
- + - + -
+ - - + +
- ]
71 : : {
72 : 1 : const Expected<int, std::string> e{Unexpected{"fail"}};
73 [ + - - + : 2 : BOOST_CHECK_THROW(e.value(), BadExpectedAccess);
- - - - -
+ + - +
- ]
74 : :
75 [ + - ]: 1 : const Expected<void, std::string> void_e{Unexpected{"fail"}};
76 [ + - - + : 2 : BOOST_CHECK_THROW(void_e.value(), BadExpectedAccess);
- - - - -
+ + - +
- ]
77 : 1 : }
78 : :
79 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(expected_error)
+ - + - -
+ + - + -
+ - + - +
- - + + -
+ - + - +
- + - - +
+ - + - +
- + - + -
- + + - +
- + - + -
+ - - + +
- ]
80 : : {
81 : 1 : Expected<void, std::string> e{};
82 [ + - + - : 2 : BOOST_CHECK(e.has_value());
+ - ]
83 [ + - ]: 1 : [&]() -> void { return e.value(); }(); // check value returns void and does not throw
84 : 1 : [&]() -> void { return *e; }();
85 : :
86 [ + - ]: 1 : e = Unexpected{"fail"};
87 [ + - + - : 2 : BOOST_CHECK(!e.has_value());
+ - ]
88 [ + - + - : 2 : BOOST_CHECK(!static_cast<bool>(e));
+ - ]
89 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(e.error(), "fail");
90 : :
91 : : // modify error
92 [ + - ]: 1 : e.error() += "1";
93 : :
94 : 1 : const auto& read{e};
95 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(read.error(), "fail1");
96 : 1 : }
97 : :
98 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(expected_error_rvalue)
+ - + - -
+ + - + -
+ - + - +
- - + + -
+ - + - +
- + - - +
+ - + - +
- + - + -
- + + - +
- + - + -
+ - - + +
- ]
99 : : {
100 : 1 : {
101 : 1 : Expected<int, std::unique_ptr<int>> nocopy_err{Unexpected{std::make_unique<int>(7)}};
102 [ + - ]: 1 : const auto moved{std::move(nocopy_err).error()};
103 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(*moved, 7);
104 : 1 : }
105 : 1 : {
106 : 1 : Expected<void, std::unique_ptr<int>> void_nocopy_err{Unexpected{std::make_unique<int>(9)}};
107 [ + - ]: 1 : const auto moved{std::move(void_nocopy_err).error()};
108 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(*moved, 9);
109 : 1 : }
110 : 1 : }
111 : :
112 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(unexpected_error_accessors)
+ - + - -
+ + - + -
+ - + - +
- - + + -
+ - + - +
- + - - +
+ - + - +
- + - + -
- + + - +
- + - + -
+ - - + +
- ]
113 : : {
114 : 1 : Unexpected u{std::make_unique<int>(-1)};
115 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(*u.error(), -1);
116 : :
117 [ + - ]: 1 : *u.error() -= 1;
118 : 1 : const auto& read{u};
119 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(*read.error(), -2);
120 : :
121 [ + - ]: 1 : const auto moved{std::move(u).error()};
122 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(*moved, -2);
123 : 1 : }
124 : :
125 [ + - + - : 7 : BOOST_AUTO_TEST_CASE(expected_swap)
+ - + - -
+ + - + -
+ - + - +
- - + + -
+ - + - +
- + - - +
+ - + - +
- + - + -
- + + - +
- + - + -
+ - - + +
- ]
126 : : {
127 : 1 : Expected<const char*, std::unique_ptr<int>> a{Unexpected{std::make_unique<int>(-1)}};
128 : 1 : Expected<const char*, std::unique_ptr<int>> b{"good"};
129 : 1 : a.swap(b);
130 [ + - + - : 1 : BOOST_CHECK_EQUAL(a.value(), "good");
+ - ]
131 [ + - + - ]: 1 : BOOST_CHECK_EQUAL(*b.error(), -1);
132 : 1 : }
133 : :
134 : : BOOST_AUTO_TEST_SUITE_END()
|