test: improve nodb and orphans coverage

This commit is contained in:
Jordan Hubbard
2025-12-28 23:45:17 -04:00
committed by Steve Yegge
parent 9cefa98528
commit cb280b0fad
3 changed files with 146 additions and 71 deletions

View File

@@ -1,82 +1,89 @@
package main
import (
"context"
"os"
"os/exec"
"path/filepath"
"errors"
"strings"
"testing"
"github.com/steveyegge/beads/cmd/bd/doctor"
)
// TestOrphansBasic tests basic orphan detection
func TestOrphansBasic(t *testing.T) {
// Create a temporary directory with a git repo and beads database
tmpDir := t.TempDir()
// Initialize git repo
cmd := exec.Command("git", "init")
cmd.Dir = tmpDir
if err := cmd.Run(); err != nil {
t.Fatalf("Failed to init git repo: %v", err)
}
// Configure git user (needed for commits)
ctx := context.Background()
for _, cmd := range []*exec.Cmd{
exec.CommandContext(ctx, "git", "-C", tmpDir, "config", "user.email", "test@example.com"),
exec.CommandContext(ctx, "git", "-C", tmpDir, "config", "user.name", "Test User"),
} {
if err := cmd.Run(); err != nil {
t.Fatalf("Failed to configure git: %v", err)
func TestFindOrphanedIssues_ConvertsDoctorOutput(t *testing.T) {
orig := doctorFindOrphanedIssues
doctorFindOrphanedIssues = func(path string) ([]doctor.OrphanIssue, error) {
if path != "/tmp/repo" {
t.Fatalf("unexpected path %q", path)
}
return []doctor.OrphanIssue{{
IssueID: "bd-123",
Title: "Fix login",
Status: "open",
LatestCommit: "abc123",
LatestCommitMessage: "(bd-123) implement fix",
}}, nil
}
t.Cleanup(func() { doctorFindOrphanedIssues = orig })
// Create .beads directory
beadsDir := filepath.Join(tmpDir, ".beads")
if err := os.MkdirAll(beadsDir, 0755); err != nil {
t.Fatalf("Failed to create .beads dir: %v", err)
}
// Create a minimal database with beads.db
// For this test, we'll skip creating an actual database
// since the test is primarily about integration
// Test: findOrphanedIssues should handle missing database gracefully
orphans, err := findOrphanedIssues(tmpDir)
result, err := findOrphanedIssues("/tmp/repo")
if err != nil {
t.Fatalf("findOrphanedIssues failed: %v", err)
t.Fatalf("findOrphanedIssues returned error: %v", err)
}
// Should be empty list since no database
if len(orphans) != 0 {
t.Errorf("Expected empty orphans list, got %d", len(orphans))
if len(result) != 1 {
t.Fatalf("expected 1 orphan, got %d", len(result))
}
orphan := result[0]
if orphan.IssueID != "bd-123" || orphan.Title != "Fix login" || orphan.Status != "open" {
t.Fatalf("unexpected orphan output: %#v", orphan)
}
if orphan.LatestCommit != "abc123" || !strings.Contains(orphan.LatestCommitMessage, "implement") {
t.Fatalf("commit metadata not preserved: %#v", orphan)
}
}
// TestOrphansNotGitRepo tests behavior in non-git directories
func TestOrphansNotGitRepo(t *testing.T) {
tmpDir := t.TempDir()
// Should not error, just return empty list
orphans, err := findOrphanedIssues(tmpDir)
if err != nil {
t.Fatalf("findOrphanedIssues failed: %v", err)
func TestFindOrphanedIssues_ErrorWrapped(t *testing.T) {
orig := doctorFindOrphanedIssues
doctorFindOrphanedIssues = func(string) ([]doctor.OrphanIssue, error) {
return nil, errors.New("boom")
}
t.Cleanup(func() { doctorFindOrphanedIssues = orig })
if len(orphans) != 0 {
t.Errorf("Expected empty orphans list for non-git repo, got %d", len(orphans))
_, err := findOrphanedIssues("/tmp/repo")
if err == nil {
t.Fatal("expected error, got nil")
}
if !strings.Contains(err.Error(), "unable to find orphaned issues") {
t.Fatalf("expected wrapped error message, got %v", err)
}
}
// TestCloseIssueCommand tests that close issue command is properly formed
func TestCloseIssueCommand(t *testing.T) {
// This is a basic test to ensure the closeIssue function
// attempts to run the correct command.
// In a real environment, this would fail since bd close requires
// a valid beads database.
func TestCloseIssue_UsesRunner(t *testing.T) {
orig := closeIssueRunner
defer func() { closeIssueRunner = orig }()
// Just test that the function doesn't panic
// (actual close will fail, which is expected)
_ = closeIssue("bd-test-invalid")
// Error is expected since the issue doesn't exist
called := false
closeIssueRunner = func(issueID string) error {
called = true
if issueID != "bd-999" {
t.Fatalf("unexpected issue id %q", issueID)
}
return nil
}
if err := closeIssue("bd-999"); err != nil {
t.Fatalf("closeIssue returned error: %v", err)
}
if !called {
t.Fatal("closeIssueRunner was not invoked")
}
}
func TestCloseIssue_PropagatesError(t *testing.T) {
orig := closeIssueRunner
closeIssueRunner = func(string) error { return errors.New("nope") }
t.Cleanup(func() { closeIssueRunner = orig })
err := closeIssue("bd-1")
if err == nil || !strings.Contains(err.Error(), "nope") {
t.Fatalf("expected delegated error, got %v", err)
}
}