package statedir
import (
"os"
"path/filepath"
"testing"
)
// Chats are filed under the config directory, one directory per root, and
// never inside the root itself.
func TestChatsLivesUnderTheConfigDirectory(t *testing.T) {
cfg := t.TempDir()
t.Setenv("XDG_CONFIG_HOME", cfg)
got, err := Chats("/home/someone/src/app")
if err != nil {
t.Fatal(err)
}
if want := filepath.Join(cfg, ChatsDir, "-home-someone-src-app"); got != want {
t.Errorf("Chats = %q, want %q", got, want)
}
other, _ := Chats("/home/someone/src/other")
if other == got {
t.Error("two roots share one chats directory")
}
}
// What an older build left in .codey/ is carried over, so -resume still finds
// yesterday's conversation and ↑ still finds yesterday's command.
func TestMigrateChatsMovesSessionsAndHistory(t *testing.T) {
root := t.TempDir()
dir := filepath.Join(t.TempDir(), "chats")
mkdirWith(t, root, filepath.Join(Dir, SessionsSubdir), "s1.json", `{"id":"s1"}`)
mkdirWith(t, root, filepath.Join(Dir, SessionsSubdir), "s2.json", `{"id":"s2"}`)
mkdirWith(t, root, Dir, HistoryFile, "\"go test\"\n")
mkdirWith(t, root, Dir, "events.jsonl", "{}\n")
moved, err := MigrateChats(root, dir)
if err != nil {
t.Fatalf("MigrateChats: %v", err)
}
if moved != 3 {
t.Errorf("moved = %d, want 3", moved)
}
if got := read(t, filepath.Join(dir, "s1.json")); got != `{"id":"s1"}` {
t.Errorf("s1.json = %q", got)
}
if got := read(t, filepath.Join(dir, HistoryFile)); got != "\"go test\"\n" {
t.Errorf("history = %q", got)
}
if _, err := os.Lstat(filepath.Join(root, Dir, SessionsSubdir)); err == nil {
t.Error("the emptied sessions directory was left behind")
}
// The event log is about the repository and stays with it.
if _, err := os.Lstat(filepath.Join(root, Dir, "events.jsonl")); err != nil {
t.Errorf("events.jsonl moved or lost: %v", err)
}
}
// A session at both ends has been written in both places, and neither copy may
// be overwritten.
func TestMigrateChatsLeavesAClashWhereItIs(t *testing.T) {
root := t.TempDir()
dir := filepath.Join(t.TempDir(), "chats")
mkdirWith(t, root, filepath.Join(Dir, SessionsSubdir), "s1.json", "old")
mkdirWith(t, dir, ".", "s1.json", "new")
moved, err := MigrateChats(root, dir)
if err != nil {
t.Fatalf("MigrateChats: %v", err)
}
if moved != 0 {
t.Errorf("moved = %d, want 0", moved)
}
if got := read(t, filepath.Join(dir, "s1.json")); got != "new" {
t.Errorf("destination = %q, want it untouched", got)
}
if got := read(t, filepath.Join(root, Dir, SessionsSubdir, "s1.json")); got != "old" {
t.Errorf("source = %q, want it left in place", got)
}
}
// The common case: nothing to move, and nothing created.
func TestMigrateChatsWithNothingToMove(t *testing.T) {
dir := filepath.Join(t.TempDir(), "chats")
moved, err := MigrateChats(t.TempDir(), dir)
if err != nil || moved != 0 {
t.Fatalf("MigrateChats = %d, %v; want 0, nil", moved, err)
}
if _, err := os.Lstat(dir); err == nil {
t.Error("created a chats directory with nothing to put in it")
}
}