/ src / test / util_expected_tests.cpp
util_expected_tests.cpp
  1  // Copyright (c) The Bitcoin Core developers
  2  // Distributed under the MIT software license, see the accompanying
  3  // file COPYING or https://opensource.org/license/mit.
  4  
  5  #include <test/util/setup_common.h>
  6  #include <util/expected.h>
  7  
  8  #include <boost/test/unit_test.hpp>
  9  
 10  #include <memory>
 11  #include <string>
 12  #include <utility>
 13  
 14  
 15  using namespace util;
 16  
 17  BOOST_AUTO_TEST_SUITE(util_expected_tests)
 18  
 19  BOOST_AUTO_TEST_CASE(expected_value)
 20  {
 21      struct Obj {
 22          int x;
 23      };
 24      Expected<Obj, int> e{};
 25      BOOST_CHECK_EQUAL(e.value().x, 0);
 26  
 27      e = Obj{42};
 28  
 29      BOOST_CHECK(e.has_value());
 30      BOOST_CHECK(static_cast<bool>(e));
 31      BOOST_CHECK_EQUAL(e.value().x, 42);
 32      BOOST_CHECK_EQUAL((*e).x, 42);
 33      BOOST_CHECK_EQUAL(e->x, 42);
 34  
 35      // modify value
 36      e.value().x += 1;
 37      (*e).x += 1;
 38      e->x += 1;
 39  
 40      const auto& read{e};
 41      BOOST_CHECK_EQUAL(read.value().x, 45);
 42      BOOST_CHECK_EQUAL((*read).x, 45);
 43      BOOST_CHECK_EQUAL(read->x, 45);
 44  }
 45  
 46  BOOST_AUTO_TEST_CASE(expected_value_rvalue)
 47  {
 48      Expected<std::unique_ptr<int>, int> no_copy{std::make_unique<int>(5)};
 49      const auto moved{std::move(no_copy).value()};
 50      BOOST_CHECK_EQUAL(*moved, 5);
 51  }
 52  
 53  BOOST_AUTO_TEST_CASE(expected_deref_rvalue)
 54  {
 55      Expected<std::unique_ptr<int>, int> no_copy{std::make_unique<int>(5)};
 56      const auto moved{*std::move(no_copy)};
 57      BOOST_CHECK_EQUAL(*moved, 5);
 58  }
 59  
 60  BOOST_AUTO_TEST_CASE(expected_value_or)
 61  {
 62      Expected<std::unique_ptr<int>, int> no_copy{std::make_unique<int>(1)};
 63      const int one{*std::move(no_copy).value_or(std::make_unique<int>(2))};
 64      BOOST_CHECK_EQUAL(one, 1);
 65  
 66      const Expected<std::string, int> const_val{Unexpected{-1}};
 67      BOOST_CHECK_EQUAL(const_val.value_or("fallback"), "fallback");
 68  }
 69  
 70  BOOST_AUTO_TEST_CASE(expected_value_throws)
 71  {
 72      const Expected<int, std::string> e{Unexpected{"fail"}};
 73      BOOST_CHECK_THROW(e.value(), BadExpectedAccess);
 74  
 75      const Expected<void, std::string> void_e{Unexpected{"fail"}};
 76      BOOST_CHECK_THROW(void_e.value(), BadExpectedAccess);
 77  }
 78  
 79  BOOST_AUTO_TEST_CASE(expected_error)
 80  {
 81      Expected<void, std::string> e{};
 82      BOOST_CHECK(e.has_value());
 83      [&]() -> void { return e.value(); }(); // check value returns void and does not throw
 84      [&]() -> void { return *e; }();
 85  
 86      e = Unexpected{"fail"};
 87      BOOST_CHECK(!e.has_value());
 88      BOOST_CHECK(!static_cast<bool>(e));
 89      BOOST_CHECK_EQUAL(e.error(), "fail");
 90  
 91      // modify error
 92      e.error() += "1";
 93  
 94      const auto& read{e};
 95      BOOST_CHECK_EQUAL(read.error(), "fail1");
 96  }
 97  
 98  BOOST_AUTO_TEST_CASE(expected_error_rvalue)
 99  {
100      {
101          Expected<int, std::unique_ptr<int>> nocopy_err{Unexpected{std::make_unique<int>(7)}};
102          const auto moved{std::move(nocopy_err).error()};
103          BOOST_CHECK_EQUAL(*moved, 7);
104      }
105      {
106          Expected<void, std::unique_ptr<int>> void_nocopy_err{Unexpected{std::make_unique<int>(9)}};
107          const auto moved{std::move(void_nocopy_err).error()};
108          BOOST_CHECK_EQUAL(*moved, 9);
109      }
110  }
111  
112  BOOST_AUTO_TEST_CASE(unexpected_error_accessors)
113  {
114      Unexpected u{std::make_unique<int>(-1)};
115      BOOST_CHECK_EQUAL(*u.error(), -1);
116  
117      *u.error() -= 1;
118      const auto& read{u};
119      BOOST_CHECK_EQUAL(*read.error(), -2);
120  
121      const auto moved{std::move(u).error()};
122      BOOST_CHECK_EQUAL(*moved, -2);
123  }
124  
125  BOOST_AUTO_TEST_CASE(expected_swap)
126  {
127      Expected<const char*, std::unique_ptr<int>> a{Unexpected{std::make_unique<int>(-1)}};
128      Expected<const char*, std::unique_ptr<int>> b{"good"};
129      a.swap(b);
130      BOOST_CHECK_EQUAL(a.value(), "good");
131      BOOST_CHECK_EQUAL(*b.error(), -1);
132  }
133  
134  BOOST_AUTO_TEST_SUITE_END()