summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBent Bisballe Nyeng <bbn@mjolner.dk>2020-10-26 15:33:28 +0100
committerBent Bisballe Nyeng <bbn@mjolner.dk>2020-10-26 15:33:28 +0100
commit1bd908531600b1392d98f2e3bfa21e3227df670b (patch)
tree8f3200c54ddfad8778b28b13ea3dc064a5f941c3
parent128ba328ae7ff645cdec616d5519f5cf0a278079 (diff)
Add exception catching to make sure, a test that results in an exception being thrown, will result in a test case failure.
-rw-r--r--uunit.h58
1 files changed, 46 insertions, 12 deletions
diff --git a/uunit.h b/uunit.h
index de9c93e..c4c53ee 100644
--- a/uunit.h
+++ b/uunit.h
@@ -13,6 +13,7 @@
#include <sstream>
#include <fstream>
#include <cmath>
+#include <exception>
class uUnit
{
@@ -47,6 +48,7 @@ public:
std::string file;
std::size_t line;
std::string msg;
+ std::string failure_type;
int id;
};
@@ -70,7 +72,7 @@ public:
try
{
suite->setup();
- test.first();
+ test.func();
suite->teardown();
}
catch(test_result& result)
@@ -78,18 +80,41 @@ public:
std::cout << "F";
fflush(stdout);
result.id = test_num;
- result.func = test.second;
+ result.func = test.name;
+ result.failure_type = "Assertion";
failed_tests.push_back(result);
++failed;
continue;
}
catch(...)
{
- break; // Uncaught exception. Do not proceed with this test.
+ test_result result;
+ std::cout << "F";
+ fflush(stdout);
+ result.id = test_num;
+ result.func = test.name;
+ result.file = test.file;
+ result.line = 0;
+ try
+ {
+ throw;
+ }
+ catch(std::exception& e)
+ {
+ result.msg = std::string("Uncaught exception: ") + e.what();
+ }
+ catch(...)
+ {
+ result.msg = "Uncaught exception without std::exception type";
+ }
+ result.failure_type = "Exception";
+ failed_tests.push_back(result);
+ ++failed;
+ continue;
}
std::cout << ".";
fflush(stdout);
- test_result result{test.second};
+ test_result result{test.name};
result.id = test_num;
successful_tests.push_back(result);
}
@@ -99,11 +124,12 @@ public:
std::endl;
out << "<TestRun>" << std::endl;
out << " <FailedTests>" << std::endl;
- for(auto test : failed_tests)
+ for(const auto& test : failed_tests)
{
- out << " <FailedTest id=\"" << test.id << "\">" << std::endl;
+ out << " <FailedTest id=\"" << test.id << "\">" << std::endl; // constexpr newline cross-platform specifik
out << " <Name>" << sanitize(test.func) << "</Name>" << std::endl;
- out << " <FailureType>Assertion</FailureType>" << std::endl;
+ out << " <FailureType>" << sanitize(test.failure_type) <<
+ "</FailureType>" << std::endl;
out << " <Location>" << std::endl;
out << " <File>" << sanitize(test.file) << "</File>" << std::endl;
out << " <Line>" << test.line << "</Line>" << std::endl;
@@ -114,7 +140,7 @@ public:
}
out << " </FailedTests>" << std::endl;
out << " <SuccessfulTests>" << std::endl;
- for(auto test : successful_tests)
+ for(const auto& test : successful_tests)
{
out << " <Test id=\"" << test.id << "\">" << std::endl;
out << " <Name>" << sanitize(test.func) << "</Name>" << std::endl;
@@ -138,12 +164,12 @@ public:
protected:
template<typename O, typename F>
- void registerTest(O* obj, const F& fn, const char* name)
+ void registerTest(O* obj, const F& fn, const char* name, const char* file)
{
- tests.emplace_back(std::make_pair(std::bind(fn, obj), name));
+ tests.push_back({std::bind(fn, obj), name, file});
}
#define uUNIT_TEST(func) \
- registerTest(this, &func, #func)
+ registerTest(this, &func, #func, __FILE__)
void u_assert(bool value, const char* expr,
const char* file, std::size_t line)
@@ -219,7 +245,15 @@ private:
static uUnit* suite_list;
uUnit* next_unit{nullptr};
- std::vector<std::pair<std::function<void()>, const char*>> tests;
+
+ struct test_t
+ {
+ std::function<void()> func;
+ const char* name;
+ const char* file;
+ };
+
+ std::vector<test_t> tests;
};
#ifdef uUNIT_MAIN