Browse Source

test: enhance common code string check

legacy
Dnomd343 2 years ago
parent
commit
954833060b
  1. 15
      src/klotski_core/common_code/serialize.cc
  2. 6
      test/all_cases.cc
  3. 42
      test/common_code.cc

15
src/klotski_core/common_code/serialize.cc

@ -3,16 +3,16 @@
using klotski::CommonCode; using klotski::CommonCode;
inline uint8_t binary_count(uint32_t bin) { // get number of non-zero bits inline uint8_t binary_count(uint32_t bin) { // get number of non-zero bits
bin -= (bin >> 1) & 0x55555555; bin -= (bin >> 1) & 0x55'55'55'55;
bin = (bin & 0x33333333) + ((bin >> 2) & 0x33333333); bin = (bin & 0x33'33'33'33) + ((bin >> 2) & 0x33'33'33'33);
bin = ((bin >> 4) + bin) & 0x0F0F0F0F; bin = ((bin >> 4) + bin) & 0x0F'0F'0F'0F;
bin += bin >> 8; bin += bin >> 8;
bin += bin >> 16; bin += bin >> 16;
return bin & 0b111111; return bin & 0b11'11'11;
} }
/// NOTE: input should not be zero /// NOTE: input should not be zero
inline uint32_t last_zero_num(uint32_t bin) { // get last zero number inline uint8_t last_zero_num(uint32_t bin) { // get last zero number
bin ^= (bin - 1); bin ^= (bin - 1);
return binary_count(bin >> 1); return binary_count(bin >> 1);
} }
@ -25,8 +25,9 @@ std::string CommonCode::to_string(bool shorten) const { // convert uint64_t code
char result[10]; // max length 9-bits char result[10]; // max length 9-bits
sprintf(result, "%09lX", code); sprintf(result, "%09lX", code);
if (shorten) { // remove `0` after common code if (shorten) { // remove `0` after common code
if (code == 0x000000000) { if ((uint32_t)code == 0x00'00'00'00) { // low 32-bits are zero
return "0"; // special case -> only one `0` result[1] = '\0'; // only keep first character
return result;
} }
result[9 - last_zero_num(code) / 4] = '\0'; // truncate string result[9 - last_zero_num(code) / 4] = '\0'; // truncate string
} }

6
test/all_cases.cc

@ -10,8 +10,6 @@ using klotski::ALL_CASES_SIZE;
using klotski::BASIC_RANGES_SIZE; using klotski::BASIC_RANGES_SIZE;
using klotski::ALL_CASES_SIZE_SUM; using klotski::ALL_CASES_SIZE_SUM;
const static int TEST_THREAD_NUM = 8;
/// basic ranges constants /// basic ranges constants
const char BASIC_RANGES_MD5[] = "6f385dc171e201089ff96bb010b47212"; const char BASIC_RANGES_MD5[] = "6f385dc171e201089ff96bb010b47212";
@ -20,7 +18,7 @@ const char ALL_CASES_MD5[] = "3888e9fab8d3cbb50908b12b147cfb23";
/// basic ranges mutex check /// basic ranges mutex check
TEST(AllCases, basic_ranges_mutex) { TEST(AllCases, basic_ranges_mutex) {
std::thread threads[TEST_THREAD_NUM]; std::thread threads[4];
EXPECT_EQ(BasicRanges::status(), BasicRanges::NO_INIT); EXPECT_EQ(BasicRanges::status(), BasicRanges::NO_INIT);
for (auto &t : threads) { for (auto &t : threads) {
t = std::thread(BasicRanges::build); t = std::thread(BasicRanges::build);
@ -52,7 +50,7 @@ TEST(AllCases, basic_ranges_data) {
/// basic ranges mutex check /// basic ranges mutex check
TEST(AllCases, all_cases_mutex) { TEST(AllCases, all_cases_mutex) {
std::thread threads[TEST_THREAD_NUM]; std::thread threads[4];
EXPECT_EQ(AllCases::status(), AllCases::NO_INIT); EXPECT_EQ(AllCases::status(), AllCases::NO_INIT);
for (auto &t : threads) { for (auto &t : threads) {
t = std::thread(AllCases::build); t = std::thread(AllCases::build);

42
test/common_code.cc

@ -1,3 +1,5 @@
#include <thread>
#include <algorithm>
#include "all_cases.h" #include "all_cases.h"
#include "common_code.h" #include "common_code.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
@ -12,23 +14,54 @@ const static uint64_t TEST_CODE = 0x1A9BF0C00;
const static std::string TEST_CODE_STR = "1A9BF0C00"; const static std::string TEST_CODE_STR = "1A9BF0C00";
TEST(CommonCode, code_verify) { TEST(CommonCode, code_verify) {
for (uint64_t head = 0; head < 16; ++head) { std::thread threads[16];
auto test = [](uint64_t head) {
for (const auto &range : AllCases::fetch()[head]) { for (const auto &range : AllCases::fetch()[head]) {
uint64_t code = head << 32 | range; uint64_t code = head << 32 | range;
EXPECT_EQ(CommonCode::check(code), true); // test static `check` interface EXPECT_EQ(CommonCode::check(code), true); // test static `check` interface
auto tmp = CommonCode::unsafe_create(code); // test dynamic `valid` interface auto tmp = CommonCode::unsafe_create(code); // test dynamic `valid` interface
EXPECT_EQ(tmp.valid(), true); EXPECT_EQ(tmp.valid(), true);
} }
};
for (uint64_t head = 0; head < 16; ++head) {
threads[head] = std::thread(test, head);
}
for (auto &t : threads) {
t.join();
} }
} }
TEST(CommonCode, code_string) { TEST(CommonCode, code_string) {
for (uint64_t head = 0; head < 16; ++head) { std::thread threads[16];
auto test = [](uint64_t head) {
for (const auto &range : AllCases::fetch()[head]) { for (const auto &range : AllCases::fetch()[head]) {
std::string code_str;
uint64_t code = head << 32 | range; uint64_t code = head << 32 | range;
auto common_code = CommonCode::unsafe_create(code); auto common_code = CommonCode::unsafe_create(code);
EXPECT_EQ(CommonCode::from_string(common_code.to_string()), common_code);
code_str = common_code.to_string(true); // with shorten
EXPECT_LE(code_str.size(), 9); // length -> (0, 9]
EXPECT_NE(code_str.size(), 0);
if (code != 0) { // skip special code string `0`
EXPECT_NE(code_str.back(), '0');
}
EXPECT_EQ(CommonCode::from_string(code_str), common_code);
code_str = common_code.to_string(false); // without shorten
EXPECT_EQ(code_str.size(), 9); // length = 9
for (const auto &c : code_str) {
EXPECT_EQ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'), true);
}
EXPECT_EQ(CommonCode::from_string(code_str), common_code); // test upper cases
std::transform(code_str.begin(), code_str.end(), code_str.begin(), ::tolower);
EXPECT_EQ(CommonCode::from_string(code_str), common_code); // test lower cases
}
};
for (uint64_t head = 0; head < 16; ++head) {
threads[head] = std::thread(test, head);
} }
for (auto &t : threads) {
t.join();
} }
} }
@ -41,12 +74,13 @@ TEST(CommonCode, constructors) {
TEST(CommonCode, operators) { TEST(CommonCode, operators) {
EXPECT_EQ(CommonCode(TEST_CODE), CommonCode(TEST_CODE)); // operator `==` EXPECT_EQ(CommonCode(TEST_CODE), CommonCode(TEST_CODE)); // operator `==`
std::cout << CommonCode(TEST_CODE) << std::endl; // ostream test std::cout << "TEST OUTPUT -> " << CommonCode(TEST_CODE) << std::endl; // ostream test
EXPECT_EQ((uint64_t)CommonCode(TEST_CODE), TEST_CODE); // convert as uint64_t EXPECT_EQ((uint64_t)CommonCode(TEST_CODE), TEST_CODE); // convert as uint64_t
EXPECT_EQ(CommonCode(TEST_CODE).unwrap(), TEST_CODE); EXPECT_EQ(CommonCode(TEST_CODE).unwrap(), TEST_CODE);
} }
TEST(CommonCode, code_convert) { TEST(CommonCode, code_convert) {
EXPECT_STREQ(CommonCode(TEST_CODE).to_string().c_str(), TEST_CODE_STR.c_str());
EXPECT_EQ(CommonCode(CommonCode(TEST_CODE).to_string()), CommonCode(TEST_CODE)); EXPECT_EQ(CommonCode(CommonCode(TEST_CODE).to_string()), CommonCode(TEST_CODE));
EXPECT_EQ(CommonCode(TEST_CODE).to_raw_code(), RawCode::from_common_code(TEST_CODE)); EXPECT_EQ(CommonCode(TEST_CODE).to_raw_code(), RawCode::from_common_code(TEST_CODE));
EXPECT_EQ(CommonCode(TEST_CODE).to_short_code(), ShortCode::from_common_code(TEST_CODE)); EXPECT_EQ(CommonCode(TEST_CODE).to_short_code(), ShortCode::from_common_code(TEST_CODE));

Loading…
Cancel
Save