diff --git a/test/codec/common_code.cc b/test/codec/common_code.cc index e14eb6b..b3730c2 100644 --- a/test/codec/common_code.cc +++ b/test/codec/common_code.cc @@ -8,12 +8,13 @@ #define SHOULD_PANIC(FUNC) \ try { \ FUNC; EXPECT_STREQ("should panic", "but no panic"); \ - } catch (...) {} + } catch (klotski::CommonCodeExp&) {} using klotski::RawCode; using klotski::AllCases; using klotski::ShortCode; using klotski::CommonCode; +using klotski::ALL_CASES_SIZE; const static uint64_t TEST_CODE = 0x1'A9BF'0C00; const static std::string TEST_CODE_STR = "1A9BF0C00"; @@ -29,30 +30,29 @@ TEST(CommonCode, validity) { EXPECT_NE(CommonCode::check(0x1'A9'BF'FC'00), true); // less than 2 space EXPECT_NE(CommonCode::check(0x1'A0'BF'0C'01), true); // low bits not fill zero + SHOULD_PANIC(CommonCode::create(0x123456789)) // invalid code SHOULD_PANIC(CommonCode::from_string("0123456789")) // length > 9 SHOULD_PANIC(CommonCode::from_string("123J432A9")) // with invalid `J` } TEST(CommonCode, code_verify) { // test all layout - std::thread threads[16]; auto test = [](uint64_t head) { for (const auto &range : AllCases::fetch()[head]) { uint64_t code = head << 32 | range; EXPECT_EQ(CommonCode::check(code), true); // test static `check` interface - auto tmp = CommonCode::unsafe_create(code); // test dynamic `valid` interface - EXPECT_EQ(tmp.valid(), true); + auto tmp = CommonCode::unsafe_create(code); + EXPECT_EQ(tmp.valid(), true); // test dynamic `valid` interface } }; + + std::thread threads[16]; for (uint64_t head = 0; head < 16; ++head) { // split into 16 threads threads[head] = std::thread(test, head); } - for (auto &t : threads) { - t.join(); - } + for (auto &t : threads) { t.join(); } } TEST(CommonCode, code_string) { // test all string code - std::thread threads[16]; auto test = [](uint64_t head) { for (const auto &range : AllCases::fetch()[head]) { std::string code_str; @@ -77,12 +77,12 @@ TEST(CommonCode, code_string) { // test all string code EXPECT_EQ(CommonCode::from_string(code_str), common_code); // test lower cases } }; + + std::thread threads[16]; for (uint64_t head = 0; head < 16; ++head) { // split into 16 threads threads[head] = std::thread(test, head); } - for (auto &t : threads) { - t.join(); - } + for (auto &t : threads) { t.join(); } } TEST(CommonCode, operators) { @@ -112,6 +112,32 @@ TEST(CommonCode, code_convert) { EXPECT_EQ(CommonCode(TEST_CODE).unwrap(), TEST_CODE); } +TEST(CommonCode, batch_convert) { + auto test = [](uint64_t head) { + std::vector raw_codes; + std::vector short_codes; + std::vector common_codes; + raw_codes.reserve(ALL_CASES_SIZE[head]); + short_codes.reserve(ALL_CASES_SIZE[head]); + common_codes.reserve(ALL_CASES_SIZE[head]); + + for (auto &&range : AllCases::fetch()[head]) { + common_codes.emplace_back(head << 32 | range); + raw_codes.emplace_back(common_codes.back()); + short_codes.emplace_back(common_codes.back()); + } + EXPECT_EQ(common_codes, CommonCode::convert(raw_codes)); + EXPECT_EQ(common_codes, CommonCode::convert(short_codes)); + }; + + std::thread threads[16]; + ShortCode::speed_up(ShortCode::FAST); + for (uint64_t head = 0; head < 16; ++head) { + threads[head] = std::thread(test, head); + } + for (auto &t : threads) { t.join(); } +} + TEST(CommonCode, constructors) { EXPECT_EQ(CommonCode(TEST_CODE).unwrap(), TEST_CODE); diff --git a/test/codec/raw_code.cc b/test/codec/raw_code.cc index ba721de..8c654d2 100644 --- a/test/codec/raw_code.cc +++ b/test/codec/raw_code.cc @@ -4,9 +4,15 @@ #include "all_cases.h" #include "gtest/gtest.h" +#define SHOULD_PANIC(FUNC) \ + try { \ + FUNC; EXPECT_STREQ("should panic", "but no panic"); \ + } catch (klotski::RawCodeExp&) {} + using klotski::RawCode; using klotski::AllCases; using klotski::CommonCode; +using klotski::ALL_CASES_SIZE; const static uint64_t TEST_CODE = 0x0603'EDF5'CAFF'F5E2; @@ -18,24 +24,25 @@ TEST(RawCode, hash) { TEST(RawCode, validity) { EXPECT_EQ(RawCode::check(0x0A34'182B'3810'2D21), false); // invalid code EXPECT_EQ(RawCode::check(0x8603'EDF5'CAFF'F5E2), false); // high 4-bits not zero + + SHOULD_PANIC(RawCode::create(0x0000'0000'0000'0000)) // invalid code } TEST(RawCode, code_verify) { // test all layouts - std::thread threads[16]; auto test = [](uint64_t head) { for (const auto &range : AllCases::fetch()[head]) { auto code = (uint64_t)RawCode::from_common_code(head << 32 | range); EXPECT_EQ(RawCode::check(code), true); // test static `check` interface - auto tmp = RawCode::unsafe_create(code); // test dynamic `valid` interface - EXPECT_EQ(tmp.valid(), true); + auto tmp = RawCode::unsafe_create(code); + EXPECT_EQ(tmp.valid(), true); // test dynamic `valid` interface } }; + + std::thread threads[16]; for (uint64_t head = 0; head < 16; ++head) { // split into 16 threads threads[head] = std::thread(test, head); } - for (auto &t : threads) { - t.join(); - } + for (auto &t : threads) { t.join(); } } TEST(RawCode, operators) { @@ -58,6 +65,27 @@ TEST(RawCode, code_convert) { EXPECT_EQ(RawCode(TEST_CODE).unwrap(), TEST_CODE); } +TEST(RawCode, batch_convert) { + auto test = [](uint64_t head) { + std::vector raw_codes; + std::vector common_codes; + raw_codes.reserve(ALL_CASES_SIZE[head]); + common_codes.reserve(ALL_CASES_SIZE[head]); + + for (auto &&range : AllCases::fetch()[head]) { + common_codes.emplace_back(head << 32 | range); + raw_codes.emplace_back(common_codes.back()); + } + EXPECT_EQ(raw_codes, RawCode::convert(common_codes)); + }; + + std::thread threads[16]; + for (uint64_t head = 0; head < 16; ++head) { + threads[head] = std::thread(test, head); + } + for (auto &t : threads) { t.join(); } +} + TEST(RawCode, constructors) { EXPECT_EQ(RawCode(TEST_CODE).unwrap(), TEST_CODE); auto common_code = CommonCode::from_raw_code(TEST_CODE); @@ -124,7 +152,6 @@ TEST(RawCode, horizontal_mirror) { } TEST(RawCode, vertical_mirror_global) { - std::thread threads[16]; auto test = [](uint64_t head) { for (const auto &range : AllCases::fetch()[head]) { /// generate code and mirror layout @@ -140,16 +167,15 @@ TEST(RawCode, vertical_mirror_global) { EXPECT_EQ(raw_code_mirror.to_vertical_mirror(), raw_code); } }; + + std::thread threads[16]; for (uint64_t head = 0; head < 16; ++head) { // split into 16 threads threads[head] = std::thread(test, head); } - for (auto &t : threads) { - t.join(); - } + for (auto &t : threads) { t.join(); } } TEST(RawCode, horizontal_mirror_global) { - std::thread threads[16]; auto test = [](uint64_t head) { for (const auto &range : AllCases::fetch()[head]) { /// generate code and mirror layout @@ -168,10 +194,10 @@ TEST(RawCode, horizontal_mirror_global) { EXPECT_EQ(raw_code_mirror.to_horizontal_mirror(), raw_code); } }; + + std::thread threads[16]; for (uint64_t head = 0; head < 16; ++head) { // split into 16 threads threads[head] = std::thread(test, head); } - for (auto &t : threads) { - t.join(); - } + for (auto &t : threads) { t.join(); } } diff --git a/test/codec/short_code.cc b/test/codec/short_code.cc index 22b2f0c..0073e0d 100644 --- a/test/codec/short_code.cc +++ b/test/codec/short_code.cc @@ -8,13 +8,14 @@ #define SHOULD_PANIC(FUNC) \ try { \ FUNC; EXPECT_STREQ("should panic", "but no panic"); \ - } catch (...) {} + } catch (klotski::ShortCodeExp&) {} using klotski::AllCases; using klotski::ShortCode; using klotski::CommonCode; using klotski::BasicRanges; +using klotski::ALL_CASES_SIZE; using klotski::SHORT_CODE_LIMIT; using klotski::ALL_CASES_SIZE_SUM; @@ -33,6 +34,8 @@ TEST(ShortCode, hash) { TEST(ShortCode, validity) { EXPECT_NE(ShortCode::check(-1), true); // out of short code range EXPECT_NE(ShortCode::check(29670987), true); // out of short code range + + SHOULD_PANIC(ShortCode::create(SHORT_CODE_LIMIT)) // invalid code SHOULD_PANIC(ShortCode::from_string("R50EH")) // with invalid `0` SHOULD_PANIC(ShortCode::from_string("123456")) // length != 5 SHOULD_PANIC(ShortCode::from_string("Z9EFV")) // out of short code range @@ -67,26 +70,24 @@ TEST(ShortCode, speed_up) { } TEST(ShortCode, code_verify) { // test all layout - std::thread threads[16]; auto test = [](uint64_t head) { for (const auto &range : AllCases::fetch()[head]) { auto code = (uint32_t)ShortCode::from_common_code(head << 32 | range); EXPECT_EQ(ShortCode::check(code), true); // test static `check` interface - auto tmp = ShortCode::unsafe_create(code); // test dynamic `valid` interface - EXPECT_EQ(tmp.valid(), true); + auto tmp = ShortCode::unsafe_create(code); + EXPECT_EQ(tmp.valid(), true); // test dynamic `valid` interface } }; + + std::thread threads[16]; + ShortCode::speed_up(ShortCode::FAST); for (uint64_t head = 0; head < 16; ++head) { // split into 16 threads - /// NOTE: ensure that short code fast mode enabled threads[head] = std::thread(test, head); } - for (auto &t : threads) { - t.join(); - } + for (auto &t : threads) { t.join(); } } TEST(ShortCode, code_string) { // test all string code - std::thread threads[16]; auto test = [](uint64_t head) { for (const auto &range : AllCases::fetch()[head]) { std::string code_str; @@ -105,12 +106,12 @@ TEST(ShortCode, code_string) { // test all string code EXPECT_EQ(ShortCode::from_string(code_str), short_code); // test lower cases } }; + + std::thread threads[16]; for (uint64_t head = 0; head < 16; ++head) { // split into 16 threads threads[head] = std::thread(test, head); } - for (auto &t : threads) { - t.join(); - } + for (auto &t : threads) { t.join(); } } TEST(ShortCode, operators) { @@ -126,6 +127,9 @@ TEST(ShortCode, operators) { EXPECT_NE(TEST_CODE + 1, ShortCode(TEST_CODE)); // uint32_t != ShortCode EXPECT_NE(ShortCode(TEST_CODE), TEST_CODE + 1); // ShortCode != uint32_t EXPECT_NE(ShortCode(TEST_CODE), ShortCode::unsafe_create(TEST_CODE + 1)); // ShortCode != ShortCode + + EXPECT_LT(ShortCode(TEST_CODE), ShortCode::unsafe_create(TEST_CODE + 1)); // ShortCode < ShortCode + EXPECT_GT(ShortCode::unsafe_create(TEST_CODE + 1), ShortCode(TEST_CODE)); // ShortCode > ShortCode } TEST(ShortCode, code_convert) { @@ -135,6 +139,28 @@ TEST(ShortCode, code_convert) { EXPECT_EQ(ShortCode(TEST_CODE).unwrap(), TEST_CODE); } +TEST(ShortCode, batch_convert) { + auto test = [](uint64_t head) { + std::vector short_codes; + std::vector common_codes; + short_codes.reserve(ALL_CASES_SIZE[head]); + common_codes.reserve(ALL_CASES_SIZE[head]); + + for (auto &&range : AllCases::fetch()[head]) { + common_codes.emplace_back(head << 32 | range); + short_codes.emplace_back(common_codes.back()); + } + EXPECT_EQ(short_codes, ShortCode::convert(common_codes)); + }; + + std::thread threads[16]; + ShortCode::speed_up(ShortCode::FAST); + for (uint64_t head = 0; head < 16; ++head) { + threads[head] = std::thread(test, head); + } + for (auto &t : threads) { t.join(); } +} + TEST(ShortCode, constructors) { EXPECT_EQ(ShortCode(TEST_CODE).unwrap(), TEST_CODE);