diff --git a/src/klotski_core/short_code/short_code.h b/src/klotski_core/short_code/short_code.h index 2bf5156..59726e5 100644 --- a/src/klotski_core/short_code/short_code.h +++ b/src/klotski_core/short_code/short_code.h @@ -35,7 +35,7 @@ namespace klotski { public: enum Mode {NORMAL, FAST}; - inline bool valid() const; + bool valid() const; static void speed_up(enum Mode mode); static bool check(uint32_t short_code); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 720b745..fb7085d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -21,13 +21,12 @@ include_directories(../src/klotski_core/raw_code) include_directories(../src/klotski_core/short_code) include_directories(../src/klotski_core/common_code) -add_executable(test_basic utils.cc all_cases.cc raw_code.cc common_code.cc) +add_executable(test_basic utils.cc all_cases.cc) target_link_libraries(test_basic PUBLIC ${TEST_DEPS} md5) add_test(NAME basic COMMAND test_basic) -# TODO: combine into basic after develop complete -add_executable(test_raw_code raw_code.cc) -target_link_libraries(test_raw_code ${TEST_DEPS}) -add_test(NAME raw_code COMMAND test_raw_code) +add_executable(test_codec short_code.cc raw_code.cc common_code.cc) +target_link_libraries(test_codec ${TEST_DEPS}) +add_test(NAME codec COMMAND test_codec) ################################################################ diff --git a/test/common_code.cc b/test/common_code.cc index 57533d9..eea92c7 100644 --- a/test/common_code.cc +++ b/test/common_code.cc @@ -65,8 +65,10 @@ TEST(CommonCode, code_string) { } TEST(CommonCode, operators) { - EXPECT_EQ(CommonCode(TEST_CODE), CommonCode(TEST_CODE)); // operator `==` + std::cout.setstate(std::ios::failbit); // hide std::cout content std::cout << "TEST OUTPUT -> " << CommonCode(TEST_CODE) << std::endl; // ostream test + std::cout.clear(); + EXPECT_EQ(CommonCode(TEST_CODE), CommonCode(TEST_CODE)); // operator `==` EXPECT_EQ((uint64_t)CommonCode(TEST_CODE), TEST_CODE); // convert as uint64_t } diff --git a/test/raw_code.cc b/test/raw_code.cc index ebd2bce..ba26c71 100644 --- a/test/raw_code.cc +++ b/test/raw_code.cc @@ -28,8 +28,10 @@ TEST(RawCode, code_verify) { } TEST(RawCode, operators) { - EXPECT_EQ(RawCode(TEST_CODE), RawCode(TEST_CODE)); // operator `==` + std::cout.setstate(std::ios::failbit); // hide std::cout content std::cout << "TEST OUTPUT" << std::endl << RawCode(TEST_CODE); // ostream test + std::cout.clear(); + EXPECT_EQ(RawCode(TEST_CODE), RawCode(TEST_CODE)); // operator `==` EXPECT_EQ((uint64_t)RawCode(TEST_CODE), TEST_CODE); // convert as uint64_t } diff --git a/test/short_code.cc b/test/short_code.cc new file mode 100644 index 0000000..a45ed08 --- /dev/null +++ b/test/short_code.cc @@ -0,0 +1,117 @@ +#include +#include +#include "all_cases.h" +#include "short_code.h" +#include "gtest/gtest.h" + +using klotski::AllCases; +using klotski::ShortCode; +using klotski::CommonCode; +using klotski::BasicRanges; + +const static uint64_t TEST_CODE = 4091296; +const static std::string TEST_CODE_STR = "4WVE1"; + +TEST(ShortCode, speed_up) { + std::thread threads[4]; + + /// speed up to normal mode + EXPECT_EQ(BasicRanges::status(), BasicRanges::NO_INIT); + for (auto &t : threads) { + t = std::thread(ShortCode::speed_up, ShortCode::NORMAL); + } + EXPECT_EQ(BasicRanges::status(), BasicRanges::BUILDING); + for (auto &t : threads) { + t.join(); + } + EXPECT_EQ(BasicRanges::status(), BasicRanges::AVAILABLE); + + /// speed up to fast mode + EXPECT_EQ(AllCases::status(), AllCases::NO_INIT); + for (auto &t : threads) { + t = std::thread(ShortCode::speed_up, ShortCode::FAST); + } + EXPECT_EQ(AllCases::status(), AllCases::BUILDING); + for (auto &t : threads) { + t.join(); + } + EXPECT_EQ(AllCases::status(), AllCases::AVAILABLE); +} + +TEST(ShortCode, code_verify) { + 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); + } + }; + for (uint64_t head = 0; head < 16; ++head) { + threads[head] = std::thread(test, head); // ensure that short code fast mode enabled + } + for (auto &t : threads) { + t.join(); + } +} + +TEST(ShortCode, code_string) { + std::thread threads[16]; + auto test = [](uint64_t head) { + for (const auto &range : AllCases::fetch()[head]) { + std::string code_str; + auto short_code = ShortCode::from_common_code(head << 32 | range); + + code_str = short_code.to_string(); + EXPECT_EQ(code_str.size(), 5); // length = 5 + for (const auto &c : code_str) { + EXPECT_EQ( + ((c >= '1' && c <= '9') || (c >= 'A' && c <= 'Z')) + && (c != 'I' && c != 'L' && c != 'O'), true + ); + } + EXPECT_EQ(ShortCode::from_string(code_str), short_code); // test upper cases + std::transform(code_str.begin(), code_str.end(), code_str.begin(), ::tolower); + EXPECT_EQ(ShortCode::from_string(code_str), short_code); // test lower cases + } + }; + for (uint64_t head = 0; head < 16; ++head) { + threads[head] = std::thread(test, head); // ensure that short code fast mode enabled + } + for (auto &t : threads) { + t.join(); + } +} + +TEST(ShortCode, operators) { + std::cout.setstate(std::ios::failbit); // hide std::cout content + std::cout << "TEST OUTPUT -> " << ShortCode(TEST_CODE) << std::endl; // ostream test + std::cout.clear(); + EXPECT_EQ(ShortCode(TEST_CODE), ShortCode(TEST_CODE)); // operator `==` + EXPECT_EQ((uint32_t)ShortCode(TEST_CODE), TEST_CODE); // convert as uint64_t +} + +TEST(ShortCode, code_convert) { + EXPECT_STREQ(ShortCode(TEST_CODE).to_string().c_str(), TEST_CODE_STR.c_str()); + EXPECT_EQ(ShortCode(ShortCode(TEST_CODE).to_string()), ShortCode(TEST_CODE)); + EXPECT_EQ(ShortCode(TEST_CODE).to_common_code(), CommonCode::from_short_code(TEST_CODE)); + EXPECT_EQ(ShortCode(TEST_CODE).unwrap(), TEST_CODE); +} + +TEST(ShortCode, constructors) { + EXPECT_EQ(ShortCode(TEST_CODE).unwrap(), TEST_CODE); + EXPECT_EQ(ShortCode(TEST_CODE_STR).unwrap(), TEST_CODE); + EXPECT_EQ(ShortCode(CommonCode::from_short_code(TEST_CODE)).unwrap(), TEST_CODE); +} + +TEST(ShortCode, initializate) { + EXPECT_EQ(ShortCode::create(TEST_CODE).unwrap(), TEST_CODE); + EXPECT_EQ(ShortCode::from_string(TEST_CODE_STR).unwrap(), TEST_CODE); + EXPECT_EQ(ShortCode::unsafe_create(TEST_CODE).unwrap(), TEST_CODE); + + auto common_code = CommonCode::from_short_code(TEST_CODE); + EXPECT_EQ(ShortCode::from_common_code(common_code).unwrap(), TEST_CODE); + EXPECT_EQ(ShortCode::from_common_code(common_code.unwrap()).unwrap(), TEST_CODE); + EXPECT_EQ(ShortCode::from_common_code(common_code.to_string()).unwrap(), TEST_CODE); +}