1package copy
2
3import (
4 "testing"
5
6 renderer "github.com/bnema/vev-vt"
7 "github.com/stretchr/testify/require"
8)
9
10func navigatorDocument() *Document {
11 return NewDocument(NewSnapshotFromRows([][]renderer.Cell{
12 documentCells("abcdef"),
13 documentCells("xy"),
14 {{Rune: '界'}, {Continuation: true}, {Rune: 'z'}},
15 {},
16 documentCells("omega"),
17 }, 6, 2), " -_@")
18}
19
20func TestNavigatorHorizontalSkipsContinuations(t *testing.T) {
21 doc := navigatorDocument()
22
23 tests := []struct {
24 name string
25 move func(*Navigator, *Document) bool
26 from Pos
27 want Pos
28 }{
29 {"right skips wide continuation", (*Navigator).Right, Pos{Row: 2, Col: 0}, Pos{Row: 2, Col: 2}},
30 {"left skips wide continuation", (*Navigator).Left, Pos{Row: 2, Col: 2}, Pos{Row: 2, Col: 0}},
31 }
32 for _, tt := range tests {
33 t.Run(tt.name, func(t *testing.T) {
34 navigator := NewNavigator(tt.from)
35
36 require.True(t, tt.move(&navigator, doc))
37 require.Equal(t, tt.want, navigator.Pos)
38 require.Equal(t, tt.want.Col, navigator.PreferredCol)
39 })
40 }
41}
42
43func TestNavigatorVerticalRetainsPreferredColumn(t *testing.T) {
44 doc := navigatorDocument()
45 navigator := NewNavigator(Pos{Row: 0, Col: 5})
46
47 require.True(t, navigator.Down(doc))
48 require.Equal(t, Pos{Row: 1, Col: 1}, navigator.Pos)
49 require.Equal(t, 5, navigator.PreferredCol)
50
51 require.True(t, navigator.Down(doc))
52 require.Equal(t, Pos{Row: 2, Col: 2}, navigator.Pos)
53 require.Equal(t, 5, navigator.PreferredCol)
54
55 require.True(t, navigator.Down(doc))
56 require.Equal(t, Pos{Row: 3, Col: 0}, navigator.Pos)
57 require.Equal(t, 5, navigator.PreferredCol)
58
59 require.True(t, navigator.Down(doc))
60 require.Equal(t, Pos{Row: 4, Col: 4}, navigator.Pos)
61 require.Equal(t, 5, navigator.PreferredCol)
62
63 require.True(t, navigator.Up(doc))
64 require.Equal(t, Pos{Row: 3, Col: 0}, navigator.Pos)
65 require.Equal(t, 5, navigator.PreferredCol)
66
67 require.True(t, navigator.Up(doc))
68 require.Equal(t, Pos{Row: 2, Col: 2}, navigator.Pos)
69 require.Equal(t, 5, navigator.PreferredCol)
70}
71
72func TestNavigatorWordMotionsCrossRows(t *testing.T) {
73 doc := navigatorDocument()
74
75 tests := []struct {
76 name string
77 move func(*Navigator, *Document) bool
78 from Pos
79 want Pos
80 }{
81 {"word next", (*Navigator).WordNext, Pos{Row: 0, Col: 5}, Pos{Row: 1, Col: 0}},
82 {"word backward", (*Navigator).WordBackward, Pos{Row: 1, Col: 0}, Pos{Row: 0, Col: 0}},
83 {"word end", (*Navigator).WordEnd, Pos{Row: 1, Col: 1}, Pos{Row: 2, Col: 2}},
84 }
85 for _, tt := range tests {
86 t.Run(tt.name, func(t *testing.T) {
87 navigator := NewNavigator(tt.from)
88
89 require.True(t, tt.move(&navigator, doc))
90 require.Equal(t, tt.want, navigator.Pos)
91 require.Equal(t, tt.want.Col, navigator.PreferredCol)
92 })
93 }
94}
95
96func TestNavigatorEmptyTopBottomPageAndSet(t *testing.T) {
97 doc := navigatorDocument()
98
99 t.Run("empty row is stable", func(t *testing.T) {
100 navigator := NewNavigator(Pos{Row: 2, Col: 2})
101 require.True(t, navigator.Down(doc))
102 require.Equal(t, Pos{Row: 3, Col: 0}, navigator.Pos)
103 require.False(t, navigator.Right(doc))
104 require.Equal(t, Pos{Row: 3, Col: 0}, navigator.Pos)
105 })
106
107 t.Run("top and bottom reset the preferred column", func(t *testing.T) {
108 navigator := NewNavigator(Pos{Row: 0, Col: 5})
109 require.True(t, navigator.Down(doc))
110 require.Equal(t, Pos{Row: 1, Col: 1}, navigator.Pos)
111 require.Equal(t, 5, navigator.PreferredCol)
112 require.True(t, navigator.Top(doc))
113 require.Equal(t, Pos{Row: 0, Col: 1}, navigator.Pos)
114 require.Equal(t, 1, navigator.PreferredCol)
115 require.True(t, navigator.Bottom(doc))
116 require.Equal(t, Pos{Row: 4, Col: 1}, navigator.Pos)
117 require.Equal(t, 1, navigator.PreferredCol)
118 })
119
120 t.Run("page keeps preferred column", func(t *testing.T) {
121 navigator := NewNavigator(Pos{Row: 0, Col: 5})
122 require.True(t, navigator.Page(doc, 2))
123 require.Equal(t, Pos{Row: 2, Col: 2}, navigator.Pos)
124 require.Equal(t, 5, navigator.PreferredCol)
125 require.True(t, navigator.Page(doc, 2))
126 require.Equal(t, Pos{Row: 4, Col: 4}, navigator.Pos)
127 require.Equal(t, 5, navigator.PreferredCol)
128 })
129
130 t.Run("set normalizes continuation and updates preferred column", func(t *testing.T) {
131 navigator := NewNavigator(Pos{Row: 0, Col: 0})
132 require.True(t, navigator.Set(doc, Pos{Row: 2, Col: 1}))
133 require.Equal(t, Pos{Row: 2, Col: 0}, navigator.Pos)
134 require.Equal(t, 0, navigator.PreferredCol)
135 require.False(t, navigator.Set(doc, Pos{Row: 9, Col: 0}))
136 require.Equal(t, Pos{Row: 2, Col: 0}, navigator.Pos)
137 })
138}