Files
gastown/internal/mail/bd_test.go
Daniel Sauer fdd4b0aeb0 test: Add test coverage for 16 files (40.3% → 45.5%) (#463)
* test: Add test coverage for 16 files (40.3% -> 45.5%)

Add comprehensive tests for previously untested packages:
- internal/agent/state_test.go
- internal/cmd/errors_test.go
- internal/crew/types_test.go
- internal/doctor/errors_test.go
- internal/dog/types_test.go
- internal/mail/bd_test.go
- internal/opencode/plugin_test.go
- internal/rig/overlay_test.go
- internal/runtime/runtime_test.go
- internal/session/town_test.go
- internal/style/style_test.go
- internal/ui/markdown_test.go
- internal/ui/terminal_test.go
- internal/wisp/io_test.go
- internal/wisp/types_test.go
- internal/witness/types_test.go

style_test.go uses func(...string) to match lipgloss variadic Render signature.

* fix(lint): remove unused error return from buildCVSummary

buildCVSummary always returned nil for its error value, causing
golangci-lint to fail with "result 1 (error) is always nil".

The function handles errors internally by returning partial data,
so the error return was misleading. Removed it and updated caller.
2026-01-13 13:19:27 -08:00

194 lines
3.9 KiB
Go

package mail
import (
"errors"
"testing"
)
func TestBdError_Error(t *testing.T) {
tests := []struct {
name string
err *bdError
want string
}{
{
name: "stderr present",
err: &bdError{
Err: errors.New("some error"),
Stderr: "stderr output",
},
want: "stderr output",
},
{
name: "no stderr, has error",
err: &bdError{
Err: errors.New("some error"),
Stderr: "",
},
want: "some error",
},
{
name: "no stderr, no error",
err: &bdError{
Err: nil,
Stderr: "",
},
want: "unknown bd error",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := tt.err.Error()
if got != tt.want {
t.Errorf("bdError.Error() = %q, want %q", got, tt.want)
}
})
}
}
func TestBdError_Unwrap(t *testing.T) {
originalErr := errors.New("original error")
bdErr := &bdError{
Err: originalErr,
Stderr: "stderr output",
}
unwrapped := bdErr.Unwrap()
if unwrapped != originalErr {
t.Errorf("bdError.Unwrap() = %v, want %v", unwrapped, originalErr)
}
}
func TestBdError_UnwrapNil(t *testing.T) {
bdErr := &bdError{
Err: nil,
Stderr: "",
}
unwrapped := bdErr.Unwrap()
if unwrapped != nil {
t.Errorf("bdError.Unwrap() with nil Err should return nil, got %v", unwrapped)
}
}
func TestBdError_ContainsError(t *testing.T) {
tests := []struct {
name string
err *bdError
substr string
contains bool
}{
{
name: "substring present",
err: &bdError{
Stderr: "error: bead not found",
},
substr: "bead not found",
contains: true,
},
{
name: "substring not present",
err: &bdError{
Stderr: "error: bead not found",
},
substr: "permission denied",
contains: false,
},
{
name: "empty stderr",
err: &bdError{
Stderr: "",
},
substr: "anything",
contains: false,
},
{
name: "case sensitive",
err: &bdError{
Stderr: "Error: Bead Not Found",
},
substr: "bead not found",
contains: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := tt.err.ContainsError(tt.substr)
if got != tt.contains {
t.Errorf("bdError.ContainsError(%q) = %v, want %v", tt.substr, got, tt.contains)
}
})
}
}
func TestBdError_ContainsErrorPartialMatch(t *testing.T) {
err := &bdError{
Stderr: "fatal: invalid bead ID format: expected prefix-#id",
}
// Test partial matches
if !err.ContainsError("invalid bead ID") {
t.Error("Should contain partial substring")
}
if !err.ContainsError("fatal:") {
t.Error("Should contain prefix")
}
if !err.ContainsError("expected prefix") {
t.Error("Should contain suffix")
}
}
func TestBdError_ContainsErrorSpecialChars(t *testing.T) {
err := &bdError{
Stderr: "error: bead 'gt-123' not found (exit 1)",
}
if !err.ContainsError("'gt-123'") {
t.Error("Should handle quotes in substring")
}
if !err.ContainsError("(exit 1)") {
t.Error("Should handle parentheses in substring")
}
}
func TestBdError_ImplementsErrorInterface(t *testing.T) {
// Verify bdError implements error interface
var err error = &bdError{
Err: errors.New("test"),
Stderr: "test stderr",
}
_ = err.Error() // Should compile and not panic
}
func TestBdError_WithAllFields(t *testing.T) {
originalErr := errors.New("original error")
bdErr := &bdError{
Err: originalErr,
Stderr: "command failed: bead not found",
}
// Test Error() returns stderr
got := bdErr.Error()
want := "command failed: bead not found"
if got != want {
t.Errorf("bdError.Error() = %q, want %q", got, want)
}
// Test Unwrap() returns original error
unwrapped := bdErr.Unwrap()
if unwrapped != originalErr {
t.Errorf("bdError.Unwrap() = %v, want %v", unwrapped, originalErr)
}
// Test ContainsError works
if !bdErr.ContainsError("bead not found") {
t.Error("ContainsError should find substring in stderr")
}
if bdErr.ContainsError("not present") {
t.Error("ContainsError should return false for non-existent substring")
}
}