rippled
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 <ripple/basics/Expected.h>
21 #include <ripple/beast/unit_test.h>
22 #include <ripple/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 
29 namespace ripple {
30 namespace test {
31 
32 struct Expected_test : beast::unit_test::suite
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 error construction from rvalue.
88  {
89  auto const expected = []() -> Expected<std::string, TER> {
90  return Unexpected(telLOCAL_ERROR);
91  }();
92  BEAST_EXPECT(!expected);
93  BEAST_EXPECT(!expected.has_value());
94  BEAST_EXPECT(expected.error() == telLOCAL_ERROR);
95 
96  bool throwOccurred = false;
97  try
98  {
99  // There's no result, so should throw.
100  [[maybe_unused]] std::string const s = *expected;
101  }
102  catch (std::runtime_error const& e)
103  {
104  BEAST_EXPECT(e.what() == std::string("bad expected access"));
105  throwOccurred = true;
106  }
107  BEAST_EXPECT(throwOccurred);
108  }
109  // Test error construction from lvalue.
110  {
111  auto const err(telLOCAL_ERROR);
112  auto expected = [&err]() -> Expected<std::string, TER> {
113  return Unexpected(err);
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::size_t const s = expected->size();
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 const char*.
133  {
134  auto const expected = []() -> Expected<int, char const*> {
135  return Unexpected("Not what is expected!");
136  }();
137  BEAST_EXPECT(!expected);
138  BEAST_EXPECT(!expected.has_value());
139  BEAST_EXPECT(
140  expected.error() == std::string("Not what is expected!"));
141  }
142  // Test error construction of string from const char*.
143  {
144  auto expected = []() -> Expected<int, std::string> {
145  return Unexpected("Not what is expected!");
146  }();
147  BEAST_EXPECT(!expected);
148  BEAST_EXPECT(!expected.has_value());
149  BEAST_EXPECT(expected.error() == "Not what is expected!");
150  std::string const s(std::move(expected.error()));
151  BEAST_EXPECT(s == "Not what is expected!");
152  }
153  // Test non-error const construction of Expected<void, T>.
154  {
155  auto const expected = []() -> Expected<void, std::string> {
156  return {};
157  }();
158  BEAST_EXPECT(expected);
159  bool throwOccurred = false;
160  try
161  {
162  // There's no error, so should throw.
163  [[maybe_unused]] std::size_t const s = expected.error().size();
164  }
165  catch (std::runtime_error const& e)
166  {
167  BEAST_EXPECT(e.what() == std::string("bad expected access"));
168  throwOccurred = true;
169  }
170  BEAST_EXPECT(throwOccurred);
171  }
172  // Test non-error non-const construction of Expected<void, T>.
173  {
174  auto expected = []() -> Expected<void, std::string> {
175  return {};
176  }();
177  BEAST_EXPECT(expected);
178  bool throwOccurred = false;
179  try
180  {
181  // There's no error, so should throw.
182  [[maybe_unused]] std::size_t const s = expected.error().size();
183  }
184  catch (std::runtime_error const& e)
185  {
186  BEAST_EXPECT(e.what() == std::string("bad expected access"));
187  throwOccurred = true;
188  }
189  BEAST_EXPECT(throwOccurred);
190  }
191  // Test error const construction of Expected<void, T>.
192  {
193  auto const 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  }
199  // Test error non-const construction of Expected<void, T>.
200  {
201  auto expected = []() -> Expected<void, std::string> {
202  return Unexpected("Not what is expected!");
203  }();
204  BEAST_EXPECT(!expected);
205  BEAST_EXPECT(expected.error() == "Not what is expected!");
206  std::string const s(std::move(expected.error()));
207  BEAST_EXPECT(s == "Not what is expected!");
208  }
209  // Test a case that previously unintentionally returned an array.
210 #if BOOST_VERSION >= 107500
211  {
212  auto expected = []() -> Expected<boost::json::value, std::string> {
213  return boost::json::object{{"oops", "me array now"}};
214  }();
215  BEAST_EXPECT(expected);
216  BEAST_EXPECT(!expected.value().is_array());
217  }
218 #endif // BOOST_VERSION
219  }
220 };
221 
222 BEAST_DEFINE_TESTSUITE(Expected, ripple_basics, ripple);
223 
224 } // namespace test
225 } // namespace ripple
std::string
STL class.
ripple::telLOCAL_ERROR
@ telLOCAL_ERROR
Definition: TER.h:51
ripple::Unexpected
Unexpected(E(&)[N]) -> Unexpected< E const * >
ripple::test::Expected_test::run
void run() override
Definition: Expected_test.cpp:35
ripple::Expected
Definition: Expected.h:132
ripple::TERSubset< CanCvtToTER >
array
cstdint
std::runtime_error
STL class.
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::test::Expected_test
Definition: Expected_test.cpp:32
std::size_t
std::runtime_error::what
T what(T... args)
ripple::test::BEAST_DEFINE_TESTSUITE
BEAST_DEFINE_TESTSUITE(DeliverMin, app, ripple)