Commit 8678f57b authored by Matthias Vallentin's avatar Matthias Vallentin

Merge pull request #407 from Lingxi-Li/topic/fix-unit-test

Fix compound Boolean expressions in unit tests
parents 532c069d 9a701255
...@@ -73,7 +73,7 @@ behavior tester(event_based_actor* self, const actor& aut) { ...@@ -73,7 +73,7 @@ behavior tester(event_based_actor* self, const actor& aut) {
// must be still alive at this point // must be still alive at this point
CAF_CHECK_EQUAL(s_testees.load(), 1); CAF_CHECK_EQUAL(s_testees.load(), 1);
CAF_CHECK_EQUAL(msg.reason, exit_reason::user_shutdown); CAF_CHECK_EQUAL(msg.reason, exit_reason::user_shutdown);
CAF_CHECK_EQUAL(self->current_message().vals()->get_reference_count(), 1); CAF_CHECK_EQUAL(self->current_message().vals()->get_reference_count(), 1u);
CAF_CHECK(&msg == self->current_message().at(0)); CAF_CHECK(&msg == self->current_message().at(0));
// testee might be still running its cleanup code in // testee might be still running its cleanup code in
// another worker thread; by waiting some milliseconds, we make sure // another worker thread; by waiting some milliseconds, we make sure
......
...@@ -167,7 +167,7 @@ CAF_TEST(broadcast_actor_pool) { ...@@ -167,7 +167,7 @@ CAF_TEST(broadcast_actor_pool) {
CAF_TEST_ERROR("didn't receive a result"); CAF_TEST_ERROR("didn't receive a result");
} }
); );
CAF_CHECK_EQUAL(results.size(), 25); CAF_CHECK_EQUAL(results.size(), 25u);
CAF_CHECK(std::all_of(results.begin(), results.end(), CAF_CHECK(std::all_of(results.begin(), results.end(),
[](int res) { return res == 3; })); [](int res) { return res == 3; }));
self->send_exit(w, exit_reason::user_shutdown); self->send_exit(w, exit_reason::user_shutdown);
......
...@@ -132,7 +132,7 @@ CAF_TEST(request_response_promise) { ...@@ -132,7 +132,7 @@ CAF_TEST(request_response_promise) {
CAF_CHECK(false); CAF_CHECK(false);
}, },
[](error err) { [](error err) {
CAF_CHECK(err.code() == sec::request_receiver_down); CAF_CHECK(err.code() == static_cast<uint8_t>(sec::request_receiver_down));
} }
); );
anon_send_exit(dbl, exit_reason::kill); anon_send_exit(dbl, exit_reason::kill);
......
...@@ -64,7 +64,7 @@ CAF_TEST(redirect_aout_globally) { ...@@ -64,7 +64,7 @@ CAF_TEST(redirect_aout_globally) {
} }
); );
self->await_all_other_actors_done(); self->await_all_other_actors_done();
CAF_CHECK_EQUAL(self->mailbox().count(), 0); CAF_CHECK_EQUAL(self->mailbox().count(), 0u);
} }
CAF_TEST(global_and_local_redirect) { CAF_TEST(global_and_local_redirect) {
...@@ -92,5 +92,5 @@ CAF_TEST(global_and_local_redirect) { ...@@ -92,5 +92,5 @@ CAF_TEST(global_and_local_redirect) {
); );
CAF_CHECK(std::is_permutation(lines.begin(), lines.end(), expected.begin())); CAF_CHECK(std::is_permutation(lines.begin(), lines.end(), expected.begin()));
self->await_all_other_actors_done(); self->await_all_other_actors_done();
CAF_CHECK_EQUAL(self->mailbox().count(), 0); CAF_CHECK_EQUAL(self->mailbox().count(), 0u);
} }
...@@ -83,7 +83,7 @@ CAF_TEST(receive_atoms) { ...@@ -83,7 +83,7 @@ CAF_TEST(receive_atoms) {
self->receive( self->receive(
[&](foo_atom, uint32_t value) { [&](foo_atom, uint32_t value) {
matched_pattern[0] = true; matched_pattern[0] = true;
CAF_CHECK_EQUAL(value, 42); CAF_CHECK_EQUAL(value, 42u);
}, },
[&](abc_atom, def_atom, const std::string& str) { [&](abc_atom, def_atom, const std::string& str) {
matched_pattern[1] = true; matched_pattern[1] = true;
......
...@@ -310,11 +310,11 @@ public: ...@@ -310,11 +310,11 @@ public:
for (int i = 0; i < 100; ++i) { for (int i = 0; i < 100; ++i) {
send(this, ok_atom::value); send(this, ok_atom::value);
} }
CAF_CHECK_EQUAL(mailbox().count(), 100); CAF_CHECK_EQUAL(mailbox().count(), 100u);
for (int i = 0; i < 100; ++i) { for (int i = 0; i < 100; ++i) {
send(this, ok_atom::value); send(this, ok_atom::value);
} }
CAF_CHECK_EQUAL(mailbox().count(), 200); CAF_CHECK_EQUAL(mailbox().count(), 200u);
return {}; return {};
} }
}; };
......
...@@ -73,12 +73,12 @@ CAF_TEST(cli_args) { ...@@ -73,12 +73,12 @@ CAF_TEST(cli_args) {
{"in-file,i", "read from file", input_file}, {"in-file,i", "read from file", input_file},
{"verbosity,v", "1-5", verbosity} {"verbosity,v", "1-5", verbosity}
}); });
CAF_CHECK_EQUAL(res.remainder.size(), 0); CAF_CHECK_EQUAL(res.remainder.size(), 0u);
CAF_CHECK(res.remainder == message{}); CAF_CHECK(res.remainder == message{});
CAF_CHECK_EQUAL(res.opts.count("no-colors"), 1); CAF_CHECK_EQUAL(res.opts.count("no-colors"), 1u);
CAF_CHECK_EQUAL(res.opts.count("verbosity"), 1); CAF_CHECK_EQUAL(res.opts.count("verbosity"), 1u);
CAF_CHECK_EQUAL(res.opts.count("out-file"), 1); CAF_CHECK_EQUAL(res.opts.count("out-file"), 1u);
CAF_CHECK_EQUAL(res.opts.count("in-file"), 0); CAF_CHECK_EQUAL(res.opts.count("in-file"), 0u);
CAF_CHECK_EQUAL(output_file, "/dev/null"); CAF_CHECK_EQUAL(output_file, "/dev/null");
CAF_CHECK_EQUAL(input_file, ""); CAF_CHECK_EQUAL(input_file, "");
} }
...@@ -39,12 +39,12 @@ CAF_TEST(basics) { ...@@ -39,12 +39,12 @@ CAF_TEST(basics) {
limited_vector<int, 2> vec5 {3, 4}; limited_vector<int, 2> vec5 {3, 4};
vec4.insert(vec4.end(), vec5.begin(), vec5.end()); vec4.insert(vec4.end(), vec5.begin(), vec5.end());
auto vec6 = vec4; auto vec6 = vec4;
CAF_CHECK_EQUAL(vec1.size(), 4); CAF_CHECK_EQUAL(vec1.size(), 4u);
CAF_CHECK_EQUAL(vec2.size(), 4); CAF_CHECK_EQUAL(vec2.size(), 4u);
CAF_CHECK_EQUAL(vec3.size(), 4); CAF_CHECK_EQUAL(vec3.size(), 4u);
CAF_CHECK_EQUAL(vec4.size(), 4); CAF_CHECK_EQUAL(vec4.size(), 4u);
CAF_CHECK_EQUAL(vec5.size(), 2); CAF_CHECK_EQUAL(vec5.size(), 2u);
CAF_CHECK_EQUAL(vec6.size(), 4); CAF_CHECK_EQUAL(vec6.size(), 4u);
CAF_CHECK_EQUAL(vec1.full(), true); CAF_CHECK_EQUAL(vec1.full(), true);
CAF_CHECK_EQUAL(vec2.full(), false); CAF_CHECK_EQUAL(vec2.full(), false);
CAF_CHECK_EQUAL(vec3.full(), true); CAF_CHECK_EQUAL(vec3.full(), true);
...@@ -71,7 +71,7 @@ CAF_TEST(basics) { ...@@ -71,7 +71,7 @@ CAF_TEST(basics) {
vec7.assign(std::begin(arr2), std::end(arr2)); vec7.assign(std::begin(arr2), std::end(arr2));
CAF_CHECK((std::equal(vec7.begin(), vec7.end(), std::begin(arr2)))); CAF_CHECK((std::equal(vec7.begin(), vec7.end(), std::begin(arr2))));
vec7.assign(5, 0); vec7.assign(5, 0);
CAF_CHECK_EQUAL(vec7.size(), 5); CAF_CHECK_EQUAL(vec7.size(), 5u);
CAF_CHECK((std::all_of(vec7.begin(), vec7.end(), CAF_CHECK((std::all_of(vec7.begin(), vec7.end(),
[](int i) { return i == 0; }))); [](int i) { return i == 0; })));
} }
...@@ -115,10 +115,10 @@ CAF_TEST(extract_opts) { ...@@ -115,10 +115,10 @@ CAF_TEST(extract_opts) {
{"file,f", "set output file", filename}, {"file,f", "set output file", filename},
{"whatever", "do whatever"} {"whatever", "do whatever"}
}); });
CAF_CHECK_EQUAL(res.opts.count("file"), 1); CAF_CHECK_EQUAL(res.opts.count("file"), 1u);
CAF_CHECK(res.remainder.empty()); CAF_CHECK(res.remainder.empty());
CAF_CHECK_EQUAL(filename, "hello.txt"); CAF_CHECK_EQUAL(filename, "hello.txt");
CAF_CHECK_EQUAL(log_level, 5); CAF_CHECK_EQUAL(log_level, 5u);
}; };
f({"--file=hello.txt", "-l", "5"}); f({"--file=hello.txt", "-l", "5"});
f({"-f", "hello.txt", "--log-level=5"}); f({"-f", "hello.txt", "--log-level=5"});
......
...@@ -44,7 +44,7 @@ public: ...@@ -44,7 +44,7 @@ public:
behavior make_behavior() override { behavior make_behavior() override {
return { return {
others >> [=] { others >> [=] {
CAF_CHECK_EQUAL(current_message().cvals()->get_reference_count(), 2); CAF_CHECK_EQUAL(current_message().cvals()->get_reference_count(), 2u);
quit(); quit();
return std::move(current_message()); return std::move(current_message());
} }
...@@ -114,18 +114,18 @@ CAF_TEST(message_lifetime_in_scoped_actor) { ...@@ -114,18 +114,18 @@ CAF_TEST(message_lifetime_in_scoped_actor) {
CAF_CHECK_EQUAL(a, 1); CAF_CHECK_EQUAL(a, 1);
CAF_CHECK_EQUAL(b, 2); CAF_CHECK_EQUAL(b, 2);
CAF_CHECK_EQUAL(c, 3); CAF_CHECK_EQUAL(c, 3);
CAF_CHECK_EQUAL(msg.cvals()->get_reference_count(), 2); CAF_CHECK_EQUAL(msg.cvals()->get_reference_count(), 2u);
CAF_CHECK_EQUAL(self->current_message().cvals()->get_reference_count(), 2); CAF_CHECK_EQUAL(self->current_message().cvals()->get_reference_count(), 2u);
CAF_CHECK(self->current_message().cvals().get() == msg.cvals().get()); CAF_CHECK(self->current_message().cvals().get() == msg.cvals().get());
} }
); );
CAF_CHECK_EQUAL(msg.cvals()->get_reference_count(), 1); CAF_CHECK_EQUAL(msg.cvals()->get_reference_count(), 1u);
msg = make_message(42); msg = make_message(42);
self->send(self, msg); self->send(self, msg);
self->receive( self->receive(
[&](int& value) { [&](int& value) {
CAF_CHECK_EQUAL(msg.cvals()->get_reference_count(), 1); CAF_CHECK_EQUAL(msg.cvals()->get_reference_count(), 1u);
CAF_CHECK_EQUAL(self->current_message().cvals()->get_reference_count(), 1); CAF_CHECK_EQUAL(self->current_message().cvals()->get_reference_count(), 1u);
CAF_CHECK(self->current_message().cvals().get() != msg.cvals().get()); CAF_CHECK(self->current_message().cvals().get() != msg.cvals().get());
value = 10; value = 10;
} }
......
...@@ -64,7 +64,7 @@ CAF_TEST(metaprogramming) { ...@@ -64,7 +64,7 @@ CAF_TEST(metaprogramming) {
CAF_CHECK((is_same<float, tl_at<l1, 1>::type>::value)); CAF_CHECK((is_same<float, tl_at<l1, 1>::type>::value));
CAF_CHECK((is_same<std::string, tl_at<l1, 2>::type>::value)); CAF_CHECK((is_same<std::string, tl_at<l1, 2>::type>::value));
CAF_CHECK_EQUAL(3, tl_size<l1>::value); CAF_CHECK_EQUAL(3u, tl_size<l1>::value);
CAF_CHECK_EQUAL(tl_size<r1>::value, tl_size<l1>::value); CAF_CHECK_EQUAL(tl_size<r1>::value, tl_size<l1>::value);
CAF_CHECK((is_same<tl_at<l1, 0>::type, tl_at<r1, 2>::type>::value)); CAF_CHECK((is_same<tl_at<l1, 0>::type, tl_at<r1, 2>::type>::value));
CAF_CHECK((is_same<tl_at<l1, 1>::type, tl_at<r1, 1>::type>::value)); CAF_CHECK((is_same<tl_at<l1, 1>::type, tl_at<r1, 1>::type>::value));
...@@ -75,8 +75,8 @@ CAF_TEST(metaprogramming) { ...@@ -75,8 +75,8 @@ CAF_TEST(metaprogramming) {
CAF_CHECK((is_same<int, tl_head<l2>::type>::value)); CAF_CHECK((is_same<int, tl_head<l2>::type>::value));
CAF_CHECK((is_same<l1, tl_tail<l2>::type>::value)); CAF_CHECK((is_same<l1, tl_tail<l2>::type>::value));
CAF_CHECK_EQUAL((detail::tl_count<l1, is_int>::value), 1); CAF_CHECK_EQUAL((detail::tl_count<l1, is_int>::value), 1u);
CAF_CHECK_EQUAL((detail::tl_count<l2, is_int>::value), 2); CAF_CHECK_EQUAL((detail::tl_count<l2, is_int>::value), 2u);
using il0 = int_list<0, 1, 2, 3, 4, 5>; using il0 = int_list<0, 1, 2, 3, 4, 5>;
using il1 = int_list<4, 5>; using il1 = int_list<4, 5>;
......
...@@ -188,7 +188,7 @@ CAF_TEST(request_response_promise) { ...@@ -188,7 +188,7 @@ CAF_TEST(request_response_promise) {
CAF_CHECK(false); CAF_CHECK(false);
}, },
[](error err) { [](error err) {
CAF_CHECK(err.code() == sec::request_receiver_down); CAF_CHECK(err.code() == static_cast<uint8_t>(sec::request_receiver_down));
} }
); );
anon_send_exit(f, exit_reason::kill); anon_send_exit(f, exit_reason::kill);
......
...@@ -218,13 +218,13 @@ CAF_TEST(ieee_754_conversion) { ...@@ -218,13 +218,13 @@ CAF_TEST(ieee_754_conversion) {
// check conversion of float // check conversion of float
float f1 = 3.1415925f; // float value float f1 = 3.1415925f; // float value
auto p1 = caf::detail::pack754(f1); // packet value auto p1 = caf::detail::pack754(f1); // packet value
CAF_CHECK_EQUAL(p1, 0x40490FDA); CAF_CHECK_EQUAL(p1, static_cast<decltype(p1)>(0x40490FDA));
auto u1 = caf::detail::unpack754(p1); // unpacked value auto u1 = caf::detail::unpack754(p1); // unpacked value
CAF_CHECK_EQUAL(f1, u1); CAF_CHECK_EQUAL(f1, u1);
// check conversion of double // check conversion of double
double f2 = 3.14159265358979311600; // double value double f2 = 3.14159265358979311600; // double value
auto p2 = caf::detail::pack754(f2); // packet value auto p2 = caf::detail::pack754(f2); // packet value
CAF_CHECK_EQUAL(p2, 0x400921FB54442D18); CAF_CHECK_EQUAL(p2, static_cast<decltype(p2)>(0x400921FB54442D18));
auto u2 = caf::detail::unpack754(p2); // unpacked value auto u2 = caf::detail::unpack754(p2); // unpacked value
CAF_CHECK_EQUAL(f2, u2); CAF_CHECK_EQUAL(f2, u2);
} }
......
...@@ -753,11 +753,11 @@ CAF_TEST(automatic_connection) { ...@@ -753,11 +753,11 @@ CAF_TEST(automatic_connection) {
basp::message_type::announce_proxy_instance, uint32_t{0}, uint64_t{0}, basp::message_type::announce_proxy_instance, uint32_t{0}, uint64_t{0},
this_node(), remote_node(0), this_node(), remote_node(0),
invalid_actor_id, pseudo_remote(0)->id()); invalid_actor_id, pseudo_remote(0)->id());
CAF_CHECK_EQUAL(mpx()->output_buffer(remote_hdl(1)).size(), 0); CAF_CHECK_EQUAL(mpx()->output_buffer(remote_hdl(1)).size(), 0u);
CAF_CHECK_EQUAL(tbl().lookup_indirect(remote_node(0)), remote_node(1)); CAF_CHECK_EQUAL(tbl().lookup_indirect(remote_node(0)), remote_node(1));
CAF_CHECK_EQUAL(tbl().lookup_indirect(remote_node(1)), invalid_node_id); CAF_CHECK_EQUAL(tbl().lookup_indirect(remote_node(1)), invalid_node_id);
auto connection_helper = system.latest_actor_id(); auto connection_helper = system.latest_actor_id();
CAF_CHECK_EQUAL(mpx()->output_buffer(remote_hdl(1)).size(), 0); CAF_CHECK_EQUAL(mpx()->output_buffer(remote_hdl(1)).size(), 0u);
// create a dummy config server and respond to the name lookup // create a dummy config server and respond to the name lookup
CAF_MESSAGE("receive ConfigServ of jupiter"); CAF_MESSAGE("receive ConfigServ of jupiter");
network::address_listing res; network::address_listing res;
......
...@@ -39,6 +39,31 @@ ...@@ -39,6 +39,31 @@
namespace caf { namespace caf {
namespace test { namespace test {
template <class T, class U,
class Common = typename std::common_type<T, U>::type,
typename std::enable_if<std::is_floating_point<Common>::value,
int>::type = 0>
bool equal_to(const T& t, const U& u) {
auto x = static_cast<double>(t);
auto y = static_cast<double>(u);
auto max = std::max(std::abs(x), std::abs(y));
auto dif = std::abs(x - y);
return dif <= max * 1e-5;
}
template <class T, class U,
class Common = typename std::common_type<T, U>::type,
typename std::enable_if<! std::is_floating_point<Common>::value,
int>::type = 0>
bool equal_to(const T& x, const U& y) {
return x == y;
}
template <class T, class U>
bool not_equal_to(const T& t, const U& u) {
return ! equal_to(t, u);
}
/// Default test-running function. /// Default test-running function.
/// This function will be called automatically unless you define /// This function will be called automatically unless you define
/// `CAF_TEST_NO_MAIN` before including `caf/test/unit_test.hpp`. In /// `CAF_TEST_NO_MAIN` before including `caf/test/unit_test.hpp`. In
...@@ -352,200 +377,48 @@ showable<T> show(const T &x) { ...@@ -352,200 +377,48 @@ showable<T> show(const T &x) {
return showable<T>{x}; return showable<T>{x};
} }
template <class T, inline bool check(test* parent, const char *file, size_t line,
bool IsFloat = std::is_floating_point<T>::value, const char *expr, bool should_fail, bool result) {
bool IsIntegral = std::is_integral<T>::value> std::stringstream ss;
class lhs_cmp { if (result) {
public:
template <class U>
bool operator()(const T& x, const U& y) {
return x == y;
}
};
template <class T>
class lhs_cmp<T, true, false> {
public:
template <class U>
bool operator()(const T& x, const U& y) {
using rt = decltype(x - y);
return std::fabs(x - y) <= std::numeric_limits<rt>::epsilon();
}
};
template <class T>
class lhs_cmp<T, false, true> {
public:
template <class U>
bool operator()(const T& x, const U& y) {
return x == static_cast<T>(y);
}
};
template <class T>
struct lhs {
public:
lhs(test* parent, const char *file, size_t line, const char *expr,
bool should_fail, const T& x)
: test_(parent),
filename_(file),
line_(line),
expr_(expr),
should_fail_(should_fail),
value_(x) {
}
lhs(const lhs&) = default;
~lhs() {
if (evaluated_) {
return;
}
if (eval(0)) {
pass();
} else {
fail_unary();
}
}
template <class U>
using elevated =
typename std::conditional<
std::is_convertible<U, T>::value,
T,
U
>::type;
explicit operator bool() {
evaluated_ = true;
return static_cast<bool>(value_) ? pass() : fail_unary();
}
// pass-or-fail
template <class U>
bool pof(bool res, const U& x) {
evaluated_ = true;
return res ? pass() : fail(x);
}
template <class U>
bool operator==(const U& x) {
lhs_cmp<T> cmp;
return pof(cmp(value_, x), x);
}
template <class U>
bool operator!=(const U& x) {
lhs_cmp<T> cmp;
return pof(! cmp(value_, x), x);
}
template <class U>
bool operator<(const U& x) {
return pof(value_ < static_cast<elevated<U>>(x), x);
}
template <class U>
bool operator<=(const U& x) {
return pof(value_ <= static_cast<elevated<U>>(x), x);
}
template <class U>
bool operator>(const U& x) {
return pof(value_ > static_cast<elevated<U>>(x), x);
}
template <class U>
bool operator>=(const U& x) {
return pof(value_ >= static_cast<elevated<U>>(x), x);
}
private:
template<class V = T>
typename std::enable_if<
std::is_convertible<V, bool>::value
&& ! std::is_floating_point<V>::value,
bool
>::type
eval(int) {
return static_cast<bool>(value_);
}
template<class V = T>
typename std::enable_if<
std::is_floating_point<V>::value,
bool
>::type
eval(int) {
return std::fabs(value_) <= std::numeric_limits<V>::epsilon();
}
bool eval(long) {
return true;
}
bool pass() {
passed_ = true;
std::stringstream ss;
ss << engine::color(green) << "** " ss << engine::color(green) << "** "
<< engine::color(blue) << filename_ << engine::color(yellow) << ":" << engine::color(blue) << file << engine::color(yellow) << ":"
<< engine::color(blue) << line_ << fill(line_) << engine::color(reset) << engine::color(blue) << line << fill(line) << engine::color(reset)
<< expr_; << expr;
test_->pass(ss.str()); parent->pass(ss.str());
return true; } else {
}
bool fail_unary() {
std::stringstream ss;
ss << engine::color(red) << "!! " ss << engine::color(red) << "!! "
<< engine::color(blue) << filename_ << engine::color(yellow) << ":" << engine::color(blue) << file << engine::color(yellow) << ":"
<< engine::color(blue) << line_ << fill(line_) << engine::color(reset) << engine::color(blue) << line << fill(line) << engine::color(reset)
<< expr_; << expr;
test_->fail(ss.str(), should_fail_); parent->fail(ss.str(), should_fail);
return false;
} }
return result;
}
template <class U> template <class T, class U>
bool fail(const U& u) { bool check(test* parent, const char *file, size_t line,
std::stringstream ss; const char *expr, bool should_fail, bool result,
const T& x, const U& y) {
std::stringstream ss;
if (result) {
ss << engine::color(green) << "** "
<< engine::color(blue) << file << engine::color(yellow) << ":"
<< engine::color(blue) << line << fill(line) << engine::color(reset)
<< expr;
parent->pass(ss.str());
} else {
ss << engine::color(red) << "!! " ss << engine::color(red) << "!! "
<< engine::color(blue) << filename_ << engine::color(yellow) << ":" << engine::color(blue) << file << engine::color(yellow) << ":"
<< engine::color(blue) << line_ << fill(line_) << engine::color(reset) << engine::color(blue) << line << fill(line) << engine::color(reset)
<< expr_ << engine::color(magenta) << " (" << expr << engine::color(magenta) << " ("
<< engine::color(red) << show(value_) << engine::color(magenta) << engine::color(red) << show(x) << engine::color(magenta)
<< " !! " << engine::color(red) << show(u) << engine::color(magenta) << " !! " << engine::color(red) << show(y) << engine::color(magenta)
<< ')' << engine::color(reset); << ')' << engine::color(reset);
test_->fail(ss.str(), should_fail_); parent->fail(ss.str(), should_fail);
return false;
}
bool evaluated_ = false;
bool passed_ = false;
test* test_;
const char* filename_;
size_t line_;
const char* expr_;
bool should_fail_;
const T& value_;
};
struct expr {
public:
expr(test* parent, const char* filename, size_t lineno, bool should_fail,
const char* expression);
template <class T>
lhs<T> operator->*(const T& x) {
return {test_, filename_, line_, expr_, should_fail_, x};
} }
return result;
private: }
test* test_;
const char* filename_;
size_t line_;
bool should_fail_;
const char* expr_;
};
} // namespace detail } // namespace detail
} // namespace test } // namespace test
...@@ -582,24 +455,50 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture; ...@@ -582,24 +455,50 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture;
#define CAF_XSTR(s) CAF_STR(s) #define CAF_XSTR(s) CAF_STR(s)
#define CAF_PRED_EXPR(pred, x_expr, y_expr) "("#x_expr") "#pred" ("#y_expr")"
#define CAF_FUNC_EXPR(func, x_expr, y_expr) #func"("#x_expr", "#y_expr")"
#define CAF_CHECK(...) \ #define CAF_CHECK(...) \
do { \ do { \
static_cast<void>(::caf::test::detail::expr{ \ static_cast<void>(::caf::test::detail::check( \
::caf::test::engine::current_test(), __FILE__, __LINE__, \ ::caf::test::engine::current_test(), __FILE__, __LINE__, \
false, #__VA_ARGS__} ->* __VA_ARGS__); \ #__VA_ARGS__, false, static_cast<bool>(__VA_ARGS__))); \
::caf::test::engine::last_check_file(__FILE__); \ ::caf::test::engine::last_check_file(__FILE__); \
::caf::test::engine::last_check_line(__LINE__); \ ::caf::test::engine::last_check_line(__LINE__); \
} while(false) } while(false)
#define CAF_CHECK_FAIL(...) \ #define CAF_CHECK_PRED(pred, x_expr, y_expr) \
do { \ do { \
(void)(::caf::test::detail::expr{ \ const auto& x_val___ = x_expr; \
::caf::test::engine::current_test(), __FILE__, __LINE__, \ const auto& y_val___ = y_expr; \
true, #__VA_ARGS__} ->* __VA_ARGS__); \ static_cast<void>(::caf::test::detail::check( \
::caf::test::engine::current_test(), __FILE__, __LINE__, \
CAF_PRED_EXPR(pred, x_expr, y_expr), false, \
x_val___ pred y_val___, x_val___, y_val___)); \
::caf::test::engine::last_check_file(__FILE__); \
::caf::test::engine::last_check_line(__LINE__); \
} while(false)
#define CAF_CHECK_FUNC(func, x_expr, y_expr) \
do { \
const auto& x_val___ = x_expr; \
const auto& y_val___ = y_expr; \
static_cast<void>(::caf::test::detail::check( \
::caf::test::engine::current_test(), __FILE__, __LINE__, \
CAF_FUNC_EXPR(func, x_expr, y_expr), false, \
func(x_val___, y_val___), x_val___, y_val___)); \
::caf::test::engine::last_check_file(__FILE__); \ ::caf::test::engine::last_check_file(__FILE__); \
::caf::test::engine::last_check_line(__LINE__); \ ::caf::test::engine::last_check_line(__LINE__); \
} while(false) } while(false)
#define CAF_CHECK_FAIL(...) \
do { \
static_cast<void>(::caf::test::detail::check( \
::caf::test::engine::current_test(), __FILE__, __LINE__, \
#__VA_ARGS__, true, static_cast<bool>(__VA_ARGS__))); \
::caf::test::engine::last_check_file(__FILE__); \
::caf::test::engine::last_check_line(__LINE__); \
} while(false)
#define CAF_FAIL(msg) \ #define CAF_FAIL(msg) \
do { \ do { \
...@@ -610,8 +509,9 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture; ...@@ -610,8 +509,9 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture;
#define CAF_REQUIRE(...) \ #define CAF_REQUIRE(...) \
do { \ do { \
auto CAF_UNIQUE(__result) = \ auto CAF_UNIQUE(__result) = \
::caf::test::detail::expr{::caf::test::engine::current_test(), \ ::caf::test::detail::check(::caf::test::engine::current_test(), \
__FILE__, __LINE__, false, #__VA_ARGS__} ->* __VA_ARGS__; \ __FILE__, __LINE__, #__VA_ARGS__, false, \
static_cast<bool>(__VA_ARGS__)); \
if (! CAF_UNIQUE(__result)) { \ if (! CAF_UNIQUE(__result)) { \
throw ::caf::test::detail::require_error{#__VA_ARGS__}; \ throw ::caf::test::detail::require_error{#__VA_ARGS__}; \
} \ } \
...@@ -619,6 +519,38 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture; ...@@ -619,6 +519,38 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture;
::caf::test::engine::last_check_line(__LINE__); \ ::caf::test::engine::last_check_line(__LINE__); \
} while(false) } while(false)
#define CAF_REQUIRE_PRED(pred, x_expr, y_expr) \
do { \
const auto& x_val___ = x_expr; \
const auto& y_val___ = y_expr; \
auto CAF_UNIQUE(__result) = \
::caf::test::detail::check(::caf::test::engine::current_test(), \
__FILE__, __LINE__, CAF_PRED_EXPR(pred, x_expr, y_expr), false, \
x_val___ pred y_val___, x_val___, y_val___); \
if (! CAF_UNIQUE(__result)) { \
throw ::caf::test::detail::require_error{ \
CAF_PRED_EXPR(pred, x_expr, y_expr)}; \
} \
::caf::test::engine::last_check_file(__FILE__); \
::caf::test::engine::last_check_line(__LINE__); \
} while(false)
#define CAF_REQUIRE_FUNC(func, x_expr, y_expr) \
do { \
const auto& x_val___ = x_expr; \
const auto& y_val___ = y_expr; \
auto CAF_UNIQUE(__result) = \
::caf::test::detail::check(::caf::test::engine::current_test(), \
__FILE__, __LINE__, CAF_FUNC_EXPR(func, x_expr, y_expr), false, \
func(x_val___, y_val___), x_val___, y_val___); \
if (! CAF_UNIQUE(__result)) { \
throw ::caf::test::detail::require_error{ \
CAF_FUNC_EXPR(func, x_expr, y_expr)}; \
} \
::caf::test::engine::last_check_file(__FILE__); \
::caf::test::engine::last_check_line(__LINE__); \
} while(false)
#define CAF_TEST(name) \ #define CAF_TEST(name) \
namespace { \ namespace { \
struct CAF_UNIQUE(test) : caf_test_case_auto_fixture { \ struct CAF_UNIQUE(test) : caf_test_case_auto_fixture { \
...@@ -635,8 +567,22 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture; ...@@ -635,8 +567,22 @@ using caf_test_case_auto_fixture = caf::test::dummy_fixture;
#define CAF_TEST_FIXTURE_SCOPE_END() \ #define CAF_TEST_FIXTURE_SCOPE_END() \
} // namespace <scope_name> } // namespace <scope_name>
// Boost Test compatibility macro // check predicate family
#define CAF_CHECK_EQUAL(x, y) CAF_CHECK(x == y) #define CAF_CHECK_EQUAL(x, y) CAF_CHECK_FUNC(::caf::test::equal_to, x, y)
#define CAF_CHECK_NOT_EQUAL(x, y) CAF_CHECK_FUNC(::caf::test::not_equal_to, x, y)
#define CAF_CHECK_LESS(x, y) CAF_CHECK_PRED(< , x, y)
#define CAF_CHECK_LESS_EQUAL(x, y) CAF_CHECK_PRED(<=, x, y)
#define CAF_CHECK_GREATER(x, y) CAF_CHECK_PRED(> , x, y)
#define CAF_CHECK_GREATER_EQUAL(x, y) CAF_CHECK_PRED(>=, x, y)
// require predicate family
#define CAF_REQUIRE_EQUAL(x, y) CAF_REQUIRE_FUNC(::caf::test::equal_to, x, y)
#define CAF_REQUIRE_NOT_EQUAL(x, y) CAF_REQUIRE_FUNC(::caf::test::not_equal_to, x, y)
#define CAF_REQUIRE_LESS(x, y) CAF_REQUIRE_PRED(< , x, y)
#define CAF_REQUIRE_LESS_EQUAL(x, y) CAF_REQUIRE_PRED(<=, x, y)
#define CAF_REQUIRE_GREATER(x, y) CAF_REQUIRE_PRED(> , x, y)
#define CAF_REQUIRE_GREATER_EQUAL(x, y) CAF_REQUIRE_PRED(>=, x, y)
#define CAF_MESSAGE(msg) CAF_TEST_VERBOSE(msg) #define CAF_MESSAGE(msg) CAF_TEST_VERBOSE(msg)
#endif // CAF_TEST_UNIT_TEST_HPP #endif // CAF_TEST_UNIT_TEST_HPP
...@@ -569,19 +569,6 @@ int main(int argc, char** argv) { ...@@ -569,19 +569,6 @@ int main(int argc, char** argv) {
return result ? 0 : 1; return result ? 0 : 1;
} }
namespace detail {
expr::expr(test* parent, const char* filename, size_t lineno,
bool should_fail, const char* expression)
: test_{parent},
filename_{filename},
line_{lineno},
should_fail_{should_fail},
expr_{expression} {
assert(test_ != nullptr);
}
} // namespace detail
} // namespace test } // namespace test
} // namespace caf } // namespace caf
......
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