93 lines
3.4 KiB
Go
93 lines
3.4 KiB
Go
package legacyimport
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
yaml "gopkg.in/yaml.v3"
|
|
)
|
|
|
|
func nonNilNode() *yaml.Node { return &yaml.Node{Kind: yaml.ScalarNode, Value: "x"} }
|
|
|
|
func TestClaudeSlug(t *testing.T) {
|
|
if got := claudeSlug("/Users/me/Code/proj.x"); got != "-Users-me-Code-proj-x" {
|
|
t.Fatalf("slug = %q", got)
|
|
}
|
|
}
|
|
|
|
func TestPlanTranscriptCopy_DestUsesOrchestratorTemplate(t *testing.T) {
|
|
plan := planTranscriptCopy("/data", "proj", "pre", "/legacy/wt", "uuid-1", "/claude")
|
|
// Destination slug = slug({dataDir}/worktrees/{projectID}/orchestrator/{prefix}-orchestrator).
|
|
wantDest := filepath.Join("/claude", claudeSlug("/data/worktrees/proj/orchestrator/pre-orchestrator"), "uuid-1.jsonl")
|
|
if plan.destPath != wantDest {
|
|
t.Fatalf("destPath = %q, want %q", plan.destPath, wantDest)
|
|
}
|
|
}
|
|
|
|
func TestRelocateTranscript_CopiesAndIsIdempotent(t *testing.T) {
|
|
dir := t.TempDir()
|
|
claudeDir := filepath.Join(dir, "claude")
|
|
worktree := filepath.Join(dir, "wt")
|
|
if err := os.MkdirAll(worktree, 0o750); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Seed the legacy transcript at the source slug. planTranscriptCopy
|
|
// realpath-resolves the worktree, so seed under the resolved slug (matters on
|
|
// macOS where /var/folders is a symlink to /private/var/folders).
|
|
resolvedWt, err := filepath.EvalSymlinks(worktree)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
srcSlug := claudeSlug(resolvedWt)
|
|
srcDir := filepath.Join(claudeDir, srcSlug)
|
|
if err := os.MkdirAll(srcDir, 0o750); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(srcDir, "uuid-1.jsonl"), []byte("hello"), 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
plan := planTranscriptCopy(filepath.Join(dir, "data"), "proj", "pre", worktree, "uuid-1", claudeDir)
|
|
out, err := relocateTranscript(plan)
|
|
if err != nil || out != transcriptCopied {
|
|
t.Fatalf("relocate = (%s,%v), want copied", out, err)
|
|
}
|
|
if b, err := os.ReadFile(plan.destPath); err != nil || string(b) != "hello" {
|
|
t.Fatalf("dest content = %q err=%v", b, err)
|
|
}
|
|
// Re-run: destination already present.
|
|
if out, _ := relocateTranscript(plan); out != transcriptAlreadyPresent {
|
|
t.Fatalf("second relocate = %s, want already-present", out)
|
|
}
|
|
}
|
|
|
|
func TestPlanTranscriptCopy_DestResolvesSymlinkedDataDir(t *testing.T) {
|
|
// The daemon resolves the orchestrator worktree through physicalAbs before
|
|
// cd-ing into it, so the dest slug must use the symlink-resolved data dir —
|
|
// not the literal one — or `claude --resume` misses the bucket.
|
|
realData := t.TempDir()
|
|
linkDir := filepath.Join(t.TempDir(), "data-link")
|
|
if err := os.Symlink(realData, linkDir); err != nil {
|
|
t.Skipf("symlink unsupported: %v", err)
|
|
}
|
|
plan := planTranscriptCopy(linkDir, "proj", "pre", "/legacy/wt", "uuid-1", "/claude")
|
|
|
|
resolvedReal, err := filepath.EvalSymlinks(realData)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
wantSlug := claudeSlug(filepath.Join(resolvedReal, "worktrees", "proj", "orchestrator", "pre-orchestrator"))
|
|
wantDest := filepath.Join("/claude", wantSlug, "uuid-1.jsonl")
|
|
if plan.destPath != wantDest {
|
|
t.Fatalf("destPath = %q,\n want %q (resolved, not the symlinked %q)", plan.destPath, wantDest, linkDir)
|
|
}
|
|
}
|
|
|
|
func TestRelocateTranscript_SourceMissing(t *testing.T) {
|
|
plan := planTranscriptCopy(t.TempDir(), "proj", "pre", "/nope/wt", "uuid-x", filepath.Join(t.TempDir(), "claude"))
|
|
if out, err := relocateTranscript(plan); err != nil || out != transcriptSourceMissing {
|
|
t.Fatalf("relocate = (%s,%v), want source-missing", out, err)
|
|
}
|
|
}
|