#ifndef _TEST_H_ #define _TEST_H_ #include #include #include #include #include #include struct test { std::string name; std::function f; }; std::vector tests; struct test_holder { test_holder(const test& t) { tests.push_back(t); } }; #define TEST(f) \ void test_##f(); \ test test_item##f = {#f, test_##f}; \ test_holder test_holder##f(test_item##f); \ void test_##f() \ #ifdef _MSC_VER # define TEST_NORETURN __declspec(noreturn) #elif defined __GNUC__ # define TEST_NORETURN __attribute__ ((noreturn)) #else # define TEST_NORETURN #endif TEST_NORETURN void error(std::string message) { std::cout << "ERROR: " << message << std::endl; exit(1); } void ensure_exit(int exit_code, std::function f) { try { f(); } catch (exit_exception& e) { if (e.getExitCode() != exit_code) { error("Expected exit code " + std::to_string(exit_code) + " but found " + std::to_string(e.getExitCode())); } else return; } catch (...) { error("Expected exit_exception, but got other exception"); } error("Expected exit_exception, but not exception got"); } void run_tests() { for (const auto& t: tests) { std::string title = "Running test '" + t.name + "'"; while (title.length() < 100) title += ' '; std::cout << title; try { t.f(); } catch (exit_exception& e) { error("Teslib exited with code " + std::to_string(e.getExitCode())); } catch (...) { error("Unexpected exception"); std::exit(1); } std::cout << "OK" << std::endl; } std::cout << std::endl << "SUCCESS " << tests.size() << " tests passed." << std::endl; } #endif