55 lines
2.3 KiB
C++
55 lines
2.3 KiB
C++
#include <gtest/gtest.h>
|
|
|
|
#include <string>
|
|
|
|
#include "Utf8.h"
|
|
|
|
namespace {
|
|
|
|
// Helpers to build NFD / expected byte sequences explicitly so the test does not
|
|
// depend on the encoding of this source file.
|
|
const std::string kCombGrave = "\xCC\x80"; // U+0300 COMBINING GRAVE ACCENT
|
|
const std::string kCombAcute = "\xCC\x81"; // U+0301 COMBINING ACUTE ACCENT
|
|
const std::string kCombCirc = "\xCC\x82"; // U+0302 COMBINING CIRCUMFLEX ACCENT
|
|
const std::string kCombDotBelow = "\xCC\xA3"; // U+0323 COMBINING DOT BELOW
|
|
|
|
} // namespace
|
|
|
|
// ASCII and already-precomposed (NFC) text must pass through untouched (fast path).
|
|
TEST(Utf8ComposeNfc, PassesThroughAsciiAndNfc) {
|
|
EXPECT_EQ(utf8ComposeNfc(""), "");
|
|
EXPECT_EQ(utf8ComposeNfc("hello world"), "hello world");
|
|
EXPECT_EQ(utf8ComposeNfc("caf\xC3\xA9"), "caf\xC3\xA9"); // é already U+00E9
|
|
}
|
|
|
|
// Single combining mark composes onto its base letter.
|
|
TEST(Utf8ComposeNfc, ComposesSingleMark) {
|
|
EXPECT_EQ(utf8ComposeNfc("e" + kCombAcute), "\xC3\xA9"); // e + ́ -> é (U+00E9)
|
|
EXPECT_EQ(utf8ComposeNfc("a" + kCombGrave), "\xC3\xA0"); // a + ̀ -> à (U+00E0)
|
|
}
|
|
|
|
// Vietnamese letters carry two stacked marks; composition must accumulate them
|
|
// onto the intermediate precomposed character (this is the crux of the feature).
|
|
TEST(Utf8ComposeNfc, ComposesStackedVietnameseMarks) {
|
|
// a + circumflex + acute -> ấ (U+1EA5)
|
|
EXPECT_EQ(utf8ComposeNfc("a" + kCombCirc + kCombAcute), "\xE1\xBA\xA5");
|
|
// a + dot-below + circumflex (canonical order) -> ậ (U+1EAD)
|
|
EXPECT_EQ(utf8ComposeNfc("a" + kCombDotBelow + kCombCirc), "\xE1\xBA\xAD");
|
|
}
|
|
|
|
// A combining mark with no composition for its base is left unchanged, and the
|
|
// base is preserved.
|
|
TEST(Utf8ComposeNfc, LeavesUncomposableMarksIntact) {
|
|
const std::string in = "q" + kCombAcute; // no precomposed "q with acute"
|
|
EXPECT_EQ(utf8ComposeNfc(in), in);
|
|
}
|
|
|
|
// A leading combining mark (no preceding base) is emitted unchanged.
|
|
TEST(Utf8ComposeNfc, HandlesLeadingMark) { EXPECT_EQ(utf8ComposeNfc(kCombAcute), kCombAcute); }
|
|
|
|
// Marks embedded in a longer word compose while surrounding text is preserved.
|
|
TEST(Utf8ComposeNfc, ComposesWithinWord) {
|
|
// "Ti" + e+circ+acute + "ng" -> "Tiếng"
|
|
EXPECT_EQ(utf8ComposeNfc("Ti" + std::string("e") + kCombCirc + kCombAcute + "ng"), "Ti\xE1\xBA\xBFng");
|
|
}
|