Browse Source

test: perf GroupUnion test suites

master
Dnomd343 2 months ago
parent
commit
490a41d1d1
  1. 1
      src/core_test/CMakeLists.txt
  2. 106
      src/core_test/cases/group_union.cc
  3. 2
      src/core_test/cases/helper/cases.h
  4. 22
      src/core_test/cases/helper/helper.cc

1
src/core_test/CMakeLists.txt

@ -19,6 +19,7 @@ set(KLSK_TEST_CASES_SRC
cases/all_cases.cc
cases/group_union.cc
cases/group.cc
cases/helper/helper.cc
cases/helper/block_num.cc
cases/helper/group_impl.cc
)

106
src/core_test/cases/group_union.cc

@ -17,44 +17,42 @@ using klotski::cases::GroupUnion;
using klotski::cases::TYPE_ID_LIMIT;
using klotski::cases::ALL_GROUP_NUM;
#define EXPECT_IOTA(R) \
EXPECT_FALSE(R.empty()); \
EXPECT_EQ(R.front(), 0); \
EXPECT_SORTED_AND_UNIQUE(R); \
EXPECT_EQ(R.back(), R.size() - 1)
TEST(GroupUnion, basic) {
// TODO: loop for all
EXPECT_TRUE(GroupUnion::create(0).has_value());
EXPECT_EQ(GroupUnion::create(0).value().unwrap(), 0);
EXPECT_FALSE(GroupUnion::create(TYPE_ID_LIMIT).has_value());
EXPECT_EQ(GroupUnion::unsafe_create(0).unwrap(), 0);
for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) {
auto group_union = GroupUnion::unsafe_create(type_id);
type_id_parallel([](uint32_t type_id) {
auto num = group_union.group_num();
EXPECT_TRUE(GroupUnion::create(type_id).has_value());
EXPECT_EQ(GroupUnion::create(type_id).value().unwrap(), type_id);
EXPECT_EQ(GroupUnion::unsafe_create(type_id).unwrap(), type_id);
auto group_union = GroupUnion::unsafe_create(type_id);
auto groups = group_union.groups();
for (auto x : groups) {
EXPECT_EQ(x.type_id(), type_id);
}
// TODO: add EXPECT_IOTA(...)
// auto group_ids = groups | std::ranges::transform([](Group x) { return x.group_id(); });
std::vector<uint32_t> group_ids;
group_ids.reserve(groups.size());
for (auto x : groups) {
group_ids.emplace_back(x.group_id());
for (const auto group : groups) {
EXPECT_EQ(group.type_id(), type_id);
}
EXPECT_SORTED_AND_UNIQUE(group_ids);
EXPECT_EQ(group_ids[0], 0);
EXPECT_EQ(group_ids[num - 1], num - 1);
EXPECT_EQ(group_ids.size(), num);
// TODO: test all
EXPECT_TRUE(group_union.group(0).has_value());
EXPECT_EQ(group_union.group(0).value().type_id(), type_id);
EXPECT_EQ(group_union.group(0).value().group_id(), 0);
auto group_ids = groups | std::views::transform([](Group g) {
return g.group_id();
}) | std::ranges::to<std::vector>();
EXPECT_IOTA(group_ids);
EXPECT_FALSE(group_union.group(num).has_value());
for (auto group_id : group_ids) {
EXPECT_TRUE(group_union.group(group_id).has_value());
EXPECT_EQ(group_union.group(group_id).value().type_id(), type_id);
EXPECT_EQ(group_union.group(group_id).value().group_id(), group_id);
}
EXPECT_FALSE(group_union.group(group_ids.size()).has_value());
});
}
TEST(GroupUnion, constant) {
@ -63,68 +61,58 @@ TEST(GroupUnion, constant) {
// TODO: verify from local builder
EXPECT_EQ(TYPE_ID_LIMIT, group_union_num());
// TODO: verify TYPE_ID_LIMIT / ALL_GROUP_NUM data
}
// TODO: verify GROUP_UNION_SIZE (size) / GROUP_NUM (group_num) / MAX_GROUP_SIZE (max_group_size)
// test from member function directly?
TEST(GroupUnion, size) {
for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) {
auto &kk = group_union_cases(type_id);
EXPECT_EQ(GroupUnion::unsafe_create(type_id).size(), kk.size());
}
}
EXPECT_EQ(TYPE_ID_LIMIT, group_union_num());
TEST(GroupUnion, group_num) {
for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) {
EXPECT_EQ(GroupUnion::unsafe_create(type_id).group_num(), group_num(type_id));
}
}
TEST(GroupUnion, cases) {
for (uint32_t type_id = 0; type_id < klotski::cases::TYPE_ID_LIMIT; ++type_id) {
auto cases = group_union_cases(type_id);
EXPECT_EQ(cases, GroupUnion::unsafe_create(type_id).cases().codes());
}
}
TEST(GroupUnion, values) {
// TODO: test max_group_size
type_id_parallel([](uint32_t type_id) {
TEST(GroupUnion, max_group_size) {
for (uint32_t type_id = 0; type_id < klotski::cases::TYPE_ID_LIMIT; ++type_id) {
auto &kk = group_union_cases(type_id);
EXPECT_EQ(GroupUnion::unsafe_create(type_id).size(), kk.size());
EXPECT_EQ(GroupUnion::unsafe_create(type_id).group_num(), group_num(type_id));
auto groups = GroupUnion::unsafe_create(type_id).groups();
auto sizes = groups | std::views::transform([](Group group) {
auto kk_view = groups | std::views::transform([](Group group) {
return group.size();
}) | std::ranges::to<std::vector>();
});
// std::cout << std::format("{} -> {}\n", type_id, sizes);
auto max_it = *std::ranges::max_element(kk_view);
auto max_item = *std::max_element(sizes.begin(), sizes.end()); // TODO: using std::ranges
EXPECT_EQ(GroupUnion::unsafe_create(type_id).max_group_size(), max_it);
EXPECT_EQ(GroupUnion::unsafe_create(type_id).max_group_size(), max_item);
});
}
TEST(GroupUnion, cases) {
type_id_parallel([](uint32_t type_id) {
auto cases = group_union_cases(type_id);
EXPECT_EQ(cases, GroupUnion::unsafe_create(type_id).cases().codes());
});
}
TEST(GroupUnion, type_id) {
ShortCode::speed_up(true);
// TODO: using `common_code_parallel`
for (uint64_t head = 0; head < 16; ++head) {
for (const auto range : AllCases::instance().fetch()[head]) {
auto common_code = CommonCode::unsafe_create(head << 32 | range);
auto short_code = common_code.to_short_code();
auto raw_code = common_code.to_raw_code();
auto expect = to_type_id(cal_block_num(range));
EXPECT_EQ(GroupUnion::from_common_code(common_code).unwrap(), expect);
EXPECT_EQ(GroupUnion::from_short_code(short_code).unwrap(), expect);
EXPECT_EQ(GroupUnion::from_raw_code(raw_code).unwrap(), expect);
EXPECT_EQ(GroupUnion::from_short_code(short_code).unwrap(), expect);
EXPECT_EQ(GroupUnion::from_common_code(common_code).unwrap(), expect);
}
}
}

2
src/core_test/cases/helper/cases.h

@ -116,3 +116,5 @@ const std::vector<CommonCode>& group_union_cases(uint32_t type_id);
const std::vector<CommonCode>& group_cases(uint32_t type_id, uint32_t group_id);
// ----------------------------------------------------------------------------------------- //
void type_id_parallel(std::function<void(uint32_t type_id)> &&func);

22
src/core_test/cases/helper/helper.cc

@ -0,0 +1,22 @@
#include <gtest/gtest.h>
#include "cases.h"
using klotski::cases::TYPE_ID_LIMIT;
void type_id_parallel(std::function<void(uint32_t type_id)> &&func) {
BS::thread_pool pool;
// TODO: using `detach_sequence`
for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) {
pool.detach_task([type_id, func = std::move(func)]() {
func(type_id);
});
}
pool.wait();
}
Loading…
Cancel
Save