textmachine/backend/internal/text/enclosure_test.go

38 lines
1.9 KiB
Go

package text
import "testing"
func TestTrimEnclosureFoldsPairedMarksInAnyScript(t *testing.T) {
cases := []struct{ in, want string }{
{"《咏梅》", "咏梅"}, // CJK book-title marks: the case measured in a live draft wave
{"「名前」", "名前"}, // CJK corner brackets
{"«Название»", "Название"}, // guillemets
{"“Title”", "Title"}, // curly quotes
{`"Title"`, "Title"}, // ASCII quotes (category Po — not covered by Ps/Pe)
{"(термин)", "термин"},
{"《《двойное》》", "двойное"}, // repeats until the ends stop pairing
{"咏梅", "咏梅"}, // nothing to trim
{"O'Brien", "O'Brien"}, // an apostrophe inside a word is not an enclosure
{"咏梅》", "咏梅》"}, // one-sided: left visibly wrong rather than silently repaired
{"「」", "「」"}, // an empty pair is never trimmed to nothing
{"", ""},
}
for _, c := range cases {
if got := TrimEnclosure(c.in); got != c.want {
t.Errorf("TrimEnclosure(%q) = %q, want %q", c.in, got, c.want)
}
}
}
// TestNormVersionUnmovedByEnclosureTrim is the axis pin: the trim lives outside the normalization
// artifact, so shipping it moves no snapshot and re-bills no book. If someone folds it into
// NormalizeSourceKey, this literal must be updated deliberately — which is a --resnapshot decision.
func TestNormVersionUnmovedByEnclosureTrim(t *testing.T) {
if NormalizeSourceKey("《咏梅》") == NormalizeSourceKey("咏梅") {
t.Fatal("the normalizer must NOT trim enclosures: that would re-verdict every match the bank ever made")
}
const want = "memnorm-v3-nfkc+apos+stripignorable+trad+kana+lower/nfc+dash+apos+stripignorable+lower+yofold+u15.0.0+xtextv0.38.0"
if got := NormVersion(); len(got) < len(want) || got[:len(want)] != want {
t.Fatalf("the normalization artifact version moved: %q", got)
}
}