grokkit/internal/prompts/analyze_test.go
Greg Gauthier 5c9689e4da
Some checks failed
CI / Test (push) Successful in 40s
CI / Lint (push) Failing after 20s
CI / Build (push) Successful in 22s
test: add unit tests for cmd, config, git, linter, logger, prompts, todo, and workon
- Introduce tests for analyze, recipe, workon commands
- Expand scaffold tests with language detection and context harvesting
- Add tests for config getters, git utilities (tags, logs, diff)
- Enhance linter with primary language detection tests
- Cover logger level setting branches
- New prompts loading tests with local/global fallback
- Todo bootstrap and structure tests
- Comprehensive workon flow tests including file moves, git integration, README updates
- Update README coverage from 54% to 62%
2026-03-31 22:47:36 +01:00

163 lines
4.4 KiB
Go

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)
}
}