add some basic unit test infra to allow testing together with impl

master
Daniel Kolesa 2017-04-23 17:54:51 +02:00
parent cc8452e265
commit d359e46818
4 changed files with 147 additions and 13 deletions

View File

@ -37,6 +37,8 @@
#ifndef OSTD_RANGE_HH
#define OSTD_RANGE_HH
#include "ostd/unit_test.hh"
#include <cstddef>
#include <new>
#include <tuple>
@ -1328,6 +1330,17 @@ inline auto range(T v) {
return detail::number_range<T>(v);
}
OSTD_UNIT_TEST(range, {
auto r = range(5, 10, 2);
fail_if(r.empty() || (r.front() != 5));
r.pop_front();
fail_if(r.empty() || (r.front() != 7));
r.pop_front();
fail_if(r.empty() || (r.front() != 9));
r.pop_front();
fail_if(!r.empty());
});
namespace detail {
template<typename T>
struct reverse_range: input_range<reverse_range<T>> {

113
ostd/unit_test.hh 100644
View File

@ -0,0 +1,113 @@
/** @defgroup Testing
*
* @brief Reusable unit test infrastructure.
*
* This module defines header-only infra for unit tests that can be used to
* integrate tests directly where the implementation is. All you really need
* to do then is enable a macro, include the file you're testing and compile
* into an executable.
*
* @{
*/
/** @file unit_test.hh
*
* @brief The unit test infrastructure implementation.
*
* Include this at the very beginning in the files you want to define unit
* tests in. It has no dependencies within libostd.
*
* @copyright See COPYING.md in the project tree for further information.
*/
#ifndef OSTD_UNIT_TEST_HH
#define OSTD_UNIT_TEST_HH
#ifdef OSTD_BUILD_TESTS
#include <cstdio>
#include <cstddef>
#include <vector>
#include <string>
#include <functional>
#include <stdexcept>
#endif
namespace ostd {
namespace test {
/** @addtogroup Testing
* @{
*/
#ifdef OSTD_BUILD_TESTS
#define OSTD_TEST_MODULE_STRINGIFY(x) #x
#define OSTD_TEST_MODULE_STR(x) OSTD_TEST_MODULE_STRINGIFY(x)
#define OSTD_TEST_MODULE OSTD_TEST_MODULE_STR(OSTD_BUILD_TESTS)
static std::vector<void (*)()> test_cases;
static bool add_test(std::string testn, void (*func)()) {
if (testn == OSTD_TEST_MODULE) {
test_cases.push_back(func);
}
return true;
}
#define OSTD_UNIT_TEST(module, body) \
static bool test_case_##module##_##__LINE__ = \
ostd::test::add_test(#module, []() { using namespace ostd::test; body });
struct test_error {};
void fail_if(bool b) {
if (b) {
throw test_error{};
}
}
void fail_if_not(bool b) {
if (!b) {
throw test_error{};
}
}
void run() {
int succ = 0, fail = 0;
for (auto &f: test_cases) {
try {
f();
} catch (test_error) {
++fail;
continue;
}
++succ;
}
#if defined(_WIN32) || defined(WIN32)
printf(
"%s...\t%d out of %d (%d failures)\n",
OSTD_TEST_MODULE, succ, succ + fail, fail
);
#else
printf(
"%s...\t%s\033[1m%d out of %d\033[0m (%d failures)\n",
OSTD_TEST_MODULE, fail ? "\033[91m" : "\033[92m",
succ, succ + fail, fail
);
#endif
}
#else /* OSTD_BUILD_TESTS */
#define OSTD_UNIT_TEST(module, body)
#endif /* OSTD_BUILD_TESTS */
/** @} */
} /* namespace test */
} /* namespace ostd */
#endif
/** @} */

View File

@ -36,17 +36,12 @@ int main() {
/* do not change past this point */
int nsuccess = 0, nfailed = 0;
std::string modname = nullptr;
std::string modname;
auto print_result = [&](string_range fmsg = nullptr) {
auto print_error = [&](string_range fmsg) {
write(modname, "...\t");
if (!fmsg.empty()) {
writeln(COLOR_RED, COLOR_BOLD, '(', fmsg, ')', COLOR_END);
++nfailed;
} else {
writeln(COLOR_GREEN, COLOR_BOLD, "(success)", COLOR_END);
++nsuccess;
}
writeln(COLOR_RED, COLOR_BOLD, '(', fmsg, ')', COLOR_END);
++nfailed;
};
filesystem::directory_iterator ds{testdir};
@ -70,7 +65,7 @@ int main() {
auto cxxcmd = appender<std::string>();
format(
cxxcmd, "%s %s%s%s -o %s %s", compiler, testdir,
cxxcmd, "%s %s%s%s -o %s %s ", compiler, testdir,
char(filesystem::path::preferred_separator),
p.filename(), exepath, cxxflags
);
@ -78,20 +73,24 @@ int main() {
cxxcmd.get() += ' ';
cxxcmd.get() += userflags;
}
cxxcmd.get() += ' ';
cxxcmd.get() += "-DOSTD_BUILD_TESTS=";
cxxcmd.get() += modname;
int ret = system(cxxcmd.get().data());
if (ret) {
print_result("compile errror");
print_error("compile errror");
continue;
}
ret = system(exepath.data());
if (ret) {
print_result("runtime error");
print_error("runtime error");
continue;
}
remove(exepath.data());
print_result();
++nsuccess;
}
writeln("\n", COLOR_BLUE, COLOR_BOLD, "testing done:", COLOR_END);

9
tests/range.cc 100644
View File

@ -0,0 +1,9 @@
#define OSTD_BUILD_TESTS range
#include <ostd/unit_test.hh>
#include <ostd/range.hh>
int main() {
ostd::test::run();
return 0;
}