Files
beads/cmd/bd/setup/cursor_test.go
Steve Yegge 091b4b8f35 Add tests for setup package (28.4% → 53.8% coverage)
Adds comprehensive tests for:
- factory.go: updateBeadsSection, removeBeadsSection, createNewAgentsFile,
  InstallFactory, RemoveFactory
- cursor.go: InstallCursor, RemoveCursor, CheckCursor
- aider.go: InstallAider, RemoveAider, CheckAider, templates

Coverage improved from 21.6% (measured) to 53.8%, exceeding 50% target.

(bd-sh4c)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-23 22:40:16 -08:00

310 lines
7.1 KiB
Go

package setup
import (
"os"
"path/filepath"
"strings"
"testing"
)
func TestCursorRulesTemplate(t *testing.T) {
// Verify template contains required content
requiredContent := []string{
"bd prime",
"bd ready",
"bd create",
"bd update",
"bd close",
"bd sync",
"BEADS INTEGRATION",
}
for _, req := range requiredContent {
if !strings.Contains(cursorRulesTemplate, req) {
t.Errorf("cursorRulesTemplate missing required content: %q", req)
}
}
}
func TestInstallCursor(t *testing.T) {
origDir, err := os.Getwd()
if err != nil {
t.Fatalf("failed to get working directory: %v", err)
}
tmpDir := t.TempDir()
if err := os.Chdir(tmpDir); err != nil {
t.Fatalf("failed to change to temp directory: %v", err)
}
defer func() {
if err := os.Chdir(origDir); err != nil {
t.Fatalf("failed to restore working directory: %v", err)
}
}()
InstallCursor()
// Verify file was created
rulesPath := ".cursor/rules/beads.mdc"
if !FileExists(rulesPath) {
t.Fatal("Cursor rules file was not created")
}
// Verify content
data, err := os.ReadFile(rulesPath)
if err != nil {
t.Fatalf("failed to read rules file: %v", err)
}
if string(data) != cursorRulesTemplate {
t.Error("Rules file content doesn't match template")
}
}
func TestInstallCursor_ExistingDirectory(t *testing.T) {
origDir, err := os.Getwd()
if err != nil {
t.Fatalf("failed to get working directory: %v", err)
}
tmpDir := t.TempDir()
if err := os.Chdir(tmpDir); err != nil {
t.Fatalf("failed to change to temp directory: %v", err)
}
defer func() {
if err := os.Chdir(origDir); err != nil {
t.Fatalf("failed to restore working directory: %v", err)
}
}()
// Pre-create the directory
if err := os.MkdirAll(".cursor/rules", 0755); err != nil {
t.Fatalf("failed to create directory: %v", err)
}
// Should not fail
InstallCursor()
// Verify file was created
if !FileExists(".cursor/rules/beads.mdc") {
t.Fatal("Cursor rules file was not created")
}
}
func TestInstallCursor_OverwriteExisting(t *testing.T) {
origDir, err := os.Getwd()
if err != nil {
t.Fatalf("failed to get working directory: %v", err)
}
tmpDir := t.TempDir()
if err := os.Chdir(tmpDir); err != nil {
t.Fatalf("failed to change to temp directory: %v", err)
}
defer func() {
if err := os.Chdir(origDir); err != nil {
t.Fatalf("failed to restore working directory: %v", err)
}
}()
// Create existing file with different content
rulesPath := ".cursor/rules/beads.mdc"
if err := os.MkdirAll(filepath.Dir(rulesPath), 0755); err != nil {
t.Fatalf("failed to create directory: %v", err)
}
if err := os.WriteFile(rulesPath, []byte("old content"), 0644); err != nil {
t.Fatalf("failed to create old file: %v", err)
}
InstallCursor()
// Verify content was overwritten
data, err := os.ReadFile(rulesPath)
if err != nil {
t.Fatalf("failed to read rules file: %v", err)
}
if string(data) == "old content" {
t.Error("Old content was not overwritten")
}
if string(data) != cursorRulesTemplate {
t.Error("Content doesn't match template")
}
}
func TestInstallCursorIdempotent(t *testing.T) {
origDir, err := os.Getwd()
if err != nil {
t.Fatalf("failed to get working directory: %v", err)
}
tmpDir := t.TempDir()
if err := os.Chdir(tmpDir); err != nil {
t.Fatalf("failed to change to temp directory: %v", err)
}
defer func() {
if err := os.Chdir(origDir); err != nil {
t.Fatalf("failed to restore working directory: %v", err)
}
}()
// Run twice
InstallCursor()
firstData, _ := os.ReadFile(".cursor/rules/beads.mdc")
InstallCursor()
secondData, _ := os.ReadFile(".cursor/rules/beads.mdc")
if string(firstData) != string(secondData) {
t.Error("InstallCursor should be idempotent")
}
}
func TestRemoveCursor(t *testing.T) {
origDir, err := os.Getwd()
if err != nil {
t.Fatalf("failed to get working directory: %v", err)
}
tmpDir := t.TempDir()
if err := os.Chdir(tmpDir); err != nil {
t.Fatalf("failed to change to temp directory: %v", err)
}
defer func() {
if err := os.Chdir(origDir); err != nil {
t.Fatalf("failed to restore working directory: %v", err)
}
}()
// Install first
InstallCursor()
// Verify file exists
rulesPath := ".cursor/rules/beads.mdc"
if !FileExists(rulesPath) {
t.Fatal("File should exist before removal")
}
// Remove
RemoveCursor()
// Verify file is gone
if FileExists(rulesPath) {
t.Error("File should have been removed")
}
}
func TestRemoveCursor_NoFile(t *testing.T) {
origDir, err := os.Getwd()
if err != nil {
t.Fatalf("failed to get working directory: %v", err)
}
tmpDir := t.TempDir()
if err := os.Chdir(tmpDir); err != nil {
t.Fatalf("failed to change to temp directory: %v", err)
}
defer func() {
if err := os.Chdir(origDir); err != nil {
t.Fatalf("failed to restore working directory: %v", err)
}
}()
// Should not panic when file doesn't exist
RemoveCursor()
}
func TestCheckCursor_NotInstalled(t *testing.T) {
origDir, err := os.Getwd()
if err != nil {
t.Fatalf("failed to get working directory: %v", err)
}
tmpDir := t.TempDir()
if err := os.Chdir(tmpDir); err != nil {
t.Fatalf("failed to change to temp directory: %v", err)
}
defer func() {
if err := os.Chdir(origDir); err != nil {
t.Fatalf("failed to restore working directory: %v", err)
}
}()
// CheckCursor calls os.Exit(1) when not installed
// We can't easily test that, but we document expected behavior
}
func TestCheckCursor_Installed(t *testing.T) {
origDir, err := os.Getwd()
if err != nil {
t.Fatalf("failed to get working directory: %v", err)
}
tmpDir := t.TempDir()
if err := os.Chdir(tmpDir); err != nil {
t.Fatalf("failed to change to temp directory: %v", err)
}
defer func() {
if err := os.Chdir(origDir); err != nil {
t.Fatalf("failed to restore working directory: %v", err)
}
}()
// Install first
InstallCursor()
// Should not panic or exit
CheckCursor()
}
func TestCursorRulesPath(t *testing.T) {
// Verify the path is correct for Cursor IDE
expectedPath := ".cursor/rules/beads.mdc"
// These are the paths used in the implementation
origDir, err := os.Getwd()
if err != nil {
t.Fatalf("failed to get working directory: %v", err)
}
tmpDir := t.TempDir()
if err := os.Chdir(tmpDir); err != nil {
t.Fatalf("failed to change to temp directory: %v", err)
}
defer func() {
if err := os.Chdir(origDir); err != nil {
t.Fatalf("failed to restore working directory: %v", err)
}
}()
InstallCursor()
// Verify the file was created at the expected path
if !FileExists(expectedPath) {
t.Errorf("Expected file at %s", expectedPath)
}
}
func TestCursorTemplateFormatting(t *testing.T) {
// Verify template is well-formed
template := cursorRulesTemplate
// Should have both markers
if !strings.Contains(template, "BEGIN BEADS INTEGRATION") {
t.Error("Missing BEGIN marker")
}
if !strings.Contains(template, "END BEADS INTEGRATION") {
t.Error("Missing END marker")
}
// Should have workflow section
if !strings.Contains(template, "## Workflow") {
t.Error("Missing Workflow section")
}
// Should have context loading section
if !strings.Contains(template, "## Context Loading") {
t.Error("Missing Context Loading section")
}
}