Files
Crosspoint/test/utf8_compose/Utf8ComposeTest.cpp
T
2026-06-18 13:00:01 +03:00

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");
}