Electroneum
expect.cpp
Go to the documentation of this file.
1 // Copyright (c) 2018, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #include <gtest/gtest.h>
30 
31 #include <boost/algorithm/string/predicate.hpp>
32 #include <boost/utility/string_ref.hpp>
33 #include <string>
34 #include <system_error>
35 #include <type_traits>
36 
37 #include "common/expect.h"
38 
39 namespace
40 {
41  struct move_only;
42  struct throw_construct;
43  struct throw_copies;
44  struct throw_moves;
45 
46  struct move_only
47  {
48  move_only() = default;
49  move_only(move_only const&) = delete;
50  move_only(move_only&&) = default;
51  ~move_only() = default;
52  move_only& operator=(move_only const&) = delete;
53  move_only& operator=(move_only&&) = default;
54  };
55 
56  struct throw_construct
57  {
58  throw_construct() {}
59  throw_construct(int) {}
60  throw_construct(throw_construct const&) = default;
61  throw_construct(throw_construct&&) = default;
62  ~throw_construct() = default;
63  throw_construct& operator=(throw_construct const&) = default;
64  throw_construct& operator=(throw_construct&&) = default;
65  };
66 
67  struct throw_copies
68  {
69  throw_copies() noexcept {}
70  throw_copies(throw_copies const&) {}
71  throw_copies(throw_copies&&) = default;
72  ~throw_copies() = default;
73  throw_copies& operator=(throw_copies const&) { return *this; }
74  throw_copies& operator=(throw_copies&&) = default;
75  bool operator==(throw_copies const&) noexcept { return true; }
76  bool operator==(throw_moves const&) noexcept { return true; }
77  };
78 
79  struct throw_moves
80  {
81  throw_moves() noexcept {}
82  throw_moves(throw_moves const&) = default;
83  throw_moves(throw_moves&&) {}
84  ~throw_moves() = default;
85  throw_moves& operator=(throw_moves const&) = default;
86  throw_moves& operator=(throw_moves&&) { return *this; }
87  bool operator==(throw_moves const&) { return true; }
88  bool operator==(throw_copies const&) { return true; }
89  };
90 
91  template<typename T>
92  void construction_bench()
93  {
94  EXPECT_TRUE(std::is_copy_constructible<expect<T>>());
95  EXPECT_TRUE(std::is_move_constructible<expect<T>>());
96  EXPECT_TRUE(std::is_copy_assignable<expect<T>>());
97  EXPECT_TRUE(std::is_move_assignable<expect<T>>());
98  EXPECT_TRUE(std::is_destructible<expect<T>>());
99  }
100 
101  template<typename T>
102  void noexcept_bench()
103  {
104  EXPECT_TRUE(std::is_nothrow_copy_constructible<expect<T>>());
105  EXPECT_TRUE(std::is_nothrow_move_constructible<expect<T>>());
106  EXPECT_TRUE(std::is_nothrow_copy_assignable<expect<T>>());
107  EXPECT_TRUE(std::is_nothrow_move_assignable<expect<T>>());
108  EXPECT_TRUE(std::is_nothrow_destructible<expect<T>>());
109 
110  EXPECT_TRUE(noexcept(bool(std::declval<expect<T>>())));
111  EXPECT_TRUE(noexcept(std::declval<expect<T>>().has_error()));
112  EXPECT_TRUE(noexcept(std::declval<expect<T>>().error()));
113  EXPECT_TRUE(noexcept(std::declval<expect<T>>().equal(std::declval<expect<T>>())));
114  EXPECT_TRUE(noexcept(std::declval<expect<T>>() == std::declval<expect<T>>()));
115  EXPECT_TRUE(noexcept(std::declval<expect<T>>() != std::declval<expect<T>>()));
116  }
117 
118  template<typename T>
119  void conversion_bench()
120  {
121  EXPECT_TRUE((std::is_convertible<std::error_code, expect<T>>()));
122  EXPECT_TRUE((std::is_convertible<std::error_code&&, expect<T>>()));
123  EXPECT_TRUE((std::is_convertible<std::error_code&, expect<T>>()));
124  EXPECT_TRUE((std::is_convertible<std::error_code const&, expect<T>>()));
125 
126  EXPECT_TRUE((std::is_constructible<expect<T>, std::error_code>()));
127  EXPECT_TRUE((std::is_constructible<expect<T>, std::error_code&&>()));
128  EXPECT_TRUE((std::is_constructible<expect<T>, std::error_code&>()));
129  EXPECT_TRUE((std::is_constructible<expect<T>, std::error_code const&>()));
130  }
131 }
132 
133 
134 TEST(Expect, Constructions)
135 {
136  construction_bench<void>();
137  construction_bench<int>();
138 
139  EXPECT_TRUE(std::is_constructible<expect<void>>());
140 
141  EXPECT_TRUE((std::is_constructible<expect<throw_construct>, expect<int>>()));
142 
143  EXPECT_TRUE(std::is_move_constructible<expect<move_only>>());
144  EXPECT_TRUE(std::is_move_assignable<expect<move_only>>());
145 }
146 
147 TEST(Expect, Conversions)
148 {
149  struct implicit { implicit(int) {} };
150  struct explicit_only { explicit explicit_only(int) {} };
151 
152  conversion_bench<void>();
153  conversion_bench<int>();
154 
155  EXPECT_TRUE((std::is_convertible<int, expect<int>>()));
156  EXPECT_TRUE((std::is_convertible<int&&, expect<int>>()));
157  EXPECT_TRUE((std::is_convertible<int&, expect<int>>()));
158  EXPECT_TRUE((std::is_convertible<int const, expect<int>>()));
159  EXPECT_TRUE((std::is_convertible<expect<unsigned>, expect<int>>()));
160  EXPECT_TRUE((std::is_convertible<expect<unsigned>&&, expect<int>>()));
161  EXPECT_TRUE((std::is_convertible<expect<unsigned>&, expect<int>>()));
162  EXPECT_TRUE((std::is_convertible<expect<unsigned> const&, expect<int>>()));
163  EXPECT_TRUE((std::is_convertible<expect<int>, expect<implicit>>()));
164  EXPECT_TRUE((std::is_convertible<expect<int>&&, expect<implicit>>()));
165  EXPECT_TRUE((std::is_convertible<expect<int>&, expect<implicit>>()));
166  EXPECT_TRUE((std::is_convertible<expect<int> const&, expect<implicit>>()));
167  EXPECT_TRUE(!(std::is_convertible<expect<int>, expect<explicit_only>>()));
168  EXPECT_TRUE(!(std::is_convertible<expect<int>&&, expect<explicit_only>>()));
169  EXPECT_TRUE(!(std::is_convertible<expect<int>&, expect<explicit_only>>()));
170  EXPECT_TRUE(!(std::is_convertible<expect<int> const&, expect<explicit_only>>()));
171 
172  EXPECT_TRUE((std::is_constructible<expect<int>, int>()));
173  EXPECT_TRUE((std::is_constructible<expect<int>, int&&>()));
174  EXPECT_TRUE((std::is_constructible<expect<int>, int&>()));
175  EXPECT_TRUE((std::is_constructible<expect<int>, int const&>()));
176  EXPECT_TRUE((std::is_constructible<expect<int>, expect<unsigned>>()));
177  EXPECT_TRUE((std::is_constructible<expect<int>, expect<unsigned>&&>()));
178  EXPECT_TRUE((std::is_constructible<expect<int>, expect<unsigned>&>()));
179  EXPECT_TRUE((std::is_constructible<expect<int>, expect<unsigned> const&>()));
180  EXPECT_TRUE((std::is_constructible<expect<implicit>, expect<int>>()));
181  EXPECT_TRUE((std::is_constructible<expect<implicit>, expect<int>&&>()));
182  EXPECT_TRUE((std::is_constructible<expect<implicit>, expect<int>&>()));
183  EXPECT_TRUE((std::is_constructible<expect<implicit>, expect<int> const&>()));
184  EXPECT_TRUE(!(std::is_constructible<expect<explicit_only>, expect<int>>()));
185  EXPECT_TRUE(!(std::is_constructible<expect<explicit_only>, expect<int>&&>()));
186  EXPECT_TRUE(!(std::is_constructible<expect<explicit_only>, expect<int>&>()));
187  EXPECT_TRUE(!(std::is_constructible<expect<explicit_only>, expect<int> const&>()));
188 
190 
192  expect<const char*> val2{"foo"};
193 
194  EXPECT_EQ(val1.value(), std::string{});
195  EXPECT_EQ(val2.value(), std::string{"foo"});
196 
197  const expect<std::string> val3{val2};
198 
199  EXPECT_EQ(val1.value(), std::string{});
200  EXPECT_EQ(val2.value(), std::string{"foo"});
201  EXPECT_EQ(val3.value(), std::string{"foo"});
202 
203  val1 = val2;
204 
205  EXPECT_EQ(val1.value(), "foo");
206  EXPECT_EQ(val2.value(), std::string{"foo"});
207  EXPECT_EQ(val3.value(), "foo");
208 }
209 
210 TEST(Expect, NoExcept)
211 {
212  noexcept_bench<void>();
213  noexcept_bench<int>();
214 
215  EXPECT_TRUE(std::is_nothrow_constructible<expect<void>>());
216 
217  EXPECT_TRUE((std::is_nothrow_constructible<expect<int>, int>()));
218  EXPECT_TRUE((std::is_nothrow_constructible<expect<int>, expect<unsigned>>()));
219  EXPECT_TRUE((std::is_nothrow_constructible<expect<int>, expect<unsigned>&&>()));
220  EXPECT_TRUE((std::is_nothrow_constructible<expect<int>, expect<unsigned>&>()));
221  EXPECT_TRUE((std::is_nothrow_constructible<expect<int>, expect<unsigned> const&>()));
222 
223  EXPECT_TRUE(noexcept(expect<int>{std::declval<expect<unsigned>&&>()}));
224  EXPECT_TRUE(noexcept(expect<int>{std::declval<expect<unsigned> const&>()}));
225  EXPECT_TRUE(noexcept(std::declval<expect<int>>().has_value()));
226  EXPECT_TRUE(noexcept(*std::declval<expect<int>>()));
227  EXPECT_TRUE(noexcept(std::declval<expect<int>>().equal(std::declval<expect<unsigned>>())));
228  EXPECT_TRUE(noexcept(std::declval<expect<unsigned>>().equal(std::declval<expect<int>>())));
229  EXPECT_TRUE(noexcept(std::declval<expect<int>>().equal(0)));
230  EXPECT_TRUE(noexcept(std::declval<expect<int>>() == std::declval<expect<unsigned>>()));
231  EXPECT_TRUE(noexcept(std::declval<expect<unsigned>>() == std::declval<expect<int>>()));
232  EXPECT_TRUE(noexcept(std::declval<expect<int>>() == 0));
233  EXPECT_TRUE(noexcept(0 == std::declval<expect<int>>()));
234  EXPECT_TRUE(noexcept(std::declval<expect<int>>() != std::declval<expect<unsigned>>()));
235  EXPECT_TRUE(noexcept(std::declval<expect<unsigned>>() != std::declval<expect<int>>()));
236  EXPECT_TRUE(noexcept(std::declval<expect<int>>() != 0));
237  EXPECT_TRUE(noexcept(0 != std::declval<expect<int>>()));
238 
239  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_construct>, std::error_code>()));
240  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_construct>, std::error_code&&>()));
241  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_construct>, std::error_code&>()));
242  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_construct>, std::error_code const&>()));
243  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_construct>, throw_construct>()));
244  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_construct>, throw_construct&&>()));
245  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_construct>, throw_construct&>()));
246  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_construct>, throw_construct const&>()));
247  EXPECT_TRUE(!(std::is_nothrow_constructible<expect<throw_construct>, expect<int>>()));
248  EXPECT_TRUE(!(std::is_nothrow_constructible<expect<throw_construct>, expect<int>&&>()));
249  EXPECT_TRUE(!(std::is_nothrow_constructible<expect<throw_construct>, expect<int>&>()));
250  EXPECT_TRUE(!(std::is_nothrow_constructible<expect<throw_construct>, expect<int> const&>()));
251  EXPECT_TRUE(std::is_nothrow_copy_constructible<expect<throw_construct>>());
252  EXPECT_TRUE(std::is_nothrow_move_constructible<expect<throw_construct>>());
253  EXPECT_TRUE(std::is_nothrow_copy_assignable<expect<throw_construct>>());
254  EXPECT_TRUE(std::is_nothrow_move_assignable<expect<throw_construct>>());
255  EXPECT_TRUE(std::is_nothrow_destructible<expect<throw_construct>>());
256 
257  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_copies>, std::error_code>()));
258  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_copies>, std::error_code&&>()));
259  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_copies>, std::error_code&>()));
260  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_copies>, std::error_code const&>()));
261  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_copies>, throw_copies>()));
262  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_copies>, throw_copies&&>()));
263  EXPECT_TRUE(!(std::is_nothrow_constructible<expect<throw_copies>, throw_copies&>()));
264  EXPECT_TRUE(!(std::is_nothrow_constructible<expect<throw_copies>, throw_copies const&>()));
265  EXPECT_TRUE(!std::is_nothrow_copy_constructible<expect<throw_copies>>());
266  EXPECT_TRUE(std::is_nothrow_move_constructible<expect<throw_copies>>());
267  EXPECT_TRUE(!std::is_nothrow_copy_assignable<expect<throw_copies>>());
268  EXPECT_TRUE(std::is_nothrow_move_assignable<expect<throw_copies>>());
269  EXPECT_TRUE(std::is_nothrow_destructible<expect<throw_copies>>());
270  EXPECT_TRUE(noexcept(std::declval<expect<throw_copies>>().equal(std::declval<expect<throw_copies>>())));
271  EXPECT_TRUE(noexcept(std::declval<expect<throw_copies>>().equal(std::declval<throw_copies>())));
272  EXPECT_TRUE(noexcept(std::declval<expect<throw_copies>>() == std::declval<expect<throw_copies>>()));
273  EXPECT_TRUE(noexcept(std::declval<expect<throw_copies>>() == std::declval<throw_copies>()));
274  EXPECT_TRUE(noexcept(std::declval<throw_copies>() == std::declval<expect<throw_copies>>()));
275  EXPECT_TRUE(noexcept(std::declval<expect<throw_copies>>() != std::declval<expect<throw_copies>>()));
276  EXPECT_TRUE(noexcept(std::declval<expect<throw_copies>>() != std::declval<throw_copies>()));
277  EXPECT_TRUE(noexcept(std::declval<throw_copies>() != std::declval<expect<throw_copies>>()));
278  EXPECT_TRUE(noexcept(std::declval<expect<throw_copies>>().equal(std::declval<expect<throw_moves>>())));
279  EXPECT_TRUE(noexcept(std::declval<expect<throw_copies>>().equal(std::declval<throw_moves>())));
280  EXPECT_TRUE(noexcept(std::declval<expect<throw_copies>>() == std::declval<expect<throw_moves>>()));
281  EXPECT_TRUE(noexcept(std::declval<expect<throw_copies>>() == std::declval<throw_moves>()));
282  EXPECT_TRUE(noexcept(std::declval<throw_moves>() == std::declval<expect<throw_copies>>()));
283  EXPECT_TRUE(noexcept(std::declval<expect<throw_copies>>() != std::declval<expect<throw_moves>>()));
284  EXPECT_TRUE(noexcept(std::declval<expect<throw_copies>>() != std::declval<throw_moves>()));
285  EXPECT_TRUE(noexcept(std::declval<throw_moves>() != std::declval<expect<throw_copies>>()));
286 
287  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_moves>, std::error_code>()));
288  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_moves>, std::error_code&&>()));
289  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_moves>, std::error_code&>()));
290  EXPECT_TRUE((std::is_nothrow_constructible<expect<throw_moves>, std::error_code const&>()));
291  EXPECT_TRUE(!(std::is_nothrow_constructible<expect<throw_moves>, throw_moves>()));
292  EXPECT_TRUE(!(std::is_nothrow_constructible<expect<throw_moves>, throw_moves&&>()));
293  EXPECT_TRUE(!(std::is_nothrow_constructible<expect<throw_moves>, throw_moves&>()));
294  EXPECT_TRUE(!(std::is_nothrow_constructible<expect<throw_moves>, throw_moves const&>()));
295  EXPECT_TRUE(std::is_nothrow_copy_constructible<expect<throw_moves>>());
296  EXPECT_TRUE(!std::is_nothrow_move_constructible<expect<throw_moves>>());
297  EXPECT_TRUE(std::is_nothrow_copy_assignable<expect<throw_moves>>());
298  EXPECT_TRUE(!std::is_nothrow_move_assignable<expect<throw_moves>>());
299  EXPECT_TRUE(std::is_nothrow_destructible<expect<throw_copies>>());
300  EXPECT_TRUE(!noexcept(std::declval<expect<throw_moves>>().equal(std::declval<expect<throw_moves>>())));
301  EXPECT_TRUE(!noexcept(std::declval<expect<throw_moves>>().equal(std::declval<throw_moves>())));
302  EXPECT_TRUE(!noexcept(std::declval<expect<throw_moves>>() == std::declval<expect<throw_moves>>()));
303  EXPECT_TRUE(!noexcept(std::declval<expect<throw_moves>>() == std::declval<throw_moves>()));
304  EXPECT_TRUE(!noexcept(std::declval<throw_moves>() == std::declval<expect<throw_moves>>()));
305  EXPECT_TRUE(!noexcept(std::declval<expect<throw_moves>>() != std::declval<expect<throw_moves>>()));
306  EXPECT_TRUE(!noexcept(std::declval<expect<throw_moves>>() != std::declval<throw_moves>()));
307  EXPECT_TRUE(!noexcept(std::declval<throw_moves>() != std::declval<expect<throw_moves>>()));
308  EXPECT_TRUE(!noexcept(std::declval<expect<throw_moves>>().equal(std::declval<expect<throw_copies>>())));
309  EXPECT_TRUE(!noexcept(std::declval<expect<throw_moves>>().equal(std::declval<throw_copies>())));
310  EXPECT_TRUE(!noexcept(std::declval<expect<throw_moves>>() == std::declval<expect<throw_copies>>()));
311  EXPECT_TRUE(!noexcept(std::declval<expect<throw_moves>>() == std::declval<throw_copies>()));
312  EXPECT_TRUE(!noexcept(std::declval<throw_copies>() == std::declval<expect<throw_moves>>()));
313  EXPECT_TRUE(!noexcept(std::declval<expect<throw_moves>>() != std::declval<expect<throw_copies>>()));
314  EXPECT_TRUE(!noexcept(std::declval<expect<throw_moves>>() != std::declval<throw_copies>()));
315  EXPECT_TRUE(!noexcept(std::declval<throw_copies>() != std::declval<expect<throw_moves>>()));
316 }
317 
318 TEST(Expect, Trivial)
319 {
320  EXPECT_TRUE(std::is_trivially_copy_constructible<expect<void>>());
321  EXPECT_TRUE(std::is_trivially_move_constructible<expect<void>>());
322  EXPECT_TRUE(std::is_trivially_destructible<expect<void>>());
323 }
324 
325 TEST(Expect, Assignment)
326 {
328  expect<std::string> val2{"foobar"};
329 
330  ASSERT_TRUE(val1.has_value());
331  ASSERT_TRUE(val2.has_value());
332  EXPECT_TRUE(bool(val1));
333  EXPECT_TRUE(bool(val2));
334  EXPECT_TRUE(!val1.has_error());
335  EXPECT_TRUE(!val2.has_error());
336  EXPECT_EQ(val1.value(), std::string{});
337  EXPECT_TRUE(*val1 == std::string{});
338  EXPECT_TRUE(boost::equals(val1->c_str(), ""));
339  EXPECT_TRUE(val2.value() == "foobar");
340  EXPECT_TRUE(*val2 == "foobar");
341  EXPECT_TRUE(boost::equals(val2->c_str(), "foobar"));
342  EXPECT_EQ(val1.error(), std::error_code{});
343  EXPECT_EQ(val2.error(), std::error_code{});
344  EXPECT_TRUE(!val1.equal(std::error_code{}));
345  EXPECT_TRUE(!val2.equal(std::error_code{}));
346  EXPECT_TRUE(!(val1 == std::error_code{}));
347  EXPECT_TRUE(!(std::error_code{} == val1));
348  EXPECT_TRUE(!(val2 == std::error_code{}));
349  EXPECT_TRUE(!(std::error_code{} == val2));
350  EXPECT_TRUE(val1 != std::error_code{});
351  EXPECT_TRUE(std::error_code{} != val1);
352  EXPECT_TRUE(val2 != std::error_code{});
353  EXPECT_TRUE(std::error_code{} != val2);
354  EXPECT_TRUE(!val1.matches(std::error_condition{}));
355  EXPECT_TRUE(!val2.matches(std::error_condition{}));
356 
357  val1 = std::move(val2);
358 
359  ASSERT_TRUE(val1.has_value());
360  ASSERT_TRUE(val2.has_value());
361  EXPECT_TRUE(bool(val1));
362  EXPECT_TRUE(bool(val2));
363  EXPECT_TRUE(!val1.has_error());
364  EXPECT_TRUE(!val2.has_error());
365  EXPECT_EQ(val1.value(), "foobar");
366  EXPECT_TRUE(*val1 == "foobar");
367  EXPECT_TRUE(boost::equals(val1->c_str(), "foobar"));
368  EXPECT_EQ(val2.value(), std::string{});
369  EXPECT_TRUE(*val2 == std::string{});
370  EXPECT_TRUE(boost::equals(val2->c_str(), ""));
371  EXPECT_EQ(val1.error(), std::error_code{});
372  EXPECT_EQ(val2.error(), std::error_code{});
373  EXPECT_TRUE(!val1.equal(std::error_code{}));
374  EXPECT_TRUE(!val2.equal(std::error_code{}));
375  EXPECT_TRUE(!(val1 == std::error_code{}));
376  EXPECT_TRUE(!(std::error_code{} == val1));
377  EXPECT_TRUE(!(val2 == std::error_code{}));
378  EXPECT_TRUE(!(std::error_code{} == val2));
379  EXPECT_TRUE(val1 != std::error_code{});
380  EXPECT_TRUE(std::error_code{} != val1);
381  EXPECT_TRUE(val2 != std::error_code{});
382  EXPECT_TRUE(std::error_code{} != val2);
383  EXPECT_TRUE(!val1.matches(std::error_condition{}));
384  EXPECT_TRUE(!val2.matches(std::error_condition{}));
385 
386  val2 = val1;
387 
388  ASSERT_TRUE(val1.has_value());
389  ASSERT_TRUE(val2.has_value());
390  EXPECT_TRUE(bool(val1));
391  EXPECT_TRUE(bool(val2));
392  EXPECT_TRUE(!val1.has_error());
393  EXPECT_TRUE(!val2.has_error());
394  EXPECT_EQ(val1.value(), "foobar");
395  EXPECT_TRUE(*val1 == "foobar");
396  EXPECT_TRUE(boost::equals(val1->c_str(), "foobar"));
397  EXPECT_EQ(val2.value(), "foobar");
398  EXPECT_TRUE(*val2 == "foobar");
399  EXPECT_TRUE(boost::equals(val2->c_str(), "foobar"));
400  EXPECT_EQ(val1.error(), std::error_code{});
401  EXPECT_EQ(val2.error(), std::error_code{});
402  EXPECT_TRUE(!val1.equal(std::error_code{}));
403  EXPECT_TRUE(!val2.equal(std::error_code{}));
404  EXPECT_TRUE(!(val1 == std::error_code{}));
405  EXPECT_TRUE(!(std::error_code{} == val1));
406  EXPECT_TRUE(!(val2 == std::error_code{}));
407  EXPECT_TRUE(!(std::error_code{} == val2));
408  EXPECT_TRUE(val1 != std::error_code{});
409  EXPECT_TRUE(std::error_code{} != val1);
410  EXPECT_TRUE(val2 != std::error_code{});
411  EXPECT_TRUE(std::error_code{} != val2);
412  EXPECT_TRUE(!val1.matches(std::error_condition{}));
413  EXPECT_TRUE(!val2.matches(std::error_condition{}));
414 
416 
417  ASSERT_TRUE(val1.has_error());
418  ASSERT_TRUE(val2.has_value());
419  EXPECT_TRUE(!val1);
420  EXPECT_TRUE(bool(val2));
421  EXPECT_TRUE(!val1.has_value());
422  EXPECT_TRUE(!val2.has_error());
426  EXPECT_STREQ(val2.value().c_str(), "foobar");
427  EXPECT_TRUE(*val2 == "foobar");
428  EXPECT_TRUE(boost::equals(val2->c_str(), "foobar"));
429  EXPECT_NE(val1.error(), std::error_code{});
430  EXPECT_EQ(val2.error(), std::error_code{});
432  EXPECT_TRUE(!val2.equal(std::error_code{}));
433  EXPECT_TRUE(!(val1 == std::error_code{}));
434  EXPECT_TRUE(!(std::error_code{} == val1));
435  EXPECT_TRUE(!(val2 == std::error_code{}));
436  EXPECT_TRUE(!(std::error_code{} == val2));
437  EXPECT_TRUE(val1 != std::error_code{});
438  EXPECT_TRUE(std::error_code{} != val1);
439  EXPECT_TRUE(val2 != std::error_code{});
440  EXPECT_TRUE(std::error_code{} != val2);
441  EXPECT_TRUE(val1.matches(std::errc::invalid_argument));
442  EXPECT_TRUE(!val1.matches(std::error_condition{}));
443  EXPECT_TRUE(!val2.matches(std::error_condition{}));
444 
445  val2 = val1;
446 
447  ASSERT_TRUE(val1.has_error());
448  ASSERT_TRUE(val2.has_error());
449  EXPECT_TRUE(!val1);
450  EXPECT_TRUE(!val2);
451  EXPECT_TRUE(!val1.has_value());
452  EXPECT_TRUE(!val2.has_value());
459  EXPECT_NE(val1.error(), std::error_code{});
460  EXPECT_NE(val2.error(), std::error_code{});
463  EXPECT_TRUE(!(val1 == std::error_code{}));
464  EXPECT_TRUE(!(std::error_code{} == val1));
465  EXPECT_TRUE(!(val2 == std::error_code{}));
466  EXPECT_TRUE(!(std::error_code{} == val2));
467  EXPECT_TRUE(val1 != std::error_code{});
468  EXPECT_TRUE(std::error_code{} != val1);
469  EXPECT_TRUE(val2 != std::error_code{});
470  EXPECT_TRUE(std::error_code{} != val2);
471  EXPECT_TRUE(val1.matches(std::errc::invalid_argument));
472  EXPECT_TRUE(val2.matches(std::errc::invalid_argument));
473  EXPECT_TRUE(!val1.matches(std::error_condition{}));
474  EXPECT_TRUE(!val2.matches(std::error_condition{}));
475 
476  val1 = std::string{"barfoo"};
477 
478  ASSERT_TRUE(val1.has_value());
479  ASSERT_TRUE(val2.has_error());
480  EXPECT_TRUE(bool(val1));
481  EXPECT_TRUE(!val2);
482  EXPECT_TRUE(!val1.has_error());
483  EXPECT_TRUE(!val2.has_value());
484  EXPECT_STREQ(val1.value().c_str(), "barfoo");
485  EXPECT_TRUE(*val1 == "barfoo");
486  EXPECT_TRUE(boost::equals(val1->c_str(), "barfoo"));
490  EXPECT_EQ(val1.error(), std::error_code{});
491  EXPECT_NE(val2.error(), std::error_code{});
492  EXPECT_TRUE(!val1.equal(std::error_code{}));
494  EXPECT_TRUE(!(val1 == std::error_code{}));
495  EXPECT_TRUE(!(std::error_code{} == val1));
496  EXPECT_TRUE(!(val2 == std::error_code{}));
497  EXPECT_TRUE(!(std::error_code{} == val2));
498  EXPECT_TRUE(val1 != std::error_code{});
499  EXPECT_TRUE(std::error_code{} != val1);
500  EXPECT_TRUE(val2 != std::error_code{});
501  EXPECT_TRUE(std::error_code{} != val2);
502  EXPECT_TRUE(val2.matches(std::errc::invalid_argument));
503  EXPECT_TRUE(!val1.matches(std::error_condition{}));
504  EXPECT_TRUE(!val2.matches(std::error_condition{}));
505 
506  val2 = val1;
507 
508  ASSERT_TRUE(val1.has_value());
509  ASSERT_TRUE(val2.has_value());
510  EXPECT_TRUE(bool(val1));
511  EXPECT_TRUE(bool(val2));
512  EXPECT_TRUE(!val1.has_error());
513  EXPECT_TRUE(!val2.has_error());
514  EXPECT_EQ(val1.value(), "barfoo");
515  EXPECT_TRUE(*val1 == "barfoo");
516  EXPECT_TRUE(boost::equals(val1->c_str(), "barfoo"));
517  EXPECT_EQ(val2.value(), "barfoo");
518  EXPECT_TRUE(*val2 == "barfoo");
519  EXPECT_TRUE(boost::equals(val2->c_str(), "barfoo"));
520  EXPECT_EQ(val1.error(), std::error_code{});
521  EXPECT_EQ(val2.error(), std::error_code{});
522  EXPECT_TRUE(!val1.equal(std::error_code{}));
523  EXPECT_TRUE(!val2.equal(std::error_code{}));
524  EXPECT_TRUE(!(val1 == std::error_code{}));
525  EXPECT_TRUE(!(std::error_code{} == val1));
526  EXPECT_TRUE(!(val2 == std::error_code{}));
527  EXPECT_TRUE(!(std::error_code{} == val2));
528  EXPECT_TRUE(val1 != std::error_code{});
529  EXPECT_TRUE(std::error_code{} != val1);
530  EXPECT_TRUE(val2 != std::error_code{});
531  EXPECT_TRUE(std::error_code{} != val2);
532  EXPECT_TRUE(!val1.matches(std::error_condition{}));
533  EXPECT_TRUE(!val2.matches(std::error_condition{}));
534 }
535 
536 TEST(Expect, AssignmentThrowsOnMove)
537 {
538  struct construct_error {};
539  struct assignment_error {};
540 
541  struct throw_on_move {
542  std::string msg;
543 
544  throw_on_move(const char* msg) : msg(msg) {}
545  throw_on_move(throw_on_move&&) {
546  throw construct_error{};
547  }
548  throw_on_move(throw_on_move const&) = default;
549  ~throw_on_move() = default;
550  throw_on_move& operator=(throw_on_move&&) {
551  throw assignment_error{};
552  }
553  throw_on_move& operator=(throw_on_move const&) = default;
554  };
555 
558 
559  ASSERT_TRUE(val1.has_value());
560  ASSERT_TRUE(val2.has_error());
561  EXPECT_TRUE(!val1.has_error());
562  EXPECT_TRUE(!val2.has_value());
563  EXPECT_STREQ(val1->msg.c_str(), "foobar");
565 
566  EXPECT_THROW(val2 = std::move(val1), construct_error);
567 
568  ASSERT_TRUE(val1.has_value());
569  ASSERT_TRUE(val2.has_error());
570  EXPECT_TRUE(!val1.has_error());
571  EXPECT_TRUE(!val2.has_value());
572  EXPECT_STREQ(val1->msg.c_str(), "foobar");
574 
575  EXPECT_THROW(val1 = expect<const char*>{"barfoo"}, assignment_error);
576 
577  ASSERT_TRUE(val1.has_value());
578  ASSERT_TRUE(val2.has_error());
579  EXPECT_TRUE(!val1.has_error());
580  EXPECT_TRUE(!val2.has_value());
581  EXPECT_STREQ(val1->msg.c_str(), "foobar");
583 
584  EXPECT_NO_THROW(val2 = val1);
585 
586  ASSERT_TRUE(val1.has_value());
587  ASSERT_TRUE(val2.has_value());
588  EXPECT_TRUE(!val1.has_error());
589  EXPECT_TRUE(!val2.has_error());
590  EXPECT_STREQ(val1->msg.c_str(), "foobar");
591  EXPECT_STREQ(val2->msg.c_str(), "foobar");
592 }
593 
594 TEST(Expect, EqualWithStrings)
595 {
597  expect<std::string> val2{"barfoo"};
598  expect<boost::string_ref> val3{boost::string_ref{}};
599 
600  EXPECT_TRUE(!val1.equal(val2));
601  EXPECT_TRUE(val1.equal(val3));
602  EXPECT_TRUE(!val2.equal(val1));
603  EXPECT_TRUE(!val2.equal(val3));
604  EXPECT_TRUE(val3.equal(val1));
605  EXPECT_TRUE(!val3.equal(val2));
606  EXPECT_TRUE(!(val1 == val2));
607  EXPECT_TRUE(!(val2 == val1));
608  EXPECT_TRUE(val1 == val3);
609  EXPECT_TRUE(val3 == val1);
610  EXPECT_TRUE(!(val2 == val3));
611  EXPECT_TRUE(!(val3 == val2));
612  EXPECT_TRUE(val1 != val2);
613  EXPECT_TRUE(val2 != val1);
614  EXPECT_TRUE(!(val1 != val3));
615  EXPECT_TRUE(!(val3 != val1));
616  EXPECT_TRUE(val2 != val3);
617  EXPECT_TRUE(val3 != val2);
618 
619  EXPECT_TRUE(val1.equal(""));
620  EXPECT_TRUE(val2.equal("barfoo"));
621  EXPECT_TRUE(val3.equal(""));
622  EXPECT_TRUE(!val1.equal(std::error_code{}));
623  EXPECT_TRUE(!val2.equal(std::error_code{}));
624  EXPECT_TRUE(!val3.equal(std::error_code{}));
625  EXPECT_TRUE(val1 == "");
626  EXPECT_TRUE("" == val1);
627  EXPECT_TRUE(val2 == "barfoo");
628  EXPECT_TRUE("barfoo" == val2);
629  EXPECT_TRUE(val3 == "");
630  EXPECT_TRUE("" == val3);
631  EXPECT_TRUE(!(val1 != ""));
632  EXPECT_TRUE(!("" != val1));
633  EXPECT_TRUE(!(val2 != "barfoo"));
634  EXPECT_TRUE(!("barfoo" != val2));
635  EXPECT_TRUE(!(val3 != ""));
636  EXPECT_TRUE(!("" != val3));
637  EXPECT_TRUE(!(val1 == std::error_code{}));
638  EXPECT_TRUE(!(std::error_code{} == val1));
639  EXPECT_TRUE(!(val2 == std::error_code{}));
640  EXPECT_TRUE(!(std::error_code{} == val2));
641  EXPECT_TRUE(!(val3 == std::error_code{}));
642  EXPECT_TRUE(!(std::error_code{} == val3));
643  EXPECT_TRUE(val1 != std::error_code{});
644  EXPECT_TRUE(std::error_code{} != val1);
645  EXPECT_TRUE(val2 != std::error_code{});
646  EXPECT_TRUE(std::error_code{} != val2);
647  EXPECT_TRUE(val3 != std::error_code{});
648  EXPECT_TRUE(std::error_code{} != val3);
649  EXPECT_TRUE(!val1.matches(std::error_condition{}));
650  EXPECT_TRUE(!val2.matches(std::error_condition{}));
651  EXPECT_TRUE(!val3.matches(std::error_condition{}));
652 
654 
655  EXPECT_TRUE(!val1.equal(val2));
656  EXPECT_TRUE(val1.equal(val3));
657  EXPECT_TRUE(!val2.equal(val1));
658  EXPECT_TRUE(!val2.equal(val3));
659  EXPECT_TRUE(val3.equal(val1));
660  EXPECT_TRUE(!val3.equal(val2));
661  EXPECT_TRUE(!(val1 == val2));
662  EXPECT_TRUE(!(val2 == val1));
663  EXPECT_TRUE(val1 == val3);
664  EXPECT_TRUE(val3 == val1);
665  EXPECT_TRUE(!(val2 == val3));
666  EXPECT_TRUE(!(val3 == val2));
667  EXPECT_TRUE(val1 != val2);
668  EXPECT_TRUE(val2 != val1);
669  EXPECT_TRUE(!(val1 != val3));
670  EXPECT_TRUE(!(val3 != val1));
671  EXPECT_TRUE(val2 != val3);
672  EXPECT_TRUE(val3 != val2);
673 
681  EXPECT_TRUE(val2.matches(std::errc::invalid_argument));
682  EXPECT_TRUE(!val2.matches(std::error_condition{}));
683 
684  val1 = expect<std::string>{"barfoo"};
685 
686  EXPECT_TRUE(!val1.equal(val2));
687  EXPECT_TRUE(!val1.equal(val3));
688  EXPECT_TRUE(!val2.equal(val1));
689  EXPECT_TRUE(!val2.equal(val3));
690  EXPECT_TRUE(!val3.equal(val1));
691  EXPECT_TRUE(!val3.equal(val2));
692  EXPECT_TRUE(!(val1 == val2));
693  EXPECT_TRUE(!(val2 == val1));
694  EXPECT_TRUE(!(val1 == val3));
695  EXPECT_TRUE(!(val3 == val1));
696  EXPECT_TRUE(!(val2 == val3));
697  EXPECT_TRUE(!(val3 == val2));
698  EXPECT_TRUE(val1 != val2);
699  EXPECT_TRUE(val2 != val1);
700  EXPECT_TRUE(val1 != val3);
701  EXPECT_TRUE(val3 != val1);
702  EXPECT_TRUE(val2 != val3);
703  EXPECT_TRUE(val3 != val2);
704 
705  EXPECT_TRUE(val1.equal("barfoo"));
706  EXPECT_TRUE(val1 == "barfoo");
707  EXPECT_TRUE("barfoo" == val1);
708  EXPECT_TRUE(!(val1 != "barfoo"));
709  EXPECT_TRUE(!("barfoo" != val1));
713  EXPECT_TRUE(!(val1 == std::error_code{}));
714  EXPECT_TRUE(!(std::error_code{} == val1));
715  EXPECT_TRUE(!val1.matches(std::error_condition{}));
716  EXPECT_TRUE(!val1.matches(std::errc::invalid_argument));
717 }
718 
719 TEST(Expect, EqualWithVoid)
720 {
721  const expect<void> val1;
722  expect<void> val2;
723 
724  EXPECT_TRUE(val1.equal(val2));
725  EXPECT_TRUE(val2.equal(val1));
726  EXPECT_TRUE(!val1.equal(std::error_code{}));
727  EXPECT_TRUE(!val2.equal(std::error_code{}));
728  EXPECT_TRUE(val1 == val2);
729  EXPECT_TRUE(val2 == val1);
730  EXPECT_TRUE(!(val1 == std::error_code{}));
731  EXPECT_TRUE(!(std::error_code{} == val1));
732  EXPECT_TRUE(!(val2 == std::error_code{}));
733  EXPECT_TRUE(!(std::error_code{} == val2));
734  EXPECT_TRUE(!(val1 != val2));
735  EXPECT_TRUE(!(val2 != val1));
736  EXPECT_TRUE(val1 != std::error_code{});
737  EXPECT_TRUE(std::error_code{} != val1);
738  EXPECT_TRUE(!(val2 == std::error_code{}));
739  EXPECT_TRUE(!(std::error_code{} == val2));
740 
742 
743  EXPECT_TRUE(!val1.equal(val2));
744  EXPECT_TRUE(!val2.equal(val1));
747  EXPECT_TRUE(!val2.equal(std::error_code{}));
748  EXPECT_TRUE(!(val1 == val2));
749  EXPECT_TRUE(!(val2 == val1));
752  EXPECT_TRUE(!(val2 == std::error_code{}));
753  EXPECT_TRUE(!(std::error_code{} == val2));
754  EXPECT_TRUE(val1 != val2);
755  EXPECT_TRUE(val2 != val1);
758  EXPECT_TRUE(val2 != std::error_code{});
759  EXPECT_TRUE(std::error_code{} != val2);
760 }
761 
762 TEST(Expect, EqualNoCopies)
763 {
764  struct copy_error {};
765 
766  struct throw_on_copy {
767  throw_on_copy() = default;
768  throw_on_copy(int) noexcept {}
769  throw_on_copy(throw_on_copy const&) {
770  throw copy_error{};
771  }
772  ~throw_on_copy() = default;
773  throw_on_copy& operator=(throw_on_copy const&) {
774  throw copy_error{};
775  }
776 
777  bool operator==(throw_on_copy const&) const noexcept { return true; }
778  };
779 
782 
783  EXPECT_TRUE(val1.equal(val2));
784  EXPECT_TRUE(val2.equal(val1));
785  EXPECT_TRUE(val1 == val2);
786  EXPECT_TRUE(val2 == val1);
787  EXPECT_TRUE(!(val1 != val2));
788  EXPECT_TRUE(!(val2 != val1));
789 
790  EXPECT_TRUE(val1.equal(throw_on_copy{}));
791  EXPECT_TRUE(val1 == throw_on_copy{});
792  EXPECT_TRUE(throw_on_copy{} == val1);
793  EXPECT_TRUE(!(val1 != throw_on_copy{}));
794  EXPECT_TRUE(!(throw_on_copy{} != val1));
795 
796  throw_on_copy val3;
797 
798  EXPECT_TRUE(val1.equal(val3));
799  EXPECT_TRUE(val1 == val3);
800  EXPECT_TRUE(val3 == val1);
801  EXPECT_TRUE(!(val1 != val3));
802  EXPECT_TRUE(!(val3 != val1));
803 
805 
806  EXPECT_TRUE(!val4.equal(throw_on_copy{}));
807  EXPECT_TRUE(!(val4 == throw_on_copy{}));
808  EXPECT_TRUE(!(throw_on_copy{} == val4));
809  EXPECT_TRUE(val4 != throw_on_copy{});
810  EXPECT_TRUE(throw_on_copy{} != val4);
811  EXPECT_TRUE(!val4.equal(val3));
812  EXPECT_TRUE(!(val4 == val3));
813  EXPECT_TRUE(!(val3 == val4));
814  EXPECT_TRUE(val4 != val3);
815  EXPECT_TRUE(val3 != val4);
816 }
817 
818 TEST(Expect, Macros) {
819  EXPECT_TRUE(
820  [] () -> ::common_error {
821  ELECTRONEUM_PRECOND(true);
824  );
825  EXPECT_TRUE(
826  [] () -> ::common_error {
827  ELECTRONEUM_PRECOND(false);
830  );
831  EXPECT_TRUE(
832  [] () -> std::error_code {
833  ELECTRONEUM_PRECOND(true);
836  );
837  EXPECT_TRUE(
838  [] () -> std::error_code {
839  ELECTRONEUM_PRECOND(false);
842  );
843  EXPECT_TRUE(
844  [] () -> expect<void> {
845  ELECTRONEUM_PRECOND(true);
848  );
849  EXPECT_TRUE(
850  [] () -> expect<void> {
851  ELECTRONEUM_PRECOND(false);
854  );
855  EXPECT_TRUE(
856  [] () -> expect<int> {
857  ELECTRONEUM_PRECOND(true);
860  );
861  EXPECT_TRUE(
862  [] () -> expect<int> {
863  ELECTRONEUM_PRECOND(false);
866  );
867 
868  EXPECT_TRUE(
869  [] () -> std::error_code {
873  );
874  EXPECT_TRUE(
875  [] () -> std::error_code {
879  );
880  EXPECT_TRUE(
881  [] () -> expect<void> {
885  );
886  EXPECT_TRUE(
887  [] () -> expect<void> {
891  );
892  EXPECT_TRUE(
893  [] () -> expect<int> {
897  );
898  EXPECT_TRUE(
899  [] () -> expect<int> {
903  );
904 
908  EXPECT_THROW(
910  );
911  EXPECT_THROW(
913  );
914 }
915 
T & value() &
Definition: expect.h:279
#define EXPECT_NO_THROW(statement)
Definition: gtest.h:1845
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
#define EXPECT_STREQ(s1, s2)
Definition: gtest.h:1995
::std::string string
Definition: gtest-port.h:1097
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
std::error_code make_error_code(::common_error value) noexcept
Definition: error.h:41
common_error
Definition: error.h:32
bool operator==(const some_test_data &a, const some_test_data &b)
A function argument is invalid.
void Expect(bool condition, const char *file, int line, const string &msg)
Definition: expect.h:70
bool equal(expect const &rhs) const noexcept
Definition: expect.h:378
#define ELECTRONEUM_CHECK(...)
Check expect<void> and return errors in current scope.
Definition: expect.h:47
#define EXPECT_NE(val1, val2)
Definition: gtest.h:1926
expect< void > success() noexcept
Definition: expect.h:397
#define ELECTRONEUM_UNWRAP(...)
Definition: expect.h:60
TEST(Expect, Constructions)
Definition: expect.cpp:134
const T & move(const T &t)
Definition: gtest-port.h:1317
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865
#define ELECTRONEUM_PRECOND(...)
If precondition fails, return ::error::kInvalidArgument in current scope.
Definition: expect.h:39
Default std::error_code given to expect<T>
connection< TProtocol > & operator=(const connection< TProtocol > &obj)
error
Tracks LMDB error codes.
Definition: error.h:44
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922