github.com/kolbycrouch/elvish@v0.14.1-0.20210614162631-215b9ac1c423/pkg/cli/mode/navigation_test.go (about)

     1  package mode
     2  
     3  import (
     4  	"errors"
     5  	"testing"
     6  
     7  	"src.elv.sh/pkg/cli"
     8  	. "src.elv.sh/pkg/cli/clitest"
     9  	"src.elv.sh/pkg/cli/lscolors"
    10  	"src.elv.sh/pkg/cli/term"
    11  	"src.elv.sh/pkg/cli/tk"
    12  	"src.elv.sh/pkg/testutil"
    13  	"src.elv.sh/pkg/ui"
    14  )
    15  
    16  var testDir = testutil.Dir{
    17  	"a": "",
    18  	"d": testutil.Dir{
    19  		"d1": "content\td1\nline 2",
    20  		"d2": testutil.Dir{
    21  			"d21":     "content d21",
    22  			"d22":     "content d22",
    23  			"d23.png": "",
    24  		},
    25  		"d3":  testutil.Dir{},
    26  		".dh": "hidden",
    27  	},
    28  	"f": "",
    29  }
    30  
    31  func TestErrorInAscend(t *testing.T) {
    32  	f := Setup()
    33  	defer f.Stop()
    34  
    35  	c := getTestCursor()
    36  	c.ascendErr = errors.New("cannot ascend")
    37  	startNavigation(f.App, NavigationSpec{Cursor: c})
    38  
    39  	f.TTY.Inject(term.K(ui.Left))
    40  	f.TestTTYNotes(t, "cannot ascend")
    41  }
    42  
    43  func TestErrorInDescend(t *testing.T) {
    44  	f := Setup()
    45  	defer f.Stop()
    46  
    47  	c := getTestCursor()
    48  	c.descendErr = errors.New("cannot descend")
    49  	startNavigation(f.App, NavigationSpec{Cursor: c})
    50  
    51  	f.TTY.Inject(term.K(ui.Down))
    52  	f.TTY.Inject(term.K(ui.Right))
    53  	f.TestTTYNotes(t, "cannot descend")
    54  }
    55  
    56  func TestErrorInCurrent(t *testing.T) {
    57  	f, cleanup := setup()
    58  	defer cleanup()
    59  	defer f.Stop()
    60  
    61  	c := getTestCursor()
    62  	c.currentErr = errors.New("ERR")
    63  	startNavigation(f.App, NavigationSpec{Cursor: c})
    64  
    65  	buf := f.MakeBuffer(
    66  		"", term.DotHere, "\n",
    67  		" NAVIGATING  \n", Styles,
    68  		"************ ",
    69  		" a   ERR            \n", Styles,
    70  		"     !!!",
    71  		" d  \n", Styles,
    72  		"////",
    73  		" f  ",
    74  	)
    75  
    76  	f.TTY.TestBuffer(t, buf)
    77  
    78  	// Test that Right does nothing.
    79  	f.TTY.Inject(term.K(ui.Right))
    80  	f.TTY.TestBuffer(t, buf)
    81  }
    82  
    83  func TestErrorInParent(t *testing.T) {
    84  	f, cleanup := setup()
    85  	defer cleanup()
    86  	defer f.Stop()
    87  
    88  	c := getTestCursor()
    89  	c.parentErr = errors.New("ERR")
    90  	startNavigation(f.App, NavigationSpec{Cursor: c})
    91  
    92  	f.TestTTY(t,
    93  		"", term.DotHere, "\n",
    94  		" NAVIGATING  \n", Styles,
    95  		"************ ",
    96  		"ERR   d1            content    d1\n", Styles,
    97  		"!!!  ++++++++++++++",
    98  		"      d2            line 2\n", Styles,
    99  		"     //////////////",
   100  		"      d3           ", Styles,
   101  		"     //////////////",
   102  	)
   103  }
   104  
   105  func TestWidthRatio(t *testing.T) {
   106  	f, cleanup := setup()
   107  	defer cleanup()
   108  	defer f.Stop()
   109  
   110  	c := getTestCursor()
   111  	startNavigation(f.App, NavigationSpec{
   112  		Cursor:     c,
   113  		WidthRatio: func() [3]int { return [3]int{1, 1, 1} },
   114  	})
   115  
   116  	f.TestTTY(t,
   117  		"", term.DotHere, "\n",
   118  		" NAVIGATING  \n", Styles,
   119  		"************ ",
   120  		" a            d1           content    d1\n", Styles,
   121  		"             +++++++++++++",
   122  		" d            d2           line 2\n", Styles,
   123  		"############ /////////////",
   124  		" f            d3          ", Styles,
   125  		"             /////////////",
   126  	)
   127  }
   128  
   129  func TestGetSelectedName(t *testing.T) {
   130  	f := Setup()
   131  	defer f.Stop()
   132  
   133  	w := startNavigation(f.App, NavigationSpec{Cursor: getTestCursor()})
   134  
   135  	wantName := "d1"
   136  	if name := w.SelectedName(); name != wantName {
   137  		t.Errorf("Got name %q, want %q", name, wantName)
   138  	}
   139  }
   140  
   141  func TestNavigation_FakeFS(t *testing.T) {
   142  	cursor := getTestCursor()
   143  	testNavigation(t, cursor)
   144  }
   145  
   146  func TestNavigation_RealFS(t *testing.T) {
   147  	_, cleanupFs := testutil.InTestDir()
   148  	defer cleanupFs()
   149  	testutil.ApplyDir(testDir)
   150  
   151  	testutil.MustChdir("d")
   152  	testNavigation(t, nil)
   153  }
   154  
   155  func testNavigation(t *testing.T, c NavigationCursor) {
   156  	f, cleanup := setup()
   157  	defer cleanup()
   158  	defer f.Stop()
   159  
   160  	w := startNavigation(f.App, NavigationSpec{Cursor: c})
   161  
   162  	// Test initial UI and file preview.
   163  	// NOTE: Buffers are named after the file that is now being selected.
   164  	d1Buf := f.MakeBuffer(
   165  		"", term.DotHere, "\n",
   166  		" NAVIGATING  \n", Styles,
   167  		"************ ",
   168  		" a    d1            content    d1\n", Styles,
   169  		"     ++++++++++++++",
   170  		" d    d2            line 2\n", Styles,
   171  		"#### //////////////",
   172  		" f    d3           ", Styles,
   173  		"     //////////////",
   174  	)
   175  	f.TTY.TestBuffer(t, d1Buf)
   176  
   177  	// Test scrolling of preview.
   178  	w.ScrollPreview(1)
   179  	f.App.Redraw()
   180  	d1Buf2 := f.MakeBuffer(
   181  		"", term.DotHere, "\n",
   182  		" NAVIGATING  \n", Styles,
   183  		"************ ",
   184  		" a    d1            line 2             │\n", Styles,
   185  		"     ++++++++++++++                    -",
   186  		" d    d2                               │\n", Styles,
   187  		"#### //////////////                    -",
   188  		" f    d3                                \n", Styles,
   189  		"     //////////////                    X",
   190  		"                                        ", Styles,
   191  		"                                       X",
   192  	)
   193  	f.TTY.TestBuffer(t, d1Buf2)
   194  
   195  	// Test handling of selection change and directory preview. Also test
   196  	// LS_COLORS.
   197  	w.Select(tk.Next)
   198  	f.App.Redraw()
   199  	d2Buf := f.MakeBuffer(
   200  		"", term.DotHere, "\n",
   201  		" NAVIGATING  \n", Styles,
   202  		"************ ",
   203  		" a    d1             d21                \n", Styles,
   204  		"                    ++++++++++++++++++++",
   205  		" d    d2             d22                \n", Styles,
   206  		"#### ##############",
   207  		" f    d3             d23.png            ", Styles,
   208  		"     ////////////// !!!!!!!!!!!!!!!!!!!!",
   209  	)
   210  	f.TTY.TestBuffer(t, d2Buf)
   211  
   212  	// Test handling of Descend.
   213  	w.Descend()
   214  	f.App.Redraw()
   215  	d21Buf := f.MakeBuffer(
   216  		"", term.DotHere, "\n",
   217  		" NAVIGATING  \n", Styles,
   218  		"************ ",
   219  		" d1   d21           content d21\n", Styles,
   220  		"     ++++++++++++++",
   221  		" d2   d22          \n", Styles,
   222  		"####",
   223  		" d3   d23.png      ", Styles,
   224  		"//// !!!!!!!!!!!!!!",
   225  	)
   226  	f.TTY.TestBuffer(t, d21Buf)
   227  
   228  	// Test handling of Ascend, and that the current column selects the
   229  	// directory we just ascended from, thus reverting to wantBuf1.
   230  	w.Ascend()
   231  	f.App.Redraw()
   232  	f.TTY.TestBuffer(t, d2Buf)
   233  
   234  	// Test handling of Descend on a regular file, i.e. do nothing. First move
   235  	// the cursor to d1, which is a regular file.
   236  	w.Select(tk.Prev)
   237  	f.App.Redraw()
   238  	f.TTY.TestBuffer(t, d1Buf)
   239  	// Now descend, and verify that the buffer has not changed.
   240  	w.Descend()
   241  	f.App.Redraw()
   242  	f.TTY.TestBuffer(t, d1Buf)
   243  
   244  	// Test showing hidden.
   245  	w.MutateShowHidden(func(bool) bool { return true })
   246  	f.App.Redraw()
   247  	f.TestTTY(t,
   248  		"", term.DotHere, "\n",
   249  		" NAVIGATING (show hidden)  \n", Styles,
   250  		"************************** ",
   251  		" a    .dh           content    d1\n",
   252  		" d    d1            line 2\n", Styles,
   253  		"#### ++++++++++++++",
   254  		" f    d2           \n", Styles,
   255  		"     //////////////",
   256  		"      d3           ", Styles,
   257  		"     //////////////",
   258  	)
   259  	w.MutateShowHidden(func(bool) bool { return false })
   260  
   261  	// Test filtering; current column shows d1, d2, d3 before filtering.
   262  	w.MutateFiltering(func(bool) bool { return true })
   263  	f.TTY.Inject(term.K('3'))
   264  	f.TestTTY(t,
   265  		"\n",
   266  		" NAVIGATING  3", Styles,
   267  		"************  ", term.DotHere, "\n",
   268  		" a    d3            \n", Styles,
   269  		"     ##############",
   270  		" d  \n", Styles,
   271  		"####",
   272  		" f  ",
   273  	)
   274  	w.MutateFiltering(func(bool) bool { return false })
   275  
   276  	// Now move into d3, an empty directory. Test that the filter has been
   277  	// cleared.
   278  	w.Select(tk.Next)
   279  	w.Select(tk.Next)
   280  	w.Descend()
   281  	f.App.Redraw()
   282  	d3NoneBuf := f.MakeBuffer(
   283  		"", term.DotHere, "\n",
   284  		" NAVIGATING  \n", Styles,
   285  		"************ ",
   286  		" d1                 \n",
   287  		" d2 \n", Styles,
   288  		"////",
   289  		" d3 ", Styles,
   290  		"####",
   291  	)
   292  	f.TTY.TestBuffer(t, d3NoneBuf)
   293  	// Test that selecting the previous does nothing in an empty directory.
   294  	w.Select(tk.Prev)
   295  	f.App.Redraw()
   296  	f.TTY.TestBuffer(t, d3NoneBuf)
   297  	// Test that selecting the next does nothing in an empty directory.
   298  	w.Select(tk.Next)
   299  	f.App.Redraw()
   300  	f.TTY.TestBuffer(t, d3NoneBuf)
   301  	// Test that Descend does nothing in an empty directory.
   302  	w.Descend()
   303  	f.App.Redraw()
   304  	f.TTY.TestBuffer(t, d3NoneBuf)
   305  }
   306  
   307  func setup() (*Fixture, func()) {
   308  	restore := lscolors.WithTestLsColors()
   309  	return Setup(WithTTY(func(tty TTYCtrl) { tty.SetSize(6, 40) })), restore
   310  }
   311  
   312  func startNavigation(app cli.App, spec NavigationSpec) Navigation {
   313  	w := NewNavigation(app, spec)
   314  	startMode(app, w, nil)
   315  	return w
   316  }
   317  
   318  func getTestCursor() *testCursor {
   319  	return &testCursor{root: testDir, pwd: []string{"d"}}
   320  }