refactor: rename testbench to test.
- rename testbench to test. - add benchmark for future development.
This commit is contained in:
65
test/CMakeLists.txt
Normal file
65
test/CMakeLists.txt
Normal file
@ -0,0 +1,65 @@
|
||||
# Create executable test
|
||||
add_executable(YYCCTest "")
|
||||
# Setup test sources
|
||||
target_sources(YYCCTest
|
||||
PRIVATE
|
||||
main.cpp
|
||||
|
||||
shared/literals.cpp
|
||||
|
||||
yycc/macro/version_cmp.cpp
|
||||
yycc/macro/os_detector.cpp
|
||||
yycc/macro/compiler_detector.cpp
|
||||
yycc/macro/endian_detector.cpp
|
||||
yycc/macro/ptr_size_detector.cpp
|
||||
yycc/macro/stl_detector.cpp
|
||||
yycc/flag_enum.cpp
|
||||
yycc/constraint.cpp
|
||||
yycc/constraint/builder.cpp
|
||||
yycc/patch/ptr_pad.cpp
|
||||
yycc/patch/fopen.cpp
|
||||
yycc/patch/stream.cpp
|
||||
yycc/patch/format.cpp
|
||||
yycc/rust/env.cpp
|
||||
yycc/string/reinterpret.cpp
|
||||
yycc/string/op.cpp
|
||||
yycc/num/parse.cpp
|
||||
yycc/num/stringify.cpp
|
||||
yycc/num/op.cpp
|
||||
yycc/num/safe_cast.cpp
|
||||
yycc/num/safe_op.cpp
|
||||
yycc/encoding/stl.cpp
|
||||
yycc/encoding/windows.cpp
|
||||
yycc/encoding/iconv.cpp
|
||||
yycc/windows/com.cpp
|
||||
yycc/windows/dialog.cpp
|
||||
yycc/windows/winfct.cpp
|
||||
yycc/windows/console.cpp
|
||||
|
||||
yycc/carton/pycodec.cpp
|
||||
yycc/carton/termcolor.cpp
|
||||
yycc/carton/wcwidth.cpp
|
||||
yycc/carton/tabulate.cpp
|
||||
yycc/carton/clap.cpp
|
||||
)
|
||||
target_sources(YYCCTest
|
||||
PRIVATE
|
||||
FILE_SET HEADERS
|
||||
FILES
|
||||
shared/literals.hpp
|
||||
)
|
||||
# Setup headers
|
||||
target_include_directories(YYCCTest
|
||||
PUBLIC
|
||||
"${CMAKE_CURRENT_LIST_DIR}"
|
||||
)
|
||||
# Setup libraries
|
||||
target_link_libraries(YYCCTest
|
||||
PRIVATE
|
||||
YYCCommonplace
|
||||
GTest::gtest_main
|
||||
)
|
||||
|
||||
# Discover all test
|
||||
include(GoogleTest)
|
||||
gtest_discover_tests(YYCCTest)
|
6
test/main.cpp
Normal file
6
test/main.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
310
test/main_legacy.cpp
Normal file
310
test/main_legacy.cpp
Normal file
@ -0,0 +1,310 @@
|
||||
#include <YYCCommonplace.hpp>
|
||||
#include <cstdio>
|
||||
#include <set>
|
||||
#include <map>
|
||||
|
||||
namespace Console = YYCC::ConsoleHelper;
|
||||
|
||||
namespace YYCCTestbench {
|
||||
|
||||
static void Assert(bool condition, const YYCC::yycc_char8_t* description) {
|
||||
if (condition) {
|
||||
Console::FormatLine(YYCC_U8(YYCC_COLOR_LIGHT_GREEN("OK: %s")), description);
|
||||
} else {
|
||||
Console::FormatLine(YYCC_U8(YYCC_COLOR_LIGHT_RED("Failed: %s\n")), description);
|
||||
std::abort();
|
||||
}
|
||||
}
|
||||
|
||||
static void ConsoleTestbench() {
|
||||
// UTF8 Output Test
|
||||
Console::WriteLine(YYCC_U8("UTF8 Output Test:"));
|
||||
for (const auto& strl : c_UTF8TestStrTable) {
|
||||
Console::FormatLine(YYCC_U8("\t%s"), strl.c_str());
|
||||
}
|
||||
|
||||
// UTF8 Input Test
|
||||
Console::WriteLine(YYCC_U8("UTF8 Input Test:"));
|
||||
for (const auto& strl : c_UTF8TestStrTable) {
|
||||
Console::FormatLine(YYCC_U8("\tPlease type: %s"), strl.c_str());
|
||||
Console::Write(YYCC_U8("\t> "));
|
||||
|
||||
YYCC::yycc_u8string gotten(Console::ReadLine());
|
||||
if (gotten == strl) Console::FormatLine(YYCC_U8(YYCC_COLOR_LIGHT_GREEN("\tMatched! Got: %s")), gotten.c_str());
|
||||
else Console::FormatLine(YYCC_U8(YYCC_COLOR_LIGHT_RED("\tNOT Matched! Got: %s")), gotten.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void ExceptionTestbench() {
|
||||
#if defined(YYCC_OS_WINDOWS)
|
||||
|
||||
YYCC::ExceptionHelper::Register([](const YYCC::yycc_u8string& log_path, const YYCC::yycc_u8string& coredump_path) -> void {
|
||||
MessageBoxW(
|
||||
NULL,
|
||||
YYCC::EncodingHelper::UTF8ToWchar(
|
||||
YYCC::StringHelper::Printf(YYCC_U8("Log generated:\nLog path: %s\nCore dump path: %s"), log_path.c_str(), coredump_path.c_str())
|
||||
).c_str(),
|
||||
L"Fatal Error", MB_OK + MB_ICONERROR
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
// Perform a div zero exception.
|
||||
#if defined (YYCC_DEBUG_UE_FILTER)
|
||||
// Reference: https://stackoverflow.com/questions/20981982/is-it-possible-to-debug-unhandledexceptionfilters-with-a-debugger
|
||||
__try {
|
||||
// all of code normally inside of main or WinMain here...
|
||||
int i = 1, j = 0;
|
||||
int k = i / j;
|
||||
} __except (YYCC::ExceptionHelper::DebugCallUExceptionImpl(GetExceptionInformation())) {
|
||||
OutputDebugStringW(L"executed filter function\n");
|
||||
}
|
||||
#else
|
||||
int i = 1, j = 0;
|
||||
int k = i / j;
|
||||
#endif
|
||||
|
||||
YYCC::ExceptionHelper::Unregister();
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
enum class TestEnum : int8_t {
|
||||
Test1, Test2, Test3
|
||||
};
|
||||
|
||||
class TestConfigManager {
|
||||
public:
|
||||
TestConfigManager() :
|
||||
m_IntSetting(YYCC_U8("int-setting"), INT32_C(0)),
|
||||
m_FloatSetting(YYCC_U8("float-setting"), 0.0f),
|
||||
m_StringSetting(YYCC_U8("string-setting"), YYCC_U8("")),
|
||||
m_BoolSetting(YYCC_U8("bool-setting"), false),
|
||||
m_ClampedFloatSetting(YYCC_U8("clamped-float-setting"), 0.0f, YYCC::Constraints::GetMinMaxRangeConstraint<float>(-1.0f, 1.0f)),
|
||||
m_EnumSetting(YYCC_U8("enum-setting"), TestEnum::Test1),
|
||||
m_CoreManager(YYCC_U8("test.cfg"), UINT64_C(0), {
|
||||
&m_IntSetting, &m_FloatSetting, &m_StringSetting, &m_BoolSetting, &m_ClampedFloatSetting, &m_EnumSetting
|
||||
}) {}
|
||||
~TestConfigManager() {}
|
||||
|
||||
void PrintSettings() {
|
||||
Console::WriteLine(YYCC_U8("Config Manager Settings:"));
|
||||
|
||||
Console::FormatLine(YYCC_U8("\tint-setting: %" PRIi32), m_IntSetting.Get());
|
||||
Console::FormatLine(YYCC_U8("\tfloat-setting: %f"), m_FloatSetting.Get());
|
||||
Console::FormatLine(YYCC_U8("\tstring-setting: %s"), m_StringSetting.Get().c_str());
|
||||
|
||||
Console::FormatLine(YYCC_U8("\tbool-setting: %s"), m_BoolSetting.Get() ? YYCC_U8("true") : YYCC_U8("false"));
|
||||
Console::FormatLine(YYCC_U8("\tfloat-setting: %f"), m_ClampedFloatSetting.Get());
|
||||
Console::FormatLine(YYCC_U8("\tenum-setting: %" PRIi8), static_cast<std::underlying_type_t<TestEnum>>(m_EnumSetting.Get()));
|
||||
}
|
||||
|
||||
YYCC::ConfigManager::NumberSetting<int32_t> m_IntSetting;
|
||||
YYCC::ConfigManager::NumberSetting<float> m_FloatSetting;
|
||||
YYCC::ConfigManager::StringSetting m_StringSetting;
|
||||
|
||||
YYCC::ConfigManager::NumberSetting<bool> m_BoolSetting;
|
||||
YYCC::ConfigManager::NumberSetting<float> m_ClampedFloatSetting;
|
||||
YYCC::ConfigManager::NumberSetting<TestEnum> m_EnumSetting;
|
||||
|
||||
YYCC::ConfigManager::CoreManager m_CoreManager;
|
||||
};
|
||||
|
||||
static void ConfigManagerTestbench() {
|
||||
// init cfg manager
|
||||
TestConfigManager test;
|
||||
|
||||
// test constraint works
|
||||
Assert(!test.m_ClampedFloatSetting.Set(2.0f), YYCC_U8("YYCC::Constraints::Constraint"));
|
||||
Assert(test.m_ClampedFloatSetting.Get() == 0.0f, YYCC_U8("YYCC::Constraints::Constraint"));
|
||||
|
||||
// test modify settings
|
||||
#define TEST_MACRO(member_name, set_val) { \
|
||||
Assert(test.member_name.Set(set_val), YYCC_U8("YYCC::ConfigManager::AbstractSetting::Set")); \
|
||||
Assert(test.member_name.Get() == set_val, YYCC_U8("YYCC::ConfigManager::AbstractSetting::Set")); \
|
||||
}
|
||||
|
||||
TEST_MACRO(m_IntSetting, INT32_C(114));
|
||||
TEST_MACRO(m_FloatSetting, 2.0f);
|
||||
TEST_MACRO(m_StringSetting, YYCC_U8("fuck"));
|
||||
TEST_MACRO(m_BoolSetting, true);
|
||||
TEST_MACRO(m_ClampedFloatSetting, 0.5f);
|
||||
TEST_MACRO(m_EnumSetting, TestEnum::Test2);
|
||||
|
||||
#undef TEST_MACRO
|
||||
|
||||
// test save
|
||||
test.PrintSettings();
|
||||
Assert(test.m_CoreManager.Save(), YYCC_U8("YYCC::ConfigManager::CoreManager::Save"));
|
||||
|
||||
// test reset
|
||||
test.m_CoreManager.Reset();
|
||||
test.PrintSettings();
|
||||
Assert(test.m_IntSetting.Get() == INT32_C(0), YYCC_U8("YYCC::ConfigManager::CoreManager::Reset"));
|
||||
Assert(test.m_FloatSetting.Get() == 0.0f, YYCC_U8("YYCC::ConfigManager::CoreManager::Reset"));
|
||||
Assert(test.m_StringSetting.Get() == YYCC_U8(""), YYCC_U8("YYCC::ConfigManager::CoreManager::Reset"));
|
||||
Assert(test.m_BoolSetting.Get() == false, YYCC_U8("YYCC::ConfigManager::CoreManager::Reset"));
|
||||
Assert(test.m_ClampedFloatSetting.Get() == 0.0f, YYCC_U8("YYCC::ConfigManager::CoreManager::Reset"));
|
||||
Assert(test.m_EnumSetting.Get() == TestEnum::Test1, YYCC_U8("YYCC::ConfigManager::CoreManager::Reset"));
|
||||
|
||||
// test load
|
||||
YYCC::ConfigManager::ConfigLoadResult wrong_result = YYCC::EnumHelper::Merge(
|
||||
YYCC::ConfigManager::ConfigLoadResult::ItemError,
|
||||
YYCC::ConfigManager::ConfigLoadResult::BrokenFile
|
||||
);
|
||||
Assert(!YYCC::EnumHelper::Has(test.m_CoreManager.Load(), wrong_result), YYCC_U8("YYCC::ConfigManager::CoreManager::Load"));
|
||||
test.PrintSettings();
|
||||
Assert(test.m_IntSetting.Get() == INT32_C(114), YYCC_U8("YYCC::ConfigManager::CoreManager::Load"));
|
||||
Assert(test.m_FloatSetting.Get() == 2.0f, YYCC_U8("YYCC::ConfigManager::CoreManager::Load"));
|
||||
Assert(test.m_StringSetting.Get() == YYCC_U8("fuck"), YYCC_U8("YYCC::ConfigManager::CoreManager::Load"));
|
||||
Assert(test.m_BoolSetting.Get() == true, YYCC_U8("YYCC::ConfigManager::CoreManager::Load"));
|
||||
Assert(test.m_ClampedFloatSetting.Get() == 0.5f, YYCC_U8("YYCC::ConfigManager::CoreManager::Load"));
|
||||
Assert(test.m_EnumSetting.Get() == TestEnum::Test2, YYCC_U8("YYCC::ConfigManager::CoreManager::Load"));
|
||||
|
||||
}
|
||||
|
||||
class TestArgParser {
|
||||
public:
|
||||
TestArgParser() :
|
||||
m_IntArgument(YYCC_U8("int"), YYCC_U8_CHAR('i'), YYCC_U8("integral argument"), YYCC_U8("114514")),
|
||||
m_FloatArgument(nullptr, YYCC_U8_CHAR('f'), nullptr, nullptr, true),
|
||||
m_StringArgument(YYCC_U8("string"), YYCC::ArgParser::AbstractArgument::NO_SHORT_NAME, nullptr, nullptr, true),
|
||||
m_BoolArgument(nullptr, YYCC_U8_CHAR('b'), nullptr),
|
||||
m_ClampedFloatArgument(YYCC_U8("clamped-float"), YYCC::ArgParser::AbstractArgument::NO_SHORT_NAME, nullptr, nullptr, true, YYCC::Constraints::GetMinMaxRangeConstraint<float>(-1.0f, 1.0f)),
|
||||
m_OptionContext(YYCC_U8("TestArgParser"), YYCC_U8("This is the testbench of argument parser."), {
|
||||
&m_IntArgument, &m_FloatArgument, &m_StringArgument,
|
||||
&m_BoolArgument, &m_ClampedFloatArgument
|
||||
}) {}
|
||||
~TestArgParser() {}
|
||||
|
||||
YYCC::ArgParser::NumberArgument<int32_t> m_IntArgument;
|
||||
YYCC::ArgParser::NumberArgument<float> m_FloatArgument;
|
||||
YYCC::ArgParser::StringArgument m_StringArgument;
|
||||
|
||||
YYCC::ArgParser::SwitchArgument m_BoolArgument;
|
||||
YYCC::ArgParser::NumberArgument<float> m_ClampedFloatArgument;
|
||||
|
||||
YYCC::ArgParser::OptionContext m_OptionContext;
|
||||
};
|
||||
|
||||
static void ArgParserTestbench(int argc, char* argv[]) {
|
||||
// test command line getter
|
||||
{
|
||||
YYCC::ConsoleHelper::WriteLine(YYCC_U8("YYCC::ArgParser::ArgumentList::CreateFromStd"));
|
||||
auto result = YYCC::ArgParser::ArgumentList::CreateFromStd(argc, argv);
|
||||
for (result.Reset(); !result.IsEOF(); result.Next()) {
|
||||
YYCC::ConsoleHelper::FormatLine(YYCC_U8("\t%s"), result.Argument().c_str());
|
||||
}
|
||||
}
|
||||
#if defined(YYCC_OS_WINDOWS)
|
||||
{
|
||||
YYCC::ConsoleHelper::WriteLine(YYCC_U8("YYCC::ArgParser::ArgumentList::CreateFromWin32"));
|
||||
auto result = YYCC::ArgParser::ArgumentList::CreateFromWin32();
|
||||
for (result.Reset(); !result.IsEOF(); result.Next()) {
|
||||
YYCC::ConsoleHelper::FormatLine(YYCC_U8("\t%s"), result.Argument().c_str());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// test option context
|
||||
// init option context
|
||||
TestArgParser test;
|
||||
|
||||
#define PREPARE_DATA(...) const char* test_argv[] = { __VA_ARGS__ }; \
|
||||
auto al = YYCC::ArgParser::ArgumentList::CreateFromStd(sizeof(test_argv) / sizeof(char*), const_cast<char**>(test_argv));
|
||||
|
||||
// normal test
|
||||
{
|
||||
PREPARE_DATA("exec", "-i", "114514");
|
||||
Assert(test.m_OptionContext.Parse(al), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
Assert(test.m_IntArgument.IsCaptured() && test.m_IntArgument.Get() == UINT32_C(114514), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
Assert(!test.m_BoolArgument.IsCaptured(), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
Assert(!test.m_FloatArgument.IsCaptured(), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
Assert(!test.m_StringArgument.IsCaptured(), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
Assert(!test.m_BoolArgument.IsCaptured(), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
Assert(!test.m_ClampedFloatArgument.IsCaptured(), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
test.m_OptionContext.Reset();
|
||||
}
|
||||
// no argument
|
||||
{
|
||||
PREPARE_DATA("exec");
|
||||
Assert(!test.m_OptionContext.Parse(al), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
test.m_OptionContext.Reset();
|
||||
}
|
||||
// error argument
|
||||
{
|
||||
PREPARE_DATA("exec", "-?", "114514");
|
||||
Assert(!test.m_OptionContext.Parse(al), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
test.m_OptionContext.Reset();
|
||||
}
|
||||
// lost argument
|
||||
{
|
||||
PREPARE_DATA("exec", "-i");
|
||||
Assert(!test.m_OptionContext.Parse(al), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
test.m_OptionContext.Reset();
|
||||
}
|
||||
// dplicated assign
|
||||
{
|
||||
PREPARE_DATA("exec", "-i", "114514" "--int", "114514");
|
||||
Assert(!test.m_OptionContext.Parse(al), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
test.m_OptionContext.Reset();
|
||||
}
|
||||
// extra useless argument
|
||||
{
|
||||
PREPARE_DATA("exec", "-i", "114514" "1919810");
|
||||
Assert(!test.m_OptionContext.Parse(al), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
test.m_OptionContext.Reset();
|
||||
}
|
||||
// invalid clamp argument
|
||||
{
|
||||
PREPARE_DATA("exec", "-i", "114514", "--clamped-float", "114.0");
|
||||
Assert(!test.m_OptionContext.Parse(al), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
test.m_OptionContext.Reset();
|
||||
}
|
||||
// full argument
|
||||
{
|
||||
PREPARE_DATA("exec", "-i", "114514", "-f", "2.0", "--string", "fuck", "-b", "--clamped-float", "0.5");
|
||||
Assert(test.m_OptionContext.Parse(al), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
Assert(test.m_IntArgument.IsCaptured() && test.m_IntArgument.Get() == UINT32_C(114514), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
Assert(test.m_FloatArgument.IsCaptured() && test.m_FloatArgument.Get() == 2.0f, YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
Assert(test.m_StringArgument.IsCaptured() && test.m_StringArgument.Get() == YYCC_U8("fuck"), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
Assert(test.m_BoolArgument.IsCaptured(), YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
Assert(test.m_ClampedFloatArgument.IsCaptured() && test.m_ClampedFloatArgument.Get() == 0.5f, YYCC_U8("YYCC::ArgParser::OptionContext::Parse"));
|
||||
test.m_OptionContext.Reset();
|
||||
}
|
||||
|
||||
// Help text
|
||||
test.m_OptionContext.Help();
|
||||
|
||||
#undef PREPARE_DATA
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
|
||||
#if YYCC_VERCMP_NE(YYCC_VER_MAJOR, YYCC_VER_MINOR, YYCC_VER_PATCH, 1, 3 ,0)
|
||||
#error "The YYCC library used when compiling is not match code expected, this may cause build error."
|
||||
#error "If you trust it, please annotate these preprocessor statement, otherwise please contact developer."
|
||||
#endif
|
||||
|
||||
// common testbench
|
||||
// normal
|
||||
YYCCTestbench::EncodingTestbench();
|
||||
YYCCTestbench::StringTestbench();
|
||||
YYCCTestbench::ParserTestbench();
|
||||
YYCCTestbench::WinFctTestbench();
|
||||
YYCCTestbench::StdPatchTestbench();
|
||||
YYCCTestbench::EnumHelperTestbench();
|
||||
YYCCTestbench::VersionMacroTestbench();
|
||||
// advanced
|
||||
YYCCTestbench::ConfigManagerTestbench();
|
||||
YYCCTestbench::ArgParserTestbench(argc, argv);
|
||||
|
||||
// testbench which may terminal app or ordering input
|
||||
YYCCTestbench::ConsoleTestbench();
|
||||
YYCCTestbench::DialogTestbench();
|
||||
YYCCTestbench::ExceptionTestbench();
|
||||
}
|
203
test/shared/literals.cpp
Normal file
203
test/shared/literals.cpp
Normal file
@ -0,0 +1,203 @@
|
||||
#include "literals.hpp"
|
||||
#include <stdexcept>
|
||||
|
||||
namespace yyccshared::literals {
|
||||
|
||||
#define CONCAT(prefix, strl) prefix##strl
|
||||
#define U8_LITERAL(strl) CONCAT(u8, strl)
|
||||
#define U16_LITERAL(strl) CONCAT(u, strl)
|
||||
#define U32_LITERAL(strl) CONCAT(U, strl)
|
||||
#define WSTR_LITERAL(strl) CONCAT(L, strl)
|
||||
|
||||
#pragma region UtfLiterals Data
|
||||
|
||||
// UNICODE Test Strings
|
||||
// Ref: https://stackoverflow.com/questions/478201/how-to-test-an-application-for-correct-encoding-e-g-utf-8
|
||||
|
||||
#define UNICODE_STR_JAPAN "\u30E6\u30FC\u30B6\u30FC\u5225\u30B5\u30A4\u30C8"
|
||||
#define UNICODE_STR_CHINA "\u7B80\u4F53\u4E2D\u6587"
|
||||
#define UNICODE_STR_KOREA "\uD06C\uB85C\uC2A4 \uD50C\uB7AB\uD3FC\uC73C\uB85C"
|
||||
#define UNICODE_STR_ISRAEL "\u05DE\u05D3\u05D5\u05E8\u05D9\u05DD \u05DE\u05D1\u05D5\u05E7\u05E9\u05D9\u05DD"
|
||||
#define UNICODE_STR_EGYPT "\u0623\u0641\u0636\u0644 \u0627\u0644\u0628\u062D\u0648\u062B"
|
||||
#define UNICODE_STR_GREECE "\u03A3\u1F72 \u03B3\u03BD\u03C9\u03C1\u03AF\u03B6\u03C9 \u1F00\u03C0\u1F78"
|
||||
#define UNICODE_STR_RUSSIA \
|
||||
"\u0414\u0435\u0441\u044F\u0442\u0443\u044E \u041C\u0435\u0436\u0434\u0443\u043D\u0430\u0440\u043E\u0434\u043D\u0443\u044E"
|
||||
#define UNICODE_STR_THAILAND \
|
||||
"\u0E41\u0E1C\u0E48\u0E19\u0E14\u0E34\u0E19\u0E2E\u0E31\u0E48\u0E19\u0E40\u0E2A\u0E37\u0E48\u0E2D\u0E21\u0E42\u0E17\u0E23\u0E21\u0E41\u0E2A\u0E19\u0E2A\u0E31\u0E07\u0E40\u0E27\u0E0A"
|
||||
#define UNICODE_STR_FRANCE "fran\u00E7ais langue \u00E9trang\u00E8re"
|
||||
#define UNICODE_STR_SPAIN "ma\u00F1ana ol\u00E9"
|
||||
#define UNICODE_STR_MATHMATICS "\u222E E\u22C5da = Q, n \u2192 \u221E, \u2211 f(i) = \u220F g(i)"
|
||||
#define UNICODE_STR_EMOJI "\U0001F363 \u2716 \U0001F37A" // sushi x beer mug
|
||||
|
||||
static std::vector<std::u8string> UTFLIT_U8STR_VEC{
|
||||
U8_LITERAL(UNICODE_STR_JAPAN),
|
||||
U8_LITERAL(UNICODE_STR_CHINA),
|
||||
U8_LITERAL(UNICODE_STR_KOREA),
|
||||
U8_LITERAL(UNICODE_STR_ISRAEL),
|
||||
U8_LITERAL(UNICODE_STR_EGYPT),
|
||||
U8_LITERAL(UNICODE_STR_GREECE),
|
||||
U8_LITERAL(UNICODE_STR_RUSSIA),
|
||||
U8_LITERAL(UNICODE_STR_THAILAND),
|
||||
U8_LITERAL(UNICODE_STR_FRANCE),
|
||||
U8_LITERAL(UNICODE_STR_SPAIN),
|
||||
U8_LITERAL(UNICODE_STR_MATHMATICS),
|
||||
U8_LITERAL(UNICODE_STR_EMOJI),
|
||||
};
|
||||
static std::vector<std::wstring> UTFLIT_WSTR_VEC{
|
||||
WSTR_LITERAL(UNICODE_STR_JAPAN),
|
||||
WSTR_LITERAL(UNICODE_STR_CHINA),
|
||||
WSTR_LITERAL(UNICODE_STR_KOREA),
|
||||
WSTR_LITERAL(UNICODE_STR_ISRAEL),
|
||||
WSTR_LITERAL(UNICODE_STR_EGYPT),
|
||||
WSTR_LITERAL(UNICODE_STR_GREECE),
|
||||
WSTR_LITERAL(UNICODE_STR_RUSSIA),
|
||||
WSTR_LITERAL(UNICODE_STR_THAILAND),
|
||||
WSTR_LITERAL(UNICODE_STR_FRANCE),
|
||||
WSTR_LITERAL(UNICODE_STR_SPAIN),
|
||||
WSTR_LITERAL(UNICODE_STR_MATHMATICS),
|
||||
WSTR_LITERAL(UNICODE_STR_EMOJI),
|
||||
};
|
||||
static std::vector<std::u16string> UTFLIT_U16STR_VEC{
|
||||
U16_LITERAL(UNICODE_STR_JAPAN),
|
||||
U16_LITERAL(UNICODE_STR_CHINA),
|
||||
U16_LITERAL(UNICODE_STR_KOREA),
|
||||
U16_LITERAL(UNICODE_STR_ISRAEL),
|
||||
U16_LITERAL(UNICODE_STR_EGYPT),
|
||||
U16_LITERAL(UNICODE_STR_GREECE),
|
||||
U16_LITERAL(UNICODE_STR_RUSSIA),
|
||||
U16_LITERAL(UNICODE_STR_THAILAND),
|
||||
U16_LITERAL(UNICODE_STR_FRANCE),
|
||||
U16_LITERAL(UNICODE_STR_SPAIN),
|
||||
U16_LITERAL(UNICODE_STR_MATHMATICS),
|
||||
U16_LITERAL(UNICODE_STR_EMOJI),
|
||||
};
|
||||
static std::vector<std::u32string> UTFLIT_U32STR_VEC{
|
||||
U32_LITERAL(UNICODE_STR_JAPAN),
|
||||
U32_LITERAL(UNICODE_STR_CHINA),
|
||||
U32_LITERAL(UNICODE_STR_KOREA),
|
||||
U32_LITERAL(UNICODE_STR_ISRAEL),
|
||||
U32_LITERAL(UNICODE_STR_EGYPT),
|
||||
U32_LITERAL(UNICODE_STR_GREECE),
|
||||
U32_LITERAL(UNICODE_STR_RUSSIA),
|
||||
U32_LITERAL(UNICODE_STR_THAILAND),
|
||||
U32_LITERAL(UNICODE_STR_FRANCE),
|
||||
U32_LITERAL(UNICODE_STR_SPAIN),
|
||||
U32_LITERAL(UNICODE_STR_MATHMATICS),
|
||||
U32_LITERAL(UNICODE_STR_EMOJI),
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region UtfLiterals
|
||||
|
||||
UtfLiterals::UtfLiterals() :
|
||||
u8str_vec(UTFLIT_U8STR_VEC), u16str_vec(UTFLIT_U16STR_VEC), u32str_vec(UTFLIT_U32STR_VEC), wstr_vec(UTFLIT_WSTR_VEC) {
|
||||
// Check whether each vector has same size.
|
||||
bool okey = true;
|
||||
size_t exp_size = this->u8str_vec.size();
|
||||
|
||||
if (this->u16str_vec.size() != exp_size) okey = false;
|
||||
if (this->u32str_vec.size() != exp_size) okey = false;
|
||||
if (this->wstr_vec.size() != exp_size) okey = false;
|
||||
|
||||
if (!okey) throw std::logic_error("utf literal vector have different size");
|
||||
}
|
||||
|
||||
UtfLiterals::~UtfLiterals() {}
|
||||
|
||||
size_t UtfLiterals::get_size() const {
|
||||
// We have checked the size of each vector in ctor.
|
||||
// So we simply return the length of one of them.
|
||||
return this->u8str_vec.size();
|
||||
}
|
||||
|
||||
const std::vector<std::u8string> &UtfLiterals::get_u8str_vec() const {
|
||||
return this->u8str_vec;
|
||||
}
|
||||
|
||||
const std::vector<std::u16string> &UtfLiterals::get_u16str_vec() const {
|
||||
return this->u16str_vec;
|
||||
}
|
||||
|
||||
const std::vector<std::u32string> &UtfLiterals::get_u32str_vec() const {
|
||||
return this->u32str_vec;
|
||||
}
|
||||
|
||||
const std::vector<std::wstring> &UtfLiterals::get_wstr_vec() const {
|
||||
return this->wstr_vec;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region OtherLiteral
|
||||
|
||||
OtherLiteral::OtherLiteral(std::string &&other_str, uint32_t windows_ident, std::string &&iconv_ident, std::u8string &&pycodec_ident) :
|
||||
other_str(std::move(other_str)), windows_ident(windows_ident), iconv_ident(std::move(iconv_ident)),
|
||||
pycodec_ident(std::move(pycodec_ident)) {}
|
||||
|
||||
OtherLiteral::~OtherLiteral() {}
|
||||
|
||||
const std::string &OtherLiteral::get_other_str() const {
|
||||
return this->other_str;
|
||||
}
|
||||
|
||||
uint32_t OtherLiteral::get_windows_ident() const {
|
||||
return this->windows_ident;
|
||||
}
|
||||
|
||||
const std::string &OtherLiteral::get_iconv_ident() const {
|
||||
return this->iconv_ident;
|
||||
}
|
||||
|
||||
const std::u8string &OtherLiteral::get_pycodec_ident() const {
|
||||
return this->pycodec_ident;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region OtherLiterals Data
|
||||
|
||||
static std::vector<OtherLiteral> OTHERLIT_OTHERSTR_VEC{{"\xC4\xE3\xBA\xC3\xD6\xD0\xB9\xFA", UINT32_C(936), "GBK", u8"gbk"}};
|
||||
|
||||
#define OTHER_STR_GBK "\u4f60\u597d\u4e2d\u56fd"
|
||||
|
||||
static std::vector<std::u8string> OTHERLIT_U8STR_VEC{U8_LITERAL(OTHER_STR_GBK)};
|
||||
static std::vector<std::wstring> OTHERLIT_WSTR_VEC{WSTR_LITERAL(OTHER_STR_GBK)};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region OtherLiterals
|
||||
|
||||
OtherLiterals::OtherLiterals() : other_str_vec(OTHERLIT_OTHERSTR_VEC), u8str_vec(OTHERLIT_U8STR_VEC), wstr_vec(OTHERLIT_WSTR_VEC) {
|
||||
// Check whether each vector has same size.
|
||||
bool okey = true;
|
||||
size_t exp_size = this->other_str_vec.size();
|
||||
|
||||
if (this->u8str_vec.size() != exp_size) okey = false;
|
||||
if (this->wstr_vec.size() != exp_size) okey = false;
|
||||
|
||||
if (!okey) throw std::logic_error("utf literal vector have different size");
|
||||
}
|
||||
|
||||
OtherLiterals::~OtherLiterals() {}
|
||||
|
||||
size_t OtherLiterals::get_size() const {
|
||||
// We have checked the size, return size directly.
|
||||
return this->other_str_vec.size();
|
||||
}
|
||||
|
||||
const std::vector<OtherLiteral> &OtherLiterals::get_other_str_vec() const {
|
||||
return this->other_str_vec;
|
||||
}
|
||||
|
||||
const std::vector<std::u8string> &OtherLiterals::get_u8str_vec() const {
|
||||
return this->u8str_vec;
|
||||
}
|
||||
|
||||
const std::vector<std::wstring> &OtherLiterals::get_wstr_vec() const {
|
||||
return this->wstr_vec;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
} // namespace yyccshared::literals
|
64
test/shared/literals.hpp
Normal file
64
test/shared/literals.hpp
Normal file
@ -0,0 +1,64 @@
|
||||
#pragma once
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/macro/class_copy_move.hpp>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace yyccshared::literals {
|
||||
|
||||
class UtfLiterals {
|
||||
public:
|
||||
UtfLiterals();
|
||||
~UtfLiterals();
|
||||
YYCC_DELETE_COPY_MOVE(UtfLiterals)
|
||||
|
||||
size_t get_size() const;
|
||||
const std::vector<std::u8string>& get_u8str_vec() const;
|
||||
const std::vector<std::u16string>& get_u16str_vec() const;
|
||||
const std::vector<std::u32string>& get_u32str_vec() const;
|
||||
const std::vector<std::wstring>& get_wstr_vec() const;
|
||||
|
||||
private:
|
||||
const std::vector<std::u8string>& u8str_vec;
|
||||
const std::vector<std::u16string>& u16str_vec;
|
||||
const std::vector<std::u32string>& u32str_vec;
|
||||
const std::vector<std::wstring>& wstr_vec;
|
||||
};
|
||||
|
||||
class OtherLiteral {
|
||||
public:
|
||||
OtherLiteral(std::string&& other_str, uint32_t windows_ident, std::string&& iconv_ident, std::u8string&& pycodec_ident);
|
||||
~OtherLiteral();
|
||||
YYCC_DEFAULT_COPY_MOVE(OtherLiteral)
|
||||
|
||||
const std::string& get_other_str() const;
|
||||
uint32_t get_windows_ident() const;
|
||||
const std::string& get_iconv_ident() const;
|
||||
const std::u8string& get_pycodec_ident() const;
|
||||
|
||||
private:
|
||||
std::string other_str;
|
||||
uint32_t windows_ident;
|
||||
std::string iconv_ident;
|
||||
std::u8string pycodec_ident;
|
||||
};
|
||||
|
||||
class OtherLiterals {
|
||||
public:
|
||||
OtherLiterals();
|
||||
~OtherLiterals();
|
||||
YYCC_DELETE_COPY_MOVE(OtherLiterals)
|
||||
|
||||
size_t get_size() const;
|
||||
const std::vector<OtherLiteral>& get_other_str_vec() const;
|
||||
const std::vector<std::u8string>& get_u8str_vec() const;
|
||||
const std::vector<std::wstring>& get_wstr_vec() const;
|
||||
|
||||
private:
|
||||
const std::vector<OtherLiteral>& other_str_vec;
|
||||
const std::vector<std::u8string>& u8str_vec;
|
||||
const std::vector<std::wstring>& wstr_vec;
|
||||
};
|
||||
|
||||
} // namespace yyccshared::literals
|
0
test/yycc/carton/clap.cpp
Normal file
0
test/yycc/carton/clap.cpp
Normal file
121
test/yycc/carton/pycodec.cpp
Normal file
121
test/yycc/carton/pycodec.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/carton/pycodec.hpp>
|
||||
#include "../../shared/literals.hpp"
|
||||
|
||||
#define ENC ::yycc::carton::pycodec
|
||||
|
||||
namespace yycctest::carton::pycodec {
|
||||
|
||||
static auto UTF_LITERALS = ::yyccshared::literals::UtfLiterals();
|
||||
static auto OTHER_LITERALS = ::yyccshared::literals::OtherLiterals();
|
||||
|
||||
TEST(CartonPycodec, ValidateName) {
|
||||
EXPECT_TRUE(ENC::is_valid_encoding_name(u8"utf-8"));
|
||||
EXPECT_TRUE(ENC::is_valid_encoding_name(u8"gb2312"));
|
||||
EXPECT_TRUE(ENC::is_valid_encoding_name(u8"cp1252"));
|
||||
|
||||
EXPECT_FALSE(ENC::is_valid_encoding_name(u8"this must not be a valid encoding name"));
|
||||
}
|
||||
|
||||
TEST(CartonPycodec, CharToUtf8) {
|
||||
const auto& other_str_literals = OTHER_LITERALS.get_other_str_vec();
|
||||
const auto& u8str_literals = OTHER_LITERALS.get_u8str_vec();
|
||||
|
||||
for (size_t i = 0; i < OTHER_LITERALS.get_size(); ++i) {
|
||||
const auto& other_str_literal = other_str_literals[i];
|
||||
ENC::CharToUtf8 cv(other_str_literal.get_pycodec_ident());
|
||||
|
||||
auto rv = cv.to_utf8(other_str_literal.get_other_str());
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u8str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CartonPycodec, Utf8ToChar) {
|
||||
const auto& other_str_literals = OTHER_LITERALS.get_other_str_vec();
|
||||
const auto& u8str_literals = OTHER_LITERALS.get_u8str_vec();
|
||||
|
||||
for (size_t i = 0; i < OTHER_LITERALS.get_size(); ++i) {
|
||||
const auto& other_str_literal = other_str_literals[i];
|
||||
ENC::Utf8ToChar cv(other_str_literal.get_pycodec_ident());
|
||||
|
||||
auto rv = cv.to_char(u8str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), other_str_literal.get_other_str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CartonPycodec, Utf8ToWchar) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& wstr_literals = UTF_LITERALS.get_wstr_vec();
|
||||
|
||||
ENC::Utf8ToWchar cv;
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = cv.to_wchar(u8str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), wstr_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CartonPycodec, WcharToUtf8) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& wstr_literals = UTF_LITERALS.get_wstr_vec();
|
||||
|
||||
ENC::WcharToUtf8 cv;
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = cv.to_utf8(wstr_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u8str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CartonPycodec, Utf8ToUtf16) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u16str_literals = UTF_LITERALS.get_u16str_vec();
|
||||
|
||||
ENC::Utf8ToUtf16 cv;
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = cv.to_utf16(u8str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u16str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CartonPycodec, Utf16ToUtf8) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u16str_literals = UTF_LITERALS.get_u16str_vec();
|
||||
|
||||
ENC::Utf16ToUtf8 cv;
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = cv.to_utf8(u16str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u8str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CartonPycodec, Utf8ToUtf32) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u32str_literals = UTF_LITERALS.get_u32str_vec();
|
||||
|
||||
ENC::Utf8ToUtf32 cv;
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = cv.to_utf32(u8str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u32str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CartonPycodec, Utf32ToUtf8) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u32str_literals = UTF_LITERALS.get_u32str_vec();
|
||||
|
||||
ENC::Utf32ToUtf8 cv;
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = cv.to_utf8(u32str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u8str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
61
test/yycc/carton/tabulate.cpp
Normal file
61
test/yycc/carton/tabulate.cpp
Normal file
@ -0,0 +1,61 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/carton/tabulate.hpp>
|
||||
#include <yycc/string/reinterpret.hpp>
|
||||
#include <sstream>
|
||||
|
||||
#define TABULATE ::yycc::carton::tabulate
|
||||
#define REINTERPRET ::yycc::string::reinterpret
|
||||
|
||||
namespace yycctest::carton::tabulate {
|
||||
|
||||
class CartonTabulate : public ::testing::Test {
|
||||
protected:
|
||||
CartonTabulate() : table(3u), ss() {
|
||||
// setup basic data
|
||||
table.set_prefix(u8"# ");
|
||||
table.set_header({u8"中文1", u8"中文2", u8"中文3"});
|
||||
table.set_bar(u8"===");
|
||||
table.add_row({u8"a", u8"b", u8"c"});
|
||||
}
|
||||
~CartonTabulate() override = default;
|
||||
|
||||
void expected_print(const std::u8string_view& exp) {
|
||||
ss.str("");
|
||||
table.print(ss);
|
||||
EXPECT_EQ(REINTERPRET::as_utf8_view(ss.view()), exp);
|
||||
}
|
||||
|
||||
TABULATE::Tabulate table;
|
||||
std::stringstream ss;
|
||||
};
|
||||
|
||||
TEST_F(CartonTabulate, Full) {
|
||||
table.show_header(true);
|
||||
table.show_bar(true);
|
||||
expected_print(u8"# 中文1 中文2 中文3 \n"
|
||||
u8"# === === === \n"
|
||||
u8"# a b c \n");
|
||||
}
|
||||
|
||||
TEST_F(CartonTabulate, NoHeader) {
|
||||
table.show_header(false);
|
||||
table.show_bar(true);
|
||||
expected_print(u8"# === === === \n"
|
||||
u8"# a b c \n");
|
||||
}
|
||||
|
||||
TEST_F(CartonTabulate, NoBar) {
|
||||
table.show_header(true);
|
||||
table.show_bar(false);
|
||||
expected_print(u8"# 中文1 中文2 中文3 \n"
|
||||
u8"# a b c \n");
|
||||
}
|
||||
|
||||
TEST_F(CartonTabulate, OnlyData) {
|
||||
table.show_header(false);
|
||||
table.show_bar(false);
|
||||
expected_print(u8"# a b c \n");
|
||||
}
|
||||
|
||||
} // namespace yycctest::carton::tabulate
|
44
test/yycc/carton/termcolor.cpp
Normal file
44
test/yycc/carton/termcolor.cpp
Normal file
@ -0,0 +1,44 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/carton/termcolor.hpp>
|
||||
#include <yycc/flag_enum.hpp>
|
||||
|
||||
#define TERMCOLOR ::yycc::carton::termcolor
|
||||
#define FLAG_ENUM ::yycc::flag_enum
|
||||
|
||||
using namespace std::literals::string_view_literals;
|
||||
using Color = TERMCOLOR::Color;
|
||||
using Attribute = TERMCOLOR::Attribute;
|
||||
|
||||
namespace yycctest::carton::termcolor {
|
||||
|
||||
TEST(CartonTermcolor, Lowlevel) {
|
||||
EXPECT_EQ(TERMCOLOR::foreground(Color::Default), u8"");
|
||||
EXPECT_EQ(TERMCOLOR::foreground(Color::Red), u8"\033[31m");
|
||||
EXPECT_EQ(TERMCOLOR::foreground(Color::LightRed), u8"\033[91m");
|
||||
|
||||
EXPECT_EQ(TERMCOLOR::background(Color::Default), u8"");
|
||||
EXPECT_EQ(TERMCOLOR::background(Color::Red), u8"\033[41m");
|
||||
EXPECT_EQ(TERMCOLOR::background(Color::LightRed), u8"\033[101m");
|
||||
|
||||
EXPECT_EQ(TERMCOLOR::style(Attribute::Default), u8"");
|
||||
EXPECT_EQ(TERMCOLOR::style(Attribute::Italic), u8"\033[3m");
|
||||
EXPECT_EQ(TERMCOLOR::styles(FLAG_ENUM::merge(Attribute::Italic, Attribute::Bold)),
|
||||
u8"\033[1m"
|
||||
"\033[3m");
|
||||
|
||||
EXPECT_EQ(TERMCOLOR::reset(), u8"\033[0m"sv);
|
||||
}
|
||||
|
||||
TEST(CartonTermcolor, Highlevel) {
|
||||
EXPECT_EQ(TERMCOLOR::colored(u8"hello"sv), u8"hello\033[0m");
|
||||
EXPECT_EQ(TERMCOLOR::colored(u8"hello"sv, Color::LightWhite, Color::Red, FLAG_ENUM::merge(Attribute::Italic, Attribute::Bold)),
|
||||
u8"\033[97m"
|
||||
"\033[41m"
|
||||
"\033[1m"
|
||||
"\033[3m"
|
||||
"hello"
|
||||
"\033[0m");
|
||||
}
|
||||
|
||||
} // namespace yycctest::carton::termcolor
|
54
test/yycc/carton/wcwidth.cpp
Normal file
54
test/yycc/carton/wcwidth.cpp
Normal file
@ -0,0 +1,54 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/carton/wcwidth.hpp>
|
||||
#include <yycc/carton/termcolor.hpp>
|
||||
|
||||
#define WCWDITH ::yycc::carton::wcwidth
|
||||
#define TERMCOLOR ::yycc::carton::termcolor
|
||||
|
||||
namespace yycctest::carton::wcwidth {
|
||||
|
||||
#define TEST_SUCCESS(strl, len) \
|
||||
{ \
|
||||
auto rv = WCWDITH::wcswidth(strl); \
|
||||
ASSERT_TRUE(rv.has_value()); \
|
||||
EXPECT_EQ(rv.value(), len); \
|
||||
}
|
||||
|
||||
#define TEST_FAIL(strl) \
|
||||
{ \
|
||||
auto rv = WCWDITH::wcswidth(strl); \
|
||||
EXPECT_FALSE(rv.has_value()); \
|
||||
}
|
||||
|
||||
TEST(CartonWcwdith, BadAnsi) {
|
||||
TEST_FAIL(u8"\033?");
|
||||
}
|
||||
|
||||
TEST(CartonWcwdith, BadCsi) {
|
||||
TEST_FAIL(u8"\033[\t");
|
||||
}
|
||||
|
||||
TEST(CartonWcwdith, English) {
|
||||
TEST_SUCCESS(u8"abc", 3);
|
||||
}
|
||||
|
||||
TEST(CartonWcwdith, Chinese) {
|
||||
TEST_SUCCESS(u8"中文", 4);
|
||||
TEST_SUCCESS(u8"中a文", 5);
|
||||
}
|
||||
|
||||
TEST(CartonWcwdith, Japanese) {
|
||||
TEST_SUCCESS(u8"ありがとう", 10);
|
||||
TEST_SUCCESS(u8"アリガトウ", 10);
|
||||
TEST_SUCCESS(u8"アリガトウ", 6);
|
||||
}
|
||||
|
||||
TEST(CartonWcwdith, Termcolor) {
|
||||
using Color = TERMCOLOR::Color;
|
||||
TEST_SUCCESS(TERMCOLOR::colored(u8"abc", Color::Red), 3);
|
||||
TEST_SUCCESS(TERMCOLOR::colored(u8"中文", Color::Red), 4);
|
||||
TEST_SUCCESS(TERMCOLOR::colored(u8"ありがとう", Color::Red), 10);
|
||||
}
|
||||
|
||||
} // namespace yycctest::carton::wcwidth
|
50
test/yycc/constraint.cpp
Normal file
50
test/yycc/constraint.cpp
Normal file
@ -0,0 +1,50 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/constraint.hpp>
|
||||
|
||||
#include <yycc/rust/prelude.hpp>
|
||||
|
||||
#define CONSTRAINT ::yycc::constraint::Constraint
|
||||
|
||||
namespace yycctest::constraint {
|
||||
|
||||
template<typename T>
|
||||
bool check(const T& value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T clamp(const T& value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
TEST(Constraint, Normal) {
|
||||
CONSTRAINT<u32> instance(check<u32>, clamp<u32>);
|
||||
EXPECT_TRUE(instance.support_check());
|
||||
EXPECT_TRUE(instance.support_clamp());
|
||||
EXPECT_FALSE(instance.check(0));
|
||||
EXPECT_EQ(instance.clamp(0), 0);
|
||||
}
|
||||
|
||||
TEST(Constraint, SomeNone) {
|
||||
{
|
||||
CONSTRAINT<u32> instance(check<u32>, nullptr);
|
||||
EXPECT_TRUE(instance.support_check());
|
||||
EXPECT_FALSE(instance.support_clamp());
|
||||
EXPECT_FALSE(instance.check(0));
|
||||
}
|
||||
{
|
||||
CONSTRAINT<u32> instance(nullptr, clamp<u32>);
|
||||
EXPECT_FALSE(instance.support_check());
|
||||
EXPECT_TRUE(instance.support_clamp());
|
||||
EXPECT_EQ(instance.clamp(0), 0);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(Constraint, AllNone) {
|
||||
CONSTRAINT<u32> instance(nullptr, nullptr);
|
||||
EXPECT_FALSE(instance.support_check());
|
||||
EXPECT_FALSE(instance.support_clamp());
|
||||
}
|
||||
|
||||
}
|
79
test/yycc/constraint/builder.cpp
Normal file
79
test/yycc/constraint/builder.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/constraint/builder.hpp>
|
||||
|
||||
#include <yycc/rust/prelude.hpp>
|
||||
|
||||
#define BUILDER ::yycc::constraint::builder
|
||||
using namespace std::literals::string_view_literals;
|
||||
|
||||
namespace yycctest::constraint::builder {
|
||||
|
||||
#define TEST_SUCCESS(constraint, value) \
|
||||
EXPECT_TRUE(constraint.check(value)); \
|
||||
EXPECT_EQ(constraint.clamp(value), value);
|
||||
|
||||
#define TEST_FAIL(constraint, value, clamped_value) \
|
||||
EXPECT_FALSE(constraint.check(value)); \
|
||||
EXPECT_EQ(constraint.clamp(value), clamped_value);
|
||||
|
||||
TEST(ConstraintBuilder, MinMaxConstraint) {
|
||||
// Integral type
|
||||
{
|
||||
auto c = BUILDER::min_max_constraint<i32>(5, 61);
|
||||
ASSERT_TRUE(c.support_check());
|
||||
ASSERT_TRUE(c.support_clamp());
|
||||
TEST_SUCCESS(c, 5);
|
||||
TEST_SUCCESS(c, 6);
|
||||
TEST_SUCCESS(c, 61);
|
||||
TEST_FAIL(c, -2, 5);
|
||||
TEST_FAIL(c, 0, 5);
|
||||
TEST_FAIL(c, 66, 61);
|
||||
}
|
||||
// Unisgned integral type
|
||||
{
|
||||
auto c = BUILDER::min_max_constraint<u32>(5, 61);
|
||||
ASSERT_TRUE(c.support_check());
|
||||
ASSERT_TRUE(c.support_clamp());
|
||||
TEST_SUCCESS(c, 5);
|
||||
TEST_SUCCESS(c, 6);
|
||||
TEST_SUCCESS(c, 61);
|
||||
TEST_FAIL(c, 0, 5);
|
||||
TEST_FAIL(c, 66, 61);
|
||||
}
|
||||
// Float point type
|
||||
{
|
||||
auto c = BUILDER::min_max_constraint<f32>(5.0f, 61.0f);
|
||||
ASSERT_TRUE(c.support_check());
|
||||
ASSERT_TRUE(c.support_clamp());
|
||||
TEST_SUCCESS(c, 5.0f);
|
||||
TEST_SUCCESS(c, 6.0f);
|
||||
TEST_SUCCESS(c, 61.0f);
|
||||
TEST_FAIL(c, 0.0f, 5.0f);
|
||||
TEST_FAIL(c, 66.0f, 61.0f);
|
||||
}
|
||||
}
|
||||
|
||||
enum class TestEnum : u8 { Entry1 = 0, Entry2 = 1, Entry3 = 2 };
|
||||
|
||||
TEST(ConstraintBuilder, EnumConstraint) {
|
||||
auto c = BUILDER::enum_constraint({TestEnum::Entry1, TestEnum::Entry2, TestEnum::Entry3}, 1u);
|
||||
ASSERT_TRUE(c.support_check());
|
||||
ASSERT_TRUE(c.support_clamp());
|
||||
TEST_SUCCESS(c, TestEnum::Entry1);
|
||||
TEST_SUCCESS(c, TestEnum::Entry2);
|
||||
TEST_SUCCESS(c, TestEnum::Entry3);
|
||||
TEST_FAIL(c, static_cast<TestEnum>(UINT8_C(61)), TestEnum::Entry2);
|
||||
}
|
||||
|
||||
TEST(ConstraintBuilder, StrEnumConstraint) {
|
||||
auto c = BUILDER::strenum_constraint({u8"first-entry"sv, u8"second-entry"sv, u8"third-entry"sv}, 1u);
|
||||
ASSERT_TRUE(c.support_check());
|
||||
ASSERT_TRUE(c.support_clamp());
|
||||
TEST_SUCCESS(c, u8"first-entry");
|
||||
TEST_SUCCESS(c, u8"second-entry");
|
||||
TEST_SUCCESS(c, u8"third-entry");
|
||||
TEST_FAIL(c, u8"wtf?", u8"second-entry");
|
||||
}
|
||||
|
||||
} // namespace yycctest::constraint::builder
|
115
test/yycc/encoding/iconv.cpp
Normal file
115
test/yycc/encoding/iconv.cpp
Normal file
@ -0,0 +1,115 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/encoding/iconv.hpp>
|
||||
#include "../../shared/literals.hpp"
|
||||
|
||||
#define ENC ::yycc::encoding::iconv
|
||||
|
||||
namespace yycctest::encoding::iconv {
|
||||
#if defined(YYCC_FEAT_ICONV)
|
||||
|
||||
static auto UTF_LITERALS = ::yyccshared::literals::UtfLiterals();
|
||||
static auto OTHER_LITERALS = ::yyccshared::literals::OtherLiterals();
|
||||
|
||||
TEST(EncodingIconv, CharToUtf8) {
|
||||
const auto& other_str_literals = OTHER_LITERALS.get_other_str_vec();
|
||||
const auto& u8str_literals = OTHER_LITERALS.get_u8str_vec();
|
||||
|
||||
for (size_t i = 0; i < OTHER_LITERALS.get_size(); ++i) {
|
||||
const auto& other_str_literal = other_str_literals[i];
|
||||
ENC::CharToUtf8 cv(other_str_literal.get_iconv_ident());
|
||||
|
||||
auto rv = cv.to_utf8(other_str_literal.get_other_str());
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u8str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingIconv, Utf8ToChar) {
|
||||
const auto& other_str_literals = OTHER_LITERALS.get_other_str_vec();
|
||||
const auto& u8str_literals = OTHER_LITERALS.get_u8str_vec();
|
||||
|
||||
for (size_t i = 0; i < OTHER_LITERALS.get_size(); ++i) {
|
||||
const auto& other_str_literal = other_str_literals[i];
|
||||
ENC::Utf8ToChar cv(other_str_literal.get_iconv_ident());
|
||||
|
||||
auto rv = cv.to_char(u8str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), other_str_literal.get_other_str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingIconv, Utf8ToWchar) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& wstr_literals = UTF_LITERALS.get_wstr_vec();
|
||||
|
||||
ENC::Utf8ToWchar cv;
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = cv.to_wchar(u8str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), wstr_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingIconv, WcharToUtf8) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& wstr_literals = UTF_LITERALS.get_wstr_vec();
|
||||
|
||||
ENC::WcharToUtf8 cv;
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = cv.to_utf8(wstr_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u8str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingIconv, Utf8ToUtf16) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u16str_literals = UTF_LITERALS.get_u16str_vec();
|
||||
|
||||
ENC::Utf8ToUtf16 cv;
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = cv.to_utf16(u8str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u16str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingIconv, Utf16ToUtf8) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u16str_literals = UTF_LITERALS.get_u16str_vec();
|
||||
|
||||
ENC::Utf16ToUtf8 cv;
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = cv.to_utf8(u16str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u8str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingIconv, Utf8ToUtf32) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u32str_literals = UTF_LITERALS.get_u32str_vec();
|
||||
|
||||
ENC::Utf8ToUtf32 cv;
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = cv.to_utf32(u8str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u32str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingIconv, Utf32ToUtf8) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u32str_literals = UTF_LITERALS.get_u32str_vec();
|
||||
|
||||
ENC::Utf32ToUtf8 cv;
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = cv.to_utf8(u32str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u8str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
} // namespace yycctest::encoding::iconv
|
56
test/yycc/encoding/stl.cpp
Normal file
56
test/yycc/encoding/stl.cpp
Normal file
@ -0,0 +1,56 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/encoding/stl.hpp>
|
||||
#include "../../shared/literals.hpp"
|
||||
|
||||
#define ENC ::yycc::encoding::stl
|
||||
|
||||
namespace yycctest::encoding::stl {
|
||||
|
||||
static auto UTF_LITERALS = ::yyccshared::literals::UtfLiterals();
|
||||
|
||||
TEST(EncodingStl, Utf8ToUtf16) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u16str_literals = UTF_LITERALS.get_u16str_vec();
|
||||
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = ENC::to_utf16(u8str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u16str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingStl, Utf16ToUtf8) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u16str_literals = UTF_LITERALS.get_u16str_vec();
|
||||
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = ENC::to_utf8(u16str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u8str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingStl, Utf8ToUtf32) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u32str_literals = UTF_LITERALS.get_u32str_vec();
|
||||
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = ENC::to_utf32(u8str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u32str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingStl, Utf32ToUtf8) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u32str_literals = UTF_LITERALS.get_u32str_vec();
|
||||
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = ENC::to_utf8(u32str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u8str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace yycctest::encoding::stl
|
137
test/yycc/encoding/windows.cpp
Normal file
137
test/yycc/encoding/windows.cpp
Normal file
@ -0,0 +1,137 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/encoding/windows.hpp>
|
||||
#include "../../shared/literals.hpp"
|
||||
|
||||
#define ENC ::yycc::encoding::windows
|
||||
|
||||
namespace yycctest::encoding::windows {
|
||||
#if defined(YYCC_OS_WINDOWS)
|
||||
|
||||
static auto UTF_LITERALS = ::yyccshared::literals::UtfLiterals();
|
||||
static auto OTHER_LITERALS = ::yyccshared::literals::OtherLiterals();
|
||||
|
||||
TEST(EncodingWindows, CharToWchar) {
|
||||
const auto& other_str_literals = OTHER_LITERALS.get_other_str_vec();
|
||||
const auto& wstr_literals = OTHER_LITERALS.get_wstr_vec();
|
||||
|
||||
for (size_t i = 0; i < OTHER_LITERALS.get_size(); ++i) {
|
||||
const auto& other_str_literal = other_str_literals[i];
|
||||
|
||||
auto rv = ENC::to_wchar(other_str_literal.get_other_str(), other_str_literal.get_windows_ident());
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), wstr_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingWindows, WcharToChar) {
|
||||
const auto& other_str_literals = OTHER_LITERALS.get_other_str_vec();
|
||||
const auto& wstr_literals = OTHER_LITERALS.get_wstr_vec();
|
||||
|
||||
for (size_t i = 0; i < OTHER_LITERALS.get_size(); ++i) {
|
||||
const auto& other_str_literal = other_str_literals[i];
|
||||
|
||||
auto rv = ENC::to_char(wstr_literals[i], other_str_literal.get_windows_ident());
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), other_str_literal.get_other_str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingWindows, CharToUtf8) {
|
||||
const auto& other_str_literals = OTHER_LITERALS.get_other_str_vec();
|
||||
const auto& u8str_literals = OTHER_LITERALS.get_u8str_vec();
|
||||
|
||||
for (size_t i = 0; i < OTHER_LITERALS.get_size(); ++i) {
|
||||
const auto& other_str_literal = other_str_literals[i];
|
||||
|
||||
auto rv = ENC::to_utf8(other_str_literal.get_other_str(), other_str_literal.get_windows_ident());
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u8str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingWindows, Utf8ToChar) {
|
||||
const auto& other_str_literals = OTHER_LITERALS.get_other_str_vec();
|
||||
const auto& u8str_literals = OTHER_LITERALS.get_u8str_vec();
|
||||
|
||||
for (size_t i = 0; i < OTHER_LITERALS.get_size(); ++i) {
|
||||
const auto& other_str_literal = other_str_literals[i];
|
||||
|
||||
auto rv = ENC::to_char(u8str_literals[i], other_str_literal.get_windows_ident());
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), other_str_literal.get_other_str());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingWindows, Utf8ToWchar) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& wstr_literals = UTF_LITERALS.get_wstr_vec();
|
||||
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = ENC::to_wchar(u8str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), wstr_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingWindows, WcharToUtf8) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& wstr_literals = UTF_LITERALS.get_wstr_vec();
|
||||
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = ENC::to_utf8(wstr_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u8str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(YYCC_STL_MSSTL)
|
||||
|
||||
TEST(EncodingWindows, Utf8ToUtf16) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u16str_literals = UTF_LITERALS.get_u16str_vec();
|
||||
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = ENC::to_utf16(u8str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u16str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingWindows, Utf16ToUtf8) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u16str_literals = UTF_LITERALS.get_u16str_vec();
|
||||
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = ENC::to_utf8(u16str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u8str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingWindows, Utf8ToUtf32) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u32str_literals = UTF_LITERALS.get_u32str_vec();
|
||||
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = ENC::to_utf32(u8str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u32str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(EncodingWindows, Utf32ToUtf8) {
|
||||
const auto& u8str_literals = UTF_LITERALS.get_u8str_vec();
|
||||
const auto& u32str_literals = UTF_LITERALS.get_u32str_vec();
|
||||
|
||||
for (size_t i = 0; i < UTF_LITERALS.get_size(); ++i) {
|
||||
auto rv = ENC::to_utf8(u32str_literals[i]);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), u8str_literals[i]);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
} // namespace yycctest::encoding::windows
|
83
test/yycc/flag_enum.cpp
Normal file
83
test/yycc/flag_enum.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/flag_enum.hpp>
|
||||
#include <cinttypes>
|
||||
|
||||
#include <yycc/rust/prelude.hpp>
|
||||
|
||||
#define FLAG_ENUM ::yycc::flag_enum
|
||||
|
||||
namespace yycctest::flag_enum {
|
||||
|
||||
enum class TestEnum : u8 {
|
||||
Bit1 = 0b00000001,
|
||||
Bit2 = 0b00000010,
|
||||
Bit3 = 0b00000100,
|
||||
Bit4 = 0b00001000,
|
||||
Bit5 = 0b00010000,
|
||||
Bit6 = 0b00100000,
|
||||
Bit7 = 0b01000000,
|
||||
Bit8 = 0b10000000,
|
||||
Empty = 0b00000000,
|
||||
InvBit8 = 0b01111111,
|
||||
MergedBit247 = Bit2 + Bit4 + Bit7,
|
||||
};
|
||||
|
||||
TEST(FlagEnum, Merge) {
|
||||
EXPECT_EQ(FLAG_ENUM::merge(TestEnum::Bit2, TestEnum::Bit4, TestEnum::Bit7), TestEnum::MergedBit247);
|
||||
}
|
||||
|
||||
TEST(FlagEnum, Invert) {
|
||||
EXPECT_EQ(FLAG_ENUM::invert(TestEnum::Bit8), TestEnum::InvBit8);
|
||||
}
|
||||
|
||||
TEST(FlagEnum, Mask) {
|
||||
TestEnum src = FLAG_ENUM::merge(TestEnum::Bit2, TestEnum::Bit4);
|
||||
TestEnum val;
|
||||
|
||||
val = src;
|
||||
FLAG_ENUM::mask(val, TestEnum::Bit2);
|
||||
EXPECT_EQ(val, TestEnum::Bit2);
|
||||
|
||||
val = src;
|
||||
FLAG_ENUM::mask(val, TestEnum::Bit4);
|
||||
EXPECT_EQ(val, TestEnum::Bit4);
|
||||
|
||||
val = src;
|
||||
FLAG_ENUM::mask(val, TestEnum::Bit3);
|
||||
EXPECT_EQ(val, TestEnum::Empty);
|
||||
}
|
||||
|
||||
TEST(FlagEnum, Add) {
|
||||
TestEnum val = TestEnum::Bit2;
|
||||
FLAG_ENUM::add(val, TestEnum::Bit4, TestEnum::Bit7);
|
||||
EXPECT_EQ(val, TestEnum::MergedBit247);
|
||||
}
|
||||
|
||||
TEST(FlagEnum, Remove) {
|
||||
TestEnum val = TestEnum::MergedBit247;
|
||||
FLAG_ENUM::remove(val, TestEnum::Bit2, TestEnum::Bit7);
|
||||
EXPECT_EQ(val, TestEnum::Bit4);
|
||||
}
|
||||
|
||||
TEST(FlagEnum, Has) {
|
||||
TestEnum val = TestEnum::MergedBit247;
|
||||
EXPECT_TRUE(FLAG_ENUM::has(val, TestEnum::Bit2));
|
||||
EXPECT_FALSE(FLAG_ENUM::has(val, TestEnum::Bit3));
|
||||
EXPECT_TRUE(FLAG_ENUM::has(val, TestEnum::Bit4));
|
||||
EXPECT_TRUE(FLAG_ENUM::has(val, TestEnum::Bit7));
|
||||
}
|
||||
|
||||
TEST(FlagEnum, Boolean) {
|
||||
EXPECT_FALSE(FLAG_ENUM::boolean(TestEnum::Empty));
|
||||
EXPECT_TRUE(FLAG_ENUM::boolean(TestEnum::Bit1));
|
||||
EXPECT_TRUE(FLAG_ENUM::boolean(TestEnum::InvBit8));
|
||||
EXPECT_TRUE(FLAG_ENUM::boolean(TestEnum::MergedBit247));
|
||||
}
|
||||
|
||||
TEST(FlagEnum, Integer) {
|
||||
EXPECT_EQ(FLAG_ENUM::integer(TestEnum::Empty), UINT8_C(0));
|
||||
EXPECT_EQ(FLAG_ENUM::integer(TestEnum::Bit1), UINT8_C(1));
|
||||
}
|
||||
|
||||
}
|
20
test/yycc/macro/compiler_detector.cpp
Normal file
20
test/yycc/macro/compiler_detector.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/macro/compiler_detector.hpp>
|
||||
|
||||
#define COMPILER ::yycc::macro::compiler
|
||||
|
||||
namespace yycctest::macro::compiler {
|
||||
|
||||
TEST(MacroCompiler, Main) {
|
||||
auto rv = COMPILER::get_compiler();
|
||||
#if defined(YYCC_CC_MSVC)
|
||||
EXPECT_EQ(rv, COMPILER::CompilerKind::Msvc);
|
||||
#elif defined(YYCC_CC_GCC)
|
||||
EXPECT_EQ(rv, COMPILER::CompilerKind::Gcc);
|
||||
#else
|
||||
EXPECT_EQ(rv, COMPILER::CompilerKind::Clang);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace yycctest::macro::compiler
|
18
test/yycc/macro/endian_detector.cpp
Normal file
18
test/yycc/macro/endian_detector.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/macro/endian_detector.hpp>
|
||||
|
||||
#define ENDIAN ::yycc::macro::endian
|
||||
|
||||
namespace yycctest::macro::endian {
|
||||
|
||||
TEST(MacroEndian, Main) {
|
||||
auto rv = ENDIAN::get_endian();
|
||||
#if defined(YYCC_ENDIAN_LITTLE)
|
||||
EXPECT_EQ(rv, ENDIAN::EndianKind::Little);
|
||||
#else
|
||||
EXPECT_EQ(rv, ENDIAN::EndianKind::Big);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace yycctest::macro::endian
|
20
test/yycc/macro/os_detector.cpp
Normal file
20
test/yycc/macro/os_detector.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/macro/os_detector.hpp>
|
||||
|
||||
#define OS ::yycc::macro::os
|
||||
|
||||
namespace yycctest::macro::os {
|
||||
|
||||
TEST(MacroOs, Main) {
|
||||
auto rv = OS::get_os();
|
||||
#if defined(YYCC_OS_WINDOWS)
|
||||
EXPECT_EQ(rv, OS::OsKind::Windows);
|
||||
#elif defined(YYCC_OS_LINUX)
|
||||
EXPECT_EQ(rv, OS::OsKind::Linux);
|
||||
#else
|
||||
EXPECT_EQ(rv, OS::OsKind::MacOs);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace yycctest::macro::os
|
18
test/yycc/macro/ptr_size_detector.cpp
Normal file
18
test/yycc/macro/ptr_size_detector.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/macro/ptr_size_detector.hpp>
|
||||
|
||||
#define PTR_SIZE ::yycc::macro::ptr_size
|
||||
|
||||
namespace yycctest::macro::ptr_size {
|
||||
|
||||
TEST(MacroPtrSize, Main) {
|
||||
auto rv = PTR_SIZE::get_ptr_size();
|
||||
#if defined(YYCC_PTRSIZE_32)
|
||||
EXPECT_EQ(rv, PTR_SIZE::PtrSizeKind::Bits32);
|
||||
#else
|
||||
EXPECT_EQ(rv, PTR_SIZE::PtrSizeKind::Bits64);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace yycctest::macro::ptr_size
|
20
test/yycc/macro/stl_detector.cpp
Normal file
20
test/yycc/macro/stl_detector.cpp
Normal file
@ -0,0 +1,20 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/macro/stl_detector.hpp>
|
||||
|
||||
#define STL ::yycc::macro::stl
|
||||
|
||||
namespace yycctest::macro::stl {
|
||||
|
||||
TEST(MacroStl, Main) {
|
||||
auto rv = STL::get_stl();
|
||||
#if defined(YYCC_STL_MSSTL)
|
||||
EXPECT_EQ(rv, STL::StlKind::MsStl);
|
||||
#elif defined(YYCC_STL_GNUSTL)
|
||||
EXPECT_EQ(rv, STL::StlKind::GnuStl);
|
||||
#else
|
||||
EXPECT_EQ(rv, STL::StlKind::ClangStl);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace yycctest::macro::stl
|
31
test/yycc/macro/version_cmp.cpp
Normal file
31
test/yycc/macro/version_cmp.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/macro/version_cmp.hpp>
|
||||
|
||||
namespace yycctest::macro::version_cmp {
|
||||
|
||||
TEST(MacroVersionCmp, Same) {
|
||||
// Test for same version.
|
||||
EXPECT_TRUE(YYCC_VERCMP_E(1, 2, 3, 1, 2, 3));
|
||||
EXPECT_FALSE(YYCC_VERCMP_NE(1, 2, 3, 1, 2, 3));
|
||||
EXPECT_FALSE(YYCC_VERCMP_G(1, 2, 3, 1, 2, 3));
|
||||
EXPECT_TRUE(YYCC_VERCMP_GE(1, 2, 3, 1, 2, 3));
|
||||
EXPECT_TRUE(YYCC_VERCMP_NL(1, 2, 3, 1, 2, 3));
|
||||
EXPECT_FALSE(YYCC_VERCMP_L(1, 2, 3, 1, 2, 3));
|
||||
EXPECT_TRUE(YYCC_VERCMP_LE(1, 2, 3, 1, 2, 3));
|
||||
EXPECT_TRUE(YYCC_VERCMP_NG(1, 2, 3, 1, 2, 3));
|
||||
}
|
||||
|
||||
TEST(MacroVersionCmp, Math) {
|
||||
// In version number, 1.2.10 is greater than 1.2.9
|
||||
EXPECT_FALSE(YYCC_VERCMP_E(1, 2, 10, 1, 2, 9));
|
||||
EXPECT_TRUE(YYCC_VERCMP_NE(1, 2, 10, 1, 2, 9));
|
||||
EXPECT_TRUE(YYCC_VERCMP_G(1, 2, 10, 1, 2, 9));
|
||||
EXPECT_TRUE(YYCC_VERCMP_GE(1, 2, 10, 1, 2, 9));
|
||||
EXPECT_TRUE(YYCC_VERCMP_NL(1, 2, 10, 1, 2, 9));
|
||||
EXPECT_FALSE(YYCC_VERCMP_L(1, 2, 10, 1, 2, 9));
|
||||
EXPECT_FALSE(YYCC_VERCMP_LE(1, 2, 10, 1, 2, 9));
|
||||
EXPECT_FALSE(YYCC_VERCMP_NG(1, 2, 10, 1, 2, 9));
|
||||
}
|
||||
|
||||
}
|
19
test/yycc/num/op.cpp
Normal file
19
test/yycc/num/op.cpp
Normal file
@ -0,0 +1,19 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/num/op.hpp>
|
||||
|
||||
#include <yycc/rust/prelude.hpp>
|
||||
|
||||
#define OP ::yycc::num::op
|
||||
|
||||
namespace yycctest::num::op {
|
||||
|
||||
TEST(NumOp, DivCeil) {
|
||||
// Normal case
|
||||
EXPECT_EQ(OP::div_ceil<u32>(8, 4), UINT32_C(2));
|
||||
EXPECT_EQ(OP::div_ceil<u32>(7, 4), UINT32_C(2));
|
||||
// Limit case
|
||||
EXPECT_EQ(OP::div_ceil<u8>(255, 2), UINT8_C(128));
|
||||
}
|
||||
|
||||
}
|
81
test/yycc/num/parse.cpp
Normal file
81
test/yycc/num/parse.cpp
Normal file
@ -0,0 +1,81 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/num/parse.hpp>
|
||||
|
||||
#include <yycc/rust/prelude.hpp>
|
||||
|
||||
#define PARSE ::yycc::num::parse
|
||||
|
||||
namespace yycctest::num::parse {
|
||||
|
||||
// These 2 test macros build string container via given string.
|
||||
// Check `try_parse` first, and then check `parse`.
|
||||
|
||||
#define TEST_SUCCESS(type_t, expected_value, string_value, ...) \
|
||||
{ \
|
||||
std::u8string cache_string(string_value); \
|
||||
auto rv = PARSE::parse<type_t>(cache_string __VA_OPT__(,) __VA_ARGS__); \
|
||||
ASSERT_TRUE(rv.has_value()); \
|
||||
EXPECT_EQ(rv.value(), expected_value); \
|
||||
}
|
||||
|
||||
#define TEST_FAIL(type_t, string_value, ...) \
|
||||
{ \
|
||||
std::u8string cache_string(string_value); \
|
||||
auto rv = PARSE::parse<type_t>(cache_string __VA_OPT__(,) __VA_ARGS__); \
|
||||
EXPECT_FALSE(rv.has_value()); \
|
||||
}
|
||||
|
||||
TEST(NumParse, Common) {
|
||||
TEST_SUCCESS(i8, INT8_C(-61), u8"-61");
|
||||
TEST_SUCCESS(u8, UINT8_C(200), u8"200");
|
||||
TEST_SUCCESS(i16, INT16_C(6161), u8"6161");
|
||||
TEST_SUCCESS(u16, UINT16_C(32800), u8"32800");
|
||||
TEST_SUCCESS(i32, INT32_C(61616161), u8"61616161");
|
||||
TEST_SUCCESS(u32, UINT32_C(4294967293), u8"4294967293");
|
||||
TEST_SUCCESS(i64, INT64_C(616161616161), u8"616161616161");
|
||||
TEST_SUCCESS(u64, UINT64_C(9223372036854775807), u8"9223372036854775807");
|
||||
|
||||
TEST_SUCCESS(float, 1.0f, u8"1.0");
|
||||
TEST_SUCCESS(double, 1.0, u8"1.0");
|
||||
|
||||
TEST_SUCCESS(bool, true, u8"true");
|
||||
TEST_SUCCESS(bool, false, u8"false");
|
||||
}
|
||||
|
||||
TEST(NumParse, Radix) {
|
||||
TEST_SUCCESS(u32, UINT32_C(0xffff), u8"ffff", 16);
|
||||
TEST_SUCCESS(u32, UINT32_C(032), u8"032", 8);
|
||||
TEST_SUCCESS(u32, UINT32_C(0B1011), u8"1011", 2);
|
||||
}
|
||||
|
||||
TEST(NumParse, CaseInsensitive) {
|
||||
TEST_SUCCESS(bool, true, u8"tRUE");
|
||||
}
|
||||
|
||||
TEST(NumParse, Overflow) {
|
||||
TEST_FAIL(i8, u8"6161");
|
||||
TEST_FAIL(u8, u8"32800");
|
||||
TEST_FAIL(i16, u8"61616161");
|
||||
TEST_FAIL(u16, u8"4294967293");
|
||||
TEST_FAIL(i32, u8"616161616161");
|
||||
TEST_FAIL(u32, u8"9223372036854775807");
|
||||
TEST_FAIL(i64, u8"616161616161616161616161");
|
||||
TEST_FAIL(u64, u8"92233720368547758079223372036854775807");
|
||||
|
||||
TEST_FAIL(float, u8"1e40");
|
||||
TEST_FAIL(double, u8"1e114514");
|
||||
}
|
||||
|
||||
TEST(NumParse, BadRadix) {
|
||||
TEST_FAIL(u32, u8"fghj", 16);
|
||||
TEST_FAIL(u32, u8"099", 8);
|
||||
TEST_FAIL(u32, u8"12345", 2);
|
||||
}
|
||||
|
||||
TEST(NumParse, InvalidWords) {
|
||||
TEST_FAIL(u32, u8"hello, world!");
|
||||
TEST_FAIL(bool, u8"hello, world!");
|
||||
}
|
||||
|
||||
} // namespace yycctest::num::parse
|
51
test/yycc/num/safe_cast.cpp
Normal file
51
test/yycc/num/safe_cast.cpp
Normal file
@ -0,0 +1,51 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/num/safe_cast.hpp>
|
||||
#include <yycc/macro/ptr_size_detector.hpp>
|
||||
|
||||
#include <yycc/rust/prelude.hpp>
|
||||
|
||||
#define CAST ::yycc::num::safe_cast
|
||||
|
||||
namespace yycctest::num::safe_cast {
|
||||
|
||||
TEST(NumSafeCast, To) {
|
||||
// Definitely okey
|
||||
auto rv = CAST::to<u32, u8>(UINT8_C(1));
|
||||
EXPECT_EQ(rv, UINT32_C(1));
|
||||
}
|
||||
|
||||
TEST(NumSafeCast, TryTo) {
|
||||
// Okey
|
||||
{
|
||||
auto rv = CAST::try_to<u8, u32>(UINT32_C(1));
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), UINT8_C(1));
|
||||
}
|
||||
// Bad cast
|
||||
{
|
||||
auto rv = CAST::try_to<u8, u32>(UINT32_C(6161));
|
||||
EXPECT_FALSE(rv.has_value());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NumSafeCast, VariableLength) {
|
||||
// Both 32-bit and 64-bit pointer size are okey.
|
||||
{
|
||||
auto rv = CAST::try_to<usize, u64>(UINT64_C(0x00000000ffffffff));
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), 0xffffffffu);
|
||||
}
|
||||
// Only 64-bit pointer size is okey.
|
||||
{
|
||||
auto rv = CAST::try_to<usize, u64>(UINT64_C(0xffffffffffffffff));
|
||||
#if defined(YYCC_PTRSIZE_64)
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), 0xffffffffffffffffu);
|
||||
#else
|
||||
EXPECT_FALSE(rv.has_value());
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
}
|
300
test/yycc/num/safe_op.cpp
Normal file
300
test/yycc/num/safe_op.cpp
Normal file
@ -0,0 +1,300 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/num/safe_op.hpp>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
#include <yycc/rust/prelude.hpp>
|
||||
|
||||
#define OP ::yycc::num::safe_op
|
||||
|
||||
namespace yycctest::num::safe_op {
|
||||
|
||||
template<typename T>
|
||||
constexpr T MAX = std::numeric_limits<T>::max();
|
||||
|
||||
template<typename T>
|
||||
constexpr T MIN = std::numeric_limits<T>::min();
|
||||
|
||||
#pragma region Wrapping operations
|
||||
|
||||
TEST(NumSafeOp, WrappingAdd) {
|
||||
// Unsigned
|
||||
EXPECT_EQ(OP::wrapping_add<u32>(200, 55), UINT32_C(255));
|
||||
EXPECT_EQ(OP::wrapping_add<u32>(200, MAX<u32>), UINT32_C(199));
|
||||
// Signed
|
||||
EXPECT_EQ(OP::wrapping_add<i32>(100, 27), INT32_C(127));
|
||||
EXPECT_EQ(OP::wrapping_add<i32>(MAX<i32>, 2), MIN<i32> + 1);
|
||||
}
|
||||
|
||||
TEST(NumSafeOp, WrappingSub) {
|
||||
// Unsigned
|
||||
EXPECT_EQ(OP::wrapping_sub<u32>(100, 100), 0);
|
||||
EXPECT_EQ(OP::wrapping_sub<u32>(100, MAX<u32>), UINT32_C(101));
|
||||
// Signed
|
||||
EXPECT_EQ(OP::wrapping_sub<i32>(0, 127), INT32_C(-127));
|
||||
EXPECT_EQ(OP::wrapping_sub<i32>(-2, MAX<i32>), MAX<i32>);
|
||||
}
|
||||
|
||||
TEST(NumSafeOp, WrappingMul) {
|
||||
// Unsigned
|
||||
EXPECT_EQ(OP::wrapping_mul<u8>(10, 12), UINT8_C(120));
|
||||
EXPECT_EQ(OP::wrapping_mul<u8>(25, 12), UINT8_C(44));
|
||||
// Signed
|
||||
EXPECT_EQ(OP::wrapping_mul<i32>(10, 12), INT32_C(120));
|
||||
EXPECT_EQ(OP::wrapping_mul<i8>(11, 12), INT32_C(-124));
|
||||
}
|
||||
|
||||
TEST(NumSafeOp, WrappingDiv) {
|
||||
// Unsigned
|
||||
EXPECT_EQ(OP::wrapping_div<u32>(100, 10), UINT32_C(10));
|
||||
// Signed
|
||||
EXPECT_EQ(OP::wrapping_div<i32>(100, 10), INT32_C(10));
|
||||
EXPECT_EQ(OP::wrapping_div<i8>(-128, -1), INT32_C(-128));
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Checked operations
|
||||
|
||||
TEST(NumSafeOp, CheckedAdd) {
|
||||
// Unsigned
|
||||
{
|
||||
auto rv = OP::checked_add<u32>(MAX<u32> - 2, 1);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), MAX<u32> - 1);
|
||||
}
|
||||
{
|
||||
auto rv = OP::checked_add<u32>(MAX<u32> - 2, 3);
|
||||
EXPECT_FALSE(rv.has_value());
|
||||
}
|
||||
// Signed
|
||||
{
|
||||
auto rv = OP::checked_add<i32>(MAX<i32> - 2, 1);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), MAX<i32> - 1);
|
||||
}
|
||||
{
|
||||
auto rv = OP::checked_add<i32>(MAX<i32> - 2, 3);
|
||||
EXPECT_FALSE(rv.has_value());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NumSafeOp, CheckedSub) {
|
||||
// Unsigned
|
||||
{
|
||||
auto rv = OP::checked_sub<u32>(1, 1);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), 0);
|
||||
}
|
||||
{
|
||||
auto rv = OP::checked_sub<u32>(0, 1);
|
||||
EXPECT_FALSE(rv.has_value());
|
||||
}
|
||||
// Signed
|
||||
{
|
||||
auto rv = OP::checked_sub<i32>(MIN<i32> + 2, 1);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), MIN<i32> + 1);
|
||||
}
|
||||
{
|
||||
auto rv = OP::checked_sub<i32>(MIN<i32> + 2, 3);
|
||||
EXPECT_FALSE(rv.has_value());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NumSafeOp, CheckedMul) {
|
||||
// Unsigned
|
||||
{
|
||||
auto rv = OP::checked_mul<u32>(5, 1);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), 5);
|
||||
}
|
||||
{
|
||||
auto rv = OP::checked_mul<u32>(MAX<u32>, 2);
|
||||
EXPECT_FALSE(rv.has_value());
|
||||
}
|
||||
// Signed
|
||||
{
|
||||
auto rv = OP::checked_mul<i32>(MAX<i32>, 1);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), MAX<i32>);
|
||||
}
|
||||
{
|
||||
auto rv = OP::checked_mul<i32>(MAX<i32>, 2);
|
||||
EXPECT_FALSE(rv.has_value());
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NumSafeOp, CheckedDiv) {
|
||||
// Unsigned
|
||||
{
|
||||
auto rv = OP::checked_div<u32>(128, 2);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), 64);
|
||||
}
|
||||
{
|
||||
auto rv = OP::checked_div<u32>(1, 0);
|
||||
EXPECT_FALSE(rv.has_value());
|
||||
}
|
||||
// Signed
|
||||
{
|
||||
auto rv = OP::checked_div<i32>(MIN<i32> + 1, -1);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), INT32_C(2147483647));
|
||||
}
|
||||
{
|
||||
auto rv = OP::checked_div<i32>(MIN<i32>, -1);
|
||||
EXPECT_FALSE(rv.has_value());
|
||||
}
|
||||
{
|
||||
auto rv = OP::checked_div<i32>(1, 0);
|
||||
EXPECT_FALSE(rv.has_value());
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Overflowing operations
|
||||
|
||||
TEST(NumSafeOp, OverflowingAdd) {
|
||||
// Unsigned
|
||||
{
|
||||
auto rv = OP::overflowing_add<u32>(5, 2);
|
||||
EXPECT_EQ(rv.first, 7);
|
||||
EXPECT_EQ(rv.second, false);
|
||||
}
|
||||
{
|
||||
auto rv = OP::overflowing_add<u32>(MAX<u32>, 1);
|
||||
EXPECT_EQ(rv.first, 0);
|
||||
EXPECT_EQ(rv.second, true);
|
||||
}
|
||||
// Signed
|
||||
{
|
||||
auto rv = OP::overflowing_add<i32>(5, 2);
|
||||
EXPECT_EQ(rv.first, 7);
|
||||
EXPECT_EQ(rv.second, false);
|
||||
}
|
||||
{
|
||||
auto rv = OP::overflowing_add<i32>(MAX<i32>, 1);
|
||||
EXPECT_EQ(rv.first, MIN<i32>);
|
||||
EXPECT_EQ(rv.second, true);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NumSafeOp, OverflowingSub) {
|
||||
// Unsigned
|
||||
{
|
||||
auto rv = OP::overflowing_sub<u32>(5, 2);
|
||||
EXPECT_EQ(rv.first, 3);
|
||||
EXPECT_EQ(rv.second, false);
|
||||
}
|
||||
{
|
||||
auto rv = OP::overflowing_sub<u32>(0, 1);
|
||||
EXPECT_EQ(rv.first, MAX<u32>);
|
||||
EXPECT_EQ(rv.second, true);
|
||||
}
|
||||
// Signed
|
||||
{
|
||||
auto rv = OP::overflowing_sub<i32>(5, 2);
|
||||
EXPECT_EQ(rv.first, 3);
|
||||
EXPECT_EQ(rv.second, false);
|
||||
}
|
||||
{
|
||||
auto rv = OP::overflowing_sub<i32>(MIN<i32>, 1);
|
||||
EXPECT_EQ(rv.first, MAX<i32>);
|
||||
EXPECT_EQ(rv.second, true);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NumSafeOp, OverflowingMul) {
|
||||
// Unsigned
|
||||
{
|
||||
auto rv = OP::overflowing_mul<u32>(5, 2);
|
||||
EXPECT_EQ(rv.first, 10);
|
||||
EXPECT_EQ(rv.second, false);
|
||||
}
|
||||
{
|
||||
auto rv = OP::overflowing_mul<u32>(UINT32_C(1000000000), 10);
|
||||
EXPECT_EQ(rv.first, UINT32_C(1410065408));
|
||||
EXPECT_EQ(rv.second, true);
|
||||
}
|
||||
// Signed
|
||||
{
|
||||
auto rv = OP::overflowing_mul<i32>(5, 2);
|
||||
EXPECT_EQ(rv.first, 10);
|
||||
EXPECT_EQ(rv.second, false);
|
||||
}
|
||||
{
|
||||
auto rv = OP::overflowing_mul<i32>(INT32_C(1000000000), 10);
|
||||
EXPECT_EQ(rv.first, INT32_C(1410065408));
|
||||
EXPECT_EQ(rv.second, true);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(NumSafeOp, OverflowingDiv) {
|
||||
// Unsigned
|
||||
{
|
||||
auto rv = OP::overflowing_div<u32>(5, 2);
|
||||
EXPECT_EQ(rv.first, 2);
|
||||
EXPECT_EQ(rv.second, false);
|
||||
}
|
||||
// Signed
|
||||
{
|
||||
auto rv = OP::overflowing_div<i32>(5, 2);
|
||||
EXPECT_EQ(rv.first, 2);
|
||||
EXPECT_EQ(rv.second, false);
|
||||
}
|
||||
{
|
||||
auto rv = OP::overflowing_div<i32>(MIN<i32>, -1);
|
||||
EXPECT_EQ(rv.first, MIN<i32>);
|
||||
EXPECT_EQ(rv.second, true);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Saturating operations
|
||||
|
||||
TEST(NumSafeOp, SaturatingAdd) {
|
||||
// Unsigned
|
||||
EXPECT_EQ(OP::saturating_add<u32>(100, 1), UINT32_C(101));
|
||||
EXPECT_EQ(OP::saturating_add<u32>(MAX<u32>, 127), MAX<u32>);
|
||||
// Signed
|
||||
EXPECT_EQ(OP::saturating_add<i32>(100, 1), INT32_C(101));
|
||||
EXPECT_EQ(OP::saturating_add<i32>(MAX<i32>, 100), MAX<i32>);
|
||||
EXPECT_EQ(OP::saturating_add<i32>(MIN<i32>, -1), MIN<i32>);
|
||||
}
|
||||
|
||||
TEST(NumSafeOp, SaturatingSub) {
|
||||
// Unsigned
|
||||
EXPECT_EQ(OP::saturating_sub<u32>(100, 27), UINT32_C(73));
|
||||
EXPECT_EQ(OP::saturating_sub<u32>(13, 127), 0);
|
||||
// Signed
|
||||
EXPECT_EQ(OP::saturating_sub<i32>(100, 127), -27);
|
||||
EXPECT_EQ(OP::saturating_sub<i32>(MIN<i32>, 100), MIN<i32>);
|
||||
EXPECT_EQ(OP::saturating_sub<i32>(MAX<i32>, -1), MAX<i32>);
|
||||
}
|
||||
|
||||
TEST(NumSafeOp, SaturatingMul) {
|
||||
// Unsigned
|
||||
EXPECT_EQ(OP::saturating_mul<u32>(2, 10), UINT32_C(20));
|
||||
EXPECT_EQ(OP::saturating_mul<u32>(MAX<u32>, 10), MAX<u32>);
|
||||
// Signed
|
||||
EXPECT_EQ(OP::saturating_mul<i32>(10, 12), 120);
|
||||
EXPECT_EQ(OP::saturating_mul<i32>(MAX<i32>, 10), MAX<i32>);
|
||||
EXPECT_EQ(OP::saturating_mul<i32>(MIN<i32>, 10), MIN<i32>);
|
||||
}
|
||||
|
||||
TEST(NumSafeOp, SaturatingDiv) {
|
||||
// Unsigned
|
||||
EXPECT_EQ(OP::saturating_div<u32>(5, 2), UINT32_C(2));
|
||||
// Signed
|
||||
EXPECT_EQ(OP::saturating_div<i32>(5, 2), 2);
|
||||
EXPECT_EQ(OP::saturating_div<i32>(MAX<i32>, -1), MIN<i32> + 1);
|
||||
EXPECT_EQ(OP::saturating_div<i32>(MIN<i32>, -1), MAX<i32>);
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
} // namespace yycctest::num::safe_op
|
41
test/yycc/num/stringify.cpp
Normal file
41
test/yycc/num/stringify.cpp
Normal file
@ -0,0 +1,41 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/num/stringify.hpp>
|
||||
|
||||
#include <yycc/rust/prelude.hpp>
|
||||
|
||||
#define STRINGIFY ::yycc::num::stringify
|
||||
|
||||
namespace yycctest::num::stringify {
|
||||
|
||||
#define TEST_SUCCESS(type_t, value, string_value, ...) \
|
||||
{ \
|
||||
type_t cache = value; \
|
||||
std::u8string ret = STRINGIFY::stringify<type_t>(cache __VA_OPT__(,) __VA_ARGS__); \
|
||||
EXPECT_EQ(ret, string_value); \
|
||||
}
|
||||
|
||||
TEST(NumStringify, Common) {
|
||||
TEST_SUCCESS(i8, INT8_C(-61), u8"-61");
|
||||
TEST_SUCCESS(u8, UINT8_C(200), u8"200");
|
||||
TEST_SUCCESS(i16, INT16_C(6161), u8"6161");
|
||||
TEST_SUCCESS(u16, UINT16_C(32800), u8"32800");
|
||||
TEST_SUCCESS(i32, INT32_C(61616161), u8"61616161");
|
||||
TEST_SUCCESS(u32, UINT32_C(4294967293), u8"4294967293");
|
||||
TEST_SUCCESS(i64, INT64_C(616161616161), u8"616161616161");
|
||||
TEST_SUCCESS(u64, UINT64_C(9223372036854775807), u8"9223372036854775807");
|
||||
|
||||
TEST_SUCCESS(float, 1.0f, u8"1.0", std::chars_format::fixed, 1);
|
||||
TEST_SUCCESS(double, 1.0, u8"1.0", std::chars_format::fixed, 1);
|
||||
|
||||
TEST_SUCCESS(bool, true, u8"true");
|
||||
TEST_SUCCESS(bool, false, u8"false");
|
||||
}
|
||||
|
||||
TEST(NumStringify, Radix) {
|
||||
TEST_SUCCESS(u32, UINT32_C(0xffff), u8"ffff", 16);
|
||||
TEST_SUCCESS(u32, UINT32_C(032), u8"32", 8);
|
||||
TEST_SUCCESS(u32, UINT32_C(0B1011), u8"1011", 2);
|
||||
}
|
||||
|
||||
} // namespace yycctest::num::stringify
|
24
test/yycc/patch/fopen.cpp
Normal file
24
test/yycc/patch/fopen.cpp
Normal file
@ -0,0 +1,24 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/patch/fopen.hpp>
|
||||
|
||||
#define FOPEN ::yycc::patch::fopen
|
||||
|
||||
namespace yycctest::patch::fopen {
|
||||
|
||||
TEST(PatchFopen, Normal) {
|
||||
FILE* handle;
|
||||
|
||||
#if defined(YYCC_OS_WINDOWS)
|
||||
// In Windows, we can always visit NUL device.
|
||||
handle = FOPEN::fopen(u8"NUL", u8"wb");
|
||||
#else
|
||||
// In other system following UNIX design, we can visit /dev/null device.
|
||||
handle = FOPEN::fopen(u8"/dev/null", u8"wb");
|
||||
#endif
|
||||
|
||||
ASSERT_TRUE(handle != nullptr);
|
||||
std::fclose(handle);
|
||||
}
|
||||
|
||||
} // namespace yycctest::patch::fopen
|
35
test/yycc/patch/format.cpp
Normal file
35
test/yycc/patch/format.cpp
Normal file
@ -0,0 +1,35 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/patch/format.hpp>
|
||||
|
||||
#define FORMAT ::yycc::patch::format
|
||||
|
||||
namespace yycctest::patch::format {
|
||||
|
||||
static constexpr char8_t PROBE[] = u8"hello";
|
||||
static std::u8string PROBE_STRING(PROBE);
|
||||
static constexpr std::u8string_view PROBE_STRING_VIEW(PROBE);
|
||||
|
||||
TEST(PatchFormat, OrdinaryFormat) {
|
||||
auto rv = FORMAT::format("{:c}{}{}{}{}{} world!",
|
||||
PROBE[0],
|
||||
PROBE_STRING.data(),
|
||||
PROBE_STRING.c_str(),
|
||||
PROBE,
|
||||
PROBE_STRING,
|
||||
PROBE_STRING_VIEW);
|
||||
EXPECT_EQ(rv, "hhellohellohellohellohello world!");
|
||||
}
|
||||
|
||||
TEST(PatchFormat, Utf8Format) {
|
||||
auto rv = FORMAT::format(u8"{:c}{}{}{}{}{} world!",
|
||||
PROBE[0],
|
||||
PROBE_STRING.data(),
|
||||
PROBE_STRING.c_str(),
|
||||
PROBE,
|
||||
PROBE_STRING,
|
||||
PROBE_STRING_VIEW);
|
||||
EXPECT_EQ(rv, u8"hhellohellohellohellohello world!");
|
||||
}
|
||||
|
||||
}
|
21
test/yycc/patch/ptr_pad.cpp
Normal file
21
test/yycc/patch/ptr_pad.cpp
Normal file
@ -0,0 +1,21 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/string/op.hpp>
|
||||
#include <yycc/patch/ptr_pad.hpp>
|
||||
#include <cinttypes>
|
||||
|
||||
#define OP ::yycc::string::op
|
||||
|
||||
namespace yycctest::patch::ptr_pad {
|
||||
|
||||
TEST(PatchPtrPad, Normal) {
|
||||
auto rv = OP::printf(u8"0x%" PRIXPTR_LPAD PRIXPTR, nullptr);
|
||||
|
||||
#if defined(YYCC_PTRSIZE_32)
|
||||
EXPECT_EQ(rv, u8"0x00000000");
|
||||
#else
|
||||
EXPECT_EQ(rv, u8"0x0000000000000000");
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
31
test/yycc/patch/stream.cpp
Normal file
31
test/yycc/patch/stream.cpp
Normal file
@ -0,0 +1,31 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/patch/stream.hpp>
|
||||
#include <yycc/string/reinterpret.hpp>
|
||||
#include <sstream>
|
||||
|
||||
#define REINTERPRET ::yycc::string::reinterpret
|
||||
using namespace std::literals::string_view_literals;
|
||||
using namespace ::yycc::patch::stream;
|
||||
|
||||
namespace yycctest::patch::stream {
|
||||
|
||||
TEST(PatchStream, StringView) {
|
||||
std::stringstream ss;
|
||||
ss << u8"hello"sv;
|
||||
EXPECT_EQ(REINTERPRET::as_utf8_view(ss.view()), u8"hello"sv);
|
||||
}
|
||||
|
||||
TEST(PatchStream, CStrPtr) {
|
||||
std::stringstream ss;
|
||||
ss << u8"hello";
|
||||
EXPECT_EQ(REINTERPRET::as_utf8_view(ss.view()), u8"hello");
|
||||
}
|
||||
|
||||
TEST(PatchStream, Character) {
|
||||
std::stringstream ss;
|
||||
ss << u8'y';
|
||||
EXPECT_EQ(REINTERPRET::as_utf8_view(ss.view()), u8"y");
|
||||
}
|
||||
|
||||
}
|
45
test/yycc/rust/env.cpp
Normal file
45
test/yycc/rust/env.cpp
Normal file
@ -0,0 +1,45 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/rust/env.hpp>
|
||||
|
||||
#define ENV ::yycc::rust::env
|
||||
|
||||
namespace yycctest::rust::env {
|
||||
|
||||
constexpr char8_t VAR_NAME[] = u8"HOMER";
|
||||
constexpr char8_t VAR_VALUE[] = u8"doh";
|
||||
|
||||
TEST(RustEnv, All) {
|
||||
// Write a new variable should okey
|
||||
{
|
||||
auto rv = ENV::set_var(VAR_NAME, VAR_VALUE);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
}
|
||||
|
||||
// After writing, we can fetch it and check its value.
|
||||
{
|
||||
auto rv = ENV::get_var(VAR_NAME);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
EXPECT_EQ(rv.value(), VAR_VALUE);
|
||||
}
|
||||
|
||||
// The we can delete it.
|
||||
{
|
||||
auto rv = ENV::del_var(VAR_NAME);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
}
|
||||
|
||||
// Delete inexisting variable also should be okey
|
||||
{
|
||||
auto rv = ENV::del_var(VAR_NAME);
|
||||
ASSERT_TRUE(rv.has_value());
|
||||
}
|
||||
|
||||
// After deleting, we can not fetch it anymore.
|
||||
{
|
||||
auto rv = ENV::get_var(VAR_NAME);
|
||||
ASSERT_FALSE(rv.has_value());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
143
test/yycc/string/op.cpp
Normal file
143
test/yycc/string/op.cpp
Normal file
@ -0,0 +1,143 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/string/op.hpp>
|
||||
|
||||
#include <yycc/rust/prelude.hpp>
|
||||
|
||||
#define OP ::yycc::string::op
|
||||
using namespace std::literals::string_view_literals;
|
||||
|
||||
namespace yycctest::string::op {
|
||||
|
||||
TEST(StringOp, Printf) {
|
||||
// UTF8 string
|
||||
{
|
||||
auto rv = OP::printf(u8"%s == %s", u8"Hello World", u8"Hello, world");
|
||||
EXPECT_EQ(rv, u8"Hello World == Hello, world");
|
||||
}
|
||||
// Ordinary string
|
||||
{
|
||||
auto rv = OP::printf("%s == %s", "Hello World", "Hello, world");
|
||||
EXPECT_EQ(rv, "Hello World == Hello, world");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(StringOp, Replace) {
|
||||
// Normal case
|
||||
{
|
||||
auto rv = OP::replace(u8"aabbcc", u8"bb", u8"dd");
|
||||
EXPECT_EQ(rv, u8"aaddcc");
|
||||
}
|
||||
// No matched expected string
|
||||
{
|
||||
auto rv = OP::replace(u8"aabbcc", u8"zz", u8"yy");
|
||||
EXPECT_EQ(rv, u8"aabbcc");
|
||||
}
|
||||
// Empty expected string
|
||||
{
|
||||
auto rv = OP::replace(u8"aabbcc", std::u8string_view(), u8"zz");
|
||||
EXPECT_EQ(rv, u8"aabbcc");
|
||||
}
|
||||
// Empty replace string
|
||||
{
|
||||
auto rv = OP::replace(u8"aaaabbaa", u8"aa", u8"");
|
||||
EXPECT_EQ(rv, u8"bb");
|
||||
}
|
||||
// Nested replacing
|
||||
{
|
||||
auto rv = OP::replace(u8"aaxcc", u8"x", u8"yx");
|
||||
EXPECT_EQ(rv, u8"aayxcc");
|
||||
}
|
||||
// Empty source string
|
||||
{
|
||||
auto rv = OP::replace(std::u8string_view(), u8"", u8"xy");
|
||||
EXPECT_EQ(rv, u8"");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(StringOp, Lower) {
|
||||
auto rv = OP::to_lower(u8"LOWER");
|
||||
EXPECT_EQ(rv, u8"lower");
|
||||
}
|
||||
|
||||
TEST(StringOp, Upper) {
|
||||
auto rv = OP::to_upper(u8"upper");
|
||||
EXPECT_EQ(rv, u8"UPPER");
|
||||
}
|
||||
|
||||
TEST(StringOp, Join) {
|
||||
std::vector<std::u8string_view> datas{u8""sv, u8"1"sv, u8"2"sv, u8""sv};
|
||||
auto rv = OP::join(datas.begin(), datas.end(), u8", ");
|
||||
EXPECT_EQ(rv, u8", 1, 2, ");
|
||||
}
|
||||
|
||||
TEST(StringOp, Strip) {
|
||||
// Normal strip
|
||||
{
|
||||
auto rv = OP::strip(u8" \taaa\n", u8" \t\r\n");
|
||||
EXPECT_EQ(rv, u8"aaa");
|
||||
}
|
||||
{
|
||||
auto rv = OP::lstrip(u8" \taaa\n", u8" \t\r\n");
|
||||
EXPECT_EQ(rv, u8"aaa\n");
|
||||
}
|
||||
{
|
||||
auto rv = OP::rstrip(u8" \taaa\n", u8" \t\r\n");
|
||||
EXPECT_EQ(rv, u8" \taaa");
|
||||
}
|
||||
|
||||
// Special strip
|
||||
{
|
||||
auto rv = OP::strip(u8"啊啊啊aaaあああ", u8"啊あ");
|
||||
EXPECT_EQ(rv, u8"aaa");
|
||||
}
|
||||
{
|
||||
auto rv = OP::strip(u8"啊啊啊aaaあああ", u8"啊");
|
||||
EXPECT_EQ(rv, u8"aaaあああ");
|
||||
}
|
||||
{
|
||||
auto rv = OP::strip(u8"啊啊啊aaaあああ", u8"あ");
|
||||
EXPECT_EQ(rv, u8"啊啊啊aaa");
|
||||
}
|
||||
|
||||
// Possible buggy strip.
|
||||
// We use 2 UTF8 code points introduced following:
|
||||
// U+00AA (UTF-8: C2 AA)
|
||||
// U+1002A (UTF-8 : F0 90 80 AA)
|
||||
{
|
||||
auto rv = OP::rstrip(u8"aaa\u00AA", u8"\u00AA\U0001002A");
|
||||
EXPECT_EQ(rv, u8"aaa");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(StringOp, Split) {
|
||||
// Normal
|
||||
{
|
||||
auto rv = OP::split(u8", 1, 2, ", u8", ");
|
||||
ASSERT_EQ(rv.size(), 4u);
|
||||
EXPECT_EQ(rv[0], u8"");
|
||||
EXPECT_EQ(rv[1], u8"1");
|
||||
EXPECT_EQ(rv[2], u8"2");
|
||||
EXPECT_EQ(rv[3], u8"");
|
||||
}
|
||||
// No matched delimiter
|
||||
{
|
||||
auto rv = OP::split(u8"test", u8"-");
|
||||
ASSERT_EQ(rv.size(), 1u);
|
||||
EXPECT_EQ(rv[0], u8"test");
|
||||
}
|
||||
// Empty delimiter
|
||||
{
|
||||
auto rv = OP::split(u8"test", std::u8string_view());
|
||||
ASSERT_EQ(rv.size(), 1u);
|
||||
EXPECT_EQ(rv[0], u8"test");
|
||||
}
|
||||
// Empty source string
|
||||
{
|
||||
auto rv = OP::split(std::u8string_view(), u8"");
|
||||
ASSERT_EQ(rv.size(), 1u);
|
||||
EXPECT_TRUE(rv[0].empty());
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace yycctest::string::op
|
71
test/yycc/string/reinterpret.cpp
Normal file
71
test/yycc/string/reinterpret.cpp
Normal file
@ -0,0 +1,71 @@
|
||||
#include <cstring>
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/string/reinterpret.hpp>
|
||||
|
||||
#include <yycc/rust/prelude.hpp>
|
||||
|
||||
#define REINTERPRET ::yycc::string::reinterpret
|
||||
#define AS_UINT8(p) static_cast<u8>(p)
|
||||
#define CONST_VOID_PTR(p) reinterpret_cast<const void*>(p)
|
||||
#define VOID_PTR(p) reinterpret_cast<void*>(p)
|
||||
|
||||
namespace yycctest::string::reinterpret {
|
||||
|
||||
static std::u8string PROBE(u8"Test");
|
||||
|
||||
TEST(StringReinterpret, Character) {
|
||||
const auto& src = PROBE[0];
|
||||
const auto dst = REINTERPRET::as_ordinary(src);
|
||||
const auto new_src = REINTERPRET::as_utf8(dst);
|
||||
|
||||
// Value should be the same after casting.
|
||||
EXPECT_EQ(AS_UINT8(src), AS_UINT8(dst));
|
||||
EXPECT_EQ(AS_UINT8(src), AS_UINT8(new_src));
|
||||
}
|
||||
|
||||
TEST(StringReinterpret, ConstPointer) {
|
||||
const auto* src = PROBE.data();
|
||||
const auto* dst = REINTERPRET::as_ordinary(src);
|
||||
const auto* new_src = REINTERPRET::as_utf8(dst);
|
||||
|
||||
// Pointer should point to the same address after casting.
|
||||
EXPECT_EQ(CONST_VOID_PTR(src), CONST_VOID_PTR(dst));
|
||||
EXPECT_EQ(CONST_VOID_PTR(src), CONST_VOID_PTR(new_src));
|
||||
}
|
||||
|
||||
TEST(StringReinterpret, Pointer) {
|
||||
auto* src = PROBE.data();
|
||||
auto* dst = REINTERPRET::as_ordinary(src);
|
||||
auto* new_src = REINTERPRET::as_utf8(dst);
|
||||
|
||||
// Pointer should point to the same address after casting.
|
||||
EXPECT_EQ(VOID_PTR(src), VOID_PTR(dst));
|
||||
EXPECT_EQ(VOID_PTR(src), VOID_PTR(new_src));
|
||||
}
|
||||
|
||||
TEST(StringReinterpret, StlString) {
|
||||
auto src = std::u8string(PROBE);
|
||||
auto dst = REINTERPRET::as_ordinary(src);
|
||||
auto new_src = REINTERPRET::as_utf8(dst);
|
||||
|
||||
// Check memory length and data.
|
||||
ASSERT_EQ(src.length(), dst.length());
|
||||
EXPECT_TRUE(std::memcmp(src.data(), dst.data(), src.length()) == 0);
|
||||
ASSERT_EQ(src.length(), new_src.length());
|
||||
EXPECT_TRUE(std::memcmp(src.data(), new_src.data(), src.length()) == 0);
|
||||
}
|
||||
|
||||
TEST(StringReinterpret, StlStringView) {
|
||||
auto src = std::u8string_view(PROBE);
|
||||
auto dst = REINTERPRET::as_ordinary_view(src);
|
||||
auto new_src = REINTERPRET::as_utf8_view(dst);
|
||||
|
||||
// Check memory length and data.
|
||||
ASSERT_EQ(src.length(), dst.length());
|
||||
EXPECT_TRUE(std::memcmp(src.data(), dst.data(), src.length()) == 0);
|
||||
ASSERT_EQ(src.length(), new_src.length());
|
||||
EXPECT_TRUE(std::memcmp(src.data(), new_src.data(), src.length()) == 0);
|
||||
}
|
||||
|
||||
} // namespace yycctest::string::reinterpret
|
16
test/yycc/windows/com.cpp
Normal file
16
test/yycc/windows/com.cpp
Normal file
@ -0,0 +1,16 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/windows/com.hpp>
|
||||
|
||||
#define COM ::yycc::windows::com
|
||||
|
||||
namespace yycctest::windows::com {
|
||||
#if defined(YYCC_OS_WINDOWS) && defined(YYCC_STL_MSSTL)
|
||||
|
||||
TEST(WindowsCom, IsInitialized) {
|
||||
// COM environment should always be ready.
|
||||
EXPECT_TRUE(COM::is_initialized());
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
17
test/yycc/windows/console.cpp
Normal file
17
test/yycc/windows/console.cpp
Normal file
@ -0,0 +1,17 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/windows/console.hpp>
|
||||
|
||||
#define CONSOLE ::yycc::windows::console
|
||||
|
||||
namespace yycctest::windows::console {
|
||||
#if defined(YYCC_OS_WINDOWS) && defined(YYCC_STL_MSSTL)
|
||||
|
||||
TEST(WindowsConsole, ColorfulConsole) {
|
||||
// Set colorful console should always be success.
|
||||
auto rv = CONSOLE::colorful_console();
|
||||
EXPECT_TRUE(rv.has_value());
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
55
test/yycc/windows/dialog.cpp
Normal file
55
test/yycc/windows/dialog.cpp
Normal file
@ -0,0 +1,55 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/windows/dialog.hpp>
|
||||
|
||||
#define DIALOG ::yycc::windows::dialog
|
||||
|
||||
namespace yycctest::windows::dialog {
|
||||
#if defined(YYCC_OS_WINDOWS) && defined(YYCC_STL_MSSTL)
|
||||
|
||||
TEST(WindowsDialog, Normal) {
|
||||
// TODO:
|
||||
// I temporaryly disable all dialog open functions in this function after testing them.
|
||||
// Because they need human to operate them to finish the test.
|
||||
// Once I find a better way to do automatic test (maybe send message to these dialogs to close them?)
|
||||
// I will add them back.
|
||||
|
||||
// Prepare parameters
|
||||
DIALOG::FileDialog params;
|
||||
auto& filters = params.configre_file_types();
|
||||
filters.add_filter(u8"Microsoft Word (*.docx; *.doc)", {u8"*.docx", u8"*.doc"});
|
||||
filters.add_filter(u8"Microsoft Excel (*.xlsx; *.xls)", {u8"*.xlsx", u8"*.xls"});
|
||||
filters.add_filter(u8"Microsoft PowerPoint (*.pptx; *.ppt)", {u8"*.pptx", u8"*.ppt"});
|
||||
filters.add_filter(u8"Text File (*.txt)", {u8"*.txt"});
|
||||
filters.add_filter(u8"All Files (*.*)", {u8"*.*"});
|
||||
params.set_default_file_type_index(1u);
|
||||
|
||||
//// Open file
|
||||
//{
|
||||
// auto rv = DIALOG::open_file(params);
|
||||
// EXPECT_TRUE(rv.has_value());
|
||||
//}
|
||||
//// Open files
|
||||
//{
|
||||
// auto rv = DIALOG::open_files(params);
|
||||
// EXPECT_TRUE(rv.has_value());
|
||||
//}
|
||||
//// Save file
|
||||
//{
|
||||
// auto rv = DIALOG::save_file(params);
|
||||
// EXPECT_TRUE(rv.has_value());
|
||||
//}
|
||||
|
||||
// Clear file filters for following operations
|
||||
params.clear();
|
||||
params.set_default_file_type_index(0u);
|
||||
|
||||
//// Open folder
|
||||
//{
|
||||
// auto rv = DIALOG::open_folder(params);
|
||||
// EXPECT_TRUE(rv.has_value());
|
||||
//}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
49
test/yycc/windows/winfct.cpp
Normal file
49
test/yycc/windows/winfct.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <yycc.hpp>
|
||||
#include <yycc/windows/winfct.hpp>
|
||||
|
||||
#define WINFCT ::yycc::windows::winfct
|
||||
|
||||
namespace yycctest::windows::winfct {
|
||||
#if defined(YYCC_OS_WINDOWS)
|
||||
|
||||
TEST(WindowsWinFct, GetCurrentModule) {
|
||||
auto rv = WINFCT::get_current_module();
|
||||
EXPECT_TRUE(rv.has_value());
|
||||
}
|
||||
|
||||
TEST(WindowsWinFct, GetTempDirectory) {
|
||||
auto rv = WINFCT::get_temp_directory();
|
||||
EXPECT_TRUE(rv.has_value());
|
||||
}
|
||||
|
||||
TEST(WindowsWinFct, GetModuleFileName) {
|
||||
auto handle = WINFCT::get_current_module();
|
||||
ASSERT_TRUE(handle.has_value());
|
||||
|
||||
auto rv = WINFCT::get_module_file_name(handle.value());
|
||||
EXPECT_TRUE(rv.has_value());
|
||||
}
|
||||
|
||||
TEST(WindowsWinFct, IsValidCodePage) {
|
||||
// Test valid code page
|
||||
EXPECT_TRUE(WINFCT::is_valid_code_page(437));
|
||||
EXPECT_TRUE(WINFCT::is_valid_code_page(65001));
|
||||
// This code page must be invalid
|
||||
EXPECT_FALSE(WINFCT::is_valid_code_page(6161));
|
||||
}
|
||||
|
||||
#if defined(YYCC_STL_MSSTL)
|
||||
|
||||
TEST(WindowsWinFct, GetKnownPath) {
|
||||
auto rv = WINFCT::get_known_path(WINFCT::KnownDirectory::LocalAppData);
|
||||
EXPECT_TRUE(rv.has_value());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// YYC MARK:
|
||||
// I can't test CopyFile, MoveFile and DeleteFile.
|
||||
|
||||
#endif
|
||||
} // namespace yycctest::windows::winfct
|
Reference in New Issue
Block a user