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.
This commit is contained in:
Daniel Sauer
2026-01-13 22:19:27 +01:00
committed by GitHub
parent f42ec42268
commit fdd4b0aeb0
16 changed files with 2659 additions and 0 deletions

196
internal/wisp/io_test.go Normal file
View File

@@ -0,0 +1,196 @@
package wisp
import (
"encoding/json"
"os"
"path/filepath"
"testing"
)
func TestEnsureDir(t *testing.T) {
tmpDir := t.TempDir()
// Test creating directory in existing root
dir, err := EnsureDir(tmpDir)
if err != nil {
t.Fatalf("EnsureDir() error = %v", err)
}
expectedDir := filepath.Join(tmpDir, WispDir)
if dir != expectedDir {
t.Errorf("EnsureDir() = %q, want %q", dir, expectedDir)
}
// Verify directory exists
info, err := os.Stat(dir)
if err != nil {
t.Fatalf("Failed to stat directory: %v", err)
}
if !info.IsDir() {
t.Error("EnsureDir() should create a directory")
}
// Test calling again (should be idempotent)
dir2, err := EnsureDir(tmpDir)
if err != nil {
t.Fatalf("EnsureDir() second call error = %v", err)
}
if dir2 != dir {
t.Errorf("EnsureDir() second call = %q, want %q", dir2, dir)
}
}
func TestEnsureDir_Permissions(t *testing.T) {
tmpDir := t.TempDir()
dir, err := EnsureDir(tmpDir)
if err != nil {
t.Fatalf("EnsureDir() error = %v", err)
}
info, err := os.Stat(dir)
if err != nil {
t.Fatalf("Failed to stat directory: %v", err)
}
// Check directory permissions are 0755
expectedPerm := os.FileMode(0755)
if info.Mode().Perm() != expectedPerm {
t.Errorf("Directory permissions = %v, want %v", info.Mode().Perm(), expectedPerm)
}
}
func TestWispPath(t *testing.T) {
tests := []struct {
name string
root string
filename string
want string
}{
{
name: "basic path",
root: "/path/to/root",
filename: "bead.json",
want: "/path/to/root/.beads/bead.json",
},
{
name: "nested filename",
root: "/path/to/root",
filename: "subdir/bead.json",
want: "/path/to/root/.beads/subdir/bead.json",
},
{
name: "empty filename",
root: "/path/to/root",
filename: "",
want: "/path/to/root/.beads",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := WispPath(tt.root, tt.filename)
if got != tt.want {
t.Errorf("WispPath() = %q, want %q", got, tt.want)
}
})
}
}
func TestWispPath_WithWispDir(t *testing.T) {
// Verify WispPath uses WispDir constant
root := "/test/root"
filename := "test.json"
expected := filepath.Join(root, WispDir, filename)
got := WispPath(root, filename)
if got != expected {
t.Errorf("WispPath() = %q, want %q (using WispDir=%q)", got, expected, WispDir)
}
}
func TestWriteJSON_Helper(t *testing.T) {
tmpDir := t.TempDir()
testPath := filepath.Join(tmpDir, "test.json")
type TestData struct {
Name string `json:"name"`
Value int `json:"value"`
}
data := TestData{
Name: "test",
Value: 42,
}
// writeJSON is unexported, so we test it indirectly through other functions
// or we can test the behavior through EnsureDir which uses similar patterns
// For now, test that we can write JSON using AtomicWriteJSON from util package
// which is what wisp would typically use
err := writeJSON(testPath, data)
if err != nil {
t.Fatalf("writeJSON() error = %v", err)
}
// Verify file exists
content, err := os.ReadFile(testPath)
if err != nil {
t.Fatalf("Failed to read file: %v", err)
}
// Verify JSON is valid
var decoded TestData
if err := json.Unmarshal(content, &decoded); err != nil {
t.Fatalf("Failed to unmarshal JSON: %v", err)
}
if decoded.Name != data.Name {
t.Errorf("Name = %q, want %q", decoded.Name, data.Name)
}
if decoded.Value != data.Value {
t.Errorf("Value = %d, want %d", decoded.Value, data.Value)
}
// Verify temp file was cleaned up
tmpPath := testPath + ".tmp"
if _, err := os.Stat(tmpPath); err == nil {
t.Error("Temp file should be removed after successful write")
}
}
func TestWriteJSON_Overwrite(t *testing.T) {
tmpDir := t.TempDir()
testPath := filepath.Join(tmpDir, "test.json")
// Write initial data
initialData := map[string]string{"key": "initial"}
if err := writeJSON(testPath, initialData); err != nil {
t.Fatalf("writeJSON() initial error = %v", err)
}
// Overwrite with new data
newData := map[string]string{"key": "updated", "new": "value"}
if err := writeJSON(testPath, newData); err != nil {
t.Fatalf("writeJSON() overwrite error = %v", err)
}
// Verify data was updated
content, err := os.ReadFile(testPath)
if err != nil {
t.Fatalf("Failed to read file: %v", err)
}
var decoded map[string]string
if err := json.Unmarshal(content, &decoded); err != nil {
t.Fatalf("Failed to unmarshal JSON: %v", err)
}
if decoded["key"] != "updated" {
t.Errorf("key = %q, want %q", decoded["key"], "updated")
}
if decoded["new"] != "value" {
t.Errorf("new = %q, want %q", decoded["new"], "value")
}
}

View File

@@ -0,0 +1,25 @@
package wisp
import "testing"
func TestWispDir(t *testing.T) {
// Test that WispDir constant is defined correctly
expected := ".beads"
if WispDir != expected {
t.Errorf("WispDir = %q, want %q", WispDir, expected)
}
}
func TestWispDirNotEmpty(t *testing.T) {
// Test that WispDir is not empty
if WispDir == "" {
t.Error("WispDir should not be empty")
}
}
func TestWispDirStartsWithDot(t *testing.T) {
// Test that WispDir is a hidden directory (starts with dot)
if len(WispDir) == 0 || WispDir[0] != '.' {
t.Errorf("WispDir should start with '.' for hidden directory, got %q", WispDir)
}
}