90 lines
4.1 KiB
Go
90 lines
4.1 KiB
Go
package runmgr
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestMaterialApprovalClaims(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
kind string
|
|
field string
|
|
value string
|
|
wantPending bool
|
|
}{
|
|
{"approved text", "analysis", "text", "预算是已批准决定", true},
|
|
{"observed A01 approval error", "analysis", "text", "需求.txt 的总预算50万元、12项需求范围与3项外部接口依赖均写为规定/包含,是已批准决定;接口交付日期尚未确认", true},
|
|
{"approved impact", "analysis", "impact", "审批通过,可执行", true},
|
|
{"approved assumption", "provisional", "assumptions", "批复同意", true},
|
|
{"approved focus", "material_record", "focus", "预算已获批", true},
|
|
{"approved remaining", "material_record", "remaining", "已通过审批", true},
|
|
{"approved next step", "material_record", "nextStep", "预算已经批准,可以推进", true},
|
|
{"approval incomplete", "analysis", "text", "审批尚未完成", false},
|
|
{"not yet approved", "analysis", "text", "预算尚未审批通过", false},
|
|
{"approval not obtained", "needs_user", "text", "预算未获审批通过", false},
|
|
{"approval question", "analysis", "text", "是否已批准需核对", false},
|
|
{"approval question particle", "needs_user", "text", "预算已批准吗", false},
|
|
{"approval direct question", "needs_user", "text", "预算已批准?", false},
|
|
{"approval question aspect", "needs_user", "text", "预算已批准了吗", false},
|
|
{"prevent false approval", "analysis", "text", "防止把50万写成已批准", false},
|
|
{"unrelated prevention does not negate approval", "analysis", "text", "防止风险且预算已批准", true},
|
|
{"unrelated question does not negate approval", "analysis", "text", "是否要修订且预算已批准", true},
|
|
{"later denial does not erase prior assertion", "analysis", "text", "预算已批准但会议说尚未批准", true},
|
|
{"other affirmative after negation", "analysis", "text", "预算尚未审批通过,另一项已批准", true},
|
|
{"other affirmative after question", "analysis", "text", "预算已批准吗?另一项已批准", true},
|
|
{"not an approved increase", "analysis", "text", "不等于已批准增加经费", false},
|
|
{"record is overwritten", "material_record", "text", "上线六月已经批准", false},
|
|
{"user question", "needs_user", "text", "请确认预算是否已批准", false},
|
|
{"user action assertion", "needs_user", "text", "预算已批准,请确认下一步", true},
|
|
}
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
c := checkpointEnvironment(t)
|
|
cp := validCheckpoint(c, "approval-claim")
|
|
cp.Findings[0].Kind = tc.kind
|
|
if tc.kind == "analysis" || tc.kind == "provisional" {
|
|
cp.Findings[0].Assumptions = "材料来源仍需核对"
|
|
}
|
|
switch tc.field {
|
|
case "text":
|
|
cp.Findings[0].Text = tc.value
|
|
case "impact":
|
|
cp.Findings[0].Impact = tc.value
|
|
case "assumptions":
|
|
cp.Findings[0].Assumptions = tc.value
|
|
case "focus":
|
|
cp.Focus = tc.value
|
|
case "remaining":
|
|
cp.Remaining = tc.value
|
|
case "nextStep":
|
|
cp.NextStep = tc.value
|
|
}
|
|
_, err := c.PublishWorkCheckpoint(cp)
|
|
if err != nil {
|
|
t.Fatalf("valid source should become a safe checkpoint: %v", err)
|
|
}
|
|
card, getErr := c.mgr.st.GetCard(c.run.Owner, c.task.cardID)
|
|
if getErr != nil {
|
|
t.Fatal(getErr)
|
|
}
|
|
if len(card.Task.Findings) != 1 {
|
|
t.Fatal("finding missing")
|
|
}
|
|
f := card.Task.Findings[0]
|
|
if tc.wantPending {
|
|
if tc.field == "focus" || tc.field == "remaining" || tc.field == "nextStep" {
|
|
if hasAffirmativeApprovalClaim(card.Task.Focus + card.Task.Remaining + card.Task.NextStep) {
|
|
t.Fatal("unsupported approval escaped into task status")
|
|
}
|
|
} else if f.Kind != "needs_user" || hasAffirmativeApprovalClaim(f.Text+f.Impact+f.Assumptions) {
|
|
t.Fatalf("unsupported approval was not converted to a pending question: %+v", f)
|
|
}
|
|
}
|
|
if tc.kind == "material_record" && (f.Kind != "material_record" || strings.Contains(f.Text, "已经批准")) {
|
|
t.Fatal("model paraphrase escaped material_record canonicalization")
|
|
}
|
|
})
|
|
}
|
|
}
|