Browse Source

test: more elegant parallelism

master
Dnomd343 2 months ago
parent
commit
1fc7d35c5e
  1. 78
      src/core_test/codec/common_code.cc
  2. 3
      src/core_test/codec/helper/codec.cc
  3. 20
      src/core_test/codec/helper/codec.h
  4. 40
      src/core_test/codec/raw_code.cc
  5. 41
      src/core_test/codec/short_code.cc

78
src/core_test/codec/common_code.cc

@ -147,59 +147,53 @@ TEST(CommonCode, initialize) {
}
TEST(CommonCode, code_verify) {
common_code_parallel([](std::span<CommonCode> codes) {
for (auto code : codes) {
EXPECT_TRUE(CommonCode::check(code.unwrap())); // verify all cases
}
COMMON_CODE_PARALLEL({
EXPECT_TRUE(CommonCode::check(code.unwrap())); // verify all cases
});
}
TEST(CommonCode, code_mirror) {
common_code_parallel([](std::span<CommonCode> codes) {
for (auto code : codes) {
const auto mirror_v = code.to_vertical_mirror();
EXPECT_TRUE(CommonCode::check(mirror_v.unwrap()));
EXPECT_EQ(mirror_v.to_vertical_mirror(), code);
EXPECT_FALSE(mirror_v.is_vertical_mirror()); // not exist
EXPECT_NE(mirror_v, code);
const auto mirror_h = code.to_horizontal_mirror();
EXPECT_TRUE(CommonCode::check(mirror_h.unwrap()));
EXPECT_EQ(mirror_h.to_horizontal_mirror(), code);
if (mirror_h.is_horizontal_mirror()) {
EXPECT_EQ(mirror_h, code);
} else {
EXPECT_NE(mirror_h, code);
}
COMMON_CODE_PARALLEL({
const auto mirror_v = code.to_vertical_mirror();
EXPECT_TRUE(CommonCode::check(mirror_v.unwrap()));
EXPECT_EQ(mirror_v.to_vertical_mirror(), code);
EXPECT_FALSE(mirror_v.is_vertical_mirror()); // not exist
EXPECT_NE(mirror_v, code);
const auto mirror_h = code.to_horizontal_mirror();
EXPECT_TRUE(CommonCode::check(mirror_h.unwrap()));
EXPECT_EQ(mirror_h.to_horizontal_mirror(), code);
if (mirror_h.is_horizontal_mirror()) {
EXPECT_EQ(mirror_h, code);
} else {
EXPECT_NE(mirror_h, code);
}
});
}
TEST(CommonCode, code_string) {
common_code_parallel([](std::span<CommonCode> codes) {
for (auto code : codes) {
auto code_shorten = code.to_string(true); // with shorten
auto code_normal = code.to_string(false); // without shorten
EXPECT_TRUE(code_normal.starts_with(code_shorten));
EXPECT_EQ(std::format("{:09X}", code.unwrap()), code_normal);
EXPECT_LE(code_shorten.size(), 9); // length -> (0, 9]
EXPECT_NE(code_shorten.size(), 0);
if (code != 0) { // skip special code string `0`
EXPECT_NE(code_shorten.back(), '0');
}
EXPECT_EQ(CommonCode::from_string(code_shorten), code); // test upper cases
std::transform(code_shorten.begin(), code_shorten.end(), code_shorten.begin(), ::tolower);
EXPECT_EQ(CommonCode::from_string(code_shorten), code); // test lower cases
COMMON_CODE_PARALLEL({
auto code_shorten = code.to_string(true); // with shorten
auto code_normal = code.to_string(false); // without shorten
EXPECT_TRUE(code_normal.starts_with(code_shorten));
EXPECT_EQ(std::format("{:09X}", code.unwrap()), code_normal);
EXPECT_LE(code_shorten.size(), 9); // length -> (0, 9]
EXPECT_NE(code_shorten.size(), 0);
if (code != 0) { // skip special code string `0`
EXPECT_NE(code_shorten.back(), '0');
}
EXPECT_EQ(CommonCode::from_string(code_shorten), code); // test upper cases
std::transform(code_shorten.begin(), code_shorten.end(), code_shorten.begin(), ::tolower);
EXPECT_EQ(CommonCode::from_string(code_shorten), code); // test lower cases
EXPECT_EQ(code_normal.size(), 9); // length = 9
for (auto c : code_normal) {
EXPECT_TRUE((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'));
}
EXPECT_EQ(CommonCode::from_string(code_normal), code); // test upper cases
std::transform(code_normal.begin(), code_normal.end(), code_normal.begin(), ::tolower);
EXPECT_EQ(CommonCode::from_string(code_normal), code); // test lower cases
EXPECT_EQ(code_normal.size(), 9); // length = 9
for (auto c : code_normal) {
EXPECT_TRUE((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'));
}
EXPECT_EQ(CommonCode::from_string(code_normal), code); // test upper cases
std::transform(code_normal.begin(), code_normal.end(), code_normal.begin(), ::tolower);
EXPECT_EQ(CommonCode::from_string(code_normal), code); // test lower cases
});
}

3
src/core_test/codec/helper/codec.cc

@ -2,6 +2,9 @@
#include "codec.h"
using klotski::cases::AllCases;
using klotski::cases::ALL_CASES_NUM_;
void head_parallel(std::function<void(uint64_t head)> &&func) {
constexpr auto heads = std::to_array({
0, 1, 2, 4, 5, 6, 8, 9, 10, 12, 13, 14

20
src/core_test/codec/helper/codec.h

@ -8,9 +8,6 @@
#include "short_code/short_code.h"
#include "common_code/common_code.h"
using klotski::cases::AllCases;
using klotski::cases::ALL_CASES_NUM_;
using klotski::codec::RawCode;
using klotski::codec::ShortCode;
using klotski::codec::CommonCode;
@ -18,11 +15,24 @@ using klotski::codec::CommonCode;
/// Build all valid CommonCodes.
std::vector<uint64_t> all_common_codes();
/// Spawn all valid klotski headers in parallel.
void head_parallel(std::function<void(uint64_t)> &&func);
// ----------------------------------------------------------------------------------------- //
/// Spawn all valid RawCodes in parallel.
void raw_code_parallel(std::function<void(std::span<RawCode>)> &&func);
/// Spawn all valid ShortCodes in parallel.
void short_code_parallel(std::function<void(std::span<ShortCode>)> &&func);
/// Spawn all valid CommonCodes in parallel.
void common_code_parallel(std::function<void(std::span<CommonCode>)> &&func);
#define CODE_PARALLEL(Type, type, impl) \
type##_code_parallel([](std::span<Type##Code> codes) { \
for (auto code : codes) {impl} \
})
#define RAW_CODE_PARALLEL(impl) CODE_PARALLEL(Raw, raw, impl)
#define SHORT_CODE_PARALLEL(impl) CODE_PARALLEL(Short, short, impl)
#define COMMON_CODE_PARALLEL(impl) CODE_PARALLEL(Common, common, impl)
// ----------------------------------------------------------------------------------------- //

40
src/core_test/codec/raw_code.cc

@ -119,32 +119,28 @@ TEST(RawCode, initialize) {
}
TEST(RawCode, code_verify) {
raw_code_parallel([](std::span<RawCode> codes) {
for (auto code : codes) {
EXPECT_TRUE(RawCode::check(code.unwrap()));
const auto common_code = code.to_common_code(); // RawCode::compact
EXPECT_EQ(RawCode::from_common_code(common_code), code); // RawCode::extract
}
RAW_CODE_PARALLEL({
EXPECT_TRUE(RawCode::check(code.unwrap()));
const auto common_code = code.to_common_code(); // RawCode::compact
EXPECT_EQ(RawCode::from_common_code(common_code), code); // RawCode::extract
});
}
TEST(RawCode, code_mirror) {
raw_code_parallel([](std::span<RawCode> codes) {
for (auto code : codes) {
const auto mirror_v = code.to_vertical_mirror();
EXPECT_TRUE(RawCode::check(mirror_v.unwrap()));
EXPECT_EQ(mirror_v.to_vertical_mirror(), code);
EXPECT_FALSE(mirror_v.is_vertical_mirror()); // not exist
EXPECT_NE(mirror_v, code);
const auto mirror_h = code.to_horizontal_mirror();
EXPECT_TRUE(RawCode::check(mirror_h.unwrap()));
EXPECT_EQ(mirror_h.to_horizontal_mirror(), code);
if (mirror_h.is_horizontal_mirror()) {
EXPECT_EQ(mirror_h, code);
} else {
EXPECT_NE(mirror_h, code);
}
RAW_CODE_PARALLEL({
const auto mirror_v = code.to_vertical_mirror();
EXPECT_TRUE(RawCode::check(mirror_v.unwrap()));
EXPECT_EQ(mirror_v.to_vertical_mirror(), code);
EXPECT_FALSE(mirror_v.is_vertical_mirror()); // not exist
EXPECT_NE(mirror_v, code);
const auto mirror_h = code.to_horizontal_mirror();
EXPECT_TRUE(RawCode::check(mirror_h.unwrap()));
EXPECT_EQ(mirror_h.to_horizontal_mirror(), code);
if (mirror_h.is_horizontal_mirror()) {
EXPECT_EQ(mirror_h, code);
} else {
EXPECT_NE(mirror_h, code);
}
});
}

41
src/core_test/codec/short_code.cc

@ -31,16 +31,7 @@ EXPOSE_STATIC_VAR(ShortCode, bool, fast_)
EXPOSE_STATIC_VAR(ShortCode, const RangesUnion*, cases_)
EXPOSE_STATIC_VAR(ShortCode, std::atomic<const Ranges*>, ranges_)
/// Reset basic ranges build state, note it is thread-unsafe.
void basic_ranges_reset() {
exposer::BasicRanges_available_(BasicRanges::instance()) = false;
}
/// Reset all cases build state, note it is thread-unsafe.
void all_cases_reset() {
exposer::AllCases_available_(AllCases::instance()) = false;
}
/// Reset ShortCode speed up state, note it is thread-unsafe.
void speed_up_reset() {
exposer::ShortCode_fast_() = false;
exposer::ShortCode_cases_() = nullptr;
@ -208,28 +199,24 @@ TEST(ShortCode, speed_up) {
TEST(ShortCode, code_verify) {
ShortCode::speed_up(true); // enter fast mode
short_code_parallel([](std::span<ShortCode> codes) {
for (auto code : codes) {
EXPECT_TRUE(ShortCode::check(code.unwrap()));
auto common_code = code.to_common_code(); // ShortCode::fast_decode
EXPECT_EQ(ShortCode::from_common_code(common_code), code); // ShortCode::fast_encode
}
SHORT_CODE_PARALLEL({
EXPECT_TRUE(ShortCode::check(code.unwrap()));
auto common_code = code.to_common_code(); // ShortCode::fast_decode
EXPECT_EQ(ShortCode::from_common_code(common_code), code); // ShortCode::fast_encode
});
}
TEST(ShortCode, code_string) {
short_code_parallel([](std::span<ShortCode> codes) {
for (auto code : codes) {
auto code_str = code.to_string();
EXPECT_EQ(code_str.size(), 5); // length = 5
for (auto c : code_str) {
EXPECT_TRUE((c >= '1' && c <= '9') || (c >= 'A' && c <= 'Z'));
EXPECT_TRUE(c != 'I' && c != 'L' && c != 'O');
}
EXPECT_EQ(ShortCode::from_string(code_str), code); // test upper cases
std::transform(code_str.begin(), code_str.end(), code_str.begin(), ::tolower);
EXPECT_EQ(ShortCode::from_string(code_str), code); // test lower cases
SHORT_CODE_PARALLEL({
auto code_str = code.to_string();
EXPECT_EQ(code_str.size(), 5); // length = 5
for (auto c : code_str) {
EXPECT_TRUE((c >= '1' && c <= '9') || (c >= 'A' && c <= 'Z'));
EXPECT_TRUE(c != 'I' && c != 'L' && c != 'O');
}
EXPECT_EQ(ShortCode::from_string(code_str), code); // test upper cases
std::transform(code_str.begin(), code_str.end(), code_str.begin(), ::tolower);
EXPECT_EQ(ShortCode::from_string(code_str), code); // test lower cases
});
}

Loading…
Cancel
Save