package prompts import ( "os" "path/filepath" "testing" ) func TestLoadAnalysisPromptProjectLocal(t *testing.T) { tmpDir := t.TempDir() promptDir := filepath.Join(tmpDir, ".grokkit", "prompts") if err := os.MkdirAll(promptDir, 0755); err != nil { t.Fatal(err) } expected := "You are a Go expert educator." if err := os.WriteFile(filepath.Join(promptDir, "go.md"), []byte(expected), 0644); err != nil { t.Fatal(err) } path, content, err := LoadAnalysisPrompt(tmpDir, "go") if err != nil { t.Fatalf("LoadAnalysisPrompt failed: %v", err) } if content != expected { t.Errorf("content = %q, want %q", content, expected) } if !filepath.IsAbs(path) || path == "" { // path should be meaningful t.Logf("returned path: %s", path) } } func TestLoadAnalysisPromptGlobalFallback(t *testing.T) { projectDir := t.TempDir() // no .grokkit/prompts here globalDir := t.TempDir() promptDir := filepath.Join(globalDir, ".config", "grokkit", "prompts") if err := os.MkdirAll(promptDir, 0755); err != nil { t.Fatal(err) } expected := "You are a Python expert." if err := os.WriteFile(filepath.Join(promptDir, "python.md"), []byte(expected), 0644); err != nil { t.Fatal(err) } // Override HOME to point to our temp global dir oldHome := os.Getenv("HOME") defer func() { _ = os.Setenv("HOME", oldHome) }() _ = os.Setenv("HOME", globalDir) path, content, err := LoadAnalysisPrompt(projectDir, "python") if err != nil { t.Fatalf("LoadAnalysisPrompt (global fallback) failed: %v", err) } if content != expected { t.Errorf("content = %q, want %q", content, expected) } _ = path } func TestLoadAnalysisPromptProjectOverridesGlobal(t *testing.T) { projectDir := t.TempDir() globalDir := t.TempDir() // Create both project-local and global prompts localPromptDir := filepath.Join(projectDir, ".grokkit", "prompts") if err := os.MkdirAll(localPromptDir, 0755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(localPromptDir, "go.md"), []byte("local prompt"), 0644); err != nil { t.Fatal(err) } globalPromptDir := filepath.Join(globalDir, ".config", "grokkit", "prompts") if err := os.MkdirAll(globalPromptDir, 0755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(globalPromptDir, "go.md"), []byte("global prompt"), 0644); err != nil { t.Fatal(err) } oldHome := os.Getenv("HOME") defer func() { _ = os.Setenv("HOME", oldHome) }() _ = os.Setenv("HOME", globalDir) _, content, err := LoadAnalysisPrompt(projectDir, "go") if err != nil { t.Fatalf("LoadAnalysisPrompt failed: %v", err) } if content != "local prompt" { t.Errorf("expected project-local to override global, got: %q", content) } } func TestLoadAnalysisPromptNotFound(t *testing.T) { projectDir := t.TempDir() emptyHome := t.TempDir() oldHome := os.Getenv("HOME") defer func() { _ = os.Setenv("HOME", oldHome) }() _ = os.Setenv("HOME", emptyHome) _, _, err := LoadAnalysisPrompt(projectDir, "rust") if err == nil { t.Fatal("expected error when no prompt found, got nil") } if !os.IsNotExist(err) { t.Errorf("expected os.ErrNotExist, got: %v", err) } } func TestLoadAnalysisPromptDefaultsToGo(t *testing.T) { projectDir := t.TempDir() promptDir := filepath.Join(projectDir, ".grokkit", "prompts") if err := os.MkdirAll(promptDir, 0755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(promptDir, "go.md"), []byte("go prompt"), 0644); err != nil { t.Fatal(err) } tests := []struct { name string language string }{ {"empty string defaults to go", ""}, {"unknown defaults to go", "unknown"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, content, err := LoadAnalysisPrompt(projectDir, tt.language) if err != nil { t.Fatalf("LoadAnalysisPrompt(%q) failed: %v", tt.language, err) } if content != "go prompt" { t.Errorf("expected go prompt, got: %q", content) } }) } } func TestLoadAnalysisPromptNormalizesCase(t *testing.T) { projectDir := t.TempDir() promptDir := filepath.Join(projectDir, ".grokkit", "prompts") if err := os.MkdirAll(promptDir, 0755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(promptDir, "python.md"), []byte("python prompt"), 0644); err != nil { t.Fatal(err) } _, content, err := LoadAnalysisPrompt(projectDir, "Python") if err != nil { t.Fatalf("LoadAnalysisPrompt with uppercase failed: %v", err) } if content != "python prompt" { t.Errorf("expected case-insensitive match, got: %q", content) } }