v0.0.4: add sessions and refine tui
This commit is contained in:
@@ -0,0 +1,170 @@
|
||||
package session
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"agentu/internal/llm"
|
||||
)
|
||||
|
||||
func tempStore(t *testing.T) *Store {
|
||||
t.Helper()
|
||||
dir := t.TempDir()
|
||||
store, err := NewStore(dir)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return store
|
||||
}
|
||||
|
||||
func TestSaveAndLoad(t *testing.T) {
|
||||
store := tempStore(t)
|
||||
sess := &Session{
|
||||
ID: GenerateID(),
|
||||
Name: "test session",
|
||||
Provider: "loveuer",
|
||||
Model: "deepseek-v4-flash",
|
||||
Messages: []llm.Message{
|
||||
{Role: llm.RoleSystem, Content: "you are helpful"},
|
||||
{Role: llm.RoleUser, Content: "hello"},
|
||||
{Role: llm.RoleAssistant, Content: "hi there"},
|
||||
},
|
||||
}
|
||||
if err := store.Save(sess); err != nil {
|
||||
t.Fatalf("save: %v", err)
|
||||
}
|
||||
|
||||
loaded, err := store.Load(sess.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("load: %v", err)
|
||||
}
|
||||
if loaded.ID != sess.ID {
|
||||
t.Errorf("ID = %q, want %q", loaded.ID, sess.ID)
|
||||
}
|
||||
if loaded.Name != sess.Name {
|
||||
t.Errorf("Name = %q, want %q", loaded.Name, sess.Name)
|
||||
}
|
||||
if len(loaded.Messages) != 3 {
|
||||
t.Errorf("Messages len = %d, want 3", len(loaded.Messages))
|
||||
}
|
||||
if loaded.Messages[1].Content != "hello" {
|
||||
t.Errorf("Messages[1].Content = %q, want %q", loaded.Messages[1].Content, "hello")
|
||||
}
|
||||
if loaded.UpdatedAt.IsZero() {
|
||||
t.Error("UpdatedAt should be set")
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadNotFound(t *testing.T) {
|
||||
store := tempStore(t)
|
||||
_, err := store.Load("nonexistent")
|
||||
if err == nil {
|
||||
t.Fatal("expected error for nonexistent session")
|
||||
}
|
||||
}
|
||||
|
||||
func TestList(t *testing.T) {
|
||||
store := tempStore(t)
|
||||
// Empty list
|
||||
metas, err := store.List()
|
||||
if err != nil {
|
||||
t.Fatalf("list: %v", err)
|
||||
}
|
||||
if len(metas) != 0 {
|
||||
t.Errorf("expected empty list, got %d", len(metas))
|
||||
}
|
||||
|
||||
// Save two sessions
|
||||
store.Save(&Session{ID: "aaa", Name: "first", Messages: []llm.Message{{Role: "user", Content: "a"}}})
|
||||
store.Save(&Session{ID: "bbb", Name: "second", Messages: []llm.Message{{Role: "user", Content: "b"}, {Role: "assistant", Content: "c"}}})
|
||||
|
||||
metas, err = store.List()
|
||||
if err != nil {
|
||||
t.Fatalf("list: %v", err)
|
||||
}
|
||||
if len(metas) != 2 {
|
||||
t.Fatalf("expected 2 sessions, got %d", len(metas))
|
||||
}
|
||||
// Sorted by updated_at desc
|
||||
if metas[0].ID != "bbb" && metas[0].ID != "aaa" {
|
||||
t.Errorf("unexpected first session ID: %q", metas[0].ID)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
store := tempStore(t)
|
||||
store.Save(&Session{ID: "todelete", Name: "temp"})
|
||||
|
||||
if err := store.Delete("todelete"); err != nil {
|
||||
t.Fatalf("delete: %v", err)
|
||||
}
|
||||
_, err := store.Load("todelete")
|
||||
if err == nil {
|
||||
t.Fatal("expected error after delete")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteNotFound(t *testing.T) {
|
||||
store := tempStore(t)
|
||||
err := store.Delete("nonexistent")
|
||||
if err == nil {
|
||||
t.Fatal("expected error for nonexistent delete")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSaveRequiresID(t *testing.T) {
|
||||
store := tempStore(t)
|
||||
err := store.Save(&Session{Name: "no id"})
|
||||
if err == nil {
|
||||
t.Fatal("expected error for empty ID")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGenerateID(t *testing.T) {
|
||||
id := GenerateID()
|
||||
if len(id) != 8 {
|
||||
t.Errorf("ID length = %d, want 8", len(id))
|
||||
}
|
||||
id2 := GenerateID()
|
||||
if id == id2 {
|
||||
t.Error("expected unique IDs")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDefaultName(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
messages []llm.Message
|
||||
want string
|
||||
}{
|
||||
{"empty", nil, ""},
|
||||
{"no user msg", []llm.Message{{Role: "system", Content: "hi"}}, ""},
|
||||
{"short", []llm.Message{{Role: "user", Content: "hello world"}}, "hello world"},
|
||||
{"long", []llm.Message{{Role: "user", Content: "this is a really long message that should be truncated at some point in the middle"}}, "this is a really long message that..."},
|
||||
{"multiline", []llm.Message{{Role: "user", Content: "first line\nsecond line"}}, "first line"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got := DefaultName(tt.messages)
|
||||
if got != tt.want {
|
||||
t.Errorf("DefaultName = %q, want %q", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewStoreCreatesDir(t *testing.T) {
|
||||
dir := filepath.Join(t.TempDir(), "nested", "sessions")
|
||||
store, err := NewStore(dir)
|
||||
if err != nil {
|
||||
t.Fatalf("NewStore: %v", err)
|
||||
}
|
||||
info, err := os.Stat(store.dir)
|
||||
if err != nil {
|
||||
t.Fatalf("stat: %v", err)
|
||||
}
|
||||
if !info.IsDir() {
|
||||
t.Error("expected directory")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user