mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-11-12 20:27:30 +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
55 lines
1.4 KiB
Go
55 lines
1.4 KiB
Go
package test
|
||
|
||
// internal/log 的黑盒判据:NewManager → Start/Stop 不 panic;
|
||
// RetentionPolicy 常量是对外契约。不读日志文件内容、不碰 m.done。
|
||
|
||
import (
|
||
"context"
|
||
"testing"
|
||
"time"
|
||
|
||
"github.com/JianFeeeee/HologramAgent/internal/log"
|
||
)
|
||
|
||
type stubCfg struct{}
|
||
|
||
func (c *stubCfg) GetString(key, def string) string { return def }
|
||
func (c *stubCfg) GetInt(key string, def int) int { return def }
|
||
|
||
// TestManagerStartStopIsSafe:构造 + 启动 + 停止不得 panic/挂住。
|
||
func TestManagerStartStopIsSafe(t *testing.T) {
|
||
m := log.NewManager(t.TempDir(), &stubCfg{})
|
||
ctx, cancel := context.WithCancel(context.Background())
|
||
m.Start(ctx)
|
||
cancel()
|
||
done := make(chan struct{})
|
||
go func() { m.Stop(); close(done) }()
|
||
select {
|
||
case <-done:
|
||
case <-time.After(3 * time.Second):
|
||
t.Fatal("★ Stop 挂住")
|
||
}
|
||
}
|
||
|
||
// TestManagerStopIsIdempotent:连停两次不得 panic(close 纪律)。
|
||
func TestManagerStopIsIdempotent(t *testing.T) {
|
||
m := log.NewManager(t.TempDir(), &stubCfg{})
|
||
m.Stop()
|
||
m.Stop()
|
||
}
|
||
|
||
// TestRetentionPoliciesAreDistinct:四个策略常量互不相同且非空。
|
||
func TestRetentionPoliciesAreDistinct(t *testing.T) {
|
||
all := []log.RetentionPolicy{
|
||
log.RetentionThisWeek, log.RetentionThisMonth,
|
||
log.RetentionNMonths, log.RetentionForever,
|
||
}
|
||
seen := map[log.RetentionPolicy]bool{}
|
||
for _, p := range all {
|
||
if p == "" || seen[p] {
|
||
t.Fatalf("★ 策略常量为空或重复:%q", p)
|
||
}
|
||
seen[p] = true
|
||
}
|
||
}
|