Analysis Software
Documentation for sPHENIX simulation software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ResultTests.cpp
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file ResultTests.cpp
1 // This file is part of the Acts project.
2 //
3 // Copyright (C) 2019 CERN for the benefit of the Acts project
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 
9 #include <boost/test/unit_test.hpp>
10 
12 
13 #include <stdexcept>
14 #include <string>
15 #include <system_error>
16 #include <type_traits>
17 #include <utility>
18 
19 using namespace std::string_literals;
20 
21 namespace {
22 
23 enum class MyError {
24  Failure = 1,
25  SomethingElse,
26 };
27 
28 std::error_code make_error_code(MyError e) {
29  return {static_cast<int>(e), std::generic_category()};
30 }
31 
32 } // namespace
33 
34 namespace std {
35 // register with STL
36 template <>
37 struct is_error_code_enum<MyError> : std::true_type {};
38 } // namespace std
39 
40 namespace Acts {
41 
42 namespace Test {
43 
44 BOOST_AUTO_TEST_SUITE(Utilities)
45 
46 BOOST_AUTO_TEST_CASE(TestConstruction) {
47  {
48  using Result = Result<int, char>;
49 
50  Result res = Result::success(42);
51  BOOST_CHECK_EQUAL(*res, 42);
52  BOOST_CHECK_EQUAL(res.value(), 42);
53  BOOST_CHECK(res.ok());
54  res = Result::success('e');
55  BOOST_CHECK_EQUAL(*res, 'e');
56  BOOST_CHECK_EQUAL(res.value(), 'e');
57  BOOST_CHECK(res.ok());
58  res = Result::failure(42);
59  BOOST_CHECK(!res.ok());
60  BOOST_CHECK_EQUAL(res.error(), 42);
61  BOOST_CHECK_THROW(res.value(), std::runtime_error);
62  res = Result::failure('e');
63  BOOST_CHECK(!res.ok());
64  BOOST_CHECK_EQUAL(res.error(), 'e');
65  BOOST_CHECK_THROW(res.value(), std::runtime_error);
66  }
67 
68  {
70 
71  Result res1("hallo");
72  BOOST_CHECK(!res1.ok());
73  BOOST_CHECK_EQUAL(res1.error(), "hallo");
74  BOOST_CHECK_THROW(res1.value(), std::runtime_error);
75  res1 = Result::failure("hallo");
76  BOOST_CHECK(!res1.ok());
77  BOOST_CHECK_EQUAL(res1.error(), "hallo");
78  BOOST_CHECK_THROW(res1.value(), std::runtime_error);
79 
80  Result res2(4.5);
81  BOOST_CHECK(res2.ok());
82  BOOST_CHECK(*res2 == 4.5);
83  BOOST_CHECK(res2.value() == 4.5);
84  res2 = Result::success(4.5);
85  BOOST_CHECK(res2.ok());
86  BOOST_CHECK_EQUAL(*res2, 4.5);
87  BOOST_CHECK_EQUAL(res2.value(), 4.5);
88  }
89 }
90 
91 BOOST_AUTO_TEST_CASE(TestErrorCodes) {
92  auto err1 = MyError::Failure;
93 
94  std::error_code ec = err1;
95 
96  {
98 
99  Result res(42.);
100  BOOST_CHECK(res.ok());
101  BOOST_CHECK_EQUAL(*res, 42.);
102 
103  Result res2(err1);
104  BOOST_CHECK(!res2.ok());
105  BOOST_CHECK_EQUAL(res2.error(), err1);
106  BOOST_CHECK_THROW(res2.value(), std::runtime_error);
107  }
108 
109  {
111 
112  Result res(42.);
113  BOOST_CHECK(res.ok());
114  BOOST_CHECK_EQUAL(*res, 42.);
115  BOOST_CHECK_EQUAL(res.value(), 42u);
116  res = 46.;
117  BOOST_CHECK(res.ok());
118  BOOST_CHECK_EQUAL(*res, 46.);
119  BOOST_CHECK_EQUAL(res.value(), 46u);
120 
121  Result res2(ec);
122  BOOST_CHECK(!res2.ok());
123  BOOST_CHECK_EQUAL(res2.error(), ec);
124  BOOST_CHECK_EQUAL(res2.error(), err1);
125 
126  res2 = MyError::SomethingElse;
127  BOOST_CHECK(!res2.ok());
128  BOOST_CHECK_EQUAL(res2.error(), MyError::SomethingElse);
129  BOOST_CHECK(res2.error() != MyError::Failure);
130  }
131 
132  {
134  Result res{0.};
135  BOOST_CHECK(res.ok());
136  BOOST_CHECK_EQUAL(*res, 0.0);
137 
138  res = 1.;
139  BOOST_CHECK(res.ok());
140  BOOST_CHECK_EQUAL(*res, 1.0);
141 
142  Result res2{"blubb"};
143  BOOST_CHECK(!res2.ok());
144  BOOST_CHECK_EQUAL(res2.error(), "blubb");
145  res2 = "sep";
146  BOOST_CHECK(!res2.ok());
147  BOOST_CHECK_EQUAL(res2.error(), "sep");
148  }
149 
150  {
152  Result res{0.};
153  BOOST_CHECK(!res.ok());
154  BOOST_CHECK_EQUAL(res.error(), 0.0);
155 
156  res = "blibb";
157  BOOST_CHECK(res.ok());
158  BOOST_CHECK_EQUAL(res.value(), "blibb");
159 
160  Result res2{"blibb"};
161  BOOST_CHECK(res2.ok());
162  BOOST_CHECK_EQUAL(res2.value(), "blibb");
163 
164  res2 = 0.;
165  BOOST_CHECK(!res2.ok());
166  BOOST_CHECK_EQUAL(res2.error(), 0.0);
167  }
168 
169  {
170  using Result = Result<double, int>;
171  Result res = Result::success(2);
172  BOOST_CHECK(res.ok());
173  BOOST_CHECK_EQUAL(res.value(), 2.0);
174 
175  res = Result::failure(3);
176  BOOST_CHECK(!res.ok());
177  BOOST_CHECK_EQUAL(res.error(), 3);
178 
179  Result res2 = Result::failure(2);
180  BOOST_CHECK(!res2.ok());
181  BOOST_CHECK_EQUAL(res2.error(), 2);
182 
183  res2 = Result::success(3.3);
184  BOOST_CHECK(res2.ok());
185  BOOST_CHECK_EQUAL(res2.value(), 3.3);
186  }
187 
188  {
189  using Result = Result<double>;
190 
191  Result res(42.);
192  BOOST_CHECK(res.ok());
193  BOOST_CHECK_EQUAL(*res, 42.);
194  BOOST_CHECK_EQUAL(res.value(), 42u);
195  res = 46.;
196  BOOST_CHECK(res.ok());
197  BOOST_CHECK_EQUAL(*res, 46.);
198  BOOST_CHECK_EQUAL(res.value(), 46u);
199 
200  Result res2(ec);
201  BOOST_CHECK(!res2.ok());
202  BOOST_CHECK_EQUAL(res2.error(), ec);
203  BOOST_CHECK_EQUAL(res2.error(), err1);
204 
205  res2 = MyError::SomethingElse;
206  BOOST_CHECK(!res2.ok());
207  BOOST_CHECK_EQUAL(res2.error(), MyError::SomethingElse);
208  BOOST_CHECK(res2.error() != MyError::Failure);
209  }
210 
211  {
212  using Result = Result<std::string>;
213 
214  Result res("hallo");
215 
216  BOOST_CHECK(res.ok());
217  BOOST_CHECK_EQUAL(*res, "hallo");
218  BOOST_CHECK_EQUAL(res.value(), "hallo");
219 
220  res = "something else";
221  BOOST_CHECK(res.ok());
222  BOOST_CHECK_EQUAL(*res, "something else");
223  BOOST_CHECK_EQUAL(res.value(), "something else");
224 
225  res = MyError::SomethingElse;
226  BOOST_CHECK(!res.ok());
227  BOOST_CHECK_EQUAL(res.error(), MyError::SomethingElse);
228  BOOST_CHECK(res.error() != MyError::Failure);
229  }
230 
231  {
233 
234  Result res{"hallo"};
235  BOOST_CHECK(res.ok());
236  BOOST_CHECK_EQUAL(res.value(), "hallo");
237 
238  Result res2{4};
239  BOOST_CHECK(!res2.ok());
240  BOOST_CHECK_EQUAL(res2.error(), 4);
241  }
242 }
243 
244 struct NoCopy {
245  NoCopy(int i) : num(i) {}
246  NoCopy(const NoCopy&) = delete;
247  NoCopy& operator=(const NoCopy&) = delete;
248  NoCopy(NoCopy&&) = default;
249  NoCopy& operator=(NoCopy&&) = default;
250 
251  int num;
252 };
253 
254 Result<NoCopy> make_nocopy(int i, bool v = true) {
255  if (!v) {
256  return MyError::Failure;
257  }
258  return i;
259 }
260 
261 BOOST_AUTO_TEST_CASE(CopyBehaviour) {
262  using Result = Result<NoCopy>;
263 
264  NoCopy n(5);
265  Result res = std::move(n);
266  BOOST_CHECK(res.ok());
267  BOOST_CHECK_EQUAL((*res).num, res.value().num);
268 
269  res = make_nocopy(3);
270  BOOST_CHECK(res.ok());
271  BOOST_CHECK_EQUAL((*res).num, res.value().num);
272  BOOST_CHECK_EQUAL((*res).num, 3);
273 
274  res = NoCopy(-4);
275  BOOST_CHECK(res.ok());
276  BOOST_CHECK_EQUAL((*res).num, res.value().num);
277  BOOST_CHECK_EQUAL((*res).num, -4.);
278 
279  NoCopy n2 = make_nocopy(7).value();
280  BOOST_CHECK_EQUAL(n2.num, 7);
281  BOOST_REQUIRE_THROW(make_nocopy(6, false).value();, std::runtime_error);
282 
283  Result n4r = make_nocopy(8);
284  BOOST_CHECK(n4r.ok());
285  BOOST_CHECK_EQUAL((*n4r).num, 8);
286  NoCopy n4 = std::move(n4r.value());
287  BOOST_CHECK_EQUAL(n4.num, 8);
288 }
289 
291  (void)b;
292  if (b > 5) {
293  return MyError::SomethingElse;
294  }
295  return {};
296 }
297 
298 BOOST_AUTO_TEST_CASE(VoidResult) {
299  using Result = Result<void>;
300 
301  Result res;
302  BOOST_CHECK(res.ok());
303 
304  Result res2 = Result::success();
305  BOOST_CHECK(res2.ok());
306 
307  res = MyError::Failure;
308  BOOST_CHECK(!res.ok());
309  BOOST_CHECK_EQUAL(res.error(), MyError::Failure);
310 
311  Result res3 = Result::failure(MyError::SomethingElse);
312  BOOST_CHECK(!res3.ok());
313  BOOST_CHECK_EQUAL(res3.error(), MyError::SomethingElse);
314 
315  Result res4 = void_res_func(4);
316  BOOST_CHECK(res4.ok());
317 
318  Result res5 = void_res_func(42);
319  BOOST_CHECK(!res5.ok());
320  BOOST_CHECK_EQUAL(res5.error(), MyError::SomethingElse);
321 }
322 
323 BOOST_AUTO_TEST_CASE(BoolResult) {
324  using Result = Result<bool>;
325 
326  Result res = Result::success(false);
327  BOOST_CHECK(res.ok());
328  BOOST_CHECK_EQUAL(*res, false);
329 
330  res = Result::success(true);
331  BOOST_CHECK(res.ok());
332  BOOST_CHECK_EQUAL(*res, true);
333 
334  res = Result::failure(MyError::Failure);
335  BOOST_CHECK(!res.ok());
336  BOOST_CHECK_EQUAL(res.error(), MyError::Failure);
337 }
338 
339 BOOST_AUTO_TEST_SUITE_END()
340 } // namespace Test
341 } // namespace Acts