Files
beads/cmd/bd/onboard_test.go
Tim Haasdyk 07c97a2b74 fix: make bd onboard output generic, not beads-specific (#465)
The copilotInstructionsContent in onboard.go contained content specific to
developing the beads project itself (Go tech stack, SQLite, Cobra, project
structure, release scripts, etc.). This content doesn't make sense when
running bd onboard in other repositories that use bd for issue tracking.

Removed:
- Tech Stack section (Go, SQLite, Cobra, etc.)
- Coding Guidelines section (beads development instructions)
- Project Structure section (beads directory tree)
- Scripts section (bump-version.sh, release.sh, etc.)
- Key Documentation section (beads-specific docs)
- Beads-specific rules (BEADS_DB testing, test issues in production DB)

Kept:
- All bd command examples and workflow (unchanged)
- Priorities and issue types
- MCP server instructions
- Generic rules applicable to any project using bd

The beads repo's own .github/copilot-instructions.md is manually maintained
and still contains the beads-specific development instructions.
2025-12-05 13:20:51 -08:00

190 lines
5.1 KiB
Go

package main
import (
"bytes"
"os"
"path/filepath"
"strings"
"testing"
)
func TestOnboardCommand(t *testing.T) {
t.Run("onboard output contains key sections", func(t *testing.T) {
var buf bytes.Buffer
if err := renderOnboardInstructions(&buf); err != nil {
t.Fatalf("renderOnboardInstructions() error = %v", err)
}
output := buf.String()
// Verify output contains expected sections
expectedSections := []string{
"bd Onboarding Instructions",
"Update AGENTS.md",
"Update CLAUDE.md",
"BEGIN AGENTS.MD CONTENT",
"END AGENTS.MD CONTENT",
"Issue Tracking with bd (beads)",
"Managing AI-Generated Planning Documents",
"history/",
}
for _, section := range expectedSections {
if !strings.Contains(output, section) {
t.Errorf("Expected output to contain '%s', but it was missing", section)
}
}
})
t.Run("agents content includes slop management", func(t *testing.T) {
// Verify the agentsContent constant includes the new slop management section
if !strings.Contains(agentsContent, "Managing AI-Generated Planning Documents") {
t.Error("agentsContent should contain 'Managing AI-Generated Planning Documents' section")
}
if !strings.Contains(agentsContent, "history/") {
t.Error("agentsContent should mention the 'history/' directory")
}
if !strings.Contains(agentsContent, "PLAN.md") {
t.Error("agentsContent should mention example files like 'PLAN.md'")
}
if !strings.Contains(agentsContent, "Do NOT clutter repo root with planning documents") {
t.Error("agentsContent should include rule about not cluttering repo root")
}
})
t.Run("agents content includes bd workflow", func(t *testing.T) {
// Verify essential bd workflow content is present
essentialContent := []string{
"bd ready",
"bd create",
"bd update",
"bd close",
"discovered-from",
"--json",
"MCP Server",
}
for _, content := range essentialContent {
if !strings.Contains(agentsContent, content) {
t.Errorf("agentsContent should contain '%s'", content)
}
}
})
}
func TestGenerateBDGuide(t *testing.T) {
t.Run("generates BD_GUIDE.md with version stamp", func(t *testing.T) {
// Create temp directory
tmpDir := t.TempDir()
outputPath := filepath.Join(tmpDir, "BD_GUIDE.md")
// Generate BD_GUIDE.md
if err := generateBDGuide(outputPath); err != nil {
t.Fatalf("generateBDGuide() error = %v", err)
}
// Read generated file
content, err := os.ReadFile(outputPath)
if err != nil {
t.Fatalf("Failed to read generated file: %v", err)
}
output := string(content)
// Verify version stamp in header
if !strings.Contains(output, "Auto-generated by bd v"+Version) {
t.Error("Generated file should contain version stamp in header")
}
if !strings.Contains(output, "DO NOT EDIT MANUALLY") {
t.Error("Generated file should contain DO NOT EDIT warning")
}
// Verify regeneration instructions
if !strings.Contains(output, "bd onboard --output") {
t.Error("Generated file should contain regeneration instructions")
}
})
t.Run("includes agents content", func(t *testing.T) {
tmpDir := t.TempDir()
outputPath := filepath.Join(tmpDir, "BD_GUIDE.md")
if err := generateBDGuide(outputPath); err != nil {
t.Fatalf("generateBDGuide() error = %v", err)
}
content, err := os.ReadFile(outputPath)
if err != nil {
t.Fatalf("Failed to read generated file: %v", err)
}
output := string(content)
// Verify key sections from agentsContent are present
expectedSections := []string{
"Issue Tracking with bd (beads)",
"bd ready",
"bd create",
"MCP Server",
}
for _, section := range expectedSections {
if !strings.Contains(output, section) {
t.Errorf("Generated file should contain '%s'", section)
}
}
})
t.Run("includes copilot instructions content", func(t *testing.T) {
tmpDir := t.TempDir()
outputPath := filepath.Join(tmpDir, "BD_GUIDE.md")
if err := generateBDGuide(outputPath); err != nil {
t.Fatalf("generateBDGuide() error = %v", err)
}
content, err := os.ReadFile(outputPath)
if err != nil {
t.Fatalf("Failed to read generated file: %v", err)
}
output := string(content)
// Verify key sections from copilotInstructionsContent are present
expectedSections := []string{
"GitHub Copilot Instructions",
"Issue Tracking with bd",
"Essential Commands",
"Important Rules",
}
for _, section := range expectedSections {
if !strings.Contains(output, section) {
t.Errorf("Generated file should contain '%s'", section)
}
}
})
t.Run("has proper structure with separators", func(t *testing.T) {
tmpDir := t.TempDir()
outputPath := filepath.Join(tmpDir, "BD_GUIDE.md")
if err := generateBDGuide(outputPath); err != nil {
t.Fatalf("generateBDGuide() error = %v", err)
}
content, err := os.ReadFile(outputPath)
if err != nil {
t.Fatalf("Failed to read generated file: %v", err)
}
output := string(content)
// Count separators (should have at least 3: after header, between sections, before footer)
separatorCount := strings.Count(output, "---")
if separatorCount < 3 {
t.Errorf("Expected at least 3 separators (---), got %d", separatorCount)
}
})
}