package tui import ( "strings" "testing" "nub/internal/tool" "nub/internal/tool/builtin" ) func TestRenderToolResult_DiffShowsAddAndRemove(t *testing.T) { res := tool.Result{ ForModel: "1 replacement(s)", ForUI: builtin.DiffResult{ Path: "f.go", Lines: []builtin.DiffLine{ {Op: builtin.DiffRemove, Text: "old line"}, {Op: builtin.DiffAdd, Text: "new line"}, }, }, } out := renderToolResult("edit", res) if !strings.Contains(out, "- old line") { t.Errorf("missing removed line in: %q", out) } if !strings.Contains(out, "+ new line") { t.Errorf("missing added line in: %q", out) } } func TestRenderToolResult_ErrorUsesErrorMarker(t *testing.T) { out := renderToolResult("bash", tool.Result{ForModel: "boom", IsError: true}) if !strings.Contains(out, "✗") { t.Errorf("expected error marker in: %q", out) } if strings.Contains(out, "✓") { t.Errorf("did not expect success marker in: %q", out) } } func TestRenderToolResult_OKUsesSuccessMarker(t *testing.T) { out := renderToolResult("bash", tool.Result{ForModel: "ok"}) if !strings.Contains(out, "✓") { t.Errorf("expected success marker in: %q", out) } } func TestWrapForViewport_WrapsLongLinesToWidth(t *testing.T) { long := strings.Repeat("word ", 40) // deutlich länger als 20 Spalten wrapped := wrapForViewport(long, 20) for _, line := range strings.Split(wrapped, "\n") { if len([]rune(line)) > 20 { t.Errorf("line exceeds width 20 (%d runes): %q", len([]rune(line)), line) } } if wrapped == long { t.Error("expected wrapping to actually change the content") } } func TestWrapForViewport_ZeroWidthIsNoop(t *testing.T) { s := "some text that would otherwise wrap" if got := wrapForViewport(s, 0); got != s { t.Errorf("width<=0 should leave content untouched, got %q", got) } } func TestRenderToolCall_PrettyPrintsJSONInput(t *testing.T) { out := renderToolCall("read", []byte(`{"path":"a.go"}`)) if !strings.Contains(out, "read") || !strings.Contains(out, "a.go") { t.Errorf("unexpected render: %q", out) } }