feat(frame): shared ~/owc frame assembler extracted for reuse
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,70 @@
|
||||
// internal/frame/frame_test.go
|
||||
package frame
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"keel/internal/knowledge"
|
||||
"keel/internal/tasks"
|
||||
)
|
||||
|
||||
// fakeTasks is a tasks.Provider returning a fixed list.
|
||||
type fakeTasks struct{ list []tasks.Task }
|
||||
|
||||
// emptyKnowledge is a knowledge.Source that returns no text for any path, so
|
||||
// Assemble emits neither a Goals nor a Life-domains section regardless of what
|
||||
// files exist on the host.
|
||||
type emptyKnowledge struct{}
|
||||
|
||||
func (emptyKnowledge) Load(context.Context, string) (knowledge.Profile, error) {
|
||||
return knowledge.Profile{}, nil
|
||||
}
|
||||
|
||||
func (f fakeTasks) Today(context.Context) ([]tasks.Task, error) { return f.list, nil }
|
||||
func (f fakeTasks) Create(context.Context, tasks.Task) error { return nil }
|
||||
|
||||
func TestAssembleListsTodaysTasks(t *testing.T) {
|
||||
tp := fakeTasks{list: []tasks.Task{{Title: "write the keel spec"}}}
|
||||
got := Assemble(context.Background(), nil, tp)
|
||||
if !strings.Contains(got, "## Today's tasks") {
|
||||
t.Fatalf("missing tasks header:\n%s", got)
|
||||
}
|
||||
if !strings.Contains(got, "write the keel spec") {
|
||||
t.Fatalf("missing task title:\n%s", got)
|
||||
}
|
||||
}
|
||||
|
||||
// With no knowledge source and no tasks, Assemble degrades to a short brief and
|
||||
// never panics — both ports may be nil.
|
||||
func TestAssembleToleratesNilPorts(t *testing.T) {
|
||||
got := Assemble(context.Background(), nil, nil)
|
||||
if !strings.Contains(got, "## Today's tasks") {
|
||||
t.Fatalf("expected a tasks header even with no ports:\n%s", got)
|
||||
}
|
||||
if !strings.Contains(got, "(none)") {
|
||||
t.Fatalf("expected (none) for absent tasks:\n%s", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAssembleWithEmptyKnowledge(t *testing.T) {
|
||||
got := Assemble(context.Background(), emptyKnowledge{}, fakeTasks{})
|
||||
if strings.Contains(got, "## Goals") {
|
||||
t.Fatalf("empty knowledge should not emit a Goals section:\n%s", got)
|
||||
}
|
||||
if strings.Contains(got, "## Life domains") {
|
||||
t.Fatalf("empty knowledge should not emit a Life domains section:\n%s", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTruncateClipsWithMarker(t *testing.T) {
|
||||
in := strings.Repeat("x", MaxBriefBytes+100)
|
||||
got := Truncate(in, MaxBriefBytes)
|
||||
if len(got) > MaxBriefBytes+len("\n…(truncated)") {
|
||||
t.Fatalf("truncate did not clip: len=%d", len(got))
|
||||
}
|
||||
if !strings.HasSuffix(got, "(truncated)") {
|
||||
t.Fatalf("missing truncation marker: %q", got[len(got)-20:])
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user