asserts_used_outside_of_tests.cpp (2806B)
1 #ifndef DOCTEST_CONFIG_DISABLE 2 #define DOCTEST_CONFIG_SUPER_FAST_ASSERTS // defined so the asserts are crazy fast - both for compilation and execution 3 #endif 4 5 #include <doctest/doctest.h> 6 7 #include "header.h" 8 9 DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_BEGIN 10 #include <iostream> 11 #include <cstring> 12 #include <algorithm> 13 DOCTEST_MAKE_STD_HEADERS_CLEAN_FROM_WARNINGS_ON_WALL_END 14 DOCTEST_GCC_SUPPRESS_WARNING("-Wmissing-declarations") 15 DOCTEST_CLANG_SUPPRESS_WARNING("-Wmissing-prototypes") 16 17 // some function which uses asserts not just for unit testing but also for ensuring contracts in production code 18 static void some_func() { 19 CHECK_EQ(true, false); 20 CHECK_UNARY(false); 21 CHECK_UNARY_FALSE(true); 22 23 CHECK(false); 24 CHECK_THROWS(std::cout << "hello! \n"); 25 } 26 27 // std::mutex g_mut; 28 29 static void handler(const doctest::AssertData& ad) { 30 using namespace doctest; 31 32 // uncomment if asserts will be used in a multi-threaded context 33 // std::lock_guard<std::mutex> lock(g_mut); 34 35 // here we can choose what to do: 36 // - log the failed assert 37 // - throw an exception 38 // - call std::abort() or std::terminate() 39 40 std::cout << Color::LightGrey << skipPathFromFilename(ad.m_file) << "(" << ad.m_line << "): "; 41 std::cout << Color::Red << failureString(ad.m_at) << ": "; 42 43 // handling only normal (comparison and unary) asserts - exceptions-related asserts have been skipped 44 if(ad.m_at & assertType::is_normal) { 45 std::cout << Color::Cyan << assertString(ad.m_at) << "( " << ad.m_expr << " ) "; 46 std::cout << Color::None << (ad.m_threw ? "THREW exception: " : "is NOT correct!\n"); 47 if(ad.m_threw) 48 std::cout << ad.m_exception; 49 else 50 std::cout << " values: " << assertString(ad.m_at) << "( " << ad.m_decomp << " )"; 51 } else { 52 std::cout << Color::None << "an assert dealing with exceptions has failed!"; 53 } 54 55 std::cout << std::endl; 56 } 57 58 void some_program_code(int argc, char** argv) { 59 // IGNORE THIS: return if the current test from the doctest CMake tests is not for this file 60 if(std::find_if(argv, argv + argc, [](const char* str) { return strcmp(str, "-sf=*asserts_used_outside_of_tests.cpp") == 0; }) == argv + argc) return; 61 62 // construct a context 63 doctest::Context context(argc, argv); 64 65 // sets the context as the default one - so asserts used outside of a testing context do not crash 66 context.setAsDefaultForAssertsOutOfTestCases(); 67 68 // set a handler with a signature: void(const doctest::AssertData&) 69 // without setting a handler we would get std::abort() called when an assert fails 70 context.setAssertHandler(handler); 71 72 // call the function with asserts out of a testing context - the above handler will be called on failure 73 some_func(); 74 }