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