Details (original message): Implement the intent core, conformance suite, catalog alignment, examples, and the intentctl diagnostics CLI.
79 lines
2.4 KiB
Go
79 lines
2.4 KiB
Go
package intent
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"os"
|
|
"testing"
|
|
)
|
|
|
|
// corpusCase 与 intentctl eval 共用同一份评测集格式(testdata/corpus.json)。
|
|
type corpusCase struct {
|
|
Name string `json:"name"`
|
|
Input string `json:"input"`
|
|
ExpectBranch string `json:"expect_branch"`
|
|
ExpectTop string `json:"expect_top"`
|
|
ExpectSlots map[string]string `json:"expect_slots"`
|
|
ExpectMissingSlots []string `json:"expect_missing_slots"`
|
|
}
|
|
|
|
type corpusDoc struct {
|
|
Cases []corpusCase `json:"cases"`
|
|
}
|
|
|
|
func runCorpus(t *testing.T, rec Recognizer, snap *Snapshot, cases []corpusCase) {
|
|
t.Helper()
|
|
for _, tc := range cases {
|
|
t.Run(tc.Name, func(t *testing.T) {
|
|
res, err := rec.Recognize(context.Background(), tc.Input, snap)
|
|
if err != nil {
|
|
t.Fatalf("recognize: %v", err)
|
|
}
|
|
if string(res.Branch) != tc.ExpectBranch {
|
|
t.Fatalf("branch = %s, want %s (top=%+v)", res.Branch, tc.ExpectBranch, res.Top)
|
|
}
|
|
if tc.ExpectTop == "" {
|
|
if res.Top != nil {
|
|
t.Fatalf("expected no top, got %+v", res.Top)
|
|
}
|
|
} else if res.Top == nil || res.Top.ID != tc.ExpectTop {
|
|
t.Fatalf("top = %+v, want %s", res.Top, tc.ExpectTop)
|
|
}
|
|
for k, v := range tc.ExpectSlots {
|
|
if res.Top == nil || res.Top.Slots[k] != v {
|
|
t.Fatalf("slot %s = %v, want %v (top=%+v)", k, res.Top.Slots, v, res.Top)
|
|
}
|
|
}
|
|
if len(tc.ExpectMissingSlots) > 0 {
|
|
if res.Top == nil || len(res.Top.MissingRequiredSlots) != len(tc.ExpectMissingSlots) {
|
|
t.Fatalf("missing slots = %+v, want %v", res.Top, tc.ExpectMissingSlots)
|
|
}
|
|
for i, k := range tc.ExpectMissingSlots {
|
|
if res.Top.MissingRequiredSlots[i] != k {
|
|
t.Fatalf("missing slots = %+v, want %v", res.Top.MissingRequiredSlots, tc.ExpectMissingSlots)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestEvalCorpus 是模块自带的评测集回归:守护内容 Go 内置 + 业务意图 JSON 配置,
|
|
// 覆盖正常路径、守卫拦截、否定写硬负例、必填槽位缺失与大小写折叠。
|
|
func TestEvalCorpus(t *testing.T) {
|
|
data, err := os.ReadFile("testdata/corpus.json")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var doc corpusDoc
|
|
if err := json.Unmarshal(data, &doc); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(doc.Cases) == 0 {
|
|
t.Fatal("empty corpus")
|
|
}
|
|
_, snap := buildDemoRegistry(t)
|
|
rec := NewRecognizer(Options{}, nil, nil)
|
|
runCorpus(t, rec, snap, doc.Cases)
|
|
}
|