1package vt
2
3import (
4 "reflect"
5 "testing"
6
7 renderer "github.com/bnema/vev-vt/core"
8)
9
10func damageKinds(d []renderer.Damage) []renderer.DamageKind {
11 ks := make([]renderer.DamageKind, len(d))
12 for i, dd := range d {
13 ks[i] = dd.Kind
14 }
15 return ks
16}
17
18func hasDamageKind(d []renderer.Damage, kind renderer.DamageKind) bool {
19 for _, dd := range d {
20 if dd.Kind == kind {
21 return true
22 }
23 }
24 return false
25}
26
27func cellAt(s *Screen, x, y int) renderer.Cell {
28 return s.frame.At(x, y)
29}
30
31func testHistoryChunk(rows [][]renderer.Cell, bounds []LineBound, rowIDs []RowID) *HistoryChunk {
32 chunks := newHistoryChunks(rows, bounds, rowIDs)
33 if len(chunks) != 1 {
34 panic("test history chunk rows must have one width")
35 }
36 return chunks[0]
37}
38
39func assertFramesEqual(t *testing.T, got, want renderer.Frame) {
40 t.Helper()
41 if !reflect.DeepEqual(got, want) {
42 t.Fatal("frame changed unexpectedly")
43 }
44}
45
46func assertCell(t *testing.T, s *Screen, x, y int, expected rune) {
47 t.Helper()
48 c := cellAt(s, x, y)
49 if c.Rune != expected {
50 t.Errorf("cell(%d,%d) rune = %q, want %q", x, y, c.Rune, expected)
51 }
52 if c.Continuation {
53 t.Errorf("cell(%d,%d) unexpectedly marked as continuation", x, y)
54 }
55}
56
57// assertContinuation asserts the cell at (x,y) is the right half of a
58// wide-character pair (Continuation set, Rune 0).
59func assertContinuation(t *testing.T, s *Screen, x, y int) {
60 t.Helper()
61 c := cellAt(s, x, y)
62 if !c.Continuation {
63 t.Errorf("cell(%d,%d) expected continuation, got rune=%q continuation=%v", x, y, c.Rune, c.Continuation)
64 }
65 if c.Rune != 0 {
66 t.Errorf("cell(%d,%d) continuation rune = %q, want 0", x, y, c.Rune)
67 }
68}
69
70// assertBlank asserts the cell at (x,y) is a blank default cell.
71func assertBlank(t *testing.T, s *Screen, x, y int) {
72 t.Helper()
73 c := cellAt(s, x, y)
74 if c.Rune != ' ' || c.Continuation {
75 t.Errorf("cell(%d,%d) = {rune:%q cont:%v}, want blank space", x, y, c.Rune, c.Continuation)
76 }
77}
78
79func assertNoOrphanWideCells(t *testing.T, s *Screen) {
80 t.Helper()
81 for y := range s.frame.Height {
82 for x := range s.frame.Width {
83 c := cellAt(s, x, y)
84 if c.Continuation {
85 if x == 0 || cellAt(s, x-1, y).Continuation || renderer.RuneWidth(cellAt(s, x-1, y).Rune) != 2 {
86 t.Fatalf("orphan continuation at (%d,%d)", x, y)
87 }
88 continue
89 }
90 if renderer.RuneWidth(c.Rune) == 2 && (x+1 >= s.frame.Width || !cellAt(s, x+1, y).Continuation) {
91 t.Fatalf("orphan wide head at (%d,%d) rune %q", x, y, c.Rune)
92 }
93 }
94 }
95}
96
97func lineText(s *Screen, y int) string {
98 out := make([]rune, s.frame.Width)
99 for x := range s.frame.Width {
100 out[x] = s.frame.At(x, y).Rune
101 }
102 return string(out)
103}
104
105func rowString(row []renderer.Cell) string {
106 out := make([]rune, len(row))
107 for i, cell := range row {
108 out[i] = cell.Rune
109 }
110 return string(out)
111}