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

     1  package cli
     2  
     3  import (
     4  	"testing"
     5  
     6  	"github.com/elves/elvish/pkg/cli/term"
     7  	"github.com/elves/elvish/pkg/tt"
     8  	"github.com/elves/elvish/pkg/ui"
     9  )
    10  
    11  var colViewRenderTests = []RenderTest{
    12  	{
    13  		Name:  "colview no column",
    14  		Given: NewColView(ColViewSpec{}),
    15  		Width: 10, Height: 24,
    16  		Want: &term.Buffer{Width: 10},
    17  	},
    18  	{
    19  		Name: "colview width < number of columns",
    20  		Given: NewColView(ColViewSpec{State: ColViewState{
    21  			Columns: []Widget{
    22  				makeListbox("x", 2, 0), makeListbox("y", 1, 0),
    23  				makeListbox("z", 3, 0), makeListbox("w", 1, 0),
    24  			},
    25  		}}),
    26  		Width: 3, Height: 24,
    27  		Want: &term.Buffer{Width: 3},
    28  	},
    29  	{
    30  		Name: "colview normal",
    31  		Given: NewColView(ColViewSpec{State: ColViewState{
    32  			Columns: []Widget{
    33  				makeListbox("x", 2, 1),
    34  				makeListbox("y", 1, 0),
    35  				makeListbox("z", 3, -1),
    36  			},
    37  		}}),
    38  		Width: 11, Height: 24,
    39  		Want: term.NewBufferBuilder(11).
    40  			// first line
    41  			Write("x0  ").
    42  			Write("y0 ", ui.Inverse).
    43  			Write(" z0").
    44  			// second line
    45  			Newline().Write("x1 ", ui.Inverse).
    46  			Write("     z1").
    47  			// third line
    48  			Newline().Write("        z2"),
    49  	},
    50  }
    51  
    52  func makeListbox(prefix string, n, selected int) Widget {
    53  	return NewListBox(ListBoxSpec{
    54  		State: ListBoxState{
    55  			Items:    TestItems{Prefix: prefix, NItems: n},
    56  			Selected: selected,
    57  		}})
    58  }
    59  
    60  func TestColView_Render(t *testing.T) {
    61  	TestRender(t, colViewRenderTests)
    62  }
    63  
    64  func TestColView_Handle(t *testing.T) {
    65  	// Channel for recording the place an event was handled. -1 for the widget
    66  	// itself, column index for column.
    67  	handledBy := make(chan int, 10)
    68  	w := NewColView(ColViewSpec{
    69  		OverlayHandler: MapHandler{
    70  			term.K('a'): func() { handledBy <- -1 },
    71  		},
    72  		State: ColViewState{
    73  			Columns: []Widget{
    74  				NewListBox(ListBoxSpec{
    75  					OverlayHandler: MapHandler{
    76  						term.K('a'): func() { handledBy <- 0 },
    77  						term.K('b'): func() { handledBy <- 0 },
    78  					}}),
    79  				NewListBox(ListBoxSpec{
    80  					OverlayHandler: MapHandler{
    81  						term.K('a'): func() { handledBy <- 1 },
    82  						term.K('b'): func() { handledBy <- 1 },
    83  					}}),
    84  			},
    85  			FocusColumn: 1,
    86  		},
    87  		OnLeft:  func(ColView) { handledBy <- 100 },
    88  		OnRight: func(ColView) { handledBy <- 101 },
    89  	})
    90  
    91  	expectHandled := func(event term.Event, wantBy int) {
    92  		t.Helper()
    93  		handled := w.Handle(event)
    94  		if !handled {
    95  			t.Errorf("Handle -> false, want true")
    96  		}
    97  		if by := <-handledBy; by != wantBy {
    98  			t.Errorf("Handled by %d, want %d", by, wantBy)
    99  		}
   100  	}
   101  
   102  	expectUnhandled := func(event term.Event) {
   103  		t.Helper()
   104  		handled := w.Handle(event)
   105  		if handled {
   106  			t.Errorf("Handle -> true, want false")
   107  		}
   108  	}
   109  
   110  	// Event handled by widget's overlay handler.
   111  	expectHandled(term.K('a'), -1)
   112  	// Event handled by the focused column.
   113  	expectHandled(term.K('b'), 1)
   114  	// Fallback handler for Left
   115  	expectHandled(term.K(ui.Left), 100)
   116  	// Fallback handler for Left
   117  	expectHandled(term.K(ui.Right), 101)
   118  	// No one to handle the event.
   119  	expectUnhandled(term.K('c'))
   120  	// No focused column: event unhandled
   121  	w.MutateState(func(s *ColViewState) { s.FocusColumn = -1 })
   122  	expectUnhandled(term.K('b'))
   123  }
   124  
   125  func TestDistribute(t *testing.T) {
   126  	tt.Test(t, tt.Fn("distribute", distribute), tt.Table{
   127  		// Nice integer distributions.
   128  		tt.Args(10, []int{1, 1}).Rets([]int{5, 5}),
   129  		tt.Args(10, []int{2, 3}).Rets([]int{4, 6}),
   130  		tt.Args(10, []int{1, 2, 2}).Rets([]int{2, 4, 4}),
   131  		// Approximate integer distributions.
   132  		tt.Args(10, []int{1, 1, 1}).Rets([]int{3, 3, 4}),
   133  		tt.Args(5, []int{1, 1, 1}).Rets([]int{1, 2, 2}),
   134  	})
   135  }