Add tests for drawing search matches

No test checks yet which cells draw shows as search matches. The next
commit changes how draw works this out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Stefan Haller
2026-11-12 11:28:00 +01:00
co-authored by Claude Opus 5.5
parent 0d77b04db3
commit 0bb4566554
+114
View File
@@ -57,6 +57,120 @@ func BenchmarkWriteToSearchedView(b *testing.B) {
}
}
// drawSearchHighlights draws the view and returns how each of its rows is highlighted:
// "#" for a search match, "*" for the current one, and "." for neither.
func drawSearchHighlights(v *View) []string {
v.draw(true)
width, height := v.InnerSize()
rows := make([]string, 0, height)
for y := range height {
row := ""
for x := range width {
_, style, _ := Screen.Get(v.x0+x+1, v.y0+y+1)
switch style.GetBackground() {
case getTcellColor(ColorYellow, OutputNormal):
row += "#"
case getTcellColor(ColorCyan, OutputNormal):
row += "*"
default:
row += "."
}
}
rows = append(rows, row)
}
return rows
}
// The search matches on screen are highlighted, and the current one in a color of its
// own.
func TestDrawSearchMatches(t *testing.T) {
WithSimulationScreen(t, 14, 6)
v := NewView("name", 0, 0, 11, 5, OutputNormal) // InnerWidth 10, InnerHeight 4
writeLines(v,
"ab",
"abab xab",
"no match",
"xxxxxxxxxab xxxxx ab",
"ab ab",
"ab",
)
v.Search("ab", nil)
_ = v.gotoNextMatch()
_ = v.gotoNextMatch()
index, total := v.GetSearchStatus()
assert.Equal(t, 2, index, "the current match is the second one in the second line")
assert.Equal(t, 9, total)
// Scrolled down past the first line, so that the last line is off screen too.
v.SetOriginY(1)
assert.Equal(t,
[]string{
"##**..##..", // abab xab
"..........", // no match
".........#", // xxxxxxxxxa
"##.##.....", // ab ab
},
drawSearchHighlights(v))
// Scrolled sideways, matches show where they are partly on screen.
v.SetOriginX(3)
assert.Equal(t,
[]string{
"*..##.....", // b xab
"..........", // match
"......##..", // xxxxxxab x
"##........", // ab
},
drawSearchHighlights(v))
}
// Where matches overlap, a cell is highlighted as part of the first match it is in.
func TestDrawOverlappingSearchMatches(t *testing.T) {
WithSimulationScreen(t, 14, 6)
v := NewView("name", 0, 0, 11, 2, OutputNormal) // InnerWidth 10, InnerHeight 1
writeLines(v, "aaaa")
v.Search("aa", nil)
_ = v.gotoNextMatch()
index, total := v.GetSearchStatus()
assert.Equal(t, 1, index, "the current match is the one in the middle")
assert.Equal(t, 3, total)
assert.Equal(t,
[]string{"##*#......"},
drawSearchHighlights(v))
}
// The model can find a match that the view doesn't show, for example in a commit hash
// that the view abbreviates. Such a match is highlighted where the model says it is.
// The other matches are highlighted where the view shows them.
func TestDrawSearchMatchesFromTheModel(t *testing.T) {
WithSimulationScreen(t, 14, 6)
v := NewView("name", 0, 0, 11, 4, OutputNormal) // InnerWidth 10, InnerHeight 3
writeLines(v, "ab ab", "1234567", "ab")
v.Search("ab", []SearchPosition{
{XStart: 2, XEnd: 6, Y: 0},
{XStart: 2, XEnd: 6, Y: 1},
{XStart: 2, XEnd: 6, Y: 2},
})
_ = v.gotoNextMatch()
_ = v.gotoNextMatch()
index, total := v.GetSearchStatus()
assert.Equal(t, 2, index, "the current match is the one the view doesn't show")
assert.Equal(t, 4, total)
assert.Equal(t,
[]string{
"##.##.....", // ab ab
"..****....", // 1234567
"##........", // ab
},
drawSearchHighlights(v))
}
func BenchmarkDrawViewWithManySearchMatches(b *testing.B) {
WithSimulationScreen(b, 102, 42)
v := NewView("name", 0, 0, 101, 41, OutputNormal)