216 lines
5.4 KiB
Go
216 lines
5.4 KiB
Go
package tools
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"testing"
|
||
|
||
"github.com/voocel/ainovel-cli/domain"
|
||
"github.com/voocel/ainovel-cli/state"
|
||
)
|
||
|
||
func TestReadChapterFinal(t *testing.T) {
|
||
dir := t.TempDir()
|
||
store := state.NewStore(dir)
|
||
if err := store.Init(); err != nil {
|
||
t.Fatalf("Init: %v", err)
|
||
}
|
||
if err := store.SaveFinalChapter(1, "第一章的终稿正文。"); err != nil {
|
||
t.Fatalf("SaveFinalChapter: %v", err)
|
||
}
|
||
|
||
tool := NewReadChapterTool(store)
|
||
args, _ := json.Marshal(map[string]any{"chapter": 1, "source": "final"})
|
||
result, err := tool.Execute(context.Background(), args)
|
||
if err != nil {
|
||
t.Fatalf("Execute: %v", err)
|
||
}
|
||
|
||
var payload struct {
|
||
Chapter int `json:"chapter"`
|
||
Content string `json:"content"`
|
||
WordCount int `json:"word_count"`
|
||
}
|
||
if err := json.Unmarshal(result, &payload); err != nil {
|
||
t.Fatalf("Unmarshal: %v", err)
|
||
}
|
||
if payload.Content == "" {
|
||
t.Fatal("expected non-empty content")
|
||
}
|
||
if payload.WordCount == 0 {
|
||
t.Fatal("expected non-zero word count")
|
||
}
|
||
}
|
||
|
||
func TestReadChapterDraft(t *testing.T) {
|
||
dir := t.TempDir()
|
||
store := state.NewStore(dir)
|
||
if err := store.Init(); err != nil {
|
||
t.Fatalf("Init: %v", err)
|
||
}
|
||
if err := store.SaveDraft(3, "第三章的草稿内容。"); err != nil {
|
||
t.Fatalf("SaveDraft: %v", err)
|
||
}
|
||
|
||
tool := NewReadChapterTool(store)
|
||
args, _ := json.Marshal(map[string]any{"chapter": 3, "source": "draft"})
|
||
result, err := tool.Execute(context.Background(), args)
|
||
if err != nil {
|
||
t.Fatalf("Execute: %v", err)
|
||
}
|
||
|
||
var payload struct {
|
||
Content string `json:"content"`
|
||
}
|
||
if err := json.Unmarshal(result, &payload); err != nil {
|
||
t.Fatalf("Unmarshal: %v", err)
|
||
}
|
||
if payload.Content == "" {
|
||
t.Fatal("expected draft content")
|
||
}
|
||
}
|
||
|
||
func TestReadChapterDialogue(t *testing.T) {
|
||
dir := t.TempDir()
|
||
store := state.NewStore(dir)
|
||
if err := store.Init(); err != nil {
|
||
t.Fatalf("Init: %v", err)
|
||
}
|
||
if err := store.SaveCharacters([]domain.Character{
|
||
{Name: "张三", Aliases: []string{"老张"}},
|
||
}); err != nil {
|
||
t.Fatalf("SaveCharacters: %v", err)
|
||
}
|
||
if err := store.SaveFinalChapter(1, "张三站起身来。\u201c我不同意这个方案,\u201d张三冷冷地说。"); err != nil {
|
||
t.Fatalf("SaveFinalChapter: %v", err)
|
||
}
|
||
|
||
tool := NewReadChapterTool(store)
|
||
args, _ := json.Marshal(map[string]any{"source": "final", "character": "张三"})
|
||
result, err := tool.Execute(context.Background(), args)
|
||
if err != nil {
|
||
t.Fatalf("Execute: %v", err)
|
||
}
|
||
|
||
var payload struct {
|
||
Character string `json:"character"`
|
||
Samples []string `json:"samples"`
|
||
}
|
||
if err := json.Unmarshal(result, &payload); err != nil {
|
||
t.Fatalf("Unmarshal: %v", err)
|
||
}
|
||
if payload.Character != "张三" {
|
||
t.Fatalf("expected character 张三, got %s", payload.Character)
|
||
}
|
||
}
|
||
|
||
func TestReadChapterRange(t *testing.T) {
|
||
dir := t.TempDir()
|
||
store := state.NewStore(dir)
|
||
if err := store.Init(); err != nil {
|
||
t.Fatalf("Init: %v", err)
|
||
}
|
||
for i := 1; i <= 3; i++ {
|
||
if err := store.SaveFinalChapter(i, "这是一段正文内容。"); err != nil {
|
||
t.Fatalf("SaveFinalChapter(%d): %v", i, err)
|
||
}
|
||
}
|
||
|
||
tool := NewReadChapterTool(store)
|
||
args, _ := json.Marshal(map[string]any{"from": 1, "to": 3, "source": "final"})
|
||
result, err := tool.Execute(context.Background(), args)
|
||
if err != nil {
|
||
t.Fatalf("Execute: %v", err)
|
||
}
|
||
|
||
var payload struct {
|
||
Chapters map[string]string `json:"chapters"`
|
||
}
|
||
if err := json.Unmarshal(result, &payload); err != nil {
|
||
t.Fatalf("Unmarshal: %v", err)
|
||
}
|
||
if len(payload.Chapters) != 3 {
|
||
t.Fatalf("expected 3 chapters, got %d", len(payload.Chapters))
|
||
}
|
||
}
|
||
|
||
func TestDraftChapterWrite(t *testing.T) {
|
||
dir := t.TempDir()
|
||
store := state.NewStore(dir)
|
||
if err := store.Init(); err != nil {
|
||
t.Fatalf("Init: %v", err)
|
||
}
|
||
|
||
tool := NewDraftChapterTool(store)
|
||
args, _ := json.Marshal(map[string]any{
|
||
"chapter": 1,
|
||
"content": "这是整章的正文内容,一次写完。",
|
||
"mode": "write",
|
||
})
|
||
result, err := tool.Execute(context.Background(), args)
|
||
if err != nil {
|
||
t.Fatalf("Execute: %v", err)
|
||
}
|
||
|
||
var payload struct {
|
||
Written bool `json:"written"`
|
||
WordCount int `json:"word_count"`
|
||
}
|
||
if err := json.Unmarshal(result, &payload); err != nil {
|
||
t.Fatalf("Unmarshal: %v", err)
|
||
}
|
||
if !payload.Written {
|
||
t.Fatal("expected written=true")
|
||
}
|
||
if payload.WordCount == 0 {
|
||
t.Fatal("expected non-zero word count")
|
||
}
|
||
|
||
// 验证能读回来
|
||
content, err := store.LoadDraft(1)
|
||
if err != nil {
|
||
t.Fatalf("LoadDraft: %v", err)
|
||
}
|
||
if content == "" {
|
||
t.Fatal("expected non-empty draft")
|
||
}
|
||
}
|
||
|
||
func TestDraftChapterAppend(t *testing.T) {
|
||
dir := t.TempDir()
|
||
store := state.NewStore(dir)
|
||
if err := store.Init(); err != nil {
|
||
t.Fatalf("Init: %v", err)
|
||
}
|
||
if err := store.SaveDraft(2, "前半部分。"); err != nil {
|
||
t.Fatalf("SaveDraft: %v", err)
|
||
}
|
||
|
||
tool := NewDraftChapterTool(store)
|
||
args, _ := json.Marshal(map[string]any{
|
||
"chapter": 2,
|
||
"content": "后半部分。",
|
||
"mode": "append",
|
||
})
|
||
result, err := tool.Execute(context.Background(), args)
|
||
if err != nil {
|
||
t.Fatalf("Execute: %v", err)
|
||
}
|
||
|
||
var payload struct {
|
||
Mode string `json:"mode"`
|
||
WordCount int `json:"word_count"`
|
||
}
|
||
if err := json.Unmarshal(result, &payload); err != nil {
|
||
t.Fatalf("Unmarshal: %v", err)
|
||
}
|
||
if payload.Mode != "append" {
|
||
t.Fatalf("expected mode=append, got %s", payload.Mode)
|
||
}
|
||
|
||
content, _ := store.LoadDraft(2)
|
||
if content == "" || content == "前半部分。" {
|
||
t.Fatal("expected appended content")
|
||
}
|
||
}
|