diff --git a/src/unittest/test.cpp b/src/unittest/test.cpp index b17aca0bf..761c90813 100644 --- a/src/unittest/test.cpp +++ b/src/unittest/test.cpp @@ -330,7 +330,7 @@ std::string TestBase::getTestTempDirectory() m_test_dir = fs::TempPath() + DIR_DELIM "mttest_" + buf; if (!fs::CreateDir(m_test_dir)) - throw TestFailedException(); + UASSERT(false); return m_test_dir; } @@ -343,6 +343,26 @@ std::string TestBase::getTestTempFile() return getTestTempDirectory() + DIR_DELIM + buf + ".tmp"; } +void TestBase::runTest(const char *name, std::function &&test) +{ + u64 t1 = porting::getTimeMs(); + try { + test(); + rawstream << "[PASS] "; + } catch (TestFailedException &e) { + rawstream << "Test assertion failed: " << e.message << std::endl; + rawstream << " at " << e.file << ":" << e.line << std::endl; + rawstream << "[FAIL] "; + num_tests_failed++; + } catch (std::exception &e) { + rawstream << "Caught unhandled exception: " << e.what() << std::endl; + rawstream << "[FAIL] "; + num_tests_failed++; + } + num_tests_run++; + u64 tdiff = porting::getTimeMs() - t1; + rawstream << name << " - " << tdiff << "ms" << std::endl; +} /* NOTE: These tests became non-working then NodeContainer was removed. diff --git a/src/unittest/test.h b/src/unittest/test.h index 8782bc92b..881189adf 100644 --- a/src/unittest/test.h +++ b/src/unittest/test.h @@ -19,7 +19,9 @@ with this program; if not, write to the Free Software Foundation, Inc., #pragma once +#include #include +#include #include #include "irrlichttypes_extrabloated.h" @@ -27,63 +29,48 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "filesys.h" #include "mapnode.h" -class TestFailedException : public std::exception { +class TestFailedException { // don’t derive from std::exception to avoid accidental catch +public: + TestFailedException(std::string in_message, const char *in_file, int in_line) + : message(std::move(in_message)) + , file(fs::GetFilenameFromPath(in_file)) + , line(in_line) + {} + + const std::string message; + const std::string file; + const int line; }; // Runs a unit test and reports results -#define TEST(fxn, ...) { \ - u64 t1 = porting::getTimeMs(); \ - try { \ - fxn(__VA_ARGS__); \ - rawstream << "[PASS] "; \ - } catch (TestFailedException &e) { \ - rawstream << "[FAIL] "; \ - num_tests_failed++; \ - } catch (std::exception &e) { \ - rawstream << "Caught unhandled exception: " << e.what() << std::endl; \ - rawstream << "[FAIL] "; \ - num_tests_failed++; \ - } \ - num_tests_run++; \ - u64 tdiff = porting::getTimeMs() - t1; \ - rawstream << #fxn << " - " << tdiff << "ms" << std::endl; \ -} +#define TEST(fxn, ...) runTest(#fxn, [&] () { fxn(__VA_ARGS__); }); // Asserts the specified condition is true, or fails the current unit test -#define UASSERT(x) \ - if (!(x)) { \ - rawstream << "Test assertion failed: " #x << std::endl \ - << " at " << fs::GetFilenameFromPath(__FILE__) \ - << ":" << __LINE__ << std::endl; \ - throw TestFailedException(); \ +#define UASSERT(x) \ + if (!(x)) { \ + throw TestFailedException(#x, __FILE__, __LINE__); \ } // Asserts the specified condition is true, or fails the current unit test // and prints the format specifier fmt -#define UTEST(x, fmt, ...) \ - if (!(x)) { \ - char utest_buf[1024]; \ - snprintf(utest_buf, sizeof(utest_buf), fmt, __VA_ARGS__); \ - rawstream << "Test assertion failed: " << utest_buf << std::endl \ - << " at " << fs::GetFilenameFromPath(__FILE__) \ - << ":" << __LINE__ << std::endl; \ - throw TestFailedException(); \ +#define UTEST(x, fmt, ...) \ + if (!(x)) { \ + char utest_buf[1024]; \ + snprintf(utest_buf, sizeof(utest_buf), fmt, __VA_ARGS__); \ + throw TestFailedException(utest_buf, __FILE__, __LINE__); \ } // Asserts the comparison specified by CMP is true, or fails the current unit test -#define UASSERTCMP(T, CMP, actual, expected) { \ - T a = (actual); \ - T e = (expected); \ - if (!(a CMP e)) { \ - rawstream \ - << "Test assertion failed: " << #actual << " " << #CMP << " " \ - << #expected << std::endl \ - << " at " << fs::GetFilenameFromPath(__FILE__) << ":" \ - << __LINE__ << std::endl \ - << " actual : " << a << std::endl << " expected: " \ - << e << std::endl; \ - throw TestFailedException(); \ - } \ +#define UASSERTCMP(T, CMP, actual, expected) { \ + T a = (actual); \ + T e = (expected); \ + if (!(a CMP e)) { \ + std::ostringstream message; \ + message << #actual " " #CMP " " #expected; \ + message << std::endl << " actual : " << a; \ + message << std::endl << " expected: " << e; \ + throw TestFailedException(message.str(), __FILE__, __LINE__); \ + } \ } #define UASSERTEQ(T, actual, expected) UASSERTCMP(T, ==, actual, expected) @@ -113,6 +100,8 @@ public: u32 num_tests_failed; u32 num_tests_run; + void runTest(const char *name, std::function &&test); + private: std::string m_test_dir; };