diff --git a/src/core_test/CMakeLists.txt b/src/core_test/CMakeLists.txt index e9f174e..581d8ff 100644 --- a/src/core_test/CMakeLists.txt +++ b/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 ) diff --git a/src/core_test/cases/group_union.cc b/src/core_test/cases/group_union.cc index 84ddd00..f2b1fe6 100644 --- a/src/core_test/cases/group_union.cc +++ b/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 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(); + 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::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, type_id) { +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); } } - } diff --git a/src/core_test/cases/helper/cases.h b/src/core_test/cases/helper/cases.h index 685873b..de76804 100644 --- a/src/core_test/cases/helper/cases.h +++ b/src/core_test/cases/helper/cases.h @@ -116,3 +116,5 @@ const std::vector& group_union_cases(uint32_t type_id); const std::vector& group_cases(uint32_t type_id, uint32_t group_id); // ----------------------------------------------------------------------------------------- // + +void type_id_parallel(std::function &&func); diff --git a/src/core_test/cases/helper/helper.cc b/src/core_test/cases/helper/helper.cc new file mode 100644 index 0000000..313b770 --- /dev/null +++ b/src/core_test/cases/helper/helper.cc @@ -0,0 +1,22 @@ +#include + +#include "cases.h" + +using klotski::cases::TYPE_ID_LIMIT; + +void type_id_parallel(std::function &&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(); + +}