Skip to content

Commit 1f3b3b8

Browse files
committed
refactor(render): remove display context inspection api
1 parent efa0cf9 commit 1f3b3b8

File tree

10 files changed

+78
-179
lines changed

10 files changed

+78
-179
lines changed

internal/ui/bookmarks/bookmarks_test.go

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package bookmarks
22

33
import (
4-
"fmt"
54
"slices"
5+
"strings"
66
"testing"
77

88
tea "charm.land/bubbletea/v2"
@@ -71,16 +71,11 @@ func TestBookmarks_ZIndex_RendersAboveMainContent(t *testing.T) {
7171

7272
dl := render.NewDisplayContext()
7373
box := layout.Box{R: layout.Rect(0, 0, 100, 40)}
74+
dl.AddDraw(box.R, strings.Repeat("x", box.R.Dx()*box.R.Dy()), render.ZBase)
7475
op.ViewRect(dl, box)
7576

76-
draws := dl.DrawList()
77-
78-
for i, draw := range draws {
79-
msg := fmt.Sprintf("Draw operation %d has z-index %d, expected >= %d. "+
80-
"Bookmarks overlay must render above main content.",
81-
i, draw.Z, render.ZMenuBorder)
82-
assert.GreaterOrEqual(t, draw.Z, render.ZMenuBorder, msg)
83-
}
77+
rendered := dl.RenderToString(box.R.Dx(), box.R.Dy())
78+
assert.Contains(t, rendered, "Remotes:", "bookmarks overlay should remain visible above base content")
8479
}
8580

8681
func Test_FilterIntentPressedTwice_ExecutesShortcut(t *testing.T) {

internal/ui/commandhistory/model_test.go

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package commandhistory
22

33
import (
44
"fmt"
5-
"strings"
65
"testing"
76

87
"github.com/idursun/jjui/internal/ui/common"
@@ -85,14 +84,9 @@ func TestCommandHistory_ViewOnlyShowsSelectedOutput(t *testing.T) {
8584
history.Update(intents.CommandHistoryNavigate{Delta: 1}) // select older
8685

8786
dl := render.NewDisplayContext()
88-
history.ViewRect(dl, layout.NewBox(layout.Rect(0, 0, 60, 12)))
89-
90-
var out strings.Builder
91-
for _, view := range dl.DrawList() {
92-
out.WriteString(view.Content)
93-
out.WriteByte('\n')
94-
}
95-
rendered := out.String()
87+
box := layout.NewBox(layout.Rect(0, 0, 60, 12))
88+
history.ViewRect(dl, box)
89+
rendered := dl.RenderToString(box.R.Dx(), box.R.Dy())
9690
assert.Contains(t, rendered, "jj older")
9791
assert.Contains(t, rendered, "older-output")
9892
assert.Contains(t, rendered, "jj newer")

internal/ui/confirmation/confirmation_test.go

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package confirmation
22

33
import (
4+
"strings"
45
"testing"
56

67
"charm.land/bubbles/v2/key"
@@ -121,29 +122,23 @@ func TestViewRect_DefaultRendersAtZBase(t *testing.T) {
121122

122123
dl := render.NewDisplayContext()
123124
box := layout.Box{R: layout.Rect(0, 0, 50, 20)}
125+
dl.AddDraw(box.R, strings.Repeat("x", box.R.Dx()*box.R.Dy()), render.ZPreview)
124126
model.ViewRect(dl, box)
125127

126-
draws := dl.DrawList()
127-
assert.NotEmpty(t, draws, "Expected confirmation to produce draw operations")
128-
129-
for _, draw := range draws {
130-
assert.Less(t, draw.Z, render.ZPreview,
131-
"Default confirmation should render below preview (ZBase level)")
132-
}
128+
rendered := dl.RenderToString(box.R.Dx(), box.R.Dy())
129+
assert.NotContains(t, rendered, "Test message",
130+
"default confirmation should render below preview content")
133131
}
134132

135133
func TestWithZIndex_RendersAtSpecifiedZIndex(t *testing.T) {
136134
model := New([]string{"Test message"}, WithZIndex(render.ZDialogs))
137135

138136
dl := render.NewDisplayContext()
139137
box := layout.Box{R: layout.Rect(0, 0, 50, 20)}
138+
dl.AddDraw(box.R, strings.Repeat("x", box.R.Dx()*box.R.Dy()), render.ZPreview)
140139
model.ViewRect(dl, box)
141140

142-
draws := dl.DrawList()
143-
assert.NotEmpty(t, draws, "Expected confirmation to produce draw operations")
144-
145-
for _, draw := range draws {
146-
assert.GreaterOrEqual(t, draw.Z, render.ZDialogs,
147-
"Confirmation with WithZIndex(ZDialogs) should render above preview")
148-
}
141+
rendered := dl.RenderToString(box.R.Dx(), box.R.Dy())
142+
assert.Contains(t, rendered, "Test message",
143+
"confirmation with WithZIndex(ZDialogs) should render above preview")
149144
}

internal/ui/flash/flash_test.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package flash
22

33
import (
44
"errors"
5+
"strings"
56
"testing"
67

78
"github.com/idursun/jjui/internal/ui/common"
@@ -67,15 +68,23 @@ func TestView_StacksFromBottomRight(t *testing.T) {
6768
m.add("de", nil)
6869

6970
dl := render.NewDisplayContext()
70-
m.ViewRect(dl, layout.NewBox(layout.Rect(0, 0, 30, 12)))
71-
views := dl.DrawList()
72-
73-
if assert.Len(t, views, 2) {
74-
assert.Contains(t, views[0].Content, "abc")
75-
assert.Contains(t, views[1].Content, "de")
76-
assert.GreaterOrEqual(t, views[0].Rect.Min.X, 0)
77-
assert.GreaterOrEqual(t, views[1].Rect.Min.X, 0)
78-
assert.Greater(t, views[0].Rect.Min.Y, views[1].Rect.Min.Y)
71+
box := layout.NewBox(layout.Rect(0, 0, 30, 12))
72+
m.ViewRect(dl, box)
73+
rendered := strings.Split(dl.RenderToString(box.R.Dx(), box.R.Dy()), "\n")
74+
75+
abcY := -1
76+
deY := -1
77+
for i, line := range rendered {
78+
if strings.Contains(line, "abc") {
79+
abcY = i
80+
}
81+
if strings.Contains(line, "de") {
82+
deY = i
83+
}
84+
}
85+
86+
if assert.NotEqual(t, -1, abcY) && assert.NotEqual(t, -1, deY) {
87+
assert.Greater(t, abcY, deY, "newer flash messages should stack lower on screen")
7988
}
8089
}
8190

internal/ui/git/git_test.go

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package git
22

33
import (
4-
"fmt"
4+
"strings"
55
"testing"
66

77
tea "charm.land/bubbletea/v2"
@@ -114,15 +114,9 @@ func TestGit_ZIndex_RendersAboveMainContent(t *testing.T) {
114114

115115
dl := render.NewDisplayContext()
116116
box := layout.Box{R: layout.Rect(0, 0, 100, 40)}
117+
dl.AddDraw(box.R, strings.Repeat("x", box.R.Dx()*box.R.Dy()), render.ZBase)
117118
op.ViewRect(dl, box)
118119

119-
draws := dl.DrawList()
120-
assert.NotEqual(t, 0, len(draws), "Expected git overlay to produce draw operations")
121-
122-
for i, draw := range draws {
123-
msg := fmt.Sprintf("Draw operation %d has z-index %d, expected >= %d. "+
124-
"Git overlay must render above main content.",
125-
i, draw.Z, render.ZMenuBorder)
126-
assert.GreaterOrEqual(t, draw.Z, render.ZMenuBorder, msg)
127-
}
120+
rendered := dl.RenderToString(box.R.Dx(), box.R.Dy())
121+
assert.Contains(t, rendered, "Remotes:", "git overlay should remain visible above base content")
128122
}

internal/ui/render/display_context.go

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,6 @@ func (dl *DisplayContext) AddInteractionFn(rect layout.Rectangle, fn func(tea.Mo
114114
})
115115
}
116116

117-
// Clear removes all operations from the display context.
118-
// Useful for reusing a DisplayContext across frames.
119-
func (dl *DisplayContext) Clear() {
120-
dl.draws = dl.draws[:0]
121-
dl.effects = dl.effects[:0]
122-
dl.interactions = dl.interactions[:0]
123-
dl.orderCounter = 0
124-
}
125-
126117
// Render executes all operations in the display context to the given screen.
127118
// Order of execution:
128119
// 1. Draw sorted by Z-index (low to high)
@@ -173,71 +164,6 @@ func (dl *DisplayContext) RenderToString(width, height int) string {
173164
return buf.Render()
174165
}
175166

176-
// DrawList returns a copy of all Draw calls (useful for debugging/inspection)
177-
func (dl *DisplayContext) DrawList() []Draw {
178-
result := make([]Draw, len(dl.draws))
179-
for i, op := range dl.draws {
180-
result[i] = op.Draw
181-
}
182-
return result
183-
}
184-
185-
// EffectsList returns a copy of all Effects (useful for debugging/inspection)
186-
func (dl *DisplayContext) EffectsList() []Effect {
187-
result := make([]Effect, len(dl.effects))
188-
for i, op := range dl.effects {
189-
result[i] = op.effect
190-
}
191-
return result
192-
}
193-
194-
// InteractionsList returns all interactions sorted by Z-index (highest first for priority).
195-
func (dl *DisplayContext) InteractionsList() []InteractionOp {
196-
sorted := make([]interactionOp, len(dl.interactions))
197-
copy(sorted, dl.interactions)
198-
sort.SliceStable(sorted, func(i, j int) bool {
199-
if sorted[i].Z != sorted[j].Z {
200-
return sorted[i].Z > sorted[j].Z
201-
}
202-
return sorted[i].order < sorted[j].order
203-
})
204-
result := make([]InteractionOp, len(sorted))
205-
for i, op := range sorted {
206-
result[i] = op.InteractionOp
207-
}
208-
return result
209-
}
210-
211-
// Merge adds all operations from another DisplayContext into this one.
212-
func (dl *DisplayContext) Merge(other *DisplayContext) {
213-
for _, op := range other.draws {
214-
dl.draws = append(dl.draws, drawOp{
215-
Draw: op.Draw,
216-
order: dl.nextOrder(),
217-
})
218-
}
219-
220-
for _, op := range other.effects {
221-
dl.effects = append(dl.effects, effectOp{
222-
effect: op.effect,
223-
order: dl.nextOrder(),
224-
z: op.z,
225-
})
226-
}
227-
228-
for _, op := range other.interactions {
229-
dl.interactions = append(dl.interactions, interactionOp{
230-
InteractionOp: op.InteractionOp,
231-
order: dl.nextOrder(),
232-
})
233-
}
234-
}
235-
236-
// Len returns the total number of operations in the display context
237-
func (dl *DisplayContext) Len() int {
238-
return len(dl.draws) + len(dl.effects) + len(dl.interactions)
239-
}
240-
241167
type drawOp struct {
242168
Draw
243169
order int

internal/ui/render/display_context_test.go

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -193,25 +193,3 @@ func TestEmptyDisplayContext(t *testing.T) {
193193
// Empty buffer output may be empty or whitespace, both are valid
194194
_ = buf.Render()
195195
}
196-
197-
func TestDisplayContext_Reuse(t *testing.T) {
198-
dl := NewDisplayContext()
199-
200-
// First frame
201-
dl.AddDraw(layout.Rect(0, 0, 5, 1), "Frame1", 0)
202-
if dl.Len() != 1 {
203-
t.Errorf("Expected 1 op, got %d", dl.Len())
204-
}
205-
206-
// Clear and reuse
207-
dl.Clear()
208-
if dl.Len() != 0 {
209-
t.Errorf("Expected 0 ops after clear, got %d", dl.Len())
210-
}
211-
212-
// Second frame
213-
dl.AddDraw(layout.Rect(0, 0, 5, 1), "Frame2", 0)
214-
if dl.Len() != 1 {
215-
t.Errorf("Expected 1 op after reuse, got %d", dl.Len())
216-
}
217-
}

internal/ui/render/text_builder_test.go

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ func TestTextBuilder_Write(t *testing.T) {
1919
Write("Hello").
2020
Done()
2121

22-
draws := dl.DrawList()
22+
draws := make([]Draw, len(dl.draws))
23+
for i, op := range dl.draws {
24+
draws[i] = op.Draw
25+
}
2326
if len(draws) != 1 {
2427
t.Fatalf("expected 1 draw, got %d", len(draws))
2528
}
@@ -37,7 +40,10 @@ func TestTextBuilder_Styled(t *testing.T) {
3740
Styled("Bold", style).
3841
Done()
3942

40-
draws := dl.DrawList()
43+
draws := make([]Draw, len(dl.draws))
44+
for i, op := range dl.draws {
45+
draws[i] = op.Draw
46+
}
4147
if len(draws) != 1 {
4248
t.Fatalf("expected 1 draw, got %d", len(draws))
4349
}
@@ -55,12 +61,18 @@ func TestTextBuilder_Clickable(t *testing.T) {
5561
Clickable("Click", lipgloss.Style{}, testClickMsg{ID: 1}).
5662
Done()
5763

58-
draws := dl.DrawList()
64+
draws := make([]Draw, len(dl.draws))
65+
for i, op := range dl.draws {
66+
draws[i] = op.Draw
67+
}
5968
if len(draws) != 1 {
6069
t.Fatalf("expected 1 draw, got %d", len(draws))
6170
}
6271

63-
interactions := dl.InteractionsList()
72+
interactions := make([]InteractionOp, len(dl.interactions))
73+
for i, op := range dl.interactions {
74+
interactions[i] = op.InteractionOp
75+
}
6476
if len(interactions) != 1 {
6577
t.Fatalf("expected 1 interaction, got %d", len(interactions))
6678
}
@@ -87,7 +99,10 @@ func TestTextBuilder_MultipleSegments(t *testing.T) {
8799
Write("C").
88100
Done()
89101

90-
draws := dl.DrawList()
102+
draws := make([]Draw, len(dl.draws))
103+
for i, op := range dl.draws {
104+
draws[i] = op.Draw
105+
}
91106
if len(draws) != 3 {
92107
t.Fatalf("expected 3 draws, got %d", len(draws))
93108
}
@@ -104,7 +119,10 @@ func TestTextBuilder_MultipleSegments(t *testing.T) {
104119
}
105120

106121
// Check only one interaction (for "B")
107-
interactions := dl.InteractionsList()
122+
interactions := make([]InteractionOp, len(dl.interactions))
123+
for i, op := range dl.interactions {
124+
interactions[i] = op.InteractionOp
125+
}
108126
if len(interactions) != 1 {
109127
t.Fatalf("expected 1 interaction, got %d", len(interactions))
110128
}
@@ -151,7 +169,10 @@ func TestTextBuilder_EmptyText(t *testing.T) {
151169
Write("Hello").
152170
Done()
153171

154-
draws := dl.DrawList()
172+
draws := make([]Draw, len(dl.draws))
173+
for i, op := range dl.draws {
174+
draws[i] = op.Draw
175+
}
155176
// Empty string should be skipped
156177
if len(draws) != 1 {
157178
t.Fatalf("expected 1 draw (empty skipped), got %d", len(draws))
@@ -176,7 +197,10 @@ func TestTextBuilder_NewLineAndMeasure(t *testing.T) {
176197
}
177198

178199
tb.Done()
179-
draws := dl.DrawList()
200+
draws := make([]Draw, len(dl.draws))
201+
for i, op := range dl.draws {
202+
draws[i] = op.Draw
203+
}
180204
if len(draws) != 2 {
181205
t.Fatalf("expected 2 draws, got %d", len(draws))
182206
}
@@ -198,7 +222,10 @@ func TestTextBuilder_Space(t *testing.T) {
198222
Write("B").
199223
Done()
200224

201-
draws := dl.DrawList()
225+
draws := make([]Draw, len(dl.draws))
226+
for i, op := range dl.draws {
227+
draws[i] = op.Draw
228+
}
202229
if len(draws) != 3 {
203230
t.Fatalf("expected 3 draws, got %d", len(draws))
204231
}

0 commit comments

Comments
 (0)