Commit 371d2450 authored by Dominik Charousset's avatar Dominik Charousset

Reduce redundancy in `test_uniform_type`

parent e1031fc8
...@@ -49,50 +49,54 @@ struct test_struct { ...@@ -49,50 +49,54 @@ struct test_struct {
using namespace caf; using namespace caf;
bool check_types(const std::set<std::string>& expected) { template <class T>
std::string tostr(T value, size_t fieldwidth = 2) {
std::ostringstream oss;
oss.width(fieldwidth);
oss << value;
return oss.str();
}
bool check_types(const std::map<std::string, uint16_t>& expected) {
// holds the type names we see at runtime // holds the type names we see at runtime
std::set<std::string> found; std::map<std::string, uint16_t> found;
// fetch all available type names // fetch all available type names
auto types = uniform_type_info::instances(); auto types = uniform_type_info::instances();
for (auto tinfo : types) { for (auto tinfo : types) {
found.insert(tinfo->name()); found.insert(std::make_pair(tinfo->name(), tinfo->type_nr()));
} }
// compare the two sets // compare the two maps
CAF_CHECK_EQUAL(expected.size(), found.size()); if (expected == found) {
bool expected_equals_found = false;
if (expected.size() == found.size()
&& std::equal(found.begin(), found.end(), expected.begin())) {
CAF_CHECKPOINT(); CAF_CHECKPOINT();
return true; return true;
} }
CAF_CHECK(false); CAF_CHECK(false);
if (!expected_equals_found) { using const_iterator = std::map<std::string, uint16_t>::const_iterator;
std::string(41, ' '); using std::setw;
std::ostringstream oss(std::string(41, ' ')); using std::left;
oss.seekp(0); std::ostringstream oss;
oss << "found (" << found.size() << ")"; oss << left << setw(20) << ("found (" + tostr(found.size(), 1) + ")")
oss.seekp(22); << " | expected (" << expected.size() << ")";
oss << "expected (" << expected.size() << ")"; CAF_PRINT(oss.str());
std::string lhs; oss.seekp(0);
std::string rhs; oss << std::setfill('-') << setw(22) << "" << "|" << setw(22) << "";
CAF_PRINT(oss.str()); CAF_PRINT(oss.str());
CAF_PRINT(std::string(41, '-')); auto fi = found.cbegin();
auto fi = found.begin(); auto fe = found.cend();
auto fe = found.end(); auto ei = expected.cbegin();
auto ei = expected.begin(); auto ee = expected.cend();
auto ee = expected.end(); std::string dummy(20, ' ');
while (fi != fe || ei != ee) { auto out = [&](const_iterator& i, const_iterator last) -> std::string {
if (fi != fe) if (i == last) {
lhs = *fi++; return dummy;
else
lhs.clear();
if (ei != ee)
rhs = *ei++;
else
rhs.clear();
lhs.resize(20, ' ');
CAF_PRINT(lhs << "| " << rhs);
} }
std::ostringstream oss;
oss << left << setw(16) << i->first << "[" << tostr(i->second) << "]";
++i;
return oss.str();
};
while (fi != fe || ei != ee) {
CAF_PRINT(out(fi, fe) << " | " << out(ei, ee));
} }
return false; return false;
} }
...@@ -104,65 +108,17 @@ T& append(T& storage) { ...@@ -104,65 +108,17 @@ T& append(T& storage) {
template <class T, typename U, class... Us> template <class T, typename U, class... Us>
T& append(T& storage, U&& u, Us&&... us) { T& append(T& storage, U&& u, Us&&... us) {
storage.insert(std::forward<U>(u)); storage.insert(std::make_pair(std::forward<U>(u), uint16_t{0}));
return append(storage, std::forward<Us>(us)...); return append(storage, std::forward<Us>(us)...);
} }
void check_builtin_type_nrs() { template <class T>
std::map<std::string, uint16_t> nrs; constexpr uint16_t tnr() {
nrs["bool"] = detail::type_nr<bool>::value; return detail::type_nr<T>::value;
nrs["@i8"] = detail::type_nr<int8_t>::value;
nrs["@i16"] = detail::type_nr<int16_t>::value;
nrs["@i32"] = detail::type_nr<int32_t>::value;
nrs["@i64"] = detail::type_nr<int64_t>::value;
nrs["@u8"] = detail::type_nr<uint8_t>::value;
nrs["@u16"] = detail::type_nr<uint16_t>::value;
nrs["@u32"] = detail::type_nr<uint32_t>::value;
nrs["@u64"] = detail::type_nr<uint64_t>::value;
nrs["@str"] = detail::type_nr<std::string>::value;
nrs["@u16str"] = detail::type_nr<std::u16string>::value;
nrs["@u32str"] = detail::type_nr<std::u32string>::value;
nrs["float"] = detail::type_nr<float>::value;
nrs["double"] = detail::type_nr<double>::value;
nrs["@ldouble"] = detail::type_nr<long double>::value;
nrs["@unit"] = detail::type_nr<unit_t>::value;
nrs["@actor"] = detail::type_nr<actor>::value;
nrs["@addr"] = detail::type_nr<actor_addr>::value;
nrs["@atom"] = detail::type_nr<atom_value>::value;
nrs["@channel"] = detail::type_nr<channel>::value;
nrs["@charbuf"] = detail::type_nr<std::vector<char>>::value;
nrs["@down"] = detail::type_nr<down_msg>::value;
nrs["@duration"] = detail::type_nr<duration>::value;
nrs["@exit"] = detail::type_nr<exit_msg>::value;
nrs["@group"] = detail::type_nr<group>::value;
nrs["@group_down"] = detail::type_nr<group_down_msg>::value;
nrs["@message"] = detail::type_nr<message>::value;
nrs["@message_id"] = detail::type_nr<message_id>::value;
nrs["@node"] = detail::type_nr<node_id>::value;
nrs["@strmap"] = detail::type_nr<std::map<std::string, std::string>>::value;
nrs["@timeout"] = detail::type_nr<timeout_msg>::value;
nrs["@sync_exited"] = detail::type_nr<sync_exited_msg>::value;
nrs["@sync_timeout"] = detail::type_nr<sync_timeout_msg>::value;
nrs["@strvec"] = detail::type_nr<std::vector<std::string>>::value;
nrs["@strset"] = detail::type_nr<std::set<std::string>>::value;
auto types = uniform_type_info::instances();
for (auto tinfo : types) {
auto i = nrs.find(tinfo->name());
if (i == nrs.end()) {
CAF_FAILURE("could not find " << tinfo->name() << " in nrs map");
} else {
if (tinfo->type_nr() != i->second) {
CAF_FAILURE(tinfo->name() << " has wrong type nr, expected "
<< i->second << ", found " << tinfo->type_nr());
}
}
}
CAF_CHECKPOINT();
} }
int main() { int main() {
CAF_TEST(test_uniform_type); CAF_TEST(test_uniform_type);
check_builtin_type_nrs();
auto announce1 = announce<foo>("foo", &foo::value); auto announce1 = announce<foo>("foo", &foo::value);
auto announce2 = announce<foo>("foo", &foo::value); auto announce2 = announce<foo>("foo", &foo::value);
auto announce3 = announce<foo>("foo", &foo::value); auto announce3 = announce<foo>("foo", &foo::value);
...@@ -176,38 +132,53 @@ int main() { ...@@ -176,38 +132,53 @@ int main() {
CAF_CHECK(uti != nullptr); CAF_CHECK(uti != nullptr);
CAF_CHECK_EQUAL(uti->name(), "@atom"); CAF_CHECK_EQUAL(uti->name(), "@atom");
} }
using detail::type_nr;
// these types (and only those) are present if // these types (and only those) are present if
// the uniform_type_info implementation is correct // the uniform_type_info implementation is correct
std::set<std::string> expected = { std::map<std::string, uint16_t> expected{
// local types // local types
"foo", {"foo", 0},
// primitive types // primitive types
"bool", {"bool", tnr<bool>()},
"@i8", "@i16", "@i32", "@i64", // signed integer names // signed integer names
"@u8", "@u16", "@u32", "@u64", // unsigned integer names {"@i8", tnr<int8_t>()},
"@str", "@u16str", "@u32str", // strings {"@i16", tnr<int16_t>()},
"float", "double", "@ldouble", // floating points {"@i32", tnr<int32_t>()},
{"@i64", tnr<int64_t>()},
// unsigned integer names
{"@u8", tnr<uint8_t>()},
{"@u16", tnr<uint16_t>()},
{"@u32", tnr<uint32_t>()},
{"@u64", tnr<uint64_t>()},
// strings
{"@str", tnr<std::string>()},
{"@u16str", tnr<std::u16string>()},
{"@u32str", tnr<std::u32string>()},
// floating points
{"float", tnr<float>()},
{"double", tnr<double>()},
{"@ldouble", tnr<long double>()},
// default announced types // default announced types
"@unit", // unit_t {"@unit", tnr<unit_t>()},
"@actor", // actor {"@actor", tnr<actor>()},
"@addr", // actor_addr {"@addr", tnr<actor_addr>()},
"@atom", // atom_value {"@atom", tnr<atom_value>()},
"@channel", // channel {"@channel", tnr<channel>()},
"@charbuf", // vector<char> {"@charbuf", tnr<std::vector<char>>()},
"@down", // down_msg {"@down", tnr<down_msg>()},
"@duration", // duration {"@duration", tnr<duration>()},
"@exit", // exit_msg {"@exit", tnr<exit_msg>()},
"@group", // group {"@group", tnr<group>()},
"@group_down", // group_down_msg {"@group_down", tnr<group_down_msg>()},
"@message", // message {"@message", tnr<message>()},
"@message_id", // message_id {"@message_id", tnr<message_id>()},
"@node", // node_id {"@node", tnr<node_id>()},
"@strmap", // map<string,string> {"@strmap", tnr<std::map<std::string,std::string>>()},
"@timeout", // timeout_msg {"@timeout", tnr<timeout_msg>()},
"@sync_exited", // sync_exited_msg {"@sync_exited", tnr<sync_exited_msg>()},
"@sync_timeout", // sync_timeout_msg {"@sync_timeout", tnr<sync_timeout_msg>()},
"@strvec", // vector<string> {"@strvec", tnr<std::vector<std::string>>()},
"@strset" // set<string> {"@strset", tnr<std::set<std::string>>()}
}; };
CAF_CHECKPOINT(); CAF_CHECKPOINT();
if (check_types(expected)) { if (check_types(expected)) {
...@@ -229,6 +200,7 @@ int main() { ...@@ -229,6 +200,7 @@ int main() {
announce<test_enum>("test_enum"); announce<test_enum>("test_enum");
announce<test_struct>("test_struct", &test_struct::test_value); announce<test_struct>("test_struct", &test_struct::test_value);
CAF_CHECKPOINT(); CAF_CHECKPOINT();
check_types(append(expected, "test_enum", "test_struct"));
shutdown(); shutdown();
return CAF_TEST_RESULT(); return CAF_TEST_RESULT();
} }
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