* 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.
194 lines
3.9 KiB
Go
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")
|
|
}
|
|
}
|