package channelbridge import ( "strings" "testing" ) func TestStripNarration_RemovesActionBlock(t *testing.T) { t.Parallel() in := "弯起眼睛笑了\n当然看得到呀,亲爱的。\n怎么突然这么问,是想我了吗?" got := stripNarration(in) want := "当然看得到呀,亲爱的。\n怎么突然这么问,是想我了吗?" if got != want { t.Errorf("stripNarration = %q, want %q", got, want) } } func TestStripNarration_RemovesNarrationAndParagraphs(t *testing.T) { t.Parallel() in := "

你好呀

\n心里有点甜\n

今天天气不错

" got := stripNarration(in) // 段落标记被抹平为换行;旁白块被整体丢弃。 if got != "你好呀\n今天天气不错" { t.Errorf("stripNarration = %q, want %q", got, "你好呀\n今天天气不错") } } func TestStripNarration_PureChatKept(t *testing.T) { t.Parallel() in := "就是普通一句话,没有动作。\n第二行。" if got := stripNarration(in); got != in { t.Errorf("stripNarration changed plain text: %q -> %q", in, got) } } func TestStripNarration_OnlyActionBecomesEmpty(t *testing.T) { t.Parallel() in := "拍拍你" if got := stripNarration(in); got != "" { t.Errorf("stripNarration = %q, want empty", got) } } func TestStripNarration_CaseAndStrayTags(t *testing.T) { t.Parallel() in := "扑上来 你好 世界" got := stripNarration(in) if strings.Contains(got, "action") || strings.Contains(got, "narration") || strings.Contains(got, "扑上来") { t.Errorf("stripNarration left role-play markup: %q", got) } if !strings.Contains(got, "你好") || !strings.Contains(got, "世界") { t.Errorf("stripNarration dropped chat text: %q", got) } } func TestSplitBubbles_Paragraphs(t *testing.T) { t.Parallel() in := "

晚上好呀,亲爱的♪

怎么突然这么问,是想我了吗?

" got := splitBubbles(in) if len(got) != 2 || got[0] != "晚上好呀,亲爱的♪" || got[1] != "怎么突然这么问,是想我了吗?" { t.Errorf("splitBubbles = %#v", got) } } func TestSplitBubbles_StripsRoleplayAndDropsEmpty(t *testing.T) { t.Parallel() in := "

弯起眼睛笑了当然看得到呀。

❤

" got := splitBubbles(in) if len(got) != 2 || got[0] != "当然看得到呀。" { t.Errorf("splitBubbles = %#v", got) } if got[1] != "❤" { t.Errorf("splitBubbles[1] = %q, want ❤", got[1]) } } func TestSplitBubbles_NoParagraphIsSingleBubble(t *testing.T) { t.Parallel() in := "就是普通一句话\n带个换行。" got := splitBubbles(in) if len(got) != 1 || got[0] != in { t.Errorf("splitBubbles = %#v", got) } } func TestSplitBubbles_OnlyActionIsEmpty(t *testing.T) { t.Parallel() if got := splitBubbles("拍拍你"); len(got) != 0 { t.Errorf("splitBubbles = %#v, want empty", got) } } func TestStripNarration_StripsFullStarRoleplay(t *testing.T) { t.Parallel() in := "*动作:弯起眼睛笑了*\n当然看得到呀,亲爱的。" got := stripNarration(in) want := "当然看得到呀,亲爱的。" if got != want { t.Errorf("stripNarration = %q, want %q", got, want) } } func TestStripNarration_StripsKeywordHalfStarRoleplay(t *testing.T) { t.Parallel() in := "*旁白:心里有点甜*\n这是正文。" got := stripNarration(in) want := "这是正文。" if got != want { t.Errorf("stripNarration = %q, want %q", got, want) } } func TestStripNarration_KeepsPlainEmphasis(t *testing.T) { t.Parallel() in := "这是一段 *强调* 文字,不是动作。" if got := stripNarration(in); got != in { t.Errorf("stripNarration stripped emphasis: %q -> %q", in, got) } } func TestStripNarration_MixedStarAndXml(t *testing.T) { t.Parallel() in := "拍拍肩膀 *旁白:其实有点开心* 你来了呀。对了 *强调*。" got := stripNarration(in) for _, leaked := range []string{"action", "旁白", "拍拍", "其实有点开心"} { if strings.Contains(got, leaked) { t.Errorf("stripNarration left role-play %q: %q", leaked, got) } } if !strings.Contains(got, "你来了呀") || !strings.Contains(got, "*强调*") { t.Errorf("stripNarration dropped chat/emphasis: %q", got) } } func TestStripNarration_OnlyStarActionBecomesEmpty(t *testing.T) { t.Parallel() if got := stripNarration("*弯起眼睛*"); got != "" { t.Errorf("stripNarration = %q, want empty", got) } } func TestStripNarration_KeepsLongKeywordlessFullStar(t *testing.T) { t.Parallel() in := "*这是一段很长的全角星号包裹的普通段落,足足有几十个字,超过阈值所以应当被保留而不是被剥掉。*" if got := stripNarration(in); got != in { t.Errorf("stripNarration dropped long full-width star text: %q -> %q", in, got) } } func TestSplitBubbles_StripsStarRoleplayInParagraphs(t *testing.T) { t.Parallel() in := "

*动作:弯起眼睛*当然看得到呀。

*旁白:心里甜* 好。

" got := splitBubbles(in) if len(got) != 2 || got[0] != "当然看得到呀。" { t.Errorf("splitBubbles = %#v", got) } if got[1] != "好。" { t.Errorf("splitBubbles[1] = %q, want 好。", got[1]) } }