/ src / test / util / common.h
common.h
 1  // Copyright (c) The Bitcoin Core developers
 2  // Distributed under the MIT software license, see the accompanying
 3  // file COPYING or https://www.opensource.org/licenses/mit-license.php.
 4  
 5  #ifndef BITCOIN_TEST_UTIL_COMMON_H
 6  #define BITCOIN_TEST_UTIL_COMMON_H
 7  
 8  #include <chrono>
 9  #include <optional>
10  #include <ostream>
11  #include <string>
12  
13  /**
14   * BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
15   * Use as
16   * BOOST_CHECK_EXCEPTION(code that throws, exception type, HasReason("foo"));
17   */
18  class HasReason
19  {
20  public:
21      explicit HasReason(std::string_view reason) : m_reason(reason) {}
22      bool operator()(std::string_view s) const { return s.find(m_reason) != std::string_view::npos; }
23      bool operator()(const std::exception& e) const { return (*this)(e.what()); }
24  
25  private:
26      const std::string m_reason;
27  };
28  
29  // Make types usable in BOOST_CHECK_* @{
30  namespace std {
31  template <typename Clock, typename Duration>
32  inline std::ostream& operator<<(std::ostream& os, const std::chrono::time_point<Clock, Duration>& tp)
33  {
34      return os << tp.time_since_epoch().count();
35  }
36  
37  template <typename T> requires std::is_enum_v<T>
38  inline std::ostream& operator<<(std::ostream& os, const T& e)
39  {
40      return os << static_cast<std::underlying_type_t<T>>(e);
41  }
42  
43  template <typename T>
44  inline std::ostream& operator<<(std::ostream& os, const std::optional<T>& v)
45  {
46      return v ? os << *v
47               : os << "std::nullopt";
48  }
49  } // namespace std
50  
51  template <typename T>
52  concept HasToString = requires(const T& t) { t.ToString(); };
53  
54  template <HasToString T>
55  inline std::ostream& operator<<(std::ostream& os, const T& obj)
56  {
57      return os << obj.ToString();
58  }
59  
60  // @}
61  
62  #endif // BITCOIN_TEST_UTIL_COMMON_H