Commit ecb4ab20 authored by Gauthier Quesnel's avatar Gauthier Quesnel
Browse files

unit-test: added

parent 68493de7
/* Copyright (C) 2016-2018 INRA
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef ORG_VLEPROJECT_BITS_UNIT_TEST_HPP
#define ORG_VLEPROJECT_BITS_UNIT_TEST_HPP
#include <cstdio>
#include <cstdlib>
namespace unit_test {
namespace detail {
struct tester
{
int errors = 0;
bool called_report_function = false;
tester& operator++() noexcept
{
errors++;
return *this;
}
~tester() noexcept
{
if (called_report_function == false) {
fprintf(stderr,
"unit_test::report_errors() not called.\n\nUsage:\n"
"int main(int argc, char*[] argc)\n"
"{\n"
" [...]\n"
" return unit_test::report_errors();\n"
"}\n");
std::abort();
}
}
};
inline tester&
test_errors()
{
static tester t;
return t;
}
inline void
ensures_impl(const char* expr,
const char* file,
int line,
const char* function)
{
fprintf(stderr,
"%s (%d): test '%s' failed in function '%s'\n",
file,
line,
expr,
function);
++test_errors();
}
inline void
ensures_equal_impl(const char* expr1,
const char* expr2,
const char* file,
int line,
const char* function)
{
fprintf(stderr,
"%s (%d): test '%s == %s' failed in function '%s'\n",
file,
line,
expr1,
expr2,
function);
++test_errors();
}
inline void
ensures_not_equal_impl(const char* expr1,
const char* expr2,
const char* file,
int line,
const char* function)
{
fprintf(stderr,
"%s (%d): test '%s != %s' failed in function '%s'\n",
file,
line,
expr1,
expr2,
function);
++test_errors();
}
inline void
ensures_throw_impl(const char* excep,
const char* file,
int line,
const char* function)
{
fprintf(stderr,
"%s (%d): exception '%s' throw failed in function '%s'\n",
file,
line,
excep,
function);
++test_errors();
}
inline void
ensures_not_throw_impl(const char* excep,
const char* file,
int line,
const char* function)
{
fprintf(stderr,
"%s (%d): exception '%s' not throw failed in function '%s'\n",
file,
line,
excep,
function);
++test_errors();
}
} // namespace details
inline int
report_errors()
{
auto& tester = unit_test::detail::test_errors();
tester.called_report_function = true;
int errors = tester.errors;
if (errors == 0) {
fprintf(stderr, "No errors detected.\n");
} else {
fprintf(
stderr, "%d error%s detected.\n", errors, (errors == 1 ? "" : "s"));
}
return errors;
}
} // namespace unit_test
#define Ensures(expr) \
do { \
if (not(expr)) { \
unit_test::detail::ensures_impl( \
#expr, __FILE__, __LINE__, __func__); \
return; \
} \
} while (0)
#define EnsuresEqual(expr1, expr2) \
do { \
if (not((expr1) == (expr2))) { \
unit_test::detail::ensures_equal_impl( \
#expr1, #expr2, __FILE__, __LINE__, __func__); \
return; \
} \
} while (0)
#define EnsuresNotEqual(expr1, expr2) \
do { \
if (not((expr1) != (expr2))) { \
unit_test::detail::ensures_not_equal_impl( \
#expr1, #expr2, __FILE__, __LINE__, __func__); \
return; \
} \
} while (0)
#define EnsuresThrow(expr, Excep) \
do { \
try { \
expr; \
unit_test::detail::ensures_throw_impl( \
#Excep, __FILE__, __LINE__, __func__); \
return; \
} catch (const Excep&) { \
} catch (...) { \
unit_test::detail::ensures_throw_impl( \
#Excep, __FILE__, __LINE__, __func__); \
return; \
} \
} while (0)
#define EnsuresNotThrow(expr, Excep) \
do { \
try { \
expr; \
} catch (const Excep&) { \
unit_test::detail::ensures_not_throw_impl( \
#Excep, __FILE__, __LINE__, __func__); \
return; \
} catch (...) { \
} \
} while (0)
#endif
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment