grokkit/cmd/recipe_test.go

150 lines
3.8 KiB
Go
Raw Permalink Normal View History

package cmd
import (
"os"
"path/filepath"
"testing"
)
func TestResolveRecipePathDirectFile(t *testing.T) {
tmpDir := t.TempDir()
recipePath := filepath.Join(tmpDir, "my-recipe.md")
if err := os.WriteFile(recipePath, []byte("# Recipe\n"), 0644); err != nil {
t.Fatal(err)
}
got, err := resolveRecipePath(recipePath)
if err != nil {
t.Fatalf("resolveRecipePath(%q) failed: %v", recipePath, err)
}
if got != recipePath {
t.Errorf("resolveRecipePath() = %q, want %q", got, recipePath)
}
}
func TestResolveRecipePathDirectFileMissing(t *testing.T) {
_, err := resolveRecipePath("/nonexistent/recipe.md")
if err == nil {
t.Fatal("expected error for missing recipe file, got nil")
}
}
func TestResolveRecipePathProjectLocal(t *testing.T) {
tmpDir := t.TempDir()
origDir, _ := os.Getwd()
if err := os.Chdir(tmpDir); err != nil {
t.Fatal(err)
}
defer func() { _ = os.Chdir(origDir) }()
// Create .grokkit/recipes with a recipe, and a .git dir for project root detection
recipeDir := filepath.Join(tmpDir, ".grokkit", "recipes")
if err := os.MkdirAll(recipeDir, 0755); err != nil {
t.Fatal(err)
}
if err := os.MkdirAll(filepath.Join(tmpDir, ".git"), 0755); err != nil {
t.Fatal(err)
}
recipePath := filepath.Join(recipeDir, "refactor.md")
if err := os.WriteFile(recipePath, []byte("# Refactor\n"), 0644); err != nil {
t.Fatal(err)
}
got, err := resolveRecipePath("refactor")
if err != nil {
t.Fatalf("resolveRecipePath('refactor') failed: %v", err)
}
if got != recipePath {
t.Errorf("resolveRecipePath() = %q, want %q", got, recipePath)
}
}
func TestResolveRecipePathNotFound(t *testing.T) {
tmpDir := t.TempDir()
origDir, _ := os.Getwd()
if err := os.Chdir(tmpDir); err != nil {
t.Fatal(err)
}
defer func() { _ = os.Chdir(origDir) }()
// Create .git so findProjectRoot works, but no recipes
if err := os.MkdirAll(filepath.Join(tmpDir, ".git"), 0755); err != nil {
t.Fatal(err)
}
// Override HOME to empty dir so global fallback also fails
oldHome := os.Getenv("HOME")
defer func() { _ = os.Setenv("HOME", oldHome) }()
_ = os.Setenv("HOME", tmpDir)
_, err := resolveRecipePath("nonexistent")
if err == nil {
t.Fatal("expected error for nonexistent recipe, got nil")
}
}
func TestFindProjectRoot(t *testing.T) {
tests := []struct {
name string
marker string
}{
{"git repo", ".git"},
{"gitignore", ".gitignore"},
{"grokkit dir", ".grokkit"},
{"go module", "go.mod"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tmpDir := t.TempDir()
origDir, _ := os.Getwd()
// Create a subdirectory and chdir into it
subDir := filepath.Join(tmpDir, "sub", "deep")
if err := os.MkdirAll(subDir, 0755); err != nil {
t.Fatal(err)
}
if err := os.Chdir(subDir); err != nil {
t.Fatal(err)
}
defer func() { _ = os.Chdir(origDir) }()
// Place the marker at the root
markerPath := filepath.Join(tmpDir, tt.marker)
if tt.marker == ".git" || tt.marker == ".grokkit" {
if err := os.MkdirAll(markerPath, 0755); err != nil {
t.Fatal(err)
}
} else {
if err := os.WriteFile(markerPath, []byte(""), 0644); err != nil {
t.Fatal(err)
}
}
root, err := findProjectRoot()
if err != nil {
t.Fatalf("findProjectRoot() failed: %v", err)
}
if root != tmpDir {
t.Errorf("findProjectRoot() = %q, want %q", root, tmpDir)
}
})
}
}
func TestFindProjectRootNotInProject(t *testing.T) {
tmpDir := t.TempDir()
origDir, _ := os.Getwd()
if err := os.Chdir(tmpDir); err != nil {
t.Fatal(err)
}
defer func() { _ = os.Chdir(origDir) }()
// Empty dir — no markers at all. This will walk up to / and fail.
_, err := findProjectRoot()
if err == nil {
// Might succeed if a parent dir has .git — that's OK in CI
t.Log("findProjectRoot() succeeded (likely found .git in a parent dir)")
}
}