package service
import (
"context"
"fmt"
"net/http"
"strings"
"testing"
"github.com/stretchr/testify/require"
)
func TestIntelligentAssessmentSeparatesAnswerAndFormat(t *testing.T) {
cfg := IntelligentTestConfig{ExpectedAnswer: "12", AnswerType: "number", AnswerUnit: "颗"}
for _, output := range []string{"12", "最后盒子里有12颗糖。", "ANSWER: 12颗", "**ANSWER: 12**", "```text\nANSWER: 12\n```", "ANSWER: 12\n这是最终数量。", "ANSWER: 12\nANSWER: 12", "ANSWER: 12.0", "ANSWER: 12", `{"answer":12}`, "ANSWER: 24/2", "ANSWER: 1.2e1"} {
t.Run(output, func(t *testing.T) {
result := evaluateIntelligentAnswer(output, cfg)
require.Equal(t, "completed", result.Status)
require.Equal(t, "correct", result.Detail["answer_verdict"], result.Detail)
require.Equal(t, 100.0, *result.Score)
require.Equal(t, "insufficient_evidence", result.Detail["capability_verdict"])
})
}
require.Equal(t, "non_compliant", evaluateIntelligentAnswer("12", cfg).Detail["format_verdict"])
require.Equal(t, "compliant", evaluateIntelligentAnswer("ANSWER: 12颗", cfg).Detail["format_verdict"])
cfg.AnswerFormat = "free_text"
require.Equal(t, "not_required", evaluateIntelligentAnswer("12", cfg).Detail["format_verdict"])
for _, output := range []string{"ANSWER: 12\nANSWER: 11", "ANSWER: 12\n11", `{"answer":12,"final_answer":11}`, "计算中出现12,但无法确定最终答案。", "ANSWER: 12米", "ANSWER: 1e999999", "ANSWER: 1,2", "ANSWER: 12或13", ""} {
result := evaluateIntelligentAnswer(output, cfg)
require.Equal(t, "undetermined", result.Detail["answer_verdict"], output)
require.Nil(t, result.Score)
}
wrong := evaluateIntelligentAnswer("中间值是12\nANSWER: 11", cfg)
require.Equal(t, "incorrect", wrong.Detail["answer_verdict"])
require.Equal(t, 0.0, *wrong.Score)
reasoning := evaluateIntelligentAnswer("错误推导: 2+2=12\nANSWER: 12", cfg)
require.Equal(t, "correct", reasoning.Detail["answer_verdict"])
require.Contains(t, reasoning.Detail["limitation"], "未验证完整推导")
cfg.ExpectedAnswer = "1,200"
require.Equal(t, "correct", evaluateIntelligentAnswer("1200", cfg).Detail["answer_verdict"])
cfg.AnswerType, cfg.ExpectedAnswer = "text", "012"
require.Equal(t, "incorrect", evaluateIntelligentAnswer("12", cfg).Detail["answer_verdict"])
}
func TestIntelligentAssessmentRejectsNegatedAndDuplicateConflicts(t *testing.T) {
cfg := IntelligentTestConfig{ExpectedAnswer: "12", AnswerType: "number", AnswerUnit: "颗"}
for _, output := range []string{"因此答案不是12", "最后盒子里没有12颗糖", "因此假设答案是12", "最终答案可能是12", "因此答案至少为12", "> ANSWER: 12", `{"answer":11,"answer":12}`, `{"answer":12,"answer":11}`} {
result := evaluateIntelligentAnswer(output, cfg)
require.Equal(t, "undetermined", result.Detail["answer_verdict"], output)
require.Nil(t, result.Score, output)
}
require.Equal(t, "correct", evaluateIntelligentAnswer(`{"answer":12,"answer":12}`, cfg).Detail["answer_verdict"])
require.Equal(t, "correct", evaluateIntelligentAnswer("最后盒子里有12颗糖。", cfg).Detail["answer_verdict"])
}
func TestIntelligentAssessmentUnitModesAreExplicit(t *testing.T) {
cfg := IntelligentTestConfig{Prompt: "盒子里有 24 颗糖。小明取走总数的四分之一", ExpectedAnswer: "12", Evaluator: "exact_answer", TimeoutSeconds: 120}
require.Equal(t, "correct", evaluateIntelligentAnswer("12颗", cfg).Detail["answer_verdict"], "old snapshots retain compatibility")
cfg.AnswerUnitMode = "none"
require.Equal(t, "undetermined", evaluateIntelligentAnswer("12颗", cfg).Detail["answer_verdict"])
require.Equal(t, "correct", evaluateIntelligentAnswer("12", cfg).Detail["answer_verdict"])
cfg.AnswerUnitMode = "configured"
require.Error(t, validateIntelligentTestConfig(&cfg, DefaultIntelligentTestEvaluators()))
cfg.AnswerUnit = "颗"
require.NoError(t, validateIntelligentTestConfig(&cfg, DefaultIntelligentTestEvaluators()))
require.Equal(t, "correct", evaluateIntelligentAnswer("12颗糖", cfg).Detail["answer_verdict"])
require.Equal(t, 3, evaluateIntelligentAnswer("12", cfg).Detail["evaluator_version"])
require.NotNil(t, PublicIntelligentAssessment(map[string]any{"evaluator_version": 2, "answer_verdict": "correct"}))
require.False(t, IsCurrentIntelligentAssessment(map[string]any{"evaluator_version": 2}))
}
func TestIntelligentSVGPreviewPreservesStaticDrawingAndRejectsEmpty(t *testing.T) {
raw := ``
safe, adjusted, err := PrepareIntelligentSVGPreview(raw)
require.NoError(t, err)
require.True(t, adjusted)
require.Contains(t, safe, `translate(30 75)`)
require.Contains(t, safe, `fill="#fff"`)
require.Contains(t, safe, `id="eye" cx="91" cy="30" r="2" fill="black"`)
require.Contains(t, safe, `>A