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