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#include <array>
28#include <cstdint>
29
30namespace ripple {
31namespace test {
32
34{
35 void
36 run() override
37 {
38 // Test non-error const construction.
39 {
40 auto const expected = []() -> Expected<std::string, TER> {
41 return "Valid value";
42 }();
43 BEAST_EXPECT(expected);
44 BEAST_EXPECT(expected.has_value());
45 BEAST_EXPECT(expected.value() == "Valid value");
46 BEAST_EXPECT(*expected == "Valid value");
47 BEAST_EXPECT(expected->at(0) == 'V');
48
49 bool throwOccurred = false;
50 try
51 {
52 // There's no error, so should throw.
53 [[maybe_unused]] TER const t = expected.error();
54 }
55 catch (std::runtime_error const& e)
56 {
57 BEAST_EXPECT(e.what() == std::string("bad expected access"));
58 throwOccurred = true;
59 }
60 BEAST_EXPECT(throwOccurred);
61 }
62 // Test non-error non-const construction.
63 {
64 auto expected = []() -> Expected<std::string, TER> {
65 return "Valid value";
66 }();
67 BEAST_EXPECT(expected);
68 BEAST_EXPECT(expected.has_value());
69 BEAST_EXPECT(expected.value() == "Valid value");
70 BEAST_EXPECT(*expected == "Valid value");
71 BEAST_EXPECT(expected->at(0) == 'V');
72 std::string mv = std::move(*expected);
73 BEAST_EXPECT(mv == "Valid value");
74
75 bool throwOccurred = false;
76 try
77 {
78 // There's no error, so should throw.
79 [[maybe_unused]] TER const t = expected.error();
80 }
81 catch (std::runtime_error const& e)
82 {
83 BEAST_EXPECT(e.what() == std::string("bad expected access"));
84 throwOccurred = true;
85 }
86 BEAST_EXPECT(throwOccurred);
87 }
88 // Test non-error overlapping type construction.
89 {
90 auto expected = []() -> Expected<std::uint32_t, std::uint16_t> {
91 return 1;
92 }();
93 BEAST_EXPECT(expected);
94 BEAST_EXPECT(expected.has_value());
95 BEAST_EXPECT(expected.value() == 1);
96 BEAST_EXPECT(*expected == 1);
97
98 bool throwOccurred = false;
99 try
100 {
101 // There's no error, so should throw.
102 [[maybe_unused]] std::uint16_t const t = expected.error();
103 }
104 catch (std::runtime_error const& e)
105 {
106 BEAST_EXPECT(e.what() == std::string("bad expected access"));
107 throwOccurred = true;
108 }
109 BEAST_EXPECT(throwOccurred);
110 }
111 // Test error construction from rvalue.
112 {
113 auto const expected = []() -> Expected<std::string, TER> {
115 }();
116 BEAST_EXPECT(!expected);
117 BEAST_EXPECT(!expected.has_value());
118 BEAST_EXPECT(expected.error() == telLOCAL_ERROR);
119
120 bool throwOccurred = false;
121 try
122 {
123 // There's no result, so should throw.
124 [[maybe_unused]] std::string const s = *expected;
125 }
126 catch (std::runtime_error const& e)
127 {
128 BEAST_EXPECT(e.what() == std::string("bad expected access"));
129 throwOccurred = true;
130 }
131 BEAST_EXPECT(throwOccurred);
132 }
133 // Test error construction from lvalue.
134 {
135 auto const err(telLOCAL_ERROR);
136 auto expected = [&err]() -> Expected<std::string, TER> {
137 return Unexpected(err);
138 }();
139 BEAST_EXPECT(!expected);
140 BEAST_EXPECT(!expected.has_value());
141 BEAST_EXPECT(expected.error() == telLOCAL_ERROR);
142
143 bool throwOccurred = false;
144 try
145 {
146 // There's no result, so should throw.
147 [[maybe_unused]] std::size_t const s = expected->size();
148 }
149 catch (std::runtime_error const& e)
150 {
151 BEAST_EXPECT(e.what() == std::string("bad expected access"));
152 throwOccurred = true;
153 }
154 BEAST_EXPECT(throwOccurred);
155 }
156 // Test error construction from const char*.
157 {
158 auto const expected = []() -> Expected<int, char const*> {
159 return Unexpected("Not what is expected!");
160 }();
161 BEAST_EXPECT(!expected);
162 BEAST_EXPECT(!expected.has_value());
163 BEAST_EXPECT(
164 expected.error() == std::string("Not what is expected!"));
165 }
166 // Test error construction of string from const char*.
167 {
168 auto expected = []() -> Expected<int, std::string> {
169 return Unexpected("Not what is expected!");
170 }();
171 BEAST_EXPECT(!expected);
172 BEAST_EXPECT(!expected.has_value());
173 BEAST_EXPECT(expected.error() == "Not what is expected!");
174 std::string const s(std::move(expected.error()));
175 BEAST_EXPECT(s == "Not what is expected!");
176 }
177 // Test non-error const construction of Expected<void, T>.
178 {
179 auto const 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 non-error non-const construction of Expected<void, T>.
197 {
198 auto expected = []() -> Expected<void, std::string> {
199 return {};
200 }();
201 BEAST_EXPECT(expected);
202 bool throwOccurred = false;
203 try
204 {
205 // There's no error, so should throw.
206 [[maybe_unused]] std::size_t const s = expected.error().size();
207 }
208 catch (std::runtime_error const& e)
209 {
210 BEAST_EXPECT(e.what() == std::string("bad expected access"));
211 throwOccurred = true;
212 }
213 BEAST_EXPECT(throwOccurred);
214 }
215 // Test error const construction of Expected<void, T>.
216 {
217 auto const expected = []() -> Expected<void, std::string> {
218 return Unexpected("Not what is expected!");
219 }();
220 BEAST_EXPECT(!expected);
221 BEAST_EXPECT(expected.error() == "Not what is expected!");
222 }
223 // Test error non-const construction of Expected<void, T>.
224 {
225 auto expected = []() -> Expected<void, std::string> {
226 return Unexpected("Not what is expected!");
227 }();
228 BEAST_EXPECT(!expected);
229 BEAST_EXPECT(expected.error() == "Not what is expected!");
230 std::string const s(std::move(expected.error()));
231 BEAST_EXPECT(s == "Not what is expected!");
232 }
233 // Test a case that previously unintentionally returned an array.
234#if BOOST_VERSION >= 107500
235 {
236 auto expected = []() -> Expected<boost::json::value, std::string> {
237 return boost::json::object{{"oops", "me array now"}};
238 }();
239 BEAST_EXPECT(expected);
240 BEAST_EXPECT(!expected.value().is_array());
241 }
242#endif // BOOST_VERSION
243 }
244};
245
246BEAST_DEFINE_TESTSUITE(Expected, basics, ripple);
247
248} // namespace test
249} // 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:25
@ telLOCAL_ERROR
Definition TER.h:52
void run() override
Runs the suite.
T what(T... args)