Repository: bitcoin/bitcoin
File: src/test/util/setup_common.h (C/C++)

Code before:

    std::vector<CTransactionRef> m_coinbase_txns; // For convenience, coinbase transactions
    CKey coinbaseKey; // private/public key needed to spend coinbase transactions
};

/**
 * Make a test setup that has disk access to the debug.log file disabled. Can
 * be used in "hot loops", for example fuzzing or benchmarking.
 */
template <class T = const BasicTestingSetup>
std::unique_ptr<T> MakeNoLogFileContext(const ChainType chain_type = ChainType::REGTEST, TestOpts opts = {})
{
    opts.extra_args = Cat(
        {
            "-nodebuglogfile",
            "-nodebug",
        },
        opts.extra_args);

    return std::make_unique<T>(chain_type, opts);
}

CBlock getBlock13b8a();

// Make types usable in BOOST_CHECK_*
std::ostream& operator<<(std::ostream& os, const arith_uint256& num);
std::ostream& operator<<(std::ostream& os, const uint160& num);
std::ostream& operator<<(std::ostream& os, const uint256& num);

/**
 * BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
 * Use as
 * BOOST_CHECK_EXCEPTION(code that throws, exception type, HasReason("foo"));
 */
class HasReason
{
public:
    explicit HasReason(const std::string& reason) : m_reason(reason) {}
    bool operator()(const std::exception& e) const
    {
        return std::string(e.what()).find(m_reason) != std::string::npos;
    };

private:
    const std::string m_reason;
};

#endif // BITCOIN_TEST_UTIL_SETUP_COMMON_H


Review comment (suggestion):
This can be cleaned up in C++20:

<details>
<summary>git diff on e0a96acc82</summary>

```diff
diff --git a/src/test/util/setup_common.h b/src/test/util/setup_common.h
index cea1481c88..0a65726395 100644
--- a/src/test/util/setup_common.h
+++ b/src/test/util/setup_common.h
@@ -243,11 +243,10 @@ CBlock getBlock13b8a();
 
 // Make types usable in BOOST_CHECK_* {
 namespace std {
-// Enum class types
-template <typename T>
-inline std::ostream& operator<<(typename std::enable_if<std::is_enum<T>::value, std::ostream>::type& stream, const T& e)
+template <typename T> requires std::is_enum_v<T>
+inline std::ostream& operator<<(std::ostream& stream, const T& e)
 {
-    return stream << static_cast<typename std::underlying_type<T>::type>(e);
+    return stream << static_cast<std::underlying_type_t<T>>(e);
 }
 
 template <typename T>

```
</details>


Code after:
/**
 * Make a test setup that has disk access to the debug.log file disabled. Can
 * be used in "hot loops", for example fuzzing or benchmarking.
 */
template <class T = const BasicTestingSetup>
std::unique_ptr<T> MakeNoLogFileContext(const ChainType chain_type = ChainType::REGTEST, TestOpts opts = {})
{
    opts.extra_args = Cat(
        {
            "-nodebuglogfile",
            "-nodebug",
        },
        opts.extra_args);

    return std::make_unique<T>(chain_type, opts);
}

CBlock getBlock13b8a();

// Make types usable in BOOST_CHECK_* @{
namespace std {
template <typename T> requires std::is_enum_v<T>
inline std::ostream& operator<<(std::ostream& os, const T& e)
{
    return os << static_cast<std::underlying_type_t<T>>(e);
}

template <typename T>
inline std::ostream& operator<<(std::ostream& os, const std::optional<T>& v)
{
    return v ? os << *v
             : os << "std::nullopt";
}
} // namespace std

std::ostream& operator<<(std::ostream& os, const arith_uint256& num);
std::ostream& operator<<(std::ostream& os, const uint160& num);
std::ostream& operator<<(std::ostream& os, const uint256& num);
// @}

/**
 * BOOST_CHECK_EXCEPTION predicates to check the specific validation error.
 * Use as
 * BOOST_CHECK_EXCEPTION(code that throws, exception type, HasReason("foo"));
 */
class HasReason
{
public:
    explicit HasReason(const std::string& reason) : m_reason(reason) {}
    bool operator()(const std::exception& e) const
    {