#include #include "group.h" #include "tiny_pool.h" #include "gtest/gtest.h" #define SHOULD_PANIC(FUNC) \ try { \ FUNC; EXPECT_STREQ("should panic", "but no panic"); \ } catch (...) {} using klotski::Group; using klotski::GroupCase; using klotski::GroupType; using klotski::CommonCode; using klotski::TYPE_ID_LIMIT; TEST(Group, group_info_invalid) { SHOULD_PANIC(GroupCase::parse(GroupCase::info_t { .type_id = TYPE_ID_LIMIT, .group_id = 0, .group_index = 0, })) SHOULD_PANIC(GroupCase::parse(GroupCase::info_t { .type_id = 0, .group_id = static_cast(GroupType(0).group_num()), .group_index = 0, })) SHOULD_PANIC(GroupCase::parse(GroupCase::info_t { .type_id = 0, .group_id = 0, .group_index = Group(0, 0).size(), })) } TEST(Group, group_info) { auto test = [](GroupType group_type) { for (uint32_t group_id = 0; group_id < group_type.group_num(); ++group_id) { auto cases = CommonCode::convert(Group(group_type, group_id).cases()); auto min = *std::min_element(cases.begin(), cases.end()); auto max = *std::max_element(cases.begin(), cases.end()); auto min_info = GroupCase::info_t{ .type_id = static_cast(group_type.unwrap()), .group_id = static_cast(group_id), .group_index = 0, }; auto max_info = GroupCase::info_t{ .type_id = static_cast(group_type.unwrap()), .group_id = static_cast(group_id), .group_index = static_cast(cases.size() - 1), }; EXPECT_EQ(min, GroupCase::parse(min_info)); EXPECT_EQ(max, GroupCase::parse(max_info)); EXPECT_EQ(min_info, GroupCase::encode(min)); EXPECT_EQ(max_info, GroupCase::encode(max)); EXPECT_EQ(min_info, GroupCase::encode(min.to_raw_code())); EXPECT_EQ(max_info, GroupCase::encode(max.to_raw_code())); } }; auto pool = TinyPool(); for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) { pool.submit(test, GroupType(type_id)); } pool.boot().join(); } TEST(Group, group_info_fast_invalid) { GroupCase::speed_up(); // switch into fast mode SHOULD_PANIC(GroupCase::parse(GroupCase::info_t { .type_id = TYPE_ID_LIMIT, .group_id = 0, .group_index = 0, })) SHOULD_PANIC(GroupCase::parse(GroupCase::info_t { .type_id = 0, .group_id = static_cast(GroupType(0).group_num()), .group_index = 0, })) SHOULD_PANIC(GroupCase::parse(GroupCase::info_t { .type_id = 0, .group_id = 0, .group_index = Group(0, 0).size(), })) } TEST(Group, group_info_fast) { auto test = [](GroupType group_type) { for (uint32_t group_id = 0; group_id < group_type.group_num(); ++group_id) { auto cases = CommonCode::convert(Group(group_type, group_id).cases()); std::sort(cases.begin(), cases.end()); for (uint32_t group_index = 0; group_index < cases.size(); ++group_index) { auto info = GroupCase::info_t { .type_id = static_cast(group_type.unwrap()), .group_id = static_cast(group_id), .group_index = group_index, }; EXPECT_EQ(cases[group_index], GroupCase::parse(info)); EXPECT_EQ(info, GroupCase::encode(cases[group_index])); } } }; auto pool = TinyPool(); GroupCase::speed_up(); // entry fast mode for (uint32_t type_id = 0; type_id < TYPE_ID_LIMIT; ++type_id) { pool.submit(test, GroupType(type_id)); } pool.boot().join(); }