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  }