Add unit tests to improve cmd/bd CLI coverage (bd-llfl)

Added 479 lines of new tests:

- utils_unit_test.go: Tests for utility functions (truncateString,
  pluralize, formatTimeAgo, containsLabel, extractIDSuffix, truncate,
  truncateDescription, showCleanupDeprecationHint, clearAutoFlushState)

- hooks_test.go: Tests for FormatHookWarnings, isRebaseInProgress,
  hasBeadsJSONL

- list_test.go: Tests for formatIssueLong, formatIssueCompact

- version_tracking_test.go: Fixed flaky tests by setting BEADS_DIR
  env var to prevent git worktree detection from finding the actual
  .beads directory instead of the temp directory

Coverage increased from 21.6% to 22.0%. The remaining 78% of untested
code involves daemon/RPC operations, command handlers requiring
database/daemon setup, and git operations that would require
integration tests with mocked dependencies.

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-30 17:12:57 -08:00
parent def4cf4efa
commit 4ab85eeb9d
4 changed files with 479 additions and 0 deletions

View File

@@ -456,6 +456,146 @@ func TestListQueryCapabilitiesSuite(t *testing.T) {
})
}
func TestFormatIssueLong(t *testing.T) {
tests := []struct {
name string
issue *types.Issue
labels []string
want string // substring to check for
}{
{
name: "open issue",
issue: &types.Issue{
ID: "test-123",
Title: "Test Issue",
Priority: 1,
IssueType: types.TypeBug,
Status: types.StatusOpen,
},
labels: nil,
want: "test-123",
},
{
name: "closed issue",
issue: &types.Issue{
ID: "test-456",
Title: "Closed Issue",
Priority: 0,
IssueType: types.TypeTask,
Status: types.StatusClosed,
},
labels: nil,
want: "test-456",
},
{
name: "issue with assignee",
issue: &types.Issue{
ID: "test-789",
Title: "Assigned Issue",
Priority: 2,
IssueType: types.TypeFeature,
Status: types.StatusInProgress,
Assignee: "alice",
},
labels: nil,
want: "Assignee: alice",
},
{
name: "issue with labels",
issue: &types.Issue{
ID: "test-abc",
Title: "Labeled Issue",
Priority: 1,
IssueType: types.TypeBug,
Status: types.StatusOpen,
},
labels: []string{"critical", "security"},
want: "Labels:",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var buf strings.Builder
formatIssueLong(&buf, tt.issue, tt.labels)
result := buf.String()
if !strings.Contains(result, tt.want) {
t.Errorf("formatIssueLong() = %q, want to contain %q", result, tt.want)
}
})
}
}
func TestFormatIssueCompact(t *testing.T) {
tests := []struct {
name string
issue *types.Issue
labels []string
want string
}{
{
name: "basic issue",
issue: &types.Issue{
ID: "test-123",
Title: "Test Issue",
Priority: 1,
IssueType: types.TypeBug,
Status: types.StatusOpen,
},
labels: nil,
want: "Test Issue",
},
{
name: "issue with assignee",
issue: &types.Issue{
ID: "test-456",
Title: "Assigned Issue",
Priority: 2,
IssueType: types.TypeTask,
Status: types.StatusInProgress,
Assignee: "bob",
},
labels: nil,
want: "@bob",
},
{
name: "issue with labels",
issue: &types.Issue{
ID: "test-789",
Title: "Labeled Issue",
Priority: 0,
IssueType: types.TypeFeature,
Status: types.StatusOpen,
},
labels: []string{"urgent"},
want: "[urgent]",
},
{
name: "closed issue",
issue: &types.Issue{
ID: "test-def",
Title: "Closed Issue",
Priority: 3,
IssueType: types.TypeTask,
Status: types.StatusClosed,
},
labels: nil,
want: "Closed Issue",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var buf strings.Builder
formatIssueCompact(&buf, tt.issue, tt.labels)
result := buf.String()
if !strings.Contains(result, tt.want) {
t.Errorf("formatIssueCompact() = %q, want to contain %q", result, tt.want)
}
})
}
}
func TestParseTimeFlag(t *testing.T) {
tests := []struct {
name string