rippled
Loading...
Searching...
No Matches
Expected_test.cpp
1#include <xrpl/basics/Expected.h>
2#include <xrpl/beast/unit_test.h>
3#include <xrpl/protocol/TER.h>
4
5#if BOOST_VERSION >= 107500
6#include <boost/json.hpp> // Not part of boost before version 1.75
7#endif // BOOST_VERSION
8#include <array>
9#include <cstdint>
10
11namespace ripple {
12namespace test {
13
15{
16 void
17 run() override
18 {
19 // Test non-error const construction.
20 {
21 auto const expected = []() -> Expected<std::string, TER> {
22 return "Valid value";
23 }();
24 BEAST_EXPECT(expected);
25 BEAST_EXPECT(expected.has_value());
26 BEAST_EXPECT(expected.value() == "Valid value");
27 BEAST_EXPECT(*expected == "Valid value");
28 BEAST_EXPECT(expected->at(0) == 'V');
29
30 bool throwOccurred = false;
31 try
32 {
33 // There's no error, so should throw.
34 [[maybe_unused]] TER const t = expected.error();
35 }
36 catch (std::runtime_error const& e)
37 {
38 BEAST_EXPECT(e.what() == std::string("bad expected access"));
39 throwOccurred = true;
40 }
41 BEAST_EXPECT(throwOccurred);
42 }
43 // Test non-error non-const construction.
44 {
45 auto expected = []() -> Expected<std::string, TER> {
46 return "Valid value";
47 }();
48 BEAST_EXPECT(expected);
49 BEAST_EXPECT(expected.has_value());
50 BEAST_EXPECT(expected.value() == "Valid value");
51 BEAST_EXPECT(*expected == "Valid value");
52 BEAST_EXPECT(expected->at(0) == 'V');
53 std::string mv = std::move(*expected);
54 BEAST_EXPECT(mv == "Valid value");
55
56 bool throwOccurred = false;
57 try
58 {
59 // There's no error, so should throw.
60 [[maybe_unused]] TER const t = expected.error();
61 }
62 catch (std::runtime_error const& e)
63 {
64 BEAST_EXPECT(e.what() == std::string("bad expected access"));
65 throwOccurred = true;
66 }
67 BEAST_EXPECT(throwOccurred);
68 }
69 // Test non-error overlapping type construction.
70 {
71 auto expected = []() -> Expected<std::uint32_t, std::uint16_t> {
72 return 1;
73 }();
74 BEAST_EXPECT(expected);
75 BEAST_EXPECT(expected.has_value());
76 BEAST_EXPECT(expected.value() == 1);
77 BEAST_EXPECT(*expected == 1);
78
79 bool throwOccurred = false;
80 try
81 {
82 // There's no error, so should throw.
83 [[maybe_unused]] std::uint16_t const t = expected.error();
84 }
85 catch (std::runtime_error const& e)
86 {
87 BEAST_EXPECT(e.what() == std::string("bad expected access"));
88 throwOccurred = true;
89 }
90 BEAST_EXPECT(throwOccurred);
91 }
92 // Test error construction from rvalue.
93 {
94 auto const expected = []() -> Expected<std::string, TER> {
96 }();
97 BEAST_EXPECT(!expected);
98 BEAST_EXPECT(!expected.has_value());
99 BEAST_EXPECT(expected.error() == telLOCAL_ERROR);
100
101 bool throwOccurred = false;
102 try
103 {
104 // There's no result, so should throw.
105 [[maybe_unused]] std::string const s = *expected;
106 }
107 catch (std::runtime_error const& e)
108 {
109 BEAST_EXPECT(e.what() == std::string("bad expected access"));
110 throwOccurred = true;
111 }
112 BEAST_EXPECT(throwOccurred);
113 }
114 // Test error construction from lvalue.
115 {
116 auto const err(telLOCAL_ERROR);
117 auto expected = [&err]() -> Expected<std::string, TER> {
118 return Unexpected(err);
119 }();
120 BEAST_EXPECT(!expected);
121 BEAST_EXPECT(!expected.has_value());
122 BEAST_EXPECT(expected.error() == telLOCAL_ERROR);
123
124 bool throwOccurred = false;
125 try
126 {
127 // There's no result, so should throw.
128 [[maybe_unused]] std::size_t const s = expected->size();
129 }
130 catch (std::runtime_error const& e)
131 {
132 BEAST_EXPECT(e.what() == std::string("bad expected access"));
133 throwOccurred = true;
134 }
135 BEAST_EXPECT(throwOccurred);
136 }
137 // Test error construction from const char*.
138 {
139 auto const expected = []() -> Expected<int, char const*> {
140 return Unexpected("Not what is expected!");
141 }();
142 BEAST_EXPECT(!expected);
143 BEAST_EXPECT(!expected.has_value());
144 BEAST_EXPECT(
145 expected.error() == std::string("Not what is expected!"));
146 }
147 // Test error construction of string from const char*.
148 {
149 auto expected = []() -> Expected<int, std::string> {
150 return Unexpected("Not what is expected!");
151 }();
152 BEAST_EXPECT(!expected);
153 BEAST_EXPECT(!expected.has_value());
154 BEAST_EXPECT(expected.error() == "Not what is expected!");
155 std::string const s(std::move(expected.error()));
156 BEAST_EXPECT(s == "Not what is expected!");
157 }
158 // Test non-error const construction of Expected<void, T>.
159 {
160 auto const expected = []() -> Expected<void, std::string> {
161 return {};
162 }();
163 BEAST_EXPECT(expected);
164 bool throwOccurred = false;
165 try
166 {
167 // There's no error, so should throw.
168 [[maybe_unused]] std::size_t const s = expected.error().size();
169 }
170 catch (std::runtime_error const& e)
171 {
172 BEAST_EXPECT(e.what() == std::string("bad expected access"));
173 throwOccurred = true;
174 }
175 BEAST_EXPECT(throwOccurred);
176 }
177 // Test non-error non-const construction of Expected<void, T>.
178 {
179 auto expected = []() -> Expected<void, std::string> {
180 return {};
181 }();
182 BEAST_EXPECT(expected);
183 bool throwOccurred = false;
184 try
185 {
186 // There's no error, so should throw.
187 [[maybe_unused]] std::size_t const s = expected.error().size();
188 }
189 catch (std::runtime_error const& e)
190 {
191 BEAST_EXPECT(e.what() == std::string("bad expected access"));
192 throwOccurred = true;
193 }
194 BEAST_EXPECT(throwOccurred);
195 }
196 // Test error const construction of Expected<void, T>.
197 {
198 auto const expected = []() -> Expected<void, std::string> {
199 return Unexpected("Not what is expected!");
200 }();
201 BEAST_EXPECT(!expected);
202 BEAST_EXPECT(expected.error() == "Not what is expected!");
203 }
204 // Test error non-const construction of Expected<void, T>.
205 {
206 auto expected = []() -> Expected<void, std::string> {
207 return Unexpected("Not what is expected!");
208 }();
209 BEAST_EXPECT(!expected);
210 BEAST_EXPECT(expected.error() == "Not what is expected!");
211 std::string const s(std::move(expected.error()));
212 BEAST_EXPECT(s == "Not what is expected!");
213 }
214 // Test a case that previously unintentionally returned an array.
215#if BOOST_VERSION >= 107500
216 {
217 auto expected = []() -> Expected<boost::json::value, std::string> {
218 return boost::json::object{{"oops", "me array now"}};
219 }();
220 BEAST_EXPECT(expected);
221 BEAST_EXPECT(!expected.value().is_array());
222 }
223#endif // BOOST_VERSION
224 }
225};
226
227BEAST_DEFINE_TESTSUITE(Expected, basics, ripple);
228
229} // namespace test
230} // namespace ripple
A testsuite class.
Definition suite.h:52
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
@ telLOCAL_ERROR
Definition TER.h:33
void run() override
Runs the suite.
T what(T... args)