github.com/elves/elvish@v0.15.0/pkg/cli/listbox_window_test.go (about)

     1  package cli
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/elves/elvish/pkg/tt"
     7  )
     8  
     9  var Args = tt.Args
    10  
    11  func TestGetVerticalWindow(t *testing.T) {
    12  	tt.Test(t, tt.Fn("getVerticalWindow", getVerticalWindow), tt.Table{
    13  		// selected = 0: always show a widow starting from 0, regardless of
    14  		// the value of oldFirst
    15  		Args(ListBoxState{Items: TestItems{NItems: 10}, Selected: 0, First: 0}, 6).Rets(0, 0),
    16  		Args(ListBoxState{Items: TestItems{NItems: 10}, Selected: 0, First: 1}, 6).Rets(0, 0),
    17  		// selected < 0 is treated as if = 0.
    18  		Args(ListBoxState{Items: TestItems{NItems: 10}, Selected: -1, First: 0}, 6).Rets(0, 0),
    19  		// selected = n-1: always show a window ending at n-1, regardless of the
    20  		// value of oldFirst
    21  		Args(ListBoxState{Items: TestItems{NItems: 10}, Selected: 9, First: 0}, 6).Rets(4, 0),
    22  		Args(ListBoxState{Items: TestItems{NItems: 10}, Selected: 9, First: 8}, 6).Rets(4, 0),
    23  		// selected >= n is treated as if = n-1.
    24  		Args(ListBoxState{Items: TestItems{NItems: 10}, Selected: 10, First: 0}, 6).Rets(4, 0),
    25  		// selected = 3, oldFirst = 2 (likely because previous selected = 4).
    26  		// Adjust first -> 1 to satisfy the upward respect distance of 2.
    27  		Args(ListBoxState{Items: TestItems{NItems: 10}, Selected: 3, First: 2}, 6).Rets(1, 0),
    28  		// selected = 6, oldFirst = 2 (likely because previous selected = 7).
    29  		// Adjust first -> 3 to satisfy the downward respect distance of 2.
    30  		Args(ListBoxState{Items: TestItems{NItems: 10}, Selected: 6, First: 2}, 6).Rets(3, 0),
    31  
    32  		// There is not enough budget to achieve respect distance on both sides.
    33  		// Split the budget in half.
    34  		Args(ListBoxState{Items: TestItems{NItems: 10}, Selected: 3, First: 1}, 3).Rets(2, 0),
    35  		Args(ListBoxState{Items: TestItems{NItems: 10}, Selected: 3, First: 0}, 3).Rets(2, 0),
    36  
    37  		// There is just enough distance to fit the selected item. Only show the
    38  		// selected item.
    39  		Args(ListBoxState{Items: TestItems{NItems: 10}, Selected: 2, First: 0}, 1).Rets(2, 0),
    40  	})
    41  }
    42  
    43  func TestGetHorizontalWindow(t *testing.T) {
    44  	tt.Test(t, tt.Fn("getHorizontalWindow", getHorizontalWindow), tt.Table{
    45  		// All items fit in a single column. Item width is 6 ("item 0").
    46  		Args(ListBoxState{Items: TestItems{NItems: 10}, Selected: 4, First: 0}, 0, 6, 10).Rets(0, 10),
    47  		// All items fit in multiple columns. Item width is 2 ("x0").
    48  		Args(ListBoxState{Items: TestItems{Prefix: "x", NItems: 10}, Selected: 4, First: 0}, 0, 6, 5).Rets(0, 5),
    49  		// All items cannot fit, selected = 0; show a window from 0. Height
    50  		// reduced to make room for scrollbar.
    51  		Args(ListBoxState{Items: TestItems{Prefix: "x", NItems: 11}, Selected: 0, First: 0}, 0, 6, 5).Rets(0, 4),
    52  		// All items cannot fit. Columns are 0-3, 4-7, 8-10 (height reduced from
    53  		// 5 to 4 for scrollbar). Selecting last item, and showing last two
    54  		// columns; height reduced to make room for scrollbar.
    55  		Args(ListBoxState{Items: TestItems{Prefix: "x", NItems: 11}, Selected: 10, First: 0}, 0, 7, 5).Rets(4, 4),
    56  		// Items are wider than terminal, and there is a single column. Show
    57  		// them all.
    58  		Args(ListBoxState{Items: TestItems{Prefix: "long prefix", NItems: 10}, Selected: 9, First: 0}, 0,
    59  			6, 10).Rets(0, 10),
    60  		// Items are wider than terminal, and there are multiple columns. Treat
    61  		// them as if each column occupies a full width. Columns are 0-4, 5-9.
    62  		Args(ListBoxState{Items: TestItems{Prefix: "long prefix", NItems: 10}, Selected: 9, First: 0}, 0,
    63  			6, 6).Rets(5, 5),
    64  
    65  		// The following cases only differ in State.First and shows that the
    66  		// algorithm respects it. In all cases, the columns are 0-4, 5-9,
    67  		// 10-14, 15-19, item 10 is selected, and the terminal can fit 2 columns.
    68  
    69  		// First = 0. Try to reach as far as possible to that, ending up showing
    70  		// columns 5-9 and 10-14.
    71  		Args(ListBoxState{Items: TestItems{Prefix: "x", NItems: 20}, Selected: 10, First: 0}, 0, 8, 6).Rets(5, 5),
    72  		// First = 2. Ditto.
    73  		Args(ListBoxState{Items: TestItems{Prefix: "x", NItems: 20}, Selected: 10, First: 2}, 0, 8, 6).Rets(5, 5),
    74  		// First = 5. Show columns 5-9 and 10-14.
    75  		Args(ListBoxState{Items: TestItems{Prefix: "x", NItems: 20}, Selected: 10, First: 5}, 0, 8, 6).Rets(5, 5),
    76  		// First = 7. Ditto.
    77  		Args(ListBoxState{Items: TestItems{Prefix: "x", NItems: 20}, Selected: 10, First: 7}, 0, 8, 6).Rets(5, 5),
    78  		// First = 10. No need to any columns to the left.
    79  		Args(ListBoxState{Items: TestItems{Prefix: "x", NItems: 20}, Selected: 10, First: 10}, 0, 8, 6).Rets(10, 5),
    80  		// First = 12. Ditto.
    81  		Args(ListBoxState{Items: TestItems{Prefix: "x", NItems: 20}, Selected: 10, First: 12}, 0, 8, 6).Rets(10, 5),
    82  	})
    83  }