1package copy
2
3import (
4 "strings"
5 "testing"
6
7 renderer "github.com/bnema/vev-vt/ansi"
8 "github.com/stretchr/testify/require"
9)
10
11func TestRenderRowsFixedSemanticCells(t *testing.T) {
12 base := renderer.DefaultStyle()
13 base.Bold = true
14 selected := renderer.DefaultStyle()
15 selected.Inverse = true
16 status := renderer.DefaultStyle()
17 status.Inverse = true
18 input := []renderer.Cell{
19 {Rune: 'A', Style: base},
20 {Rune: '界', Style: base},
21 {Continuation: true, Style: base},
22 {Rune: 'Z', Style: base},
23 }
24 m := NewMode(NewDocument(NewSnapshotFromRows([][]renderer.Cell{input}, 32, 3), ""))
25 require.True(t, m.Search("A"))
26 require.True(t, m.StartCharacterSelection(Pos{Col: 1}))
27 require.True(t, m.ExtendCharacterSelection(Pos{Col: 2}))
28
29 want := make([][]renderer.Cell, 4)
30 for y := range want {
31 want[y] = make([]renderer.Cell, 32)
32 for x := range want[y] {
33 want[y][x] = renderer.BlankCell()
34 }
35 }
36 copy(want[0], input)
37 // Search highlights A; selection covers both cells of the wide glyph.
38 // Inverse highlighting preserves the source's bold style, including the
39 // cursor already covered by selection (it must not toggle inverse twice).
40 for x := 0; x < 3; x++ {
41 want[0][x].Style.Inverse = true
42 }
43 text := " [SELECT] 1/1 1/1 /A "
44 for x, r := range text + strings.Repeat(" ", 32-len(text)) {
45 want[3][x] = renderer.Cell{Rune: r, Style: status}
46 }
47
48 var got [][]renderer.Cell
49 m.RenderRows(func(y int, cells []renderer.Cell) {
50 require.Equal(t, len(got), y, "body rows precede the final status row")
51 // Own the callback data; later callbacks reuse the borrowed row.
52 got = append(got, append([]renderer.Cell(nil), cells...))
53 }, status, selected)
54 require.Equal(t, want, got)
55 require.Equal(t, input, m.Document().Row(0), "rendering must not style the immutable document")
56}