github.com/markusbkk/elvish@v0.0.0-20231204143114-91dc52438621/pkg/cli/term/buffer_test.go (about) 1 package term 2 3 import ( 4 "reflect" 5 "testing" 6 ) 7 8 var cellsWidthTests = []struct { 9 cells []Cell 10 wantWidth int 11 }{ 12 {[]Cell{}, 0}, 13 {[]Cell{{"a", ""}, {"好", ""}}, 3}, 14 } 15 16 func TestCellsWidth(t *testing.T) { 17 for _, test := range cellsWidthTests { 18 if width := CellsWidth(test.cells); width != test.wantWidth { 19 t.Errorf("cellsWidth(%v) = %v, want %v", 20 test.cells, width, test.wantWidth) 21 } 22 } 23 } 24 25 var makeSpacingTests = []struct { 26 n int 27 want []Cell 28 }{ 29 {0, []Cell{}}, 30 {1, []Cell{{" ", ""}}}, 31 {4, []Cell{{" ", ""}, {" ", ""}, {" ", ""}, {" ", ""}}}, 32 } 33 34 func TestMakeSpacing(t *testing.T) { 35 for _, test := range makeSpacingTests { 36 if got := makeSpacing(test.n); !reflect.DeepEqual(got, test.want) { 37 t.Errorf("makeSpacing(%v) = %v, want %v", test.n, got, test.want) 38 } 39 } 40 } 41 42 var compareCellsTests = []struct { 43 cells1 []Cell 44 cells2 []Cell 45 wantEqual bool 46 wantIndex int 47 }{ 48 {[]Cell{}, []Cell{}, true, 0}, 49 {[]Cell{}, []Cell{{"a", ""}}, false, 0}, 50 { 51 []Cell{{"a", ""}, {"好", ""}, {"b", ""}}, 52 []Cell{{"a", ""}, {"好", ""}, {"c", ""}}, 53 false, 2, 54 }, 55 { 56 []Cell{{"a", ""}, {"好", ""}, {"b", ""}}, 57 []Cell{{"a", ""}, {"好", "1"}, {"c", ""}}, 58 false, 1, 59 }, 60 } 61 62 func TestCompareCells(t *testing.T) { 63 for _, test := range compareCellsTests { 64 equal, index := CompareCells(test.cells1, test.cells2) 65 if equal != test.wantEqual || index != test.wantIndex { 66 t.Errorf("compareCells(%v, %v) = (%v, %v), want (%v, %v)", 67 test.cells1, test.cells2, 68 equal, index, test.wantEqual, test.wantIndex) 69 } 70 } 71 } 72 73 var bufferCursorTests = []struct { 74 buf *Buffer 75 want Pos 76 }{ 77 { 78 &Buffer{Width: 10, Lines: Lines{Line{}}}, 79 Pos{0, 0}, 80 }, 81 { 82 &Buffer{Width: 10, Lines: Lines{Line{Cell{"a", ""}}, Line{Cell{"好", ""}}}}, 83 Pos{1, 2}, 84 }, 85 } 86 87 func TestBufferCursor(t *testing.T) { 88 for _, test := range bufferCursorTests { 89 if p := test.buf.Cursor(); p != test.want { 90 t.Errorf("(%v).cursor() = %v, want %v", test.buf, p, test.want) 91 } 92 } 93 } 94 95 var buffersHeighTests = []struct { 96 buffers []*Buffer 97 want int 98 }{ 99 {nil, 0}, 100 {[]*Buffer{NewBuffer(10)}, 1}, 101 { 102 []*Buffer{ 103 {Width: 10, Lines: Lines{Line{}, Line{}}}, 104 {Width: 10, Lines: Lines{Line{}}}, 105 {Width: 10, Lines: Lines{Line{}, Line{}}}, 106 }, 107 5, 108 }, 109 } 110 111 func TestBuffersHeight(t *testing.T) { 112 for _, test := range buffersHeighTests { 113 if h := BuffersHeight(test.buffers...); h != test.want { 114 t.Errorf("buffersHeight(%v...) = %v, want %v", 115 test.buffers, h, test.want) 116 } 117 } 118 } 119 120 var bufferTrimToLinesTests = []struct { 121 buf *Buffer 122 low int 123 high int 124 want *Buffer 125 }{ 126 { 127 &Buffer{Width: 10, Lines: Lines{ 128 Line{Cell{"a", ""}}, Line{Cell{"b", ""}}, Line{Cell{"c", ""}}, Line{Cell{"d", ""}}, 129 }}, 130 0, 2, 131 &Buffer{Width: 10, Lines: Lines{ 132 Line{Cell{"a", ""}}, Line{Cell{"b", ""}}, 133 }}, 134 }, 135 // Negative low is treated as 0. 136 137 { 138 &Buffer{Width: 10, Lines: Lines{ 139 Line{Cell{"a", ""}}, Line{Cell{"b", ""}}, Line{Cell{"c", ""}}, Line{Cell{"d", ""}}, 140 }}, 141 -1, 2, 142 &Buffer{Width: 10, Lines: Lines{ 143 Line{Cell{"a", ""}}, Line{Cell{"b", ""}}, 144 }}, 145 }, 146 // With dot. 147 { 148 &Buffer{Width: 10, Lines: Lines{ 149 Line{Cell{"a", ""}}, Line{Cell{"b", ""}}, Line{Cell{"c", ""}}, Line{Cell{"d", ""}}, 150 }, Dot: Pos{1, 1}}, 151 1, 3, 152 &Buffer{Width: 10, Lines: Lines{ 153 Line{Cell{"b", ""}}, Line{Cell{"c", ""}}, 154 }, Dot: Pos{0, 1}}, 155 }, 156 // With dot that is going to be trimmed away. 157 { 158 &Buffer{Width: 10, Lines: Lines{ 159 Line{Cell{"a", ""}}, Line{Cell{"b", ""}}, Line{Cell{"c", ""}}, Line{Cell{"d", ""}}, 160 }, Dot: Pos{0, 1}}, 161 1, 3, 162 &Buffer{Width: 10, Lines: Lines{ 163 Line{Cell{"b", ""}}, Line{Cell{"c", ""}}, 164 }, Dot: Pos{0, 1}}, 165 }, 166 } 167 168 func TestBufferTrimToLines(t *testing.T) { 169 for _, test := range bufferTrimToLinesTests { 170 b := cloneBuffer(test.buf) 171 b.TrimToLines(test.low, test.high) 172 if !reflect.DeepEqual(b, test.want) { 173 t.Errorf("buf.trimToLines(%v, %v) makes it %v, want %v", 174 test.low, test.high, b, test.want) 175 } 176 } 177 } 178 179 var bufferExtendTests = []struct { 180 buf *Buffer 181 buf2 *Buffer 182 moveDot bool 183 want *Buffer 184 }{ 185 { 186 &Buffer{Width: 10, Lines: Lines{ 187 Line{Cell{"a", ""}}, Line{Cell{"b", ""}}}}, 188 &Buffer{Width: 11, Lines: Lines{ 189 Line{Cell{"c", ""}}, Line{Cell{"d", ""}}}}, 190 false, 191 &Buffer{Width: 10, Lines: Lines{ 192 Line{Cell{"a", ""}}, Line{Cell{"b", ""}}, 193 Line{Cell{"c", ""}}, Line{Cell{"d", ""}}}}, 194 }, 195 // Moving dot. 196 { 197 &Buffer{Width: 10, Lines: Lines{ 198 Line{Cell{"a", ""}}, Line{Cell{"b", ""}}}}, 199 &Buffer{ 200 Width: 11, 201 Lines: Lines{Line{Cell{"c", ""}}, Line{Cell{"d", ""}}}, 202 Dot: Pos{1, 1}, 203 }, 204 true, 205 &Buffer{ 206 Width: 10, 207 Lines: Lines{ 208 Line{Cell{"a", ""}}, Line{Cell{"b", ""}}, 209 Line{Cell{"c", ""}}, Line{Cell{"d", ""}}}, 210 Dot: Pos{3, 1}, 211 }, 212 }, 213 } 214 215 func TestBufferExtend(t *testing.T) { 216 for _, test := range bufferExtendTests { 217 buf := cloneBuffer(test.buf) 218 buf.Extend(test.buf2, test.moveDot) 219 if !reflect.DeepEqual(buf, test.want) { 220 t.Errorf("buf.extend(%v, %v) makes it %v, want %v", 221 test.buf2, test.moveDot, buf, test.want) 222 } 223 } 224 } 225 226 var bufferExtendRightTests = []struct { 227 buf *Buffer 228 buf2 *Buffer 229 want *Buffer 230 }{ 231 // No padding, equal height. 232 { 233 &Buffer{Width: 1, Lines: Lines{Line{Cell{"a", ""}}, Line{Cell{"b", ""}}}}, 234 &Buffer{Width: 1, Lines: Lines{Line{Cell{"c", ""}}, Line{Cell{"d", ""}}}}, 235 &Buffer{Width: 2, Lines: Lines{ 236 Line{Cell{"a", ""}, Cell{"c", ""}}, 237 Line{Cell{"b", ""}, Cell{"d", ""}}}}, 238 }, 239 // With padding, equal height. 240 { 241 &Buffer{Width: 2, Lines: Lines{Line{Cell{"a", ""}}, Line{Cell{"b", ""}}}}, 242 &Buffer{Width: 1, Lines: Lines{Line{Cell{"c", ""}}, Line{Cell{"d", ""}}}}, 243 &Buffer{Width: 3, Lines: Lines{ 244 Line{Cell{"a", ""}, Cell{" ", ""}, Cell{"c", ""}}, 245 Line{Cell{"b", ""}, Cell{" ", ""}, Cell{"d", ""}}}}, 246 }, 247 // buf is higher. 248 { 249 &Buffer{Width: 1, Lines: Lines{ 250 Line{Cell{"a", ""}}, Line{Cell{"b", ""}}, Line{Cell{"x", ""}}}}, 251 &Buffer{Width: 1, Lines: Lines{ 252 Line{Cell{"c", ""}}, Line{Cell{"d", ""}}, 253 }}, 254 &Buffer{Width: 2, Lines: Lines{ 255 Line{Cell{"a", ""}, Cell{"c", ""}}, 256 Line{Cell{"b", ""}, Cell{"d", ""}}, 257 Line{Cell{"x", ""}}}}, 258 }, 259 // buf2 is higher. 260 { 261 &Buffer{Width: 1, Lines: Lines{Line{Cell{"a", ""}}, Line{Cell{"b", ""}}}}, 262 &Buffer{Width: 1, Lines: Lines{ 263 Line{Cell{"c", ""}}, Line{Cell{"d", ""}}, Line{Cell{"e", ""}}, 264 }}, 265 &Buffer{Width: 2, Lines: Lines{ 266 Line{Cell{"a", ""}, Cell{"c", ""}}, 267 Line{Cell{"b", ""}, Cell{"d", ""}}, 268 Line{Cell{" ", ""}, Cell{"e", ""}}}}, 269 }, 270 } 271 272 func TestBufferExtendRight(t *testing.T) { 273 for _, test := range bufferExtendRightTests { 274 buf := cloneBuffer(test.buf) 275 buf.ExtendRight(test.buf2) 276 if !reflect.DeepEqual(buf, test.want) { 277 t.Errorf("buf.extendRight(%v) makes it %v, want %v", 278 test.buf2, buf, test.want) 279 } 280 } 281 } 282 283 func TestBufferBuffer(t *testing.T) { 284 b := NewBufferBuilder(4).Write("text").Buffer() 285 if b.Buffer() != b { 286 t.Errorf("Buffer did not return itself") 287 } 288 } 289 290 var bufferTTYStringTests = []struct { 291 buf *Buffer 292 want string 293 }{ 294 { 295 nil, 296 "nil", 297 }, 298 { 299 NewBufferBuilder(4). 300 Write("ABCD"). 301 Newline(). 302 Write("XY"). 303 Buffer(), 304 "Width = 4, Dot = (0, 0)\n" + 305 "┌────┐\n" + 306 "│ABCD│\n" + 307 "│XY$ │\n" + 308 "└────┘\n", 309 }, 310 { 311 NewBufferBuilder(4). 312 Write("A").SetDotHere(). 313 WriteStringSGR("B", "1"). 314 WriteStringSGR("C", "7"). 315 Write("D"). 316 Newline(). 317 WriteStringSGR("XY", "7"). 318 Buffer(), 319 "Width = 4, Dot = (0, 1)\n" + 320 "┌────┐\n" + 321 "│A\033[1mB\033[;7mC\033[mD│\n" + 322 "│\033[7mXY\033[m$ │\n" + 323 "└────┘\n", 324 }, 325 } 326 327 func TestBufferTTYString(t *testing.T) { 328 for _, test := range bufferTTYStringTests { 329 ttyString := test.buf.TTYString() 330 if ttyString != test.want { 331 t.Errorf("TTYString -> %q, want %q", ttyString, test.want) 332 } 333 } 334 } 335 336 func cloneBuffer(b *Buffer) *Buffer { 337 return &Buffer{b.Width, cloneLines(b.Lines), b.Dot} 338 } 339 340 func cloneLines(lines Lines) Lines { 341 newLines := make(Lines, len(lines)) 342 for i, line := range lines { 343 if line != nil { 344 newLines[i] = make(Line, len(line)) 345 copy(newLines[i], line) 346 } 347 } 348 return newLines 349 }