feat(daemon-beta t3/t4): 可插拔本地萃取器——claude 路(叫起用戶訂閱跑 /wiki-capture、stub 驗呼叫契約)+gemma 路(實戰 prompt/thought 淨化/httptest 替身);測試 6 支全綠

This commit is contained in:
2026-07-24 12:21:41 +08:00
parent 73a5a67b72
commit be47afe26e
4 changed files with 362 additions and 0 deletions
+61
View File
@@ -0,0 +1,61 @@
// extract_test.go — task 3 claude 萃取路(用 stub 執行檔驗呼叫契約,不需真 claude)。
package main
import (
"fmt"
"os"
"path/filepath"
"runtime"
"testing"
)
// writeStubClaude 產生一支假 claude:驗證收到的參數與 cwd,並寫一張卡進 cards/。
func writeStubClaude(t *testing.T, dir string, script string) string {
t.Helper()
if runtime.GOOS == "windows" {
t.Skip("stub 腳本測試僅跑 unix")
}
p := filepath.Join(dir, "claude")
if err := os.WriteFile(p, []byte("#!/bin/sh\n"+script), 0o755); err != nil {
t.Fatal(err)
}
return p
}
// 正常路:stub 收到 -p "/wiki-capture <檔>"、cwd=監看根,寫卡後被 diff 偵測到。
func TestExtractWithClaudeHappyPath(t *testing.T) {
root := t.TempDir()
if err := os.MkdirAll(filepath.Join(root, "system-dev", "wiki", "cards"), 0o755); err != nil {
t.Fatal(err)
}
stub := writeStubClaude(t, t.TempDir(), fmt.Sprintf(`
[ "$1" = "-p" ] || { echo "第一參數應為 -pgot $1" >&2; exit 9; }
case "$2" in "/wiki-capture 我的筆記.md") ;; *) echo "prompt 錯:$2" >&2; exit 9;; esac
[ "$(pwd)" = "%s" ] || { echo "cwd 錯:$(pwd)" >&2; exit 9; }
mkdir -p system-dev/wiki/cards
printf '# 我的筆記\n\n## 摘要\nstub 卡\n' > "system-dev/wiki/cards/我的筆記.md"
`, root))
cards, err := ExtractWithClaude(stub, root, "我的筆記.md")
if err != nil {
t.Fatal(err)
}
if len(cards) != 1 || cards[0] != "system-dev/wiki/cards/我的筆記.md" {
t.Fatalf("cards=%v", cards)
}
}
// claude 跑完但沒寫卡=誠實報錯(不假綠)。
func TestExtractWithClaudeNoCard(t *testing.T) {
root := t.TempDir()
stub := writeStubClaude(t, t.TempDir(), "exit 0\n")
if _, err := ExtractWithClaude(stub, root, "x.md"); err == nil {
t.Fatal("沒寫卡應報錯")
}
}
// 找不到執行檔=引導改用 gemma 路的錯誤訊息。
func TestExtractWithClaudeMissingBin(t *testing.T) {
if _, err := ExtractWithClaude("/no/such/claude-bin", t.TempDir(), "x.md"); err == nil {
t.Fatal("缺執行檔應報錯")
}
}