mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-11-12 12:17:36 +00:00
4 个文件全部在 `<module>/test/`,源码目录仍零 `_test.go`。
共 20 条判据,只调导出接口,输入 → 可观察输出。
## internal/agent —— 人格文件
TestSaveThenLoadPersonality Save → Load 内容/路径
TestLoadMissingPersonalityGivesEmpty 文件不存在 → 空人格
TestInjectPromptContainsContentAndRules 注入含原文 + 内核说话规则
TestInjectPromptEmptyPersonalityIsEmpty
TestPersonaStaleHints 陈旧措辞给提示;干净文本不报
TestSavePersonalityCreatesParentDirs 自动建父目录
## internal/lua —— VM 适配器
TestNewVMExposesAdapterDir 构造参数 → AdapterDir
TestListAdaptersEmptyThenLoaded LoadAdapterSource → ListAdapters
TestLoadAdapterSourceRejectsBadScript
TestCallTransformRequestUnknownAdapter
TestGetAdapterEndpointUnknownIsEmpty
## providers/ollama —— httptest 真实 HTTP
TestGenerateReturnsText 200 → Response.Text
TestGenerateMarksTruncated done_reason=length → Truncated
TestGenerateHTTPError 5xx → 报错
TestGenerateRejectsInvalidJSONSchema
TestNewFallsBackToDefaultModel 空 model 走默认值
**判据写错过一次**:第一版断言"空 model 构造失败",但 `optString`
对空值回退默认,构造成功才是真实契约,按此修正。
## internal/log —— Manager 生命周期
TestManagerStartStopIsSafe Start/cancel/Stop 不挂住
TestManagerStopIsIdempotent 连停两次不 panic
TestRetentionPoliciesAreDistinct 四个策略常量互异
## 变异验证(改回旧实现必须红)
agent SavePersonality 不建父目录 → ★ 文件没落盘
lua ListAdapters 恒空 → ★ ListAdapters = [],期望 1 个
ollama 丢 Truncated → ★ done_reason=length 未标记 Truncated
log Stop 重复 close → panic: close of closed channel
lua / log 第一版变异分别是文本不匹配与"import 变未使用导致编译失败",
都不算干净的断言红;重做成只改行为后确认有效。
## 验证
go build ./... PASS
go vet ./... PASS
gofmt -l 干净
python3 .github/scripts/check-ci-gates.py PASS
go test ./... -count=1 39 个测试包 / 100 包无测试 / 0 FAIL
4 个新包 -race 全绿
源码目录 _test.go 0
86 lines
2.8 KiB
Go
86 lines
2.8 KiB
Go
package test
|
||
|
||
// internal/agent 的黑盒判据:人格文件往返 + InjectPrompt 输出。
|
||
// 不碰内部正则表、不读源码。
|
||
|
||
import (
|
||
"os"
|
||
"path/filepath"
|
||
"strings"
|
||
"testing"
|
||
|
||
"github.com/JianFeeeee/HologramAgent/internal/agent"
|
||
)
|
||
|
||
// TestSaveThenLoadPersonality:Save → Load 拿回原文与路径。
|
||
func TestSaveThenLoadPersonality(t *testing.T) {
|
||
path := filepath.Join(t.TempDir(), "nested", "personal.md")
|
||
const content = "你是小宅,说话自然一点。"
|
||
if err := agent.SavePersonality(path, content); err != nil {
|
||
t.Fatalf("SavePersonality: %v", err)
|
||
}
|
||
p, err := agent.LoadPersonality(path)
|
||
if err != nil {
|
||
t.Fatalf("LoadPersonality: %v", err)
|
||
}
|
||
if p.Content != content {
|
||
t.Fatalf("★ Content = %q,期望原文", p.Content)
|
||
}
|
||
if p.Path != path {
|
||
t.Fatalf("★ Path = %q,期望 %q", p.Path, path)
|
||
}
|
||
}
|
||
|
||
// TestLoadMissingPersonalityGivesEmpty:文件不存在返回空人格而非报错。
|
||
func TestLoadMissingPersonalityGivesEmpty(t *testing.T) {
|
||
p, err := agent.LoadPersonality(filepath.Join(t.TempDir(), "nope.md"))
|
||
if err != nil {
|
||
t.Fatalf("★ 文件不存在却报错:%v", err)
|
||
}
|
||
if p == nil || p.Content != "" {
|
||
t.Fatalf("★ 期望空人格,实际 %+v", p)
|
||
}
|
||
}
|
||
|
||
// TestInjectPromptContainsContentAndRules:非空人格注入后含原文与说话规则。
|
||
func TestInjectPromptContainsContentAndRules(t *testing.T) {
|
||
p := &agent.Personality{Content: "你是小宅"}
|
||
out := p.InjectPrompt()
|
||
if !strings.Contains(out, "你是小宅") || !strings.Contains(out, "[Persona]") {
|
||
t.Fatalf("★ InjectPrompt 输出不符:%q", out)
|
||
}
|
||
if len(out) <= len(p.Content) {
|
||
t.Fatal("★ 内核没追加说话规则")
|
||
}
|
||
}
|
||
|
||
// TestInjectPromptEmptyPersonalityIsEmpty:空人格不注入任何内容。
|
||
func TestInjectPromptEmptyPersonalityIsEmpty(t *testing.T) {
|
||
if got := (&agent.Personality{}).InjectPrompt(); got != "" {
|
||
t.Fatalf("★ 空人格却注入了内容:%q", got)
|
||
}
|
||
}
|
||
|
||
// TestPersonaStaleHints:含版本号字面量/陈旧措辞时给出提示;干净文本不提示。
|
||
func TestPersonaStaleHints(t *testing.T) {
|
||
dirty := "你是 HΔ-Kernel v1.0.3 型号的家政型 AI 管家助手。"
|
||
if got := agent.PersonaStaleHints(dirty); len(got) == 0 {
|
||
t.Fatal("★ 陈旧人格卡没给出提示")
|
||
}
|
||
clean := "你是小宅,说话自然,别用客服腔。"
|
||
if got := agent.PersonaStaleHints(clean); len(got) != 0 {
|
||
t.Fatalf("★ 干净人格卡被误报:%v", got)
|
||
}
|
||
}
|
||
|
||
// TestSavePersonalityCreatesParentDirs:父目录不存在时自动创建。
|
||
func TestSavePersonalityCreatesParentDirs(t *testing.T) {
|
||
path := filepath.Join(t.TempDir(), "a", "b", "personal.md")
|
||
if err := agent.SavePersonality(path, "x"); err != nil {
|
||
t.Fatalf("SavePersonality: %v", err)
|
||
}
|
||
if _, err := os.Stat(path); err != nil {
|
||
t.Fatalf("★ 文件没落盘:%v", err)
|
||
}
|
||
}
|