doctest

FORK: The fastest feature-rich C++11/14/17/20 single-header testing framework
git clone https://git.neptards.moe/neptards/doctest.git
Log | Files | Refs | README

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 }