rippled
Loading...
Searching...
No Matches
Expected_test.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github0.com/ripple/rippled
4 Copyright (c) 2012-2016 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpl/basics/Expected.h>
21#include <xrpl/beast/unit_test.h>
22#include <xrpl/protocol/TER.h>
23
24#if BOOST_VERSION >= 107500
25#include <boost/json.hpp> // Not part of boost before version 1.75
26#endif // BOOST_VERSION
27
28#include <array>
29#include <cstdint>
30
31namespace ripple {
32namespace test {
33
35{
36 void
37 run() override
38 {
39 // Test non-error const construction.
40 {
41 auto const expected = []() -> Expected<std::string, TER> {
42 return "Valid value";
43 }();
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
50 bool throwOccurred = false;
51 try
52 {
53 // There's no error, so should throw.
54 [[maybe_unused]] TER const t = expected.error();
55 }
56 catch (std::runtime_error const& e)
57 {
58 BEAST_EXPECT(e.what() == std::string("bad expected access"));
59 throwOccurred = true;
60 }
61 BEAST_EXPECT(throwOccurred);
62 }
63 // Test non-error non-const construction.
64 {
65 auto expected = []() -> Expected<std::string, TER> {
66 return "Valid value";
67 }();
68 BEAST_EXPECT(expected);
69 BEAST_EXPECT(expected.has_value());
70 BEAST_EXPECT(expected.value() == "Valid value");
71 BEAST_EXPECT(*expected == "Valid value");
72 BEAST_EXPECT(expected->at(0) == 'V');
73 std::string mv = std::move(*expected);
74 BEAST_EXPECT(mv == "Valid value");
75
76 bool throwOccurred = false;
77 try
78 {
79 // There's no error, so should throw.
80 [[maybe_unused]] TER const t = expected.error();
81 }
82 catch (std::runtime_error const& e)
83 {
84 BEAST_EXPECT(e.what() == std::string("bad expected access"));
85 throwOccurred = true;
86 }
87 BEAST_EXPECT(throwOccurred);
88 }
89 // Test non-error overlapping type construction.
90 {
91 auto expected = []() -> Expected<std::uint32_t, std::uint16_t> {
92 return 1;
93 }();
94 BEAST_EXPECT(expected);
95 BEAST_EXPECT(expected.has_value());
96 BEAST_EXPECT(expected.value() == 1);
97 BEAST_EXPECT(*expected == 1);
98
99 bool throwOccurred = false;
100 try
101 {
102 // There's no error, so should throw.
103 [[maybe_unused]] std::uint16_t const t = expected.error();
104 }
105 catch (std::runtime_error const& e)
106 {
107 BEAST_EXPECT(e.what() == std::string("bad expected access"));
108 throwOccurred = true;
109 }
110 BEAST_EXPECT(throwOccurred);
111 }
112 // Test error construction from rvalue.
113 {
114 auto const expected = []() -> Expected<std::string, TER> {
116 }();
117 BEAST_EXPECT(!expected);
118 BEAST_EXPECT(!expected.has_value());
119 BEAST_EXPECT(expected.error() == telLOCAL_ERROR);
120
121 bool throwOccurred = false;
122 try
123 {
124 // There's no result, so should throw.
125 [[maybe_unused]] std::string const s = *expected;
126 }
127 catch (std::runtime_error const& e)
128 {
129 BEAST_EXPECT(e.what() == std::string("bad expected access"));
130 throwOccurred = true;
131 }
132 BEAST_EXPECT(throwOccurred);
133 }
134 // Test error construction from lvalue.
135 {
136 auto const err(telLOCAL_ERROR);
137 auto expected = [&err]() -> Expected<std::string, TER> {
138 return Unexpected(err);
139 }();
140 BEAST_EXPECT(!expected);
141 BEAST_EXPECT(!expected.has_value());
142 BEAST_EXPECT(expected.error() == telLOCAL_ERROR);
143
144 bool throwOccurred = false;
145 try
146 {
147 // There's no result, so should throw.
148 [[maybe_unused]] std::size_t const s = expected->size();
149 }
150 catch (std::runtime_error const& e)
151 {
152 BEAST_EXPECT(e.what() == std::string("bad expected access"));
153 throwOccurred = true;
154 }
155 BEAST_EXPECT(throwOccurred);
156 }
157 // Test error construction from const char*.
158 {
159 auto const expected = []() -> Expected<int, char const*> {
160 return Unexpected("Not what is expected!");
161 }();
162 BEAST_EXPECT(!expected);
163 BEAST_EXPECT(!expected.has_value());
164 BEAST_EXPECT(
165 expected.error() == std::string("Not what is expected!"));
166 }
167 // Test error construction of string from const char*.
168 {
169 auto expected = []() -> Expected<int, std::string> {
170 return Unexpected("Not what is expected!");
171 }();
172 BEAST_EXPECT(!expected);
173 BEAST_EXPECT(!expected.has_value());
174 BEAST_EXPECT(expected.error() == "Not what is expected!");
175 std::string const s(std::move(expected.error()));
176 BEAST_EXPECT(s == "Not what is expected!");
177 }
178 // Test non-error const construction of Expected<void, T>.
179 {
180 auto const expected = []() -> Expected<void, std::string> {
181 return {};
182 }();
183 BEAST_EXPECT(expected);
184 bool throwOccurred = false;
185 try
186 {
187 // There's no error, so should throw.
188 [[maybe_unused]] std::size_t const s = expected.error().size();
189 }
190 catch (std::runtime_error const& e)
191 {
192 BEAST_EXPECT(e.what() == std::string("bad expected access"));
193 throwOccurred = true;
194 }
195 BEAST_EXPECT(throwOccurred);
196 }
197 // Test non-error non-const construction of Expected<void, T>.
198 {
199 auto expected = []() -> Expected<void, std::string> {
200 return {};
201 }();
202 BEAST_EXPECT(expected);
203 bool throwOccurred = false;
204 try
205 {
206 // There's no error, so should throw.
207 [[maybe_unused]] std::size_t const s = expected.error().size();
208 }
209 catch (std::runtime_error const& e)
210 {
211 BEAST_EXPECT(e.what() == std::string("bad expected access"));
212 throwOccurred = true;
213 }
214 BEAST_EXPECT(throwOccurred);
215 }
216 // Test error const construction of Expected<void, T>.
217 {
218 auto const expected = []() -> Expected<void, std::string> {
219 return Unexpected("Not what is expected!");
220 }();
221 BEAST_EXPECT(!expected);
222 BEAST_EXPECT(expected.error() == "Not what is expected!");
223 }
224 // Test error non-const construction of Expected<void, T>.
225 {
226 auto expected = []() -> Expected<void, std::string> {
227 return Unexpected("Not what is expected!");
228 }();
229 BEAST_EXPECT(!expected);
230 BEAST_EXPECT(expected.error() == "Not what is expected!");
231 std::string const s(std::move(expected.error()));
232 BEAST_EXPECT(s == "Not what is expected!");
233 }
234 // Test a case that previously unintentionally returned an array.
235#if BOOST_VERSION >= 107500
236 {
237 auto expected = []() -> Expected<boost::json::value, std::string> {
238 return boost::json::object{{"oops", "me array now"}};
239 }();
240 BEAST_EXPECT(expected);
241 BEAST_EXPECT(!expected.value().is_array());
242 }
243#endif // BOOST_VERSION
244 }
245};
246
247BEAST_DEFINE_TESTSUITE(Expected, ripple_basics, ripple);
248
249} // namespace test
250} // namespace ripple
A testsuite class.
Definition: suite.h:55
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
@ telLOCAL_ERROR
Definition: TER.h:52
void run() override
Runs the suite.
T what(T... args)