ci / go (push) Waiting to run
ci / go-db (agent) (push) Waiting to run
ci / go-db (config) (push) Waiting to run
ci / go-db (db) (push) Waiting to run
ci / go-db (evidence) (push) Waiting to run
ci / go-db (llmrec) (push) Waiting to run
ci / go-db (server) (push) Waiting to run
detections / detections (push) Waiting to run
docs / links (push) Waiting to run
web / web (push) Waiting to run
79 lines
3.0 KiB
Go
79 lines
3.0 KiB
Go
package sidequestion
|
||
|
||
import (
|
||
"errors"
|
||
"fmt"
|
||
"testing"
|
||
"unicode"
|
||
)
|
||
|
||
// assertChinese fails if msg is empty, carries Hangul (= leftover untranslated
|
||
// Korean), or has no Han ideograph at all. ASCII field names and the
|
||
// "1–4000"-style ranges are fine; only Hangul marks an unlocalized string.
|
||
func assertChinese(t *testing.T, label, msg string) {
|
||
t.Helper()
|
||
if msg == "" {
|
||
t.Fatalf("%s: 빈 메시지", label)
|
||
}
|
||
han := false
|
||
for _, r := range msg {
|
||
if unicode.Is(unicode.Hangul, r) {
|
||
t.Fatalf("%s: 한국어가 남아 있습니다: %q", label, msg)
|
||
}
|
||
if unicode.Is(unicode.Han, r) {
|
||
han = true
|
||
}
|
||
}
|
||
if !han {
|
||
t.Fatalf("%s: 汉字缺失: %q", label, msg)
|
||
}
|
||
}
|
||
|
||
// TestSideQuestionOutputsLocalized guards F21: every user-facing side-question
|
||
// (곁질문) error and answer-text literal produced by this package must be Korean.
|
||
// These surface through /api/.../side-questions into the chat 곁질문 panel, so a
|
||
// revert to Chinese here is a user-visible regression and must fail the build.
|
||
func TestSideQuestionOutputsLocalized(t *testing.T) {
|
||
assertChinese(t, "ErrContextBudget", ErrContextBudget.Error())
|
||
assertChinese(t, "errSideModelInterrupted", errSideModelInterrupted.Error())
|
||
assertChinese(t, "errSideNoAnswer", errSideNoAnswer.Error())
|
||
assertChinese(t, "msgSideToolUnavailable", msgSideToolUnavailable)
|
||
assertChinese(t, "errSideSummaryCallCap", errSideSummaryCallCap.Error())
|
||
assertChinese(t, "sideSummaryFailedPrefix", sideSummaryFailedPrefix)
|
||
assertChinese(t, "errSideSummaryIncomplete", errSideSummaryIncomplete.Error())
|
||
assertChinese(t, "errSideSummaryOverBudget", errSideSummaryOverBudget.Error())
|
||
assertChinese(t, "errSideHistoryCursor", errSideHistoryCursor.Error())
|
||
assertChinese(t, "errSideCompactionStalled", errSideCompactionStalled.Error())
|
||
}
|
||
|
||
// TestSideQuestionBudgetSentinelPreserved: localizing the message must not break
|
||
// callers that branch on the ErrContextBudget sentinel with errors.Is (see
|
||
// context_test.go, which relies on it after the recovery path gives up).
|
||
func TestSideQuestionBudgetSentinelPreserved(t *testing.T) {
|
||
if !errors.Is(fmt.Errorf("prepare: %w", ErrContextBudget), ErrContextBudget) {
|
||
t.Fatal("ErrContextBudget 센티넬 식별(errors.Is)이 깨졌습니다")
|
||
}
|
||
}
|
||
|
||
// TestSideQuestionBrainPreserved: the agent-brain prompts (the answering
|
||
// instruction and the summary instruction) must stay in their benchmarked
|
||
// Chinese. BRIEF 현지화 방침은 두뇌 본문을 번역하지 말고 출력 언어만 한국어로
|
||
// 강제하라는 것이라, 이 두 프롬프트가 한국어로 바뀌면 벤치마크 동작이 드리프트한다.
|
||
func TestSideQuestionBrainPreserved(t *testing.T) {
|
||
for _, c := range []struct{ label, text string }{
|
||
{"instruction", instruction},
|
||
{"summaryInstruction", summaryInstruction},
|
||
} {
|
||
han := false
|
||
for _, r := range c.text {
|
||
if unicode.Is(unicode.Han, r) {
|
||
han = true
|
||
break
|
||
}
|
||
}
|
||
if !han {
|
||
t.Errorf("%s: 두뇌 프롬프트가 더 이상 중국어가 아닙니다(벤치마크 드리프트 위험)", c.label)
|
||
}
|
||
}
|
||
}
|