mirror of
https://github.com/thunderbrewhq/squall.git
synced 2026-02-04 16:59:08 +00:00
1149 lines
49 KiB
C++
1149 lines
49 KiB
C++
#include "storm/Unicode.hpp"
|
||
#include "storm/String.hpp"
|
||
#include "test/Test.hpp"
|
||
#include <algorithm>
|
||
|
||
constexpr uint32_t RESULT_STR_SIZE = 100;
|
||
|
||
static std::pair<std::u16string, std::string> make_testcase(const std::u16string& strA, const std::string& strB) {
|
||
return std::make_pair(strA, strB);
|
||
}
|
||
|
||
TEST_CASE("SUniConvertUTF16ToDos", "[unicode]") {
|
||
SECTION("does nothing on empty dest size") {
|
||
auto result = SUniConvertUTF16ToDos(nullptr, nullptr, 0);
|
||
CHECK(result == 0);
|
||
}
|
||
|
||
SECTION("operates on empty string") {
|
||
char resultStr[RESULT_STR_SIZE];
|
||
const char16_t str[] = u"";
|
||
|
||
auto result = SUniConvertUTF16ToDos(resultStr, str, RESULT_STR_SIZE);
|
||
CHECK(std::string(resultStr) == "");
|
||
CHECK(result == 1); // wrote 1 null terminator
|
||
}
|
||
|
||
SECTION("translates ASCII string") {
|
||
char resultStr[RESULT_STR_SIZE];
|
||
const char16_t str[] = u"Quick lazy brown fox or something";
|
||
|
||
auto result = SUniConvertUTF16ToDos(resultStr, str, RESULT_STR_SIZE);
|
||
CHECK(std::string(resultStr) == "Quick lazy brown fox or something");
|
||
CHECK(result == 34);
|
||
}
|
||
|
||
SECTION("fails to write null terminator if string isn't long enough") {
|
||
char resultStr[RESULT_STR_SIZE];
|
||
std::fill(std::begin(resultStr), std::end(resultStr), 0xCC);
|
||
const char16_t str[] = u"Quick lazy brown fox or something";
|
||
|
||
auto result = SUniConvertUTF16ToDos(resultStr, str, 5);
|
||
CHECK(std::string(resultStr, 5) == "Quick");
|
||
CHECK(static_cast<uint8_t>(resultStr[5]) == 0xCC);
|
||
CHECK(result == 5);
|
||
}
|
||
|
||
SECTION("writes ??? on unsupported characters") {
|
||
char resultStr[RESULT_STR_SIZE];
|
||
const char16_t str[] = u"\u8080\u8080lol\u8080\u8080\u8080";
|
||
|
||
auto result = SUniConvertUTF16ToDos(resultStr, str, RESULT_STR_SIZE);
|
||
CHECK(std::string(resultStr) == "??lol???");
|
||
CHECK(result == 9);
|
||
}
|
||
|
||
SECTION("translates shared ASCII characters") {
|
||
for (int i = 1; i < 128; i++) {
|
||
char16_t str[2] = { static_cast<char16_t>(i) };
|
||
char resultStr[2];
|
||
|
||
auto result = SUniConvertUTF16ToDos(resultStr, str, 2);
|
||
INFO(i);
|
||
CHECK(resultStr[0] == static_cast<char>(i));
|
||
CHECK(resultStr[1] == '\0');
|
||
CHECK(result == 2);
|
||
}
|
||
}
|
||
|
||
SECTION("translates special characters") {
|
||
auto testCase = GENERATE(
|
||
make_testcase(u"\u00C7", "\x80"), // Ç
|
||
make_testcase(u"\u00FC", "\x81"), // ü
|
||
make_testcase(u"\u00E9", "\x82"), // é
|
||
make_testcase(u"\u00E2", "\x83"), // â
|
||
make_testcase(u"\u00E4", "\x84"), // ä
|
||
make_testcase(u"\u00E0", "\x85"), // à
|
||
make_testcase(u"\u00E5", "\x86"), // å
|
||
make_testcase(u"\u00E7", "\x87"), // ç
|
||
make_testcase(u"\u00EA", "\x88"), // ê
|
||
make_testcase(u"\u00EB", "\x89"), // ë
|
||
make_testcase(u"\u00E8", "\x8A"), // è
|
||
make_testcase(u"\u00EF", "\x8B"), // ï
|
||
make_testcase(u"\u00EE", "\x8C"), // î
|
||
make_testcase(u"\u00EC", "\x8D"), // ì
|
||
make_testcase(u"\u00C4", "\x8E"), // Ä
|
||
make_testcase(u"\u00C5", "\x8F"), // Å
|
||
make_testcase(u"\u00C9", "\x90"), // É
|
||
make_testcase(u"\u00E6", "\x91"), // æ
|
||
make_testcase(u"\u00C6", "\x92"), // Æ
|
||
make_testcase(u"\u00F4", "\x93"), // ô
|
||
make_testcase(u"\u00F6", "\x94"), // ö
|
||
make_testcase(u"\u00F2", "\x95"), // ò
|
||
make_testcase(u"\u00FB", "\x96"), // û
|
||
make_testcase(u"\u00F9", "\x97"), // ù
|
||
make_testcase(u"\u00FF", "\x98"), // ÿ
|
||
make_testcase(u"\u00D6", "\x99"), // Ö
|
||
make_testcase(u"\u00DC", "\x9A"), // Ü
|
||
make_testcase(u"\u00A2", "\x9B"), // ¢
|
||
make_testcase(u"\u00A3", "\x9C"), // £
|
||
make_testcase(u"\u00A5", "\x9D"), // ¥
|
||
make_testcase(u"\u20A7", "\x9E"), // ₧
|
||
make_testcase(u"\u0192", "\x9F"), // ƒ
|
||
make_testcase(u"\u00E1", "\xA0"), // á
|
||
make_testcase(u"\u00ED", "\xA1"), // í
|
||
make_testcase(u"\u00F3", "\xA2"), // ó
|
||
make_testcase(u"\u00FA", "\xA3"), // ú
|
||
make_testcase(u"\u00F1", "\xA4"), // ñ
|
||
make_testcase(u"\u00D1", "\xA5"), // Ñ
|
||
make_testcase(u"\u00AA", "\xA6"), // ª
|
||
make_testcase(u"\u00BA", "\xA7"), // º
|
||
make_testcase(u"\u00BF", "\xA8"), // ¿
|
||
make_testcase(u"\u2310", "\xA9"), // ⌐
|
||
make_testcase(u"\u00AC", "\xAA"), // ¬
|
||
make_testcase(u"\u00BD", "\xAB"), // ½
|
||
make_testcase(u"\u00BC", "\xAC"), // ¼
|
||
make_testcase(u"\u00A1", "\xAD"), // ¡
|
||
make_testcase(u"\u00AB", "\xAE"), // «
|
||
make_testcase(u"\u00BB", "\xAF"), // »
|
||
make_testcase(u"\u2591", "\xB0"), // ░
|
||
make_testcase(u"\u2592", "\xB1"), // ▒
|
||
make_testcase(u"\u2593", "\xB2"), // ▓
|
||
make_testcase(u"\u2502", "\xB3"), // │
|
||
make_testcase(u"\u2524", "\xB4"), // ┤
|
||
make_testcase(u"\u2561", "\xB5"), // ╡
|
||
make_testcase(u"\u2562", "\xB6"), // ╢
|
||
make_testcase(u"\u2556", "\xB7"), // ╖
|
||
make_testcase(u"\u2555", "\xB8"), // ╕
|
||
make_testcase(u"\u2563", "\xB9"), // ╣
|
||
make_testcase(u"\u2551", "\xBA"), // ║
|
||
make_testcase(u"\u2557", "\xBB"), // ╗
|
||
make_testcase(u"\u255D", "\xBC"), // ╝
|
||
make_testcase(u"\u255C", "\xBD"), // ╜
|
||
make_testcase(u"\u255B", "\xBE"), // ╛
|
||
make_testcase(u"\u2510", "\xBF"), // ┐
|
||
make_testcase(u"\u2514", "\xC0"), // └
|
||
make_testcase(u"\u2534", "\xC1"), // ┴
|
||
make_testcase(u"\u252C", "\xC2"), // ┬
|
||
make_testcase(u"\u251C", "\xC3"), // ├
|
||
make_testcase(u"\u2500", "\xC4"), // ─
|
||
make_testcase(u"\u253C", "\xC5"), // ┼
|
||
make_testcase(u"\u255E", "\xC6"), // ╞
|
||
make_testcase(u"\u255F", "\xC7"), // ╟
|
||
make_testcase(u"\u255A", "\xC8"), // ╚
|
||
make_testcase(u"\u2554", "\xC9"), // ╔
|
||
make_testcase(u"\u2569", "\xCA"), // ╩
|
||
make_testcase(u"\u2566", "\xCB"), // ╦
|
||
make_testcase(u"\u2560", "\xCC"), // ╠
|
||
make_testcase(u"\u2550", "\xCD"), // ═
|
||
make_testcase(u"\u256C", "\xCE"), // ╬
|
||
make_testcase(u"\u2567", "\xCF"), // ╧
|
||
make_testcase(u"\u2568", "\xD0"), // ╨
|
||
make_testcase(u"\u2564", "\xD1"), // ╤
|
||
make_testcase(u"\u2565", "\xD2"), // ╥
|
||
make_testcase(u"\u2559", "\xD3"), // ╙
|
||
make_testcase(u"\u2558", "\xD4"), // ╘
|
||
make_testcase(u"\u2552", "\xD5"), // ╒
|
||
make_testcase(u"\u2553", "\xD6"), // ╓
|
||
make_testcase(u"\u256B", "\xD7"), // ╫
|
||
make_testcase(u"\u256A", "\xD8"), // ╪
|
||
make_testcase(u"\u2518", "\xD9"), // ┘
|
||
make_testcase(u"\u250C", "\xDA"), // ┌
|
||
make_testcase(u"\u2588", "\xDB"), // █
|
||
make_testcase(u"\u2584", "\xDC"), // ▄
|
||
make_testcase(u"\u258C", "\xDD"), // ▌
|
||
make_testcase(u"\u2590", "\xDE"), // ▐
|
||
make_testcase(u"\u2580", "\xDF"), // ▀
|
||
make_testcase(u"\u03B1", "\xE0"), // α
|
||
make_testcase(u"\u00DF", "\xE1"), // ß
|
||
make_testcase(u"\u0393", "\xE2"), // Γ
|
||
make_testcase(u"\u03C0", "\xE3"), // π
|
||
make_testcase(u"\u03A3", "\xE4"), // Σ
|
||
make_testcase(u"\u03C3", "\xE5"), // σ
|
||
make_testcase(u"\u00B5", "\xE6"), // µ
|
||
make_testcase(u"\u03C4", "\xE7"), // τ
|
||
make_testcase(u"\u03A6", "\xE8"), // Φ
|
||
make_testcase(u"\u0398", "\xE9"), // Θ
|
||
make_testcase(u"\u03A9", "\xEA"), // Ω
|
||
make_testcase(u"\u03B4", "\xEB"), // δ
|
||
make_testcase(u"\u221E", "\xEC"), // ∞
|
||
make_testcase(u"\u03C6", "\xED"), // φ
|
||
make_testcase(u"\u03B5", "\xEE"), // ε
|
||
make_testcase(u"\u2229", "\xEF"), // ∩
|
||
make_testcase(u"\u2261", "\xF0"), // ≡
|
||
make_testcase(u"\u00B1", "\xF1"), // ±
|
||
make_testcase(u"\u2265", "\xF2"), // ≥
|
||
make_testcase(u"\u2264", "\xF3"), // ≤
|
||
make_testcase(u"\u2320", "\xF4"), // ⌠
|
||
make_testcase(u"\u2321", "\xF5"), // ⌡
|
||
make_testcase(u"\u00F7", "\xF6"), // ÷
|
||
make_testcase(u"\u2248", "\xF7"), // ≈
|
||
make_testcase(u"\u00B0", "\xF8"), // °
|
||
make_testcase(u"\u2219", "\xF9"), // ∙
|
||
make_testcase(u"\u00B7", "\xFA"), // ·
|
||
make_testcase(u"\u221A", "\xFB"), // √
|
||
make_testcase(u"\u207F", "\xFC"), // ⁿ
|
||
make_testcase(u"\u00B2", "\xFD"), // ²
|
||
make_testcase(u"\u25A0", "\xFE"), // ■
|
||
make_testcase(u"\u00A0", "\xFF") // r
|
||
);
|
||
|
||
char resultStr[2];
|
||
auto result = SUniConvertUTF16ToDos(resultStr, testCase.first.c_str(), 2);
|
||
|
||
INFO(testCase.second);
|
||
CHECK(std::string(resultStr) == testCase.second);
|
||
CHECK(result == 2);
|
||
}
|
||
}
|
||
|
||
TEST_CASE("SUniConvertUTF16ToMac", "[unicode]") {
|
||
SECTION("does nothing on empty dest size") {
|
||
auto result = SUniConvertUTF16ToMac(nullptr, nullptr, 0);
|
||
CHECK(result == 0);
|
||
}
|
||
|
||
SECTION("operates on empty string") {
|
||
char resultStr[RESULT_STR_SIZE];
|
||
const char16_t str[] = u"";
|
||
|
||
auto result = SUniConvertUTF16ToMac(resultStr, str, RESULT_STR_SIZE);
|
||
CHECK(std::string(resultStr) == "");
|
||
CHECK(result == 1); // wrote 1 null terminator
|
||
}
|
||
|
||
SECTION("translates ASCII string") {
|
||
char resultStr[RESULT_STR_SIZE];
|
||
const char16_t str[] = u"Quick lazy brown fox or something";
|
||
|
||
auto result = SUniConvertUTF16ToMac(resultStr, str, RESULT_STR_SIZE);
|
||
CHECK(std::string(resultStr) == "Quick lazy brown fox or something");
|
||
CHECK(result == 34);
|
||
}
|
||
|
||
SECTION("fails to write null terminator if string isn't long enough") {
|
||
char resultStr[RESULT_STR_SIZE];
|
||
std::fill(std::begin(resultStr), std::end(resultStr), 0xCC);
|
||
const char16_t str[] = u"Quick lazy brown fox or something";
|
||
|
||
auto result = SUniConvertUTF16ToMac(resultStr, str, 5);
|
||
CHECK(std::string(resultStr, 5) == "Quick");
|
||
CHECK(static_cast<uint8_t>(resultStr[5]) == 0xCC);
|
||
CHECK(result == 5);
|
||
}
|
||
|
||
SECTION("writes ??? on unsupported characters") {
|
||
char resultStr[RESULT_STR_SIZE];
|
||
const char16_t str[] = u"\u8080\u8080lol\u8080\u8080\u8080";
|
||
|
||
auto result = SUniConvertUTF16ToMac(resultStr, str, RESULT_STR_SIZE);
|
||
CHECK(std::string(resultStr) == "??lol???");
|
||
CHECK(result == 9);
|
||
}
|
||
|
||
SECTION("translates shared ASCII characters") {
|
||
for (int i = 1; i < 128; i++) {
|
||
char16_t str[2] = { static_cast<char16_t>(i) };
|
||
char resultStr[2];
|
||
|
||
auto result = SUniConvertUTF16ToMac(resultStr, str, 2);
|
||
INFO(i);
|
||
CHECK(resultStr[0] == static_cast<char>(i));
|
||
CHECK(resultStr[1] == '\0');
|
||
CHECK(result == 2);
|
||
}
|
||
}
|
||
|
||
SECTION("translates special characters") {
|
||
auto testCase = GENERATE(
|
||
make_testcase(u"\u00C4", "\x80"), // Ä
|
||
make_testcase(u"\u00C5", "\x81"), // Å
|
||
make_testcase(u"\u00C7", "\x82"), // Ç
|
||
make_testcase(u"\u00C9", "\x83"), // É
|
||
make_testcase(u"\u00D1", "\x84"), // Ñ
|
||
make_testcase(u"\u00D6", "\x85"), // Ö
|
||
make_testcase(u"\u00DC", "\x86"), // Ü
|
||
make_testcase(u"\u00E1", "\x87"), // á
|
||
make_testcase(u"\u00E0", "\x88"), // à
|
||
make_testcase(u"\u00E2", "\x89"), // â
|
||
make_testcase(u"\u00E4", "\x8A"), // ä
|
||
make_testcase(u"\u00E3", "\x8B"), // ã
|
||
make_testcase(u"\u00E5", "\x8C"), // å
|
||
make_testcase(u"\u00E7", "\x8D"), // ç
|
||
make_testcase(u"\u00E9", "\x8E"), // é
|
||
make_testcase(u"\u00E8", "\x8F"), // è
|
||
make_testcase(u"\u00EA", "\x90"), // ê
|
||
make_testcase(u"\u00EB", "\x91"), // ë
|
||
make_testcase(u"\u00ED", "\x92"), // í
|
||
make_testcase(u"\u00EC", "\x93"), // ì
|
||
make_testcase(u"\u00EE", "\x94"), // î
|
||
make_testcase(u"\u00EF", "\x95"), // ï
|
||
make_testcase(u"\u00F1", "\x96"), // ñ
|
||
make_testcase(u"\u00F3", "\x97"), // ó
|
||
make_testcase(u"\u00F2", "\x98"), // ò
|
||
make_testcase(u"\u00F4", "\x99"), // ô
|
||
make_testcase(u"\u00F6", "\x9A"), // ö
|
||
make_testcase(u"\u00F5", "\x9B"), // õ
|
||
make_testcase(u"\u00FA", "\x9C"), // ú
|
||
make_testcase(u"\u00F9", "\x9D"), // ù
|
||
make_testcase(u"\u00FB", "\x9E"), // û
|
||
make_testcase(u"\u00FC", "\x9F"), // ü
|
||
make_testcase(u"\u2020", "\xA0"), // †
|
||
make_testcase(u"\u00B0", "\xA1"), // °
|
||
make_testcase(u"\u00A2", "\xA2"), // ¢
|
||
make_testcase(u"\u00A3", "\xA3"), // £
|
||
make_testcase(u"\u00A7", "\xA4"), // §
|
||
make_testcase(u"\u2022", "\xA5"), // •
|
||
make_testcase(u"\u00B6", "\xA6"), // ¶
|
||
make_testcase(u"\u00DF", "\xA7"), // ß
|
||
make_testcase(u"\u00AE", "\xA8"), // ®
|
||
make_testcase(u"\u00A9", "\xA9"), // ©
|
||
make_testcase(u"\u2122", "\xAA"), // ™
|
||
make_testcase(u"\u00B4", "\xAB"), // ´
|
||
make_testcase(u"\u00A8", "\xAC"), // ¨
|
||
make_testcase(u"\u2260", "\xAD"), // ≠
|
||
make_testcase(u"\u00C6", "\xAE"), // Æ
|
||
make_testcase(u"\u00D8", "\xAF"), // Ø
|
||
make_testcase(u"\u221E", "\xB0"), // ∞
|
||
make_testcase(u"\u00B1", "\xB1"), // ±
|
||
make_testcase(u"\u2264", "\xB2"), // ≤
|
||
make_testcase(u"\u2265", "\xB3"), // ≥
|
||
make_testcase(u"\u00A5", "\xB4"), // ¥
|
||
make_testcase(u"\u00B5", "\xB5"), // µ
|
||
make_testcase(u"\u2202", "\xB6"), // ∂
|
||
make_testcase(u"\u2211", "\xB7"), // ∑
|
||
make_testcase(u"\u220F", "\xB8"), // ∏
|
||
make_testcase(u"\u03C0", "\xB9"), // π
|
||
make_testcase(u"\u222B", "\xBA"), // ∫
|
||
make_testcase(u"\u00AA", "\xBB"), // ª
|
||
make_testcase(u"\u00BA", "\xBC"), // º
|
||
make_testcase(u"\u2126", "\xBD"), // Ω
|
||
make_testcase(u"\u00E6", "\xBE"), // æ
|
||
make_testcase(u"\u00F8", "\xBF"), // ø
|
||
make_testcase(u"\u00BF", "\xC0"), // ¿
|
||
make_testcase(u"\u00A1", "\xC1"), // ¡
|
||
make_testcase(u"\u00AC", "\xC2"), // ¬
|
||
make_testcase(u"\u221A", "\xC3"), // √
|
||
make_testcase(u"\u0192", "\xC4"), // ƒ
|
||
make_testcase(u"\u2248", "\xC5"), // ≈
|
||
make_testcase(u"\u2206", "\xC6"), // ∆
|
||
make_testcase(u"\u00AB", "\xC7"), // «
|
||
make_testcase(u"\u00BB", "\xC8"), // »
|
||
make_testcase(u"\u2026", "\xC9"), // …
|
||
make_testcase(u"\u00A0", "\xCA"), // NBSP
|
||
make_testcase(u"\u00C0", "\xCB"), // À
|
||
make_testcase(u"\u00C3", "\xCC"), // Ã
|
||
make_testcase(u"\u00D5", "\xCD"), // Õ
|
||
make_testcase(u"\u0152", "\xCE"), // Œ
|
||
make_testcase(u"\u0153", "\xCF"), // œ
|
||
make_testcase(u"\u2013", "\xD0"), // –
|
||
make_testcase(u"\u2014", "\xD1"), // —
|
||
make_testcase(u"\u201C", "\xD2"), // “
|
||
make_testcase(u"\u201D", "\xD3"), // ”
|
||
make_testcase(u"\u2018", "\xD4"), // ‘
|
||
make_testcase(u"\u2019", "\xD5"), // ’
|
||
make_testcase(u"\u00F7", "\xD6"), // ÷
|
||
make_testcase(u"\u25CA", "\xD7"), // ◊
|
||
make_testcase(u"\u00FF", "\xD8"), // ÿ
|
||
make_testcase(u"\u0178", "\xD9"), // Ÿ
|
||
make_testcase(u"\u2044", "\xDA"), // ⁄
|
||
make_testcase(u"\u00A4", "\xDB"), // ¤
|
||
make_testcase(u"\u2039", "\xDC"), // ‹
|
||
make_testcase(u"\u203A", "\xDD"), // ›
|
||
make_testcase(u"\uFB01", "\xDE"), // fi
|
||
make_testcase(u"\uFB02", "\xDF"), // fl
|
||
make_testcase(u"\u2021", "\xE0"), // ‡
|
||
make_testcase(u"\u00B7", "\xE1"), // ·
|
||
make_testcase(u"\u201A", "\xE2"), // ‚
|
||
make_testcase(u"\u201E", "\xE3"), // „
|
||
make_testcase(u"\u2030", "\xE4"), // ‰
|
||
make_testcase(u"\u00C2", "\xE5"), // Â
|
||
make_testcase(u"\u00CA", "\xE6"), // Ê
|
||
make_testcase(u"\u00C1", "\xE7"), // Á
|
||
make_testcase(u"\u00CB", "\xE8"), // Ë
|
||
make_testcase(u"\u00C8", "\xE9"), // È
|
||
make_testcase(u"\u00CD", "\xEA"), // Í
|
||
make_testcase(u"\u00CE", "\xEB"), // Î
|
||
make_testcase(u"\u00CF", "\xEC"), // Ï
|
||
make_testcase(u"\u00CC", "\xED"), // Ì
|
||
make_testcase(u"\u00D3", "\xEE"), // Ó
|
||
make_testcase(u"\u00D4", "\xEF"), // Ô
|
||
make_testcase(u"\uFFFF", "\xF0"), // invalid (apple logo)
|
||
make_testcase(u"\u00D2", "\xF1"), // Ò
|
||
make_testcase(u"\u00DA", "\xF2"), // Ú
|
||
make_testcase(u"\u00DB", "\xF3"), // Û
|
||
make_testcase(u"\u00D9", "\xF4"), // Ù
|
||
make_testcase(u"\u0131", "\xF5"), // ı
|
||
make_testcase(u"\u02C6", "\xF6"), // ˆ
|
||
make_testcase(u"\u02DC", "\xF7"), // ˜
|
||
make_testcase(u"\u00AF", "\xF8"), // ¯
|
||
make_testcase(u"\u02D8", "\xF9"), // ˘
|
||
make_testcase(u"\u02D9", "\xFA"), // ˙
|
||
make_testcase(u"\u02DA", "\xFB"), // ˚
|
||
make_testcase(u"\u00B8", "\xFC"), // ¸
|
||
make_testcase(u"\u02DD", "\xFD"), // ˝
|
||
make_testcase(u"\u02DB", "\xFE"), // ˛
|
||
make_testcase(u"\u02C7", "\xFF") // ˇ
|
||
);
|
||
|
||
char resultStr[2];
|
||
auto result = SUniConvertUTF16ToMac(resultStr, testCase.first.c_str(), 2);
|
||
|
||
INFO(testCase.second);
|
||
CHECK(std::string(resultStr) == testCase.second);
|
||
CHECK(result == 2);
|
||
}
|
||
}
|
||
|
||
TEST_CASE("SUniConvertUTF16ToWin", "[unicode]") {
|
||
SECTION("does nothing on empty dest size") {
|
||
auto result = SUniConvertUTF16ToWin(nullptr, nullptr, 0);
|
||
CHECK(result == 0);
|
||
}
|
||
|
||
SECTION("operates on empty string") {
|
||
char resultStr[RESULT_STR_SIZE];
|
||
const char16_t str[] = u"";
|
||
|
||
auto result = SUniConvertUTF16ToWin(resultStr, str, RESULT_STR_SIZE);
|
||
CHECK(std::string(resultStr) == "");
|
||
CHECK(result == 1); // wrote 1 null terminator
|
||
}
|
||
|
||
SECTION("translates ASCII string") {
|
||
char resultStr[RESULT_STR_SIZE];
|
||
const char16_t str[] = u"Quick lazy brown fox or something";
|
||
|
||
auto result = SUniConvertUTF16ToWin(resultStr, str, RESULT_STR_SIZE);
|
||
CHECK(std::string(resultStr) == "Quick lazy brown fox or something");
|
||
CHECK(result == 34);
|
||
}
|
||
|
||
SECTION("fails to write null terminator if string isn't long enough") {
|
||
char resultStr[RESULT_STR_SIZE];
|
||
std::fill(std::begin(resultStr), std::end(resultStr), 0xCC);
|
||
const char16_t str[] = u"Quick lazy brown fox or something";
|
||
|
||
auto result = SUniConvertUTF16ToWin(resultStr, str, 5);
|
||
CHECK(std::string(resultStr, 5) == "Quick");
|
||
CHECK(static_cast<uint8_t>(resultStr[5]) == 0xCC);
|
||
CHECK(result == 5);
|
||
}
|
||
|
||
SECTION("writes ??? on unsupported characters") {
|
||
char resultStr[RESULT_STR_SIZE];
|
||
const char16_t str[] = u"\u8080\u8080lol\u8080\u8080\u8080";
|
||
|
||
auto result = SUniConvertUTF16ToWin(resultStr, str, RESULT_STR_SIZE);
|
||
CHECK(std::string(resultStr) == "??lol???");
|
||
CHECK(result == 9);
|
||
}
|
||
|
||
SECTION("translates shared ASCII characters") {
|
||
for (int i = 1; i < 128; i++) {
|
||
char16_t str[2] = { static_cast<char16_t>(i) };
|
||
char resultStr[2];
|
||
|
||
auto result = SUniConvertUTF16ToWin(resultStr, str, 2);
|
||
INFO(i);
|
||
CHECK(resultStr[0] == static_cast<char>(i));
|
||
CHECK(resultStr[1] == '\0');
|
||
CHECK(result == 2);
|
||
}
|
||
}
|
||
|
||
SECTION("translates special characters") {
|
||
auto testCase = GENERATE(
|
||
make_testcase(u"\u20AC", "\x80"), // €
|
||
//make_testcase(u"\uFFFF", "\x81"), // invalid
|
||
make_testcase(u"\u201A", "\x82"), // ‚
|
||
make_testcase(u"\u0192", "\x83"), // ƒ
|
||
make_testcase(u"\u201E", "\x84"), // „
|
||
make_testcase(u"\u2026", "\x85"), // …
|
||
make_testcase(u"\u2020", "\x86"), // †
|
||
make_testcase(u"\u2021", "\x87"), // ‡
|
||
make_testcase(u"\u02C6", "\x88"), // ˆ
|
||
make_testcase(u"\u2030", "\x89"), // ‰
|
||
make_testcase(u"\u0160", "\x8A"), // Š
|
||
make_testcase(u"\u2039", "\x8B"), // ‹
|
||
make_testcase(u"\u0152", "\x8C"), // Œ
|
||
//make_testcase(u"\uFFFF", "\x8D"), // invalid
|
||
make_testcase(u"\u017D", "\x8E"), // Ž
|
||
//make_testcase(u"\uFFFF", "\x8F"), // invalid
|
||
//make_testcase(u"\uFFFF", "\x90"), // invalid
|
||
make_testcase(u"\u2018", "\x91"), // ‘
|
||
make_testcase(u"\u2019", "\x92"), // ’
|
||
make_testcase(u"\u201C", "\x93"), // “
|
||
make_testcase(u"\u201D", "\x94"), // ”
|
||
make_testcase(u"\u2022", "\x95"), // •
|
||
make_testcase(u"\u2013", "\x96"), // –
|
||
make_testcase(u"\u2014", "\x97"), // —
|
||
make_testcase(u"\u02DC", "\x98"), // ˜
|
||
make_testcase(u"\u2122", "\x99"), // ™
|
||
make_testcase(u"\u0161", "\x9A"), // š
|
||
make_testcase(u"\u203A", "\x9B"), // ›
|
||
make_testcase(u"\u0153", "\x9C"), // œ
|
||
make_testcase(u"\uFFFF", "\x9D"), // invalid
|
||
make_testcase(u"\u017E", "\x9E"), // ž
|
||
make_testcase(u"\u0178", "\x9F") // Ÿ
|
||
);
|
||
|
||
char resultStr[2];
|
||
auto result = SUniConvertUTF16ToWin(resultStr, testCase.first.c_str(), 2);
|
||
|
||
INFO(testCase.second);
|
||
CHECK(std::string(resultStr) == testCase.second);
|
||
CHECK(result == 2);
|
||
}
|
||
|
||
SECTION("translates extended ASCII characters") {
|
||
for (int i = 0xA0; i < 256; i++) {
|
||
char16_t str[2] = { static_cast<char16_t>(i) };
|
||
char resultStr[2];
|
||
|
||
auto result = SUniConvertUTF16ToWin(resultStr, str, 2);
|
||
INFO(i);
|
||
CHECK(resultStr[0] == static_cast<char>(i));
|
||
CHECK(resultStr[1] == '\0');
|
||
CHECK(result == 2);
|
||
}
|
||
}
|
||
|
||
// TODO: Starcraft flavour Korean codepage
|
||
}
|
||
|
||
TEST_CASE("SUniConvertDosToUTF16", "[unicode]") {
|
||
SECTION("does nothing on empty dest size") {
|
||
auto result = SUniConvertDosToUTF16(nullptr, nullptr, 0);
|
||
CHECK(result == 0);
|
||
}
|
||
|
||
SECTION("operates on empty string") {
|
||
char16_t resultStr[RESULT_STR_SIZE];
|
||
const char str[] = "";
|
||
|
||
auto result = SUniConvertDosToUTF16(resultStr, str, RESULT_STR_SIZE);
|
||
CHECK(std::u16string(resultStr) == u"");
|
||
CHECK(result == 1); // wrote 1 null terminator
|
||
}
|
||
|
||
SECTION("translates ASCII string") {
|
||
char16_t resultStr[RESULT_STR_SIZE];
|
||
const char str[] = "Quick lazy brown fox or something";
|
||
|
||
auto result = SUniConvertDosToUTF16(resultStr, str, RESULT_STR_SIZE);
|
||
CHECK(std::u16string(resultStr) == u"Quick lazy brown fox or something");
|
||
CHECK(result == 34);
|
||
}
|
||
|
||
SECTION("fails to write null terminator if string isn't long enough") {
|
||
char16_t resultStr[RESULT_STR_SIZE];
|
||
std::fill(std::begin(resultStr), std::end(resultStr), 0xCCCC);
|
||
const char str[] = "Quick lazy brown fox or something";
|
||
|
||
auto result = SUniConvertDosToUTF16(resultStr, str, 5);
|
||
CHECK(std::u16string(resultStr, 5) == u"Quick");
|
||
CHECK(static_cast<uint16_t>(resultStr[5]) == 0xCCCC);
|
||
CHECK(result == 5);
|
||
}
|
||
|
||
SECTION("translates shared ASCII characters") {
|
||
for (int i = 1; i < 128; i++) {
|
||
char str[2] = { static_cast<char>(i) };
|
||
char16_t resultStr[2];
|
||
|
||
auto result = SUniConvertDosToUTF16(resultStr, str, 2);
|
||
INFO(i);
|
||
CHECK(resultStr[0] == static_cast<char16_t>(i));
|
||
CHECK(resultStr[1] == L'\0');
|
||
CHECK(result == 2);
|
||
}
|
||
}
|
||
|
||
SECTION("translates special characters") {
|
||
auto testCase = GENERATE(
|
||
make_testcase(u"\u00C7", "\x80"), // Ç
|
||
make_testcase(u"\u00FC", "\x81"), // ü
|
||
make_testcase(u"\u00E9", "\x82"), // é
|
||
make_testcase(u"\u00E2", "\x83"), // â
|
||
make_testcase(u"\u00E4", "\x84"), // ä
|
||
make_testcase(u"\u00E0", "\x85"), // à
|
||
make_testcase(u"\u00E5", "\x86"), // å
|
||
make_testcase(u"\u00E7", "\x87"), // ç
|
||
make_testcase(u"\u00EA", "\x88"), // ê
|
||
make_testcase(u"\u00EB", "\x89"), // ë
|
||
make_testcase(u"\u00E8", "\x8A"), // è
|
||
make_testcase(u"\u00EF", "\x8B"), // ï
|
||
make_testcase(u"\u00EE", "\x8C"), // î
|
||
make_testcase(u"\u00EC", "\x8D"), // ì
|
||
make_testcase(u"\u00C4", "\x8E"), // Ä
|
||
make_testcase(u"\u00C5", "\x8F"), // Å
|
||
make_testcase(u"\u00C9", "\x90"), // É
|
||
make_testcase(u"\u00E6", "\x91"), // æ
|
||
make_testcase(u"\u00C6", "\x92"), // Æ
|
||
make_testcase(u"\u00F4", "\x93"), // ô
|
||
make_testcase(u"\u00F6", "\x94"), // ö
|
||
make_testcase(u"\u00F2", "\x95"), // ò
|
||
make_testcase(u"\u00FB", "\x96"), // û
|
||
make_testcase(u"\u00F9", "\x97"), // ù
|
||
make_testcase(u"\u00FF", "\x98"), // ÿ
|
||
make_testcase(u"\u00D6", "\x99"), // Ö
|
||
make_testcase(u"\u00DC", "\x9A"), // Ü
|
||
make_testcase(u"\u00A2", "\x9B"), // ¢
|
||
make_testcase(u"\u00A3", "\x9C"), // £
|
||
make_testcase(u"\u00A5", "\x9D"), // ¥
|
||
make_testcase(u"\u20A7", "\x9E"), // ₧
|
||
make_testcase(u"\u0192", "\x9F"), // ƒ
|
||
make_testcase(u"\u00E1", "\xA0"), // á
|
||
make_testcase(u"\u00ED", "\xA1"), // í
|
||
make_testcase(u"\u00F3", "\xA2"), // ó
|
||
make_testcase(u"\u00FA", "\xA3"), // ú
|
||
make_testcase(u"\u00F1", "\xA4"), // ñ
|
||
make_testcase(u"\u00D1", "\xA5"), // Ñ
|
||
make_testcase(u"\u00AA", "\xA6"), // ª
|
||
make_testcase(u"\u00BA", "\xA7"), // º
|
||
make_testcase(u"\u00BF", "\xA8"), // ¿
|
||
make_testcase(u"\u2310", "\xA9"), // ⌐
|
||
make_testcase(u"\u00AC", "\xAA"), // ¬
|
||
make_testcase(u"\u00BD", "\xAB"), // ½
|
||
make_testcase(u"\u00BC", "\xAC"), // ¼
|
||
make_testcase(u"\u00A1", "\xAD"), // ¡
|
||
make_testcase(u"\u00AB", "\xAE"), // «
|
||
make_testcase(u"\u00BB", "\xAF"), // »
|
||
make_testcase(u"\u2591", "\xB0"), // ░
|
||
make_testcase(u"\u2592", "\xB1"), // ▒
|
||
make_testcase(u"\u2593", "\xB2"), // ▓
|
||
make_testcase(u"\u2502", "\xB3"), // │
|
||
make_testcase(u"\u2524", "\xB4"), // ┤
|
||
make_testcase(u"\u2561", "\xB5"), // ╡
|
||
make_testcase(u"\u2562", "\xB6"), // ╢
|
||
make_testcase(u"\u2556", "\xB7"), // ╖
|
||
make_testcase(u"\u2555", "\xB8"), // ╕
|
||
make_testcase(u"\u2563", "\xB9"), // ╣
|
||
make_testcase(u"\u2551", "\xBA"), // ║
|
||
make_testcase(u"\u2557", "\xBB"), // ╗
|
||
make_testcase(u"\u255D", "\xBC"), // ╝
|
||
make_testcase(u"\u255C", "\xBD"), // ╜
|
||
make_testcase(u"\u255B", "\xBE"), // ╛
|
||
make_testcase(u"\u2510", "\xBF"), // ┐
|
||
make_testcase(u"\u2514", "\xC0"), // └
|
||
make_testcase(u"\u2534", "\xC1"), // ┴
|
||
make_testcase(u"\u252C", "\xC2"), // ┬
|
||
make_testcase(u"\u251C", "\xC3"), // ├
|
||
make_testcase(u"\u2500", "\xC4"), // ─
|
||
make_testcase(u"\u253C", "\xC5"), // ┼
|
||
make_testcase(u"\u255E", "\xC6"), // ╞
|
||
make_testcase(u"\u255F", "\xC7"), // ╟
|
||
make_testcase(u"\u255A", "\xC8"), // ╚
|
||
make_testcase(u"\u2554", "\xC9"), // ╔
|
||
make_testcase(u"\u2569", "\xCA"), // ╩
|
||
make_testcase(u"\u2566", "\xCB"), // ╦
|
||
make_testcase(u"\u2560", "\xCC"), // ╠
|
||
make_testcase(u"\u2550", "\xCD"), // ═
|
||
make_testcase(u"\u256C", "\xCE"), // ╬
|
||
make_testcase(u"\u2567", "\xCF"), // ╧
|
||
make_testcase(u"\u2568", "\xD0"), // ╨
|
||
make_testcase(u"\u2564", "\xD1"), // ╤
|
||
make_testcase(u"\u2565", "\xD2"), // ╥
|
||
make_testcase(u"\u2559", "\xD3"), // ╙
|
||
make_testcase(u"\u2558", "\xD4"), // ╘
|
||
make_testcase(u"\u2552", "\xD5"), // ╒
|
||
make_testcase(u"\u2553", "\xD6"), // ╓
|
||
make_testcase(u"\u256B", "\xD7"), // ╫
|
||
make_testcase(u"\u256A", "\xD8"), // ╪
|
||
make_testcase(u"\u2518", "\xD9"), // ┘
|
||
make_testcase(u"\u250C", "\xDA"), // ┌
|
||
make_testcase(u"\u2588", "\xDB"), // █
|
||
make_testcase(u"\u2584", "\xDC"), // ▄
|
||
make_testcase(u"\u258C", "\xDD"), // ▌
|
||
make_testcase(u"\u2590", "\xDE"), // ▐
|
||
make_testcase(u"\u2580", "\xDF"), // ▀
|
||
make_testcase(u"\u03B1", "\xE0"), // α
|
||
make_testcase(u"\u00DF", "\xE1"), // ß
|
||
make_testcase(u"\u0393", "\xE2"), // Γ
|
||
make_testcase(u"\u03C0", "\xE3"), // π
|
||
make_testcase(u"\u03A3", "\xE4"), // Σ
|
||
make_testcase(u"\u03C3", "\xE5"), // σ
|
||
make_testcase(u"\u00B5", "\xE6"), // µ
|
||
make_testcase(u"\u03C4", "\xE7"), // τ
|
||
make_testcase(u"\u03A6", "\xE8"), // Φ
|
||
make_testcase(u"\u0398", "\xE9"), // Θ
|
||
make_testcase(u"\u03A9", "\xEA"), // Ω
|
||
make_testcase(u"\u03B4", "\xEB"), // δ
|
||
make_testcase(u"\u221E", "\xEC"), // ∞
|
||
make_testcase(u"\u03C6", "\xED"), // φ
|
||
make_testcase(u"\u03B5", "\xEE"), // ε
|
||
make_testcase(u"\u2229", "\xEF"), // ∩
|
||
make_testcase(u"\u2261", "\xF0"), // ≡
|
||
make_testcase(u"\u00B1", "\xF1"), // ±
|
||
make_testcase(u"\u2265", "\xF2"), // ≥
|
||
make_testcase(u"\u2264", "\xF3"), // ≤
|
||
make_testcase(u"\u2320", "\xF4"), // ⌠
|
||
make_testcase(u"\u2321", "\xF5"), // ⌡
|
||
make_testcase(u"\u00F7", "\xF6"), // ÷
|
||
make_testcase(u"\u2248", "\xF7"), // ≈
|
||
make_testcase(u"\u00B0", "\xF8"), // °
|
||
make_testcase(u"\u2219", "\xF9"), // ∙
|
||
make_testcase(u"\u00B7", "\xFA"), // ·
|
||
make_testcase(u"\u221A", "\xFB"), // √
|
||
make_testcase(u"\u207F", "\xFC"), // ⁿ
|
||
make_testcase(u"\u00B2", "\xFD"), // ²
|
||
make_testcase(u"\u25A0", "\xFE"), // ■
|
||
make_testcase(u"\u00A0", "\xFF") // r
|
||
);
|
||
|
||
char16_t resultStr[2];
|
||
auto result = SUniConvertDosToUTF16(resultStr, testCase.second.c_str(), 2);
|
||
|
||
INFO(testCase.second);
|
||
CHECK(std::u16string(resultStr) == testCase.first);
|
||
CHECK(result == 2);
|
||
}
|
||
}
|
||
|
||
TEST_CASE("SUniConvertMacToUTF16", "[unicode]") {
|
||
SECTION("does nothing on empty dest size") {
|
||
auto result = SUniConvertMacToUTF16(nullptr, nullptr, 0);
|
||
CHECK(result == 0);
|
||
}
|
||
|
||
SECTION("operates on empty string") {
|
||
char16_t resultStr[RESULT_STR_SIZE];
|
||
const char str[] = "";
|
||
|
||
auto result = SUniConvertMacToUTF16(resultStr, str, RESULT_STR_SIZE);
|
||
CHECK(std::u16string(resultStr) == u"");
|
||
CHECK(result == 1); // wrote 1 null terminator
|
||
}
|
||
|
||
SECTION("translates ASCII string") {
|
||
char16_t resultStr[RESULT_STR_SIZE];
|
||
const char str[] = "Quick lazy brown fox or something";
|
||
|
||
auto result = SUniConvertMacToUTF16(resultStr, str, RESULT_STR_SIZE);
|
||
CHECK(std::u16string(resultStr) == u"Quick lazy brown fox or something");
|
||
CHECK(result == 34);
|
||
}
|
||
|
||
SECTION("fails to write null terminator if string isn't long enough") {
|
||
char16_t resultStr[RESULT_STR_SIZE];
|
||
std::fill(std::begin(resultStr), std::end(resultStr), 0xCCCC);
|
||
const char str[] = "Quick lazy brown fox or something";
|
||
|
||
auto result = SUniConvertMacToUTF16(resultStr, str, 5);
|
||
CHECK(std::u16string(resultStr, 5) == u"Quick");
|
||
CHECK(static_cast<uint16_t>(resultStr[5]) == 0xCCCC);
|
||
CHECK(result == 5);
|
||
}
|
||
|
||
SECTION("translates shared ASCII characters") {
|
||
for (int i = 1; i < 128; i++) {
|
||
char str[2] = { static_cast<char>(i) };
|
||
char16_t resultStr[2];
|
||
|
||
auto result = SUniConvertMacToUTF16(resultStr, str, 2);
|
||
INFO(i);
|
||
CHECK(resultStr[0] == static_cast<char16_t>(i));
|
||
CHECK(resultStr[1] == L'\0');
|
||
CHECK(result == 2);
|
||
}
|
||
}
|
||
|
||
SECTION("translates special characters") {
|
||
auto testCase = GENERATE(
|
||
make_testcase(u"\u00C4", "\x80"), // Ä
|
||
make_testcase(u"\u00C5", "\x81"), // Å
|
||
make_testcase(u"\u00C7", "\x82"), // Ç
|
||
make_testcase(u"\u00C9", "\x83"), // É
|
||
make_testcase(u"\u00D1", "\x84"), // Ñ
|
||
make_testcase(u"\u00D6", "\x85"), // Ö
|
||
make_testcase(u"\u00DC", "\x86"), // Ü
|
||
make_testcase(u"\u00E1", "\x87"), // á
|
||
make_testcase(u"\u00E0", "\x88"), // à
|
||
make_testcase(u"\u00E2", "\x89"), // â
|
||
make_testcase(u"\u00E4", "\x8A"), // ä
|
||
make_testcase(u"\u00E3", "\x8B"), // ã
|
||
make_testcase(u"\u00E5", "\x8C"), // å
|
||
make_testcase(u"\u00E7", "\x8D"), // ç
|
||
make_testcase(u"\u00E9", "\x8E"), // é
|
||
make_testcase(u"\u00E8", "\x8F"), // è
|
||
make_testcase(u"\u00EA", "\x90"), // ê
|
||
make_testcase(u"\u00EB", "\x91"), // ë
|
||
make_testcase(u"\u00ED", "\x92"), // í
|
||
make_testcase(u"\u00EC", "\x93"), // ì
|
||
make_testcase(u"\u00EE", "\x94"), // î
|
||
make_testcase(u"\u00EF", "\x95"), // ï
|
||
make_testcase(u"\u00F1", "\x96"), // ñ
|
||
make_testcase(u"\u00F3", "\x97"), // ó
|
||
make_testcase(u"\u00F2", "\x98"), // ò
|
||
make_testcase(u"\u00F4", "\x99"), // ô
|
||
make_testcase(u"\u00F6", "\x9A"), // ö
|
||
make_testcase(u"\u00F5", "\x9B"), // õ
|
||
make_testcase(u"\u00FA", "\x9C"), // ú
|
||
make_testcase(u"\u00F9", "\x9D"), // ù
|
||
make_testcase(u"\u00FB", "\x9E"), // û
|
||
make_testcase(u"\u00FC", "\x9F"), // ü
|
||
make_testcase(u"\u2020", "\xA0"), // †
|
||
make_testcase(u"\u00B0", "\xA1"), // °
|
||
make_testcase(u"\u00A2", "\xA2"), // ¢
|
||
make_testcase(u"\u00A3", "\xA3"), // £
|
||
make_testcase(u"\u00A7", "\xA4"), // §
|
||
make_testcase(u"\u2022", "\xA5"), // •
|
||
make_testcase(u"\u00B6", "\xA6"), // ¶
|
||
make_testcase(u"\u00DF", "\xA7"), // ß
|
||
make_testcase(u"\u00AE", "\xA8"), // ®
|
||
make_testcase(u"\u00A9", "\xA9"), // ©
|
||
make_testcase(u"\u2122", "\xAA"), // ™
|
||
make_testcase(u"\u00B4", "\xAB"), // ´
|
||
make_testcase(u"\u00A8", "\xAC"), // ¨
|
||
make_testcase(u"\u2260", "\xAD"), // ≠
|
||
make_testcase(u"\u00C6", "\xAE"), // Æ
|
||
make_testcase(u"\u00D8", "\xAF"), // Ø
|
||
make_testcase(u"\u221E", "\xB0"), // ∞
|
||
make_testcase(u"\u00B1", "\xB1"), // ±
|
||
make_testcase(u"\u2264", "\xB2"), // ≤
|
||
make_testcase(u"\u2265", "\xB3"), // ≥
|
||
make_testcase(u"\u00A5", "\xB4"), // ¥
|
||
make_testcase(u"\u00B5", "\xB5"), // µ
|
||
make_testcase(u"\u2202", "\xB6"), // ∂
|
||
make_testcase(u"\u2211", "\xB7"), // ∑
|
||
make_testcase(u"\u220F", "\xB8"), // ∏
|
||
make_testcase(u"\u03C0", "\xB9"), // π
|
||
make_testcase(u"\u222B", "\xBA"), // ∫
|
||
make_testcase(u"\u00AA", "\xBB"), // ª
|
||
make_testcase(u"\u00BA", "\xBC"), // º
|
||
make_testcase(u"\u2126", "\xBD"), // Ω
|
||
make_testcase(u"\u00E6", "\xBE"), // æ
|
||
make_testcase(u"\u00F8", "\xBF"), // ø
|
||
make_testcase(u"\u00BF", "\xC0"), // ¿
|
||
make_testcase(u"\u00A1", "\xC1"), // ¡
|
||
make_testcase(u"\u00AC", "\xC2"), // ¬
|
||
make_testcase(u"\u221A", "\xC3"), // √
|
||
make_testcase(u"\u0192", "\xC4"), // ƒ
|
||
make_testcase(u"\u2248", "\xC5"), // ≈
|
||
make_testcase(u"\u2206", "\xC6"), // ∆
|
||
make_testcase(u"\u00AB", "\xC7"), // «
|
||
make_testcase(u"\u00BB", "\xC8"), // »
|
||
make_testcase(u"\u2026", "\xC9"), // …
|
||
make_testcase(u"\u00A0", "\xCA"), // NBSP
|
||
make_testcase(u"\u00C0", "\xCB"), // À
|
||
make_testcase(u"\u00C3", "\xCC"), // Ã
|
||
make_testcase(u"\u00D5", "\xCD"), // Õ
|
||
make_testcase(u"\u0152", "\xCE"), // Œ
|
||
make_testcase(u"\u0153", "\xCF"), // œ
|
||
make_testcase(u"\u2013", "\xD0"), // –
|
||
make_testcase(u"\u2014", "\xD1"), // —
|
||
make_testcase(u"\u201C", "\xD2"), // “
|
||
make_testcase(u"\u201D", "\xD3"), // ”
|
||
make_testcase(u"\u2018", "\xD4"), // ‘
|
||
make_testcase(u"\u2019", "\xD5"), // ’
|
||
make_testcase(u"\u00F7", "\xD6"), // ÷
|
||
make_testcase(u"\u25CA", "\xD7"), // ◊
|
||
make_testcase(u"\u00FF", "\xD8"), // ÿ
|
||
make_testcase(u"\u0178", "\xD9"), // Ÿ
|
||
make_testcase(u"\u2044", "\xDA"), // ⁄
|
||
make_testcase(u"\u00A4", "\xDB"), // ¤
|
||
make_testcase(u"\u2039", "\xDC"), // ‹
|
||
make_testcase(u"\u203A", "\xDD"), // ›
|
||
make_testcase(u"\uFB01", "\xDE"), // fi
|
||
make_testcase(u"\uFB02", "\xDF"), // fl
|
||
make_testcase(u"\u2021", "\xE0"), // ‡
|
||
make_testcase(u"\u00B7", "\xE1"), // ·
|
||
make_testcase(u"\u201A", "\xE2"), // ‚
|
||
make_testcase(u"\u201E", "\xE3"), // „
|
||
make_testcase(u"\u2030", "\xE4"), // ‰
|
||
make_testcase(u"\u00C2", "\xE5"), // Â
|
||
make_testcase(u"\u00CA", "\xE6"), // Ê
|
||
make_testcase(u"\u00C1", "\xE7"), // Á
|
||
make_testcase(u"\u00CB", "\xE8"), // Ë
|
||
make_testcase(u"\u00C8", "\xE9"), // È
|
||
make_testcase(u"\u00CD", "\xEA"), // Í
|
||
make_testcase(u"\u00CE", "\xEB"), // Î
|
||
make_testcase(u"\u00CF", "\xEC"), // Ï
|
||
make_testcase(u"\u00CC", "\xED"), // Ì
|
||
make_testcase(u"\u00D3", "\xEE"), // Ó
|
||
make_testcase(u"\u00D4", "\xEF"), // Ô
|
||
make_testcase(u"\uFFFF", "\xF0"), // invalid (apple logo)
|
||
make_testcase(u"\u00D2", "\xF1"), // Ò
|
||
make_testcase(u"\u00DA", "\xF2"), // Ú
|
||
make_testcase(u"\u00DB", "\xF3"), // Û
|
||
make_testcase(u"\u00D9", "\xF4"), // Ù
|
||
make_testcase(u"\u0131", "\xF5"), // ı
|
||
make_testcase(u"\u02C6", "\xF6"), // ˆ
|
||
make_testcase(u"\u02DC", "\xF7"), // ˜
|
||
make_testcase(u"\u00AF", "\xF8"), // ¯
|
||
make_testcase(u"\u02D8", "\xF9"), // ˘
|
||
make_testcase(u"\u02D9", "\xFA"), // ˙
|
||
make_testcase(u"\u02DA", "\xFB"), // ˚
|
||
make_testcase(u"\u00B8", "\xFC"), // ¸
|
||
make_testcase(u"\u02DD", "\xFD"), // ˝
|
||
make_testcase(u"\u02DB", "\xFE"), // ˛
|
||
make_testcase(u"\u02C7", "\xFF") // ˇ
|
||
);
|
||
|
||
char16_t resultStr[2];
|
||
auto result = SUniConvertMacToUTF16(resultStr, testCase.second.c_str(), 2);
|
||
|
||
INFO(testCase.second);
|
||
CHECK(std::u16string(resultStr) == testCase.first);
|
||
CHECK(result == 2);
|
||
}
|
||
}
|
||
|
||
TEST_CASE("SUniConvertWinToUTF16", "[unicode]") {
|
||
SECTION("does nothing on empty dest size") {
|
||
auto result = SUniConvertWinToUTF16(nullptr, nullptr, 0);
|
||
CHECK(result == 0);
|
||
}
|
||
|
||
SECTION("operates on empty string") {
|
||
char16_t resultStr[RESULT_STR_SIZE];
|
||
const char str[] = "";
|
||
|
||
auto result = SUniConvertWinToUTF16(resultStr, str, RESULT_STR_SIZE);
|
||
CHECK(std::u16string(resultStr) == u"");
|
||
CHECK(result == 1); // wrote 1 null terminator
|
||
}
|
||
|
||
SECTION("translates ASCII string") {
|
||
char16_t resultStr[RESULT_STR_SIZE];
|
||
const char str[] = "Quick lazy brown fox or something";
|
||
|
||
auto result = SUniConvertWinToUTF16(resultStr, str, RESULT_STR_SIZE);
|
||
CHECK(std::u16string(resultStr) == u"Quick lazy brown fox or something");
|
||
CHECK(result == 34);
|
||
}
|
||
|
||
SECTION("fails to write null terminator if string isn't long enough") {
|
||
char16_t resultStr[RESULT_STR_SIZE];
|
||
std::fill(std::begin(resultStr), std::end(resultStr), 0xCCCC);
|
||
const char str[] = "Quick lazy brown fox or something";
|
||
|
||
auto result = SUniConvertWinToUTF16(resultStr, str, 5);
|
||
CHECK(std::u16string(resultStr, 5) == u"Quick");
|
||
CHECK(static_cast<uint16_t>(resultStr[5]) == 0xCCCC);
|
||
CHECK(result == 5);
|
||
}
|
||
|
||
SECTION("translates shared ASCII characters") {
|
||
for (int i = 1; i < 128; i++) {
|
||
char str[2] = { static_cast<char>(i) };
|
||
char16_t resultStr[2];
|
||
|
||
auto result = SUniConvertWinToUTF16(resultStr, str, 2);
|
||
INFO(i);
|
||
CHECK(resultStr[0] == static_cast<char16_t>(i));
|
||
CHECK(resultStr[1] == L'\0');
|
||
CHECK(result == 2);
|
||
}
|
||
}
|
||
|
||
SECTION("translates special characters") {
|
||
auto testCase = GENERATE(
|
||
make_testcase(u"\u20AC", "\x80"), // €
|
||
make_testcase(u"\uFFFF", "\x81"), // invalid
|
||
make_testcase(u"\u201A", "\x82"), // ‚
|
||
make_testcase(u"\u0192", "\x83"), // ƒ
|
||
make_testcase(u"\u201E", "\x84"), // „
|
||
make_testcase(u"\u2026", "\x85"), // …
|
||
make_testcase(u"\u2020", "\x86"), // †
|
||
make_testcase(u"\u2021", "\x87"), // ‡
|
||
make_testcase(u"\u02C6", "\x88"), // ˆ
|
||
make_testcase(u"\u2030", "\x89"), // ‰
|
||
make_testcase(u"\u0160", "\x8A"), // Š
|
||
make_testcase(u"\u2039", "\x8B"), // ‹
|
||
make_testcase(u"\u0152", "\x8C"), // Œ
|
||
make_testcase(u"\uFFFF", "\x8D"), // invalid
|
||
make_testcase(u"\u017D", "\x8E"), // Ž
|
||
make_testcase(u"\uFFFF", "\x8F"), // invalid
|
||
make_testcase(u"\uFFFF", "\x90"), // invalid
|
||
make_testcase(u"\u2018", "\x91"), // ‘
|
||
make_testcase(u"\u2019", "\x92"), // ’
|
||
make_testcase(u"\u201C", "\x93"), // “
|
||
make_testcase(u"\u201D", "\x94"), // ”
|
||
make_testcase(u"\u2022", "\x95"), // •
|
||
make_testcase(u"\u2013", "\x96"), // –
|
||
make_testcase(u"\u2014", "\x97"), // —
|
||
make_testcase(u"\u02DC", "\x98"), // ˜
|
||
make_testcase(u"\u2122", "\x99"), // ™
|
||
make_testcase(u"\u0161", "\x9A"), // š
|
||
make_testcase(u"\u203A", "\x9B"), // ›
|
||
make_testcase(u"\u0153", "\x9C"), // œ
|
||
make_testcase(u"\uFFFF", "\x9D"), // invalid
|
||
make_testcase(u"\u017E", "\x9E"), // ž
|
||
make_testcase(u"\u0178", "\x9F") // Ÿ
|
||
);
|
||
|
||
char16_t resultStr[2];
|
||
auto result = SUniConvertWinToUTF16(resultStr, testCase.second.c_str(), 2);
|
||
|
||
INFO(testCase.second);
|
||
CHECK(std::u16string(resultStr) == testCase.first);
|
||
CHECK(result == 2);
|
||
}
|
||
|
||
SECTION("translates extended ASCII characters") {
|
||
for (int i = 0xA0; i < 256; i++) {
|
||
char str[2] = { static_cast<char>(i) };
|
||
char16_t resultStr[2];
|
||
|
||
auto result = SUniConvertWinToUTF16(resultStr, str, 2);
|
||
INFO(i);
|
||
CHECK(resultStr[0] == static_cast<char16_t>(i));
|
||
CHECK(resultStr[1] == u'\0');
|
||
CHECK(result == 2);
|
||
}
|
||
}
|
||
|
||
// TODO: Starcraft flavour Korean codepage
|
||
}
|
||
|
||
TEST_CASE("SUniFindAfterUTF8Chr", "[unicode]") {
|
||
SECTION("returns index+1 if index is negative") {
|
||
CHECK(SUniFindAfterUTF8Chr(nullptr, -1) == 0);
|
||
}
|
||
|
||
SECTION("returns 1 on string with 1 char") {
|
||
CHECK(SUniFindAfterUTF8Chr(" ", 0) == 1);
|
||
}
|
||
|
||
SECTION("returns next char on non-UTF8 string") {
|
||
CHECK(SUniFindAfterUTF8Chr("happy cakes", 4) == 5);
|
||
}
|
||
|
||
SECTION("finds the character after an emoji") {
|
||
const char str[] = "Merry 🎄 Christmas";
|
||
CHECK(sizeof(str) == 21);
|
||
CHECK(SUniFindAfterUTF8Chr(str, 4) == 5);
|
||
CHECK(SUniFindAfterUTF8Chr(str, 5) == 6);
|
||
CHECK(SUniFindAfterUTF8Chr(str, 6) == 10);
|
||
CHECK(SUniFindAfterUTF8Chr(str, 7) == 10);
|
||
CHECK(SUniFindAfterUTF8Chr(str, 8) == 10);
|
||
CHECK(SUniFindAfterUTF8Chr(str, 9) == 10);
|
||
CHECK(SUniFindAfterUTF8Chr(str, 10) == 11);
|
||
CHECK(SUniFindAfterUTF8Chr(str, 11) == 12);
|
||
}
|
||
|
||
SECTION("finds the character after a Korean char") {
|
||
const char str[] = "메리 크리스마스";
|
||
CHECK(sizeof(str) == 23);
|
||
CHECK(SUniFindAfterUTF8Chr(str, 3) == 6);
|
||
CHECK(SUniFindAfterUTF8Chr(str, 4) == 6);
|
||
CHECK(SUniFindAfterUTF8Chr(str, 5) == 6);
|
||
CHECK(SUniFindAfterUTF8Chr(str, 6) == 7); // ASCII space
|
||
CHECK(SUniFindAfterUTF8Chr(str, 7) == 10);
|
||
CHECK(SUniFindAfterUTF8Chr(str, 8) == 10);
|
||
CHECK(SUniFindAfterUTF8Chr(str, 9) == 10);
|
||
}
|
||
}
|
||
|
||
TEST_CASE("SUniFindUTF8ChrStart", "[unicode]") {
|
||
SECTION("returns index if index is negative") {
|
||
CHECK(SUniFindUTF8ChrStart(nullptr, -1) == -1);
|
||
}
|
||
|
||
SECTION("returns 0 if index is 0") {
|
||
CHECK(SUniFindUTF8ChrStart(nullptr, 0) == 0);
|
||
}
|
||
|
||
SECTION("returns 0 on empty string") {
|
||
CHECK(SUniFindUTF8ChrStart("", 0) == 0);
|
||
}
|
||
|
||
SECTION("returns current char on non-UTF8 string") {
|
||
CHECK(SUniFindUTF8ChrStart("happy cakes", 5) == 5);
|
||
}
|
||
|
||
SECTION("finds the beginning of an emoji") {
|
||
const char str[] = "Merry 🎄 Christmas";
|
||
CHECK(sizeof(str) == 21);
|
||
CHECK(SUniFindUTF8ChrStart(str, 4) == 4);
|
||
CHECK(SUniFindUTF8ChrStart(str, 5) == 5);
|
||
CHECK(SUniFindUTF8ChrStart(str, 6) == 6);
|
||
CHECK(SUniFindUTF8ChrStart(str, 7) == 6);
|
||
CHECK(SUniFindUTF8ChrStart(str, 8) == 6);
|
||
CHECK(SUniFindUTF8ChrStart(str, 9) == 6);
|
||
CHECK(SUniFindUTF8ChrStart(str, 10) == 10);
|
||
CHECK(SUniFindUTF8ChrStart(str, 11) == 11);
|
||
}
|
||
|
||
SECTION("finds the beginning of a Korean char") {
|
||
const char str[] = "메리 크리스마스";
|
||
CHECK(sizeof(str) == 23);
|
||
CHECK(SUniFindUTF8ChrStart(str, 3) == 3);
|
||
CHECK(SUniFindUTF8ChrStart(str, 4) == 3);
|
||
CHECK(SUniFindUTF8ChrStart(str, 5) == 3);
|
||
CHECK(SUniFindUTF8ChrStart(str, 6) == 6); // ASCII space
|
||
CHECK(SUniFindUTF8ChrStart(str, 7) == 7);
|
||
CHECK(SUniFindUTF8ChrStart(str, 8) == 7);
|
||
CHECK(SUniFindUTF8ChrStart(str, 9) == 7);
|
||
}
|
||
}
|
||
|
||
TEST_CASE("SUniSGetUTF8", "[unicode]") {
|
||
SECTION("returns ascii-range utf-8 first character") {
|
||
auto string = "foobar";
|
||
int32_t chars = 0;
|
||
auto code = SUniSGetUTF8(reinterpret_cast<const uint8_t*>(string), &chars);
|
||
|
||
REQUIRE(code == 'f');
|
||
REQUIRE(chars == 1);
|
||
}
|
||
|
||
SECTION("returns non-ascii-range utf-8 first character") {
|
||
auto string = "\xF0\x9F\x99\x82"
|
||
"foobar";
|
||
int32_t chars = 0;
|
||
auto code = SUniSGetUTF8(reinterpret_cast<const uint8_t*>(string), &chars);
|
||
|
||
REQUIRE(code == 0x1F642);
|
||
REQUIRE(chars == 4);
|
||
}
|
||
|
||
SECTION("returns null first character") {
|
||
auto string = "";
|
||
int32_t chars = 0;
|
||
auto code = SUniSGetUTF8(reinterpret_cast<const uint8_t*>(string), &chars);
|
||
|
||
REQUIRE(code == ~0u);
|
||
REQUIRE(chars == 0);
|
||
}
|
||
}
|
||
|
||
TEST_CASE("SUniSPutUTF8", "[unicode]") {
|
||
SECTION("writes ascii-range utf-8 first character") {
|
||
auto code = 'f';
|
||
char buffer[RESULT_STR_SIZE] = { 0 };
|
||
SUniSPutUTF8(code, buffer);
|
||
|
||
REQUIRE(SStrLen(buffer) == 1);
|
||
REQUIRE(!SStrCmp(buffer, "f", SStrLen(buffer)));
|
||
}
|
||
|
||
SECTION("writes non-ascii-range utf-8 first character") {
|
||
auto code = 0x1F642;
|
||
char buffer[RESULT_STR_SIZE] = { 0 };
|
||
SUniSPutUTF8(code, buffer);
|
||
|
||
REQUIRE(SStrLen(buffer) == 4);
|
||
REQUIRE(!SStrCmp(buffer, "\xF0\x9F\x99\x82", SStrLen(buffer)));
|
||
}
|
||
|
||
SECTION("writes null first character") {
|
||
auto code = '\0';
|
||
char buffer[RESULT_STR_SIZE] = { 0 };
|
||
SUniSPutUTF8(code, buffer);
|
||
|
||
REQUIRE(SStrLen(buffer) == 0);
|
||
}
|
||
}
|