Browse Source

test: enhance ShortCode test suites

legacy
Dnomd343 2 weeks ago
parent
commit
0a3b334c30
  1. 7
      src/core/main.cc
  2. 1
      src/core/short_code/short_code.h
  3. 53
      src/core_test/codec/short_code.cc

7
src/core/main.cc

@ -45,13 +45,6 @@ int main() {
const auto start = std::chrono::system_clock::now(); const auto start = std::chrono::system_clock::now();
static_assert(ShortCode::check(4091296));
constexpr auto short_code = ShortCode::unsafe_create(4091296);
static_assert(short_code.unwrap() == 4091296);
static_assert(static_cast<uint32_t>(short_code) == 4091296);
static_assert(short_code == ShortCode::create(4091296)->unwrap());
// const auto code = CommonCode::unsafe_create(0x1A9BF0C00).to_raw_code(); // const auto code = CommonCode::unsafe_create(0x1A9BF0C00).to_raw_code();
// const auto code = CommonCode::unsafe_create(0x4FEA13400).to_raw_code(); // const auto code = CommonCode::unsafe_create(0x4FEA13400).to_raw_code();
// FastCal fc {code}; // FastCal fc {code};

1
src/core/short_code/short_code.h

@ -189,6 +189,7 @@ private:
static_assert(sizeof(ShortCode) == 4); static_assert(sizeof(ShortCode) == 4);
static_assert(std::is_standard_layout_v<ShortCode>); static_assert(std::is_standard_layout_v<ShortCode>);
static_assert(std::is_trivially_copyable_v<ShortCode>); static_assert(std::is_trivially_copyable_v<ShortCode>);
static_assert(std::has_unique_object_representations_v<ShortCode>);
} // namespace klotski::codec } // namespace klotski::codec

53
src/core_test/codec/short_code.cc

@ -1,10 +1,11 @@
#include <algorithm>
#include <gtest/gtest.h> #include <gtest/gtest.h>
#include <utility/exposer.h>
#include "test_samples.h" #include "test_samples.h"
#include "helper/hash.h"
#include "helper/expect.h" #include "helper/expect.h"
#include "helper/parallel.h" #include "helper/parallel.h"
#include "utility/exposer.h"
#include "helper/concurrent.h" #include "helper/concurrent.h"
#include "all_cases/all_cases.h" #include "all_cases/all_cases.h"
@ -23,6 +24,15 @@ using klotski::cases::ALL_CASES_NUM;
using klotski::cases::ALL_CASES_NUM_; using klotski::cases::ALL_CASES_NUM_;
using klotski::codec::SHORT_CODE_LIMIT; using klotski::codec::SHORT_CODE_LIMIT;
static_assert(helper::is_hashable_v<ShortCode>);
static_assert(!std::is_default_constructible_v<ShortCode>);
static_assert(std::is_trivially_destructible_v<ShortCode>);
static_assert(std::is_trivially_copy_assignable_v<ShortCode>);
static_assert(std::is_trivially_move_assignable_v<ShortCode>);
static_assert(std::is_trivially_copy_constructible_v<ShortCode>);
static_assert(std::is_trivially_move_constructible_v<ShortCode>);
/// Forcibly modify private variables to reset state. /// Forcibly modify private variables to reset state.
EXPOSE_VAR(AllCases, bool, available_) EXPOSE_VAR(AllCases, bool, available_)
EXPOSE_VAR(BasicRanges, bool, available_) EXPOSE_VAR(BasicRanges, bool, available_)
@ -31,7 +41,7 @@ EXPOSE_STATIC_VAR(ShortCode, const RangesUnion*, cases_)
EXPOSE_STATIC_VAR(ShortCode, std::atomic<const Ranges*>, ranges_) EXPOSE_STATIC_VAR(ShortCode, std::atomic<const Ranges*>, ranges_)
/// Reset ShortCode speed up state, note it is thread-unsafe. /// Reset ShortCode speed up state, note it is thread-unsafe.
void speed_up_reset() { static void speed_up_reset() {
exposer::ShortCode_fast_() = false; exposer::ShortCode_fast_() = false;
exposer::ShortCode_cases_() = nullptr; exposer::ShortCode_cases_() = nullptr;
exposer::ShortCode_ranges_() = nullptr; exposer::ShortCode_ranges_() = nullptr;
@ -47,7 +57,7 @@ TEST(ShortCode, basic) {
EXPECT_FALSE(ShortCode::from_string("123456").has_value()); // length != 5 EXPECT_FALSE(ShortCode::from_string("123456").has_value()); // length != 5
EXPECT_FALSE(ShortCode::from_string("Z9EFV").has_value()); // out of short code range EXPECT_FALSE(ShortCode::from_string("Z9EFV").has_value()); // out of short code range
const auto sum = std::accumulate(ALL_CASES_NUM.begin(), ALL_CASES_NUM.end(), 0); constexpr auto sum = std::accumulate(ALL_CASES_NUM.begin(), ALL_CASES_NUM.end(), 0);
EXPECT_EQ(sum, SHORT_CODE_LIMIT); EXPECT_EQ(sum, SHORT_CODE_LIMIT);
#ifndef KLSK_NDEBUG #ifndef KLSK_NDEBUG
@ -57,7 +67,7 @@ TEST(ShortCode, basic) {
} }
TEST(ShortCode, operators) { TEST(ShortCode, operators) {
auto short_code = ShortCode::unsafe_create(TEST_S_CODE); const auto short_code = ShortCode::unsafe_create(TEST_S_CODE);
EXPECT_EQ(static_cast<uint32_t>(short_code), TEST_S_CODE); // uint32_t cast EXPECT_EQ(static_cast<uint32_t>(short_code), TEST_S_CODE); // uint32_t cast
EXPECT_NE(0, short_code); // uint32_t != ShortCode EXPECT_NE(0, short_code); // uint32_t != ShortCode
@ -94,7 +104,7 @@ TEST(ShortCode, operators) {
} }
TEST(ShortCode, exporter) { TEST(ShortCode, exporter) {
auto short_code = ShortCode::unsafe_create(TEST_S_CODE); const auto short_code = ShortCode::unsafe_create(TEST_S_CODE);
EXPECT_EQ(short_code.unwrap(), TEST_S_CODE); EXPECT_EQ(short_code.unwrap(), TEST_S_CODE);
EXPECT_EQ(short_code.to_string(), TEST_S_CODE_STR); EXPECT_EQ(short_code.to_string(), TEST_S_CODE_STR);
@ -104,13 +114,26 @@ TEST(ShortCode, exporter) {
EXPECT_EQ(short_code.to_common_code(), TEST_C_CODE); EXPECT_EQ(short_code.to_common_code(), TEST_C_CODE);
} }
TEST(ShortCode, constexpr) {
static_assert(ShortCode::check(TEST_S_CODE));
static_assert(!ShortCode::check(TEST_S_CODE_ERR));
static_assert(ShortCode::create(TEST_S_CODE).has_value());
static_assert(!ShortCode::create(TEST_S_CODE_ERR).has_value());
static_assert(ShortCode::create(TEST_S_CODE).value() == TEST_S_CODE);
constexpr auto code = ShortCode::unsafe_create(TEST_S_CODE);
static_assert(static_cast<uint32_t>(code) == TEST_S_CODE);
static_assert(code.unwrap() == TEST_S_CODE);
}
TEST(ShortCode, initialize) { TEST(ShortCode, initialize) {
auto short_code = ShortCode::unsafe_create(TEST_S_CODE); const auto short_code = ShortCode::unsafe_create(TEST_S_CODE);
auto common_code = CommonCode::unsafe_create(TEST_C_CODE); const auto common_code = CommonCode::unsafe_create(TEST_C_CODE);
// operator= // operator=
auto s1 = short_code; const auto s1 = short_code;
auto s2 = ShortCode {short_code}; const auto s2 = ShortCode {short_code};
EXPECT_EQ(s1, TEST_S_CODE); // l-value EXPECT_EQ(s1, TEST_S_CODE); // l-value
EXPECT_EQ(s2, TEST_S_CODE); // r-value EXPECT_EQ(s2, TEST_S_CODE); // r-value
@ -199,7 +222,7 @@ TEST(ShortCode, code_verify) {
ShortCode::speed_up(true); // enter fast mode ShortCode::speed_up(true); // enter fast mode
SHORT_CODE_PARALLEL({ SHORT_CODE_PARALLEL({
EXPECT_TRUE(ShortCode::check(code.unwrap())); EXPECT_TRUE(ShortCode::check(code.unwrap()));
auto common_code = code.to_common_code(); // ShortCode::fast_decode const auto common_code = code.to_common_code(); // ShortCode::fast_decode
EXPECT_EQ(ShortCode::from_common_code(common_code), code); // ShortCode::fast_encode EXPECT_EQ(ShortCode::from_common_code(common_code), code); // ShortCode::fast_encode
}); });
} }
@ -208,23 +231,23 @@ TEST(ShortCode, code_string) {
SHORT_CODE_PARALLEL({ SHORT_CODE_PARALLEL({
auto code_str = code.to_string(); auto code_str = code.to_string();
EXPECT_EQ(code_str.size(), 5); // length = 5 EXPECT_EQ(code_str.size(), 5); // length = 5
for (auto c : code_str) { for (const auto c : code_str) {
EXPECT_TRUE((c >= '1' && c <= '9') || (c >= 'A' && c <= 'Z')); EXPECT_TRUE((c >= '1' && c <= '9') || (c >= 'A' && c <= 'Z'));
EXPECT_TRUE(c != 'I' && c != 'L' && c != 'O'); EXPECT_TRUE(c != 'I' && c != 'L' && c != 'O');
} }
EXPECT_EQ(ShortCode::from_string(code_str), code); // test upper cases EXPECT_EQ(ShortCode::from_string(code_str), code); // test upper cases
std::transform(code_str.begin(), code_str.end(), code_str.begin(), ::tolower); std::ranges::transform(code_str.begin(), code_str.end(), code_str.begin(), ::tolower);
EXPECT_EQ(ShortCode::from_string(code_str), code); // test lower cases EXPECT_EQ(ShortCode::from_string(code_str), code); // test lower cases
}); });
} }
TEST(ShortCode, DISABLED_global_verify) { TEST(ShortCode, DISABLED_global_verify) {
speed_up_reset(); speed_up_reset();
const auto result = SCOPE_PARALLEL(SHORT_CODE_LIMIT, [](uint32_t start, uint32_t end) { const auto result = SCOPE_PARALLEL(SHORT_CODE_LIMIT, [](const uint32_t start, const uint32_t end) {
std::vector<CommonCode> codes; std::vector<CommonCode> codes;
codes.reserve(end - start); codes.reserve(end - start);
for (uint32_t short_code = start; short_code < end; ++short_code) { for (uint32_t short_code = start; short_code < end; ++short_code) {
auto common_code = CommonCode::from_short_code(short_code).value(); // ShortCode::tiny_decode const auto common_code = CommonCode::from_short_code(short_code).value(); // ShortCode::tiny_decode
EXPECT_EQ(common_code.to_short_code(), short_code); // ShortCode::tiny_encode EXPECT_EQ(common_code.to_short_code(), short_code); // ShortCode::tiny_encode
codes.emplace_back(common_code); codes.emplace_back(common_code);
} }

Loading…
Cancel
Save