Improve failure reporting and add more assertions
Adds BV_NOTHROW, BV_THROWS, and BV_THROWS_ANY. Improves failure reporting.
This commit is contained in:
@@ -40,6 +40,10 @@ namespace bitshift::validate
|
|||||||
o << "\033[0m";
|
o << "\033[0m";
|
||||||
|
|
||||||
switch (ansi.get_color()) {
|
switch (ansi.get_color()) {
|
||||||
|
case ansi::kNone:
|
||||||
|
o << "\033[0";
|
||||||
|
break;
|
||||||
|
|
||||||
case ansi::kBlack:
|
case ansi::kBlack:
|
||||||
o << "\033[30";
|
o << "\033[30";
|
||||||
break;
|
break;
|
||||||
@@ -109,7 +113,7 @@ namespace bitshift::validate
|
|||||||
ostream&
|
ostream&
|
||||||
operator<<(ostream& o, ansi::style const& style)
|
operator<<(ostream& o, ansi::style const& style)
|
||||||
{
|
{
|
||||||
return o << ansi{ansi::color::kBlack, style};
|
return o << ansi{ansi::color::kNone, style};
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace bitshift::validate
|
} // namespace bitshift::validate
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ namespace bitshift::validate
|
|||||||
enum color
|
enum color
|
||||||
: uint8_t
|
: uint8_t
|
||||||
{
|
{
|
||||||
|
kNone,
|
||||||
kBlack,
|
kBlack,
|
||||||
kRed,
|
kRed,
|
||||||
kGreen,
|
kGreen,
|
||||||
|
|||||||
@@ -1,9 +1,10 @@
|
|||||||
#ifndef bitshift__validate__assert_hxx_
|
#ifndef bitshift__validate__assert_hxx_
|
||||||
#define bitshift__validate__assert_hxx_
|
#define bitshift__validate__assert_hxx_
|
||||||
|
|
||||||
#include <bitshift/validate/types.hxx>
|
|
||||||
#include <bitshift/validate/failure.hxx>
|
#include <bitshift/validate/failure.hxx>
|
||||||
|
#include <bitshift/validate/reporting.hxx>
|
||||||
#include <bitshift/validate/traits.hxx>
|
#include <bitshift/validate/traits.hxx>
|
||||||
|
#include <bitshift/validate/types.hxx>
|
||||||
|
|
||||||
namespace bitshift::validate::assertion
|
namespace bitshift::validate::assertion
|
||||||
{
|
{
|
||||||
@@ -42,6 +43,21 @@ namespace bitshift::validate::assertion
|
|||||||
string const& rhs_str,
|
string const& rhs_str,
|
||||||
source_location const& origin = source_location::current());
|
source_location const& origin = source_location::current());
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
void
|
||||||
|
assert_nothrow(F const& f,
|
||||||
|
source_location const& origin = source_location::current());
|
||||||
|
|
||||||
|
template<typename T, typename F>
|
||||||
|
void
|
||||||
|
assert_throws(F const& f,
|
||||||
|
source_location const& origin = source_location::current());
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
void
|
||||||
|
assert_throws_any(F const& f,
|
||||||
|
source_location const& origin = source_location::current());
|
||||||
|
|
||||||
} // namespace bitshift::validate::assertion
|
} // namespace bitshift::validate::assertion
|
||||||
|
|
||||||
#include <bitshift/validate/assert.txx>
|
#include <bitshift/validate/assert.txx>
|
||||||
|
|||||||
+122
-79
@@ -11,20 +11,18 @@ namespace bitshift::validate::assertion
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string value_str;
|
throw failure{
|
||||||
|
[=](reporter& r)
|
||||||
if constexpr (traits::has_output_operator<T>) {
|
{
|
||||||
stringstream str;
|
auto p = r.log_failure(
|
||||||
str << expr;
|
|
||||||
value_str = str.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw unary_assertion_failure{
|
|
||||||
"expected expression to be true; was false",
|
"expected expression to be true; was false",
|
||||||
origin.file_name(),
|
origin.file_name(),
|
||||||
origin.line(),
|
origin.line()
|
||||||
std::move(expr_str),
|
);
|
||||||
std::move(value_str)
|
|
||||||
|
p << "expression: " << expr_str << '\n';
|
||||||
|
p << "value : " << expr << '\n';
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -38,20 +36,18 @@ namespace bitshift::validate::assertion
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string value_str;
|
throw failure{
|
||||||
|
[=](reporter& r)
|
||||||
if constexpr (traits::has_output_operator<T>) {
|
{
|
||||||
stringstream str;
|
auto p = r.log_failure(
|
||||||
str << expr;
|
|
||||||
value_str = str.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw unary_assertion_failure{
|
|
||||||
"expected expression to be false; was true",
|
"expected expression to be false; was true",
|
||||||
origin.file_name(),
|
origin.file_name(),
|
||||||
origin.line(),
|
origin.line()
|
||||||
std::move(expr_str),
|
);
|
||||||
std::move(value_str)
|
|
||||||
|
p << "expression: " << expr_str << '\n';
|
||||||
|
p << "value : " << expr << '\n';
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,20 +61,18 @@ namespace bitshift::validate::assertion
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string value_str;
|
throw failure{
|
||||||
|
[=](reporter& r)
|
||||||
if constexpr (traits::has_output_operator<T>) {
|
{
|
||||||
stringstream str;
|
auto p = r.log_failure(
|
||||||
str << expr;
|
"expected expression to be null; was not",
|
||||||
value_str = str.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw unary_assertion_failure{
|
|
||||||
"expected expression to be null; was not null",
|
|
||||||
origin.file_name(),
|
origin.file_name(),
|
||||||
origin.line(),
|
origin.line()
|
||||||
std::move(expr_str),
|
);
|
||||||
std::move(value_str)
|
|
||||||
|
p << "expression: " << expr_str << '\n';
|
||||||
|
p << "value : " << expr << '\n';
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -94,29 +88,20 @@ namespace bitshift::validate::assertion
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string lhs_val;
|
throw failure{
|
||||||
std::string rhs_val;
|
[=](reporter& r)
|
||||||
|
{
|
||||||
if constexpr (traits::has_output_operator<T1>) {
|
auto p = r.log_failure(
|
||||||
std::stringstream str;
|
|
||||||
str << lhs;
|
|
||||||
lhs_val = str.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
if constexpr (traits::has_output_operator<T2>) {
|
|
||||||
std::stringstream str;
|
|
||||||
str << rhs;
|
|
||||||
rhs_val = str.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw binary_assertion_failure{
|
|
||||||
"expected lhs to equal rhs",
|
"expected lhs to equal rhs",
|
||||||
origin.file_name(),
|
origin.file_name(),
|
||||||
origin.line(),
|
origin.line()
|
||||||
std::move(lhs_str),
|
);
|
||||||
std::move(lhs_val),
|
|
||||||
std::move(rhs_str),
|
p << "lhs : " << lhs_str << '\n';
|
||||||
std::move(rhs_val)
|
p << "lhs value: " << lhs << '\n';
|
||||||
|
p << "rhs : " << rhs_str << '\n';
|
||||||
|
p << "rhs value: " << rhs << '\n';
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,29 +117,87 @@ namespace bitshift::validate::assertion
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string lhs_val;
|
throw failure{
|
||||||
std::string rhs_val;
|
[=](reporter& r)
|
||||||
|
{
|
||||||
if constexpr (traits::has_output_operator<T1>) {
|
auto p = r.log_failure(
|
||||||
std::stringstream str;
|
|
||||||
str << lhs;
|
|
||||||
lhs_val = str.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
if constexpr (traits::has_output_operator<T2>) {
|
|
||||||
std::stringstream str;
|
|
||||||
str << rhs;
|
|
||||||
rhs_val = str.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
throw binary_assertion_failure{
|
|
||||||
"expected lhs to not equal rhs",
|
"expected lhs to not equal rhs",
|
||||||
origin.file_name(),
|
origin.file_name(),
|
||||||
origin.line(),
|
origin.line()
|
||||||
std::move(lhs_str),
|
);
|
||||||
std::move(lhs_val),
|
|
||||||
std::move(rhs_str),
|
p << "lhs : " << lhs_str << '\n';
|
||||||
std::move(rhs_val)
|
p << "lhs value: " << lhs << '\n';
|
||||||
|
p << "rhs : " << rhs_str << '\n';
|
||||||
|
p << "rhs value: " << rhs << '\n';
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
void
|
||||||
|
assert_nothrow(F const& f, source_location const& origin)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
throw failure{
|
||||||
|
[=](reporter& r)
|
||||||
|
{
|
||||||
|
auto p = r.log_failure(
|
||||||
|
"expression unexpectedly threw an exception",
|
||||||
|
origin.file_name(),
|
||||||
|
origin.line()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, typename F>
|
||||||
|
void
|
||||||
|
assert_throws(F const& f, source_location const& origin)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
catch (T const&) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw failure{
|
||||||
|
[=](reporter& r)
|
||||||
|
{
|
||||||
|
auto p = r.log_failure(
|
||||||
|
"expected expression was not thrown",
|
||||||
|
origin.file_name(),
|
||||||
|
origin.line()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename F>
|
||||||
|
void
|
||||||
|
assert_throws_any(F const& f, source_location const& origin)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
f();
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw failure{
|
||||||
|
[=](reporter& r)
|
||||||
|
{
|
||||||
|
auto p = r.log_failure(
|
||||||
|
"expected expression was not thrown",
|
||||||
|
origin.file_name(),
|
||||||
|
origin.line()
|
||||||
|
);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,11 +73,15 @@ namespace bitshift::validate
|
|||||||
try {
|
try {
|
||||||
tc.run();
|
tc.run();
|
||||||
}
|
}
|
||||||
catch (ignore const&) {
|
catch (ignored const&) {
|
||||||
execute_teardown(r);
|
execute_teardown(r);
|
||||||
return kExecuteIgnored;
|
return kExecuteIgnored;
|
||||||
}
|
}
|
||||||
catch (assertion_failure const& failure) {
|
catch (passed const&) {
|
||||||
|
// No-op.
|
||||||
|
//
|
||||||
|
}
|
||||||
|
catch (failure const& failure) {
|
||||||
failure.report(r);
|
failure.report(r);
|
||||||
execute_teardown(r);
|
execute_teardown(r);
|
||||||
return kExecuteFailed;
|
return kExecuteFailed;
|
||||||
|
|||||||
@@ -1,130 +0,0 @@
|
|||||||
#include <bitshift/validate/failure.hxx>
|
|
||||||
|
|
||||||
#include <bitshift/validate/reporting.hxx>
|
|
||||||
|
|
||||||
namespace bitshift::validate
|
|
||||||
{
|
|
||||||
|
|
||||||
unary_assertion_failure::
|
|
||||||
unary_assertion_failure(string message,
|
|
||||||
string file,
|
|
||||||
uint32_t line,
|
|
||||||
string expr,
|
|
||||||
string val)
|
|
||||||
: _message{std::move(message)}
|
|
||||||
, _file {std::move(file)}
|
|
||||||
, _line {line}
|
|
||||||
, _expr {std::move(expr)}
|
|
||||||
, _val {std::move(val)}
|
|
||||||
{}
|
|
||||||
|
|
||||||
string const&
|
|
||||||
unary_assertion_failure::
|
|
||||||
get_file() const
|
|
||||||
{
|
|
||||||
return _file;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
unary_assertion_failure::
|
|
||||||
get_line() const
|
|
||||||
{
|
|
||||||
return _line;
|
|
||||||
}
|
|
||||||
|
|
||||||
string const&
|
|
||||||
unary_assertion_failure::
|
|
||||||
get_expr() const
|
|
||||||
{
|
|
||||||
return _expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
string const&
|
|
||||||
unary_assertion_failure::
|
|
||||||
get_val() const
|
|
||||||
{
|
|
||||||
return _val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
unary_assertion_failure::
|
|
||||||
report(reporter& r) const
|
|
||||||
{
|
|
||||||
auto p = r.log_failure(_message, _file, _line);
|
|
||||||
|
|
||||||
p << "expression: " << _expr << '\n';
|
|
||||||
p << "value : " << _val << '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
binary_assertion_failure::
|
|
||||||
binary_assertion_failure(string message,
|
|
||||||
string file,
|
|
||||||
uint32_t line,
|
|
||||||
string lhs_expr,
|
|
||||||
string lhs_val,
|
|
||||||
string rhs_expr,
|
|
||||||
string rhs_val)
|
|
||||||
: _message {std::move(message)}
|
|
||||||
, _file {std::move(file)}
|
|
||||||
, _line {line}
|
|
||||||
, _lhs_expr{std::move(lhs_expr)}
|
|
||||||
, _lhs_val {std::move(lhs_val)}
|
|
||||||
, _rhs_expr{std::move(rhs_expr)}
|
|
||||||
, _rhs_val {std::move(rhs_val)}
|
|
||||||
{}
|
|
||||||
|
|
||||||
string const&
|
|
||||||
binary_assertion_failure::
|
|
||||||
get_file() const
|
|
||||||
{
|
|
||||||
return _file;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t
|
|
||||||
binary_assertion_failure::
|
|
||||||
get_line() const
|
|
||||||
{
|
|
||||||
return _line;
|
|
||||||
}
|
|
||||||
|
|
||||||
string const&
|
|
||||||
binary_assertion_failure::
|
|
||||||
get_lhs_expr() const
|
|
||||||
{
|
|
||||||
return _lhs_expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
string const&
|
|
||||||
binary_assertion_failure::
|
|
||||||
get_lhs_val() const
|
|
||||||
{
|
|
||||||
return _lhs_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
string const&
|
|
||||||
binary_assertion_failure::
|
|
||||||
get_rhs_expr() const
|
|
||||||
{
|
|
||||||
return _rhs_expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
string const&
|
|
||||||
binary_assertion_failure::
|
|
||||||
get_rhs_val() const
|
|
||||||
{
|
|
||||||
return _rhs_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
binary_assertion_failure::
|
|
||||||
report(reporter& r) const
|
|
||||||
{
|
|
||||||
auto p = r.log_failure(_message, _file, _line);
|
|
||||||
|
|
||||||
p << "lhs expression: " << _lhs_expr << '\n';
|
|
||||||
p << "lhs value : " << _lhs_val << '\n';
|
|
||||||
p << "rhs expression: " << _rhs_expr << '\n';
|
|
||||||
p << "rhs value : " << _rhs_val << '\n';
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace bitshift::validate
|
|
||||||
+52
-177
@@ -2,204 +2,79 @@
|
|||||||
#define bitshift__validate__failure_hxx_
|
#define bitshift__validate__failure_hxx_
|
||||||
|
|
||||||
#include <bitshift/validate/types.hxx>
|
#include <bitshift/validate/types.hxx>
|
||||||
|
#include <bitshift/validate/reporting.hxx>
|
||||||
|
|
||||||
namespace bitshift::validate
|
namespace bitshift::validate
|
||||||
{
|
{
|
||||||
|
|
||||||
struct ignore { };
|
/// @brief Class used to explicitly ignore a test.
|
||||||
|
|
||||||
class reporter;
|
|
||||||
|
|
||||||
/// @brief Class used to indicate an assertion failure.
|
|
||||||
///
|
///
|
||||||
class assertion_failure
|
struct ignored {};
|
||||||
|
|
||||||
|
/// @brief Class used to explicitly pass a test.
|
||||||
|
///
|
||||||
|
struct passed {};
|
||||||
|
|
||||||
|
/// @brief Class used to explicitly fail a test.
|
||||||
|
///
|
||||||
|
class failure
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/// @brief Destructor.
|
/// @brief Constructor.
|
||||||
|
/// @param rf The reporter function.
|
||||||
///
|
///
|
||||||
virtual
|
explicit
|
||||||
~assertion_failure() noexcept = default;
|
failure(function<void(reporter&)> rf)
|
||||||
|
: _rf{rf}
|
||||||
|
{}
|
||||||
|
|
||||||
|
/// @brief Copy-construction is disabled.
|
||||||
|
///
|
||||||
|
failure(failure const&) = delete;
|
||||||
|
|
||||||
|
/// @brief Move-construction is disabled.
|
||||||
|
///
|
||||||
|
failure(failure&&) = delete;
|
||||||
|
|
||||||
/// @brief Report assertion failure.
|
/// @brief Report assertion failure.
|
||||||
///
|
///
|
||||||
/// @param r The reporter.
|
|
||||||
///
|
|
||||||
virtual
|
|
||||||
void
|
void
|
||||||
report(reporter& r) const = 0;
|
report(reporter& r) const
|
||||||
|
|
||||||
protected:
|
|
||||||
/// @brief Constructor.
|
|
||||||
///
|
|
||||||
assertion_failure() = default;
|
|
||||||
|
|
||||||
/// @brief Copy-construction is disabled.
|
|
||||||
///
|
|
||||||
assertion_failure(assertion_failure const&) = delete;
|
|
||||||
|
|
||||||
/// @brief Move-construction is disabled.
|
|
||||||
///
|
|
||||||
assertion_failure(assertion_failure&&) = delete;
|
|
||||||
|
|
||||||
/// @brief Copy-assignment is disabled.
|
|
||||||
///
|
|
||||||
assertion_failure& operator=(assertion_failure const&) = delete;
|
|
||||||
|
|
||||||
/// @brief Move-assignment is disabled.
|
|
||||||
///
|
|
||||||
assertion_failure& operator=(assertion_failure&&) = delete;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @brief Indicates a unary assertion failure.
|
|
||||||
///
|
|
||||||
class unary_assertion_failure
|
|
||||||
: public assertion_failure
|
|
||||||
{
|
{
|
||||||
public:
|
_rf(r);
|
||||||
/// @brief Constructor.
|
}
|
||||||
///
|
|
||||||
/// @param message The assertion failure message.
|
|
||||||
/// @param file The file in which the assertion failure occurred.
|
|
||||||
/// @param line The line on which the assertion failure occurred.
|
|
||||||
/// @param expr The expression that caused the assertion failure.
|
|
||||||
/// @param val The expression value that caused the assertion failure.
|
|
||||||
///
|
|
||||||
unary_assertion_failure(string message,
|
|
||||||
string file,
|
|
||||||
uint32_t line,
|
|
||||||
string expr,
|
|
||||||
string val);
|
|
||||||
|
|
||||||
/// @brief Copy-construction is disabled.
|
|
||||||
///
|
|
||||||
unary_assertion_failure(unary_assertion_failure const&) = delete;
|
|
||||||
|
|
||||||
/// @brief Move-construction is disabled.
|
|
||||||
///
|
|
||||||
unary_assertion_failure(unary_assertion_failure&&) = delete;
|
|
||||||
|
|
||||||
/// @brief Get file.
|
|
||||||
///
|
|
||||||
string const&
|
|
||||||
get_file() const;
|
|
||||||
|
|
||||||
/// @brief Get line.
|
|
||||||
///
|
|
||||||
uint32_t
|
|
||||||
get_line() const;
|
|
||||||
|
|
||||||
/// @brief Get expression.
|
|
||||||
///
|
|
||||||
string const&
|
|
||||||
get_expr() const;
|
|
||||||
|
|
||||||
/// @brief Get expression value.
|
|
||||||
///
|
|
||||||
string const&
|
|
||||||
get_val() const;
|
|
||||||
|
|
||||||
void
|
|
||||||
report(reporter&) const override;
|
|
||||||
|
|
||||||
/// @brief Copy-assignment is disabled.
|
/// @brief Copy-assignment is disabled.
|
||||||
///
|
///
|
||||||
unary_assertion_failure& operator=(unary_assertion_failure const&) = delete;
|
failure& operator=(failure const&) = delete;
|
||||||
|
|
||||||
/// @brief Move-assignment is disabled.
|
/// @brief Move-assignment is disabled.
|
||||||
///
|
///
|
||||||
unary_assertion_failure& operator=(unary_assertion_failure&&) = delete;
|
failure& operator=(failure&&) = delete;
|
||||||
|
|
||||||
|
/// @brief Helper function to throw a failure exception.
|
||||||
|
///
|
||||||
|
/// @param message The message describing the failure.
|
||||||
|
///
|
||||||
|
static
|
||||||
|
void
|
||||||
|
fail(string const& message,
|
||||||
|
source_location const& origin = source_location::current())
|
||||||
|
{
|
||||||
|
throw failure{
|
||||||
|
[=](reporter& r)
|
||||||
|
{
|
||||||
|
r.log_failure(
|
||||||
|
message,
|
||||||
|
origin.file_name(),
|
||||||
|
origin.line()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
string _message;
|
function<void(reporter&)> _rf;
|
||||||
string _file;
|
|
||||||
uint32_t _line{};
|
|
||||||
string _expr;
|
|
||||||
string _val;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @brief Indicates a binary assertion failure.
|
|
||||||
///
|
|
||||||
class binary_assertion_failure
|
|
||||||
: public assertion_failure
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
/// @brief Constructor.
|
|
||||||
///
|
|
||||||
/// @param message The assertion failure message.
|
|
||||||
/// @param file The file in which the assertion failure occurred.
|
|
||||||
/// @param line The line on which the assertion failure occurred.
|
|
||||||
/// @param lhs_expr The left-hand side expression that caused the assertion failure.
|
|
||||||
/// @param lhs_val The left-hand side expression value that caused the assertion failure.
|
|
||||||
/// @param rhs_expr The right-hand side expression that caused the assertion failure.
|
|
||||||
/// @param rhs_val The right-hand side expression value that caused the assertion failure.
|
|
||||||
///
|
|
||||||
binary_assertion_failure(string message,
|
|
||||||
string file,
|
|
||||||
uint32_t line,
|
|
||||||
string lhs_expr,
|
|
||||||
string lhs_val,
|
|
||||||
string rhs_expr,
|
|
||||||
string rhs_val);
|
|
||||||
|
|
||||||
/// @brief Copy-construction is disabled.
|
|
||||||
///
|
|
||||||
binary_assertion_failure(binary_assertion_failure const&) = delete;
|
|
||||||
|
|
||||||
/// @brief Move-construction is disabled.
|
|
||||||
///
|
|
||||||
binary_assertion_failure(binary_assertion_failure&&) = delete;
|
|
||||||
|
|
||||||
/// @brief Get file.
|
|
||||||
///
|
|
||||||
string const&
|
|
||||||
get_file() const;
|
|
||||||
|
|
||||||
/// @brief Get line.
|
|
||||||
///
|
|
||||||
uint32_t
|
|
||||||
get_line() const;
|
|
||||||
|
|
||||||
/// @brief Get left-hand side expression.
|
|
||||||
///
|
|
||||||
string const&
|
|
||||||
get_lhs_expr() const;
|
|
||||||
|
|
||||||
/// @brief Get left-hand side expression value.
|
|
||||||
///
|
|
||||||
string const&
|
|
||||||
get_lhs_val() const;
|
|
||||||
|
|
||||||
/// @brief Get right-hand side expression.
|
|
||||||
///
|
|
||||||
string const&
|
|
||||||
get_rhs_expr() const;
|
|
||||||
|
|
||||||
/// @brief Get right-hand side expression value.
|
|
||||||
///
|
|
||||||
string const&
|
|
||||||
get_rhs_val() const;
|
|
||||||
|
|
||||||
void
|
|
||||||
report(reporter&) const override;
|
|
||||||
|
|
||||||
/// @brief Copy-assignment is disabled.
|
|
||||||
///
|
|
||||||
binary_assertion_failure& operator=(binary_assertion_failure const&) = delete;
|
|
||||||
|
|
||||||
/// @brief Move-assignment is disabled.
|
|
||||||
///
|
|
||||||
binary_assertion_failure& operator=(binary_assertion_failure&&) = delete;
|
|
||||||
|
|
||||||
private:
|
|
||||||
string _message;
|
|
||||||
string _file;
|
|
||||||
uint32_t _line{};
|
|
||||||
string _lhs_expr;
|
|
||||||
string _lhs_val;
|
|
||||||
string _rhs_expr;
|
|
||||||
string _rhs_val;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,20 @@
|
|||||||
/// @brief Ignore a test.
|
/// @brief Ignore a test.
|
||||||
/// @hideinitializer
|
/// @hideinitializer
|
||||||
///
|
///
|
||||||
#define BV_IGNORE throw bitshift::validate::ignore {};
|
#define BV_IGNORE throw bitshift::validate::ignored{};
|
||||||
|
|
||||||
|
/// @ingroup assertions
|
||||||
|
/// @brief Explicitly pass a test.
|
||||||
|
/// @hideinitializer
|
||||||
|
///
|
||||||
|
#define BV_PASS throw bitshift::validate::passed{};
|
||||||
|
|
||||||
|
/// @ingroup assertions
|
||||||
|
/// @brief Explicitly fail a test.
|
||||||
|
/// @hideinitializer
|
||||||
|
///
|
||||||
|
#define BV_FAIL(msg) \
|
||||||
|
bitshift::validate::failure::fail(msg);
|
||||||
|
|
||||||
/// @ingroup assertions
|
/// @ingroup assertions
|
||||||
/// @brief Assert a @c true value.
|
/// @brief Assert a @c true value.
|
||||||
@@ -199,4 +212,18 @@
|
|||||||
#define BV_ASSERT_NOT_EQUAL(lhs, rhs) \
|
#define BV_ASSERT_NOT_EQUAL(lhs, rhs) \
|
||||||
bitshift::validate::assertion::assert_not_equal((lhs), (rhs), #lhs, #rhs)
|
bitshift::validate::assertion::assert_not_equal((lhs), (rhs), #lhs, #rhs)
|
||||||
|
|
||||||
|
/// @ingroup assertions
|
||||||
|
/// @brief Assert @a expr does not throw.
|
||||||
|
/// @param expr The expression to test.
|
||||||
|
/// @hideinitializer
|
||||||
|
///
|
||||||
|
#define BV_ASSERT_NOTHROW(expr) \
|
||||||
|
bitshift::validate::assertion::assert_nothrow([] { (expr); })
|
||||||
|
|
||||||
|
#define BV_ASSERT_THROWS(except, expr) \
|
||||||
|
bitshift::validate::assertion::assert_throws<except>([] { (expr); })
|
||||||
|
|
||||||
|
#define BV_ASSERT_THROWS_ANY(expr) \
|
||||||
|
bitshift::validate::assertion::assert_throws_any([] { (expr); })
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#include <bitshift/validate/setup.hxx>
|
#include <bitshift/validate/setup.hxx>
|
||||||
#include <bitshift/validate/teardown.hxx>
|
#include <bitshift/validate/teardown.hxx>
|
||||||
#include <bitshift/validate/test-case.hxx>
|
#include <bitshift/validate/test-case.hxx>
|
||||||
|
#include <bitshift/validate/traits.hxx>
|
||||||
|
|
||||||
namespace bitshift::validate
|
namespace bitshift::validate
|
||||||
{
|
{
|
||||||
@@ -174,7 +175,13 @@ namespace bitshift::validate
|
|||||||
proxy&
|
proxy&
|
||||||
operator<<(U const& other)
|
operator<<(U const& other)
|
||||||
{
|
{
|
||||||
|
if constexpr (traits::has_output_operator<U>) {
|
||||||
_detail << std::boolalpha << other;
|
_detail << std::boolalpha << other;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_detail << "<no output operator defined>";
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,110 @@ BV_TEST(sanity, "basic sanity check")
|
|||||||
BV_ASSERT_NOT_EQUAL(0, 1);
|
BV_ASSERT_NOT_EQUAL(0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
BV_TEST(ignored, "ignored test")
|
BV_TEST(ignore, "test BV_IGNORE")
|
||||||
{
|
{
|
||||||
|
try {
|
||||||
BV_IGNORE;
|
BV_IGNORE;
|
||||||
|
}
|
||||||
|
catch (bitshift::validate::ignored const&) {
|
||||||
|
BV_PASS;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
// Fall-through.
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
BV_FAIL("expected exception not thrown");
|
||||||
|
}
|
||||||
|
|
||||||
|
BV_TEST(pass, "test BV_PASS")
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
BV_PASS;
|
||||||
|
}
|
||||||
|
catch (bitshift::validate::passed const&) {
|
||||||
|
BV_PASS;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
// Fall-through.
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
BV_FAIL("expected exception not thrown");
|
||||||
|
}
|
||||||
|
|
||||||
|
BV_TEST(fail, "test BV_FAIL")
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
BV_FAIL("message");
|
||||||
|
}
|
||||||
|
catch (bitshift::validate::failure const&) {
|
||||||
|
BV_PASS;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
// Fall-through.
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
BV_FAIL("expected exception not thrown");
|
||||||
|
}
|
||||||
|
|
||||||
|
BV_TEST(nothrow, "test BV_ASSERT_NOTHROW")
|
||||||
|
{
|
||||||
|
struct except {};
|
||||||
|
|
||||||
|
try {
|
||||||
|
// This assertion should fail.
|
||||||
|
//
|
||||||
|
BV_ASSERT_NOTHROW(throw except{});
|
||||||
|
}
|
||||||
|
catch (bitshift::validate::failure const&) {
|
||||||
|
BV_PASS;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
// Fall-through.
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
BV_FAIL("expected exception not thrown");
|
||||||
|
}
|
||||||
|
|
||||||
|
BV_TEST(throws, "test BV_ASSERT_THROWS")
|
||||||
|
{
|
||||||
|
struct except {};
|
||||||
|
|
||||||
|
try {
|
||||||
|
// This assertion should fail.
|
||||||
|
//
|
||||||
|
BV_ASSERT_THROWS(except, (void)0);
|
||||||
|
}
|
||||||
|
catch (bitshift::validate::failure const&) {
|
||||||
|
BV_PASS;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
// Fall-through.
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
BV_FAIL("expected exception not thrown");
|
||||||
|
}
|
||||||
|
|
||||||
|
BV_TEST(throws_any, "test BV_ASSERT_THROWS_ANY")
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// This assertion should fail.
|
||||||
|
//
|
||||||
|
BV_ASSERT_THROWS_ANY((void)0);
|
||||||
|
}
|
||||||
|
catch (bitshift::validate::failure const&) {
|
||||||
|
BV_PASS;
|
||||||
|
}
|
||||||
|
catch (...) {
|
||||||
|
// Fall-through.
|
||||||
|
//
|
||||||
|
}
|
||||||
|
|
||||||
|
BV_FAIL("expected exception not thrown");
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
|
|||||||
Reference in New Issue
Block a user