src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/edit/navigation_test.go (about)

     1  package edit
     2  
     3  import (
     4  	"path/filepath"
     5  	"testing"
     6  
     7  	"src.elv.sh/pkg/cli/lscolors"
     8  	"src.elv.sh/pkg/cli/term"
     9  	"src.elv.sh/pkg/must"
    10  	"src.elv.sh/pkg/testutil"
    11  	"src.elv.sh/pkg/ui"
    12  )
    13  
    14  func TestNavigation(t *testing.T) {
    15  	f := setupNav(t)
    16  
    17  	feedInput(f.TTYCtrl, "put")
    18  	f.TTYCtrl.Inject(term.K('N', ui.Ctrl))
    19  	f.TestTTY(t,
    20  		filepath.Join("~", "d"), "> ",
    21  		"put", Styles,
    22  		"vvv", term.DotHere, "\n",
    23  		" NAVIGATING            Ctrl-H hidden Ctrl-F filter\n", Styles,
    24  		"************           ++++++        ++++++       ",
    25  		" d      a                 \n", Styles,
    26  		"###### ++++++++++++++++++ ",
    27  		"        e                ", Styles,
    28  		"       //////////////////",
    29  	)
    30  
    31  	// Test $edit:selected-file.
    32  	evals(f.Evaler, `var file = $edit:selected-file`)
    33  	wantFile := "a"
    34  	if file, _ := f.Evaler.Global().Index("file"); file != wantFile {
    35  		t.Errorf("Got $edit:selected-file %q, want %q", file, wantFile)
    36  	}
    37  
    38  	// Test Alt-Enter: inserts filename without quitting.
    39  	f.TTYCtrl.Inject(term.K(ui.Enter, ui.Alt))
    40  	f.TestTTY(t,
    41  		filepath.Join("~", "d"), "> ",
    42  		"put a", Styles,
    43  		"vvv ", term.DotHere, "\n",
    44  		" NAVIGATING            Ctrl-H hidden Ctrl-F filter\n", Styles,
    45  		"************           ++++++        ++++++       ",
    46  		" d      a                 \n", Styles,
    47  		"###### ++++++++++++++++++ ",
    48  		"        e                ", Styles,
    49  		"       //////////////////",
    50  	)
    51  
    52  	// Test Enter: inserts filename and quits.
    53  	f.TTYCtrl.Inject(term.K(ui.Enter))
    54  	f.TestTTY(t,
    55  		filepath.Join("~", "d"), "> ",
    56  		"put a a", Styles,
    57  		"vvv    ", term.DotHere,
    58  	)
    59  }
    60  
    61  func TestNavigation_WidthRatio(t *testing.T) {
    62  	f := setupNav(t)
    63  
    64  	evals(f.Evaler, `set @edit:navigation:width-ratio = 1 1 1`)
    65  	f.TTYCtrl.Inject(term.K('N', ui.Ctrl))
    66  	f.TestTTY(t,
    67  		filepath.Join("~", "d"), "> ", term.DotHere, "\n",
    68  		" NAVIGATING            Ctrl-H hidden Ctrl-F filter\n", Styles,
    69  		"************           ++++++        ++++++       ",
    70  		" d                a               \n", Styles,
    71  		"################ ++++++++++++++++ ",
    72  		"                  e              ", Styles,
    73  		"                 ////////////////",
    74  	)
    75  }
    76  
    77  // Test corner case: Inserting a selection when the CLI cursor is not at the
    78  // start of the edit buffer, but the preceding char is a space, does not
    79  // insert another space.
    80  func TestNavigation_EnterDoesNotAddSpaceAfterSpace(t *testing.T) {
    81  	f := setupNav(t)
    82  
    83  	feedInput(f.TTYCtrl, "put ")
    84  	f.TTYCtrl.Inject(term.K('N', ui.Ctrl)) // begin navigation mode
    85  	f.TTYCtrl.Inject(term.K(ui.Down))      // select "e"
    86  	f.TTYCtrl.Inject(term.K(ui.Enter))     // insert the "e" file name
    87  	f.TestTTY(t,
    88  		filepath.Join("~", "d"), "> ",
    89  		"put e", Styles,
    90  		"vvv", term.DotHere,
    91  	)
    92  }
    93  
    94  // Test corner case: Inserting a selection when the CLI cursor is at the start
    95  // of the edit buffer omits the space char prefix.
    96  func TestNavigation_EnterDoesNotAddSpaceAtStartOfBuffer(t *testing.T) {
    97  	f := setupNav(t)
    98  
    99  	f.TTYCtrl.Inject(term.K('N', ui.Ctrl)) // begin navigation mode
   100  	f.TTYCtrl.Inject(term.K(ui.Enter))     // insert the "a" file name
   101  	f.TestTTY(t,
   102  		filepath.Join("~", "d"), "> ",
   103  		"a", Styles,
   104  		"!", term.DotHere,
   105  	)
   106  }
   107  
   108  // Test corner case: Inserting a selection when the CLI cursor is at the start
   109  // of a line buffer omits the space char prefix.
   110  func TestNavigation_EnterDoesNotAddSpaceAtStartOfLine(t *testing.T) {
   111  	f := setupNav(t)
   112  
   113  	feedInput(f.TTYCtrl, "put [\n")
   114  	f.TTYCtrl.Inject(term.K('N', ui.Ctrl)) // begin navigation mode
   115  	f.TTYCtrl.Inject(term.K(ui.Enter))     // insert the "a" file name
   116  	f.TestTTY(t,
   117  		filepath.Join("~", "d"), "> ",
   118  		"put [", Styles,
   119  		"vvv b", "\n",
   120  		"     a", term.DotHere,
   121  	)
   122  }
   123  
   124  // Test corner case: Inserting the "selection" in an empty directory inserts
   125  // nothing. Regression test for https://b.elv.sh/1169.
   126  func TestNavigation_EnterDoesNothingInEmptyDir(t *testing.T) {
   127  	f := setupNav(t)
   128  
   129  	feedInput(f.TTYCtrl, "pu")
   130  	f.TTYCtrl.Inject(term.K('N', ui.Ctrl))     // begin navigation mode
   131  	f.TTYCtrl.Inject(term.K(ui.Down))          // select empty directory "e"
   132  	f.TTYCtrl.Inject(term.K(ui.Right))         // move into "e" directory
   133  	f.TTYCtrl.Inject(term.K(ui.Enter, ui.Alt)) // insert nothing since the dir is empty
   134  	f.TTYCtrl.Inject(term.K('t'))              // user presses 'a'
   135  	f.TestTTY(t,
   136  		filepath.Join("~", "d", "e"), "> ",
   137  		"put", Styles,
   138  		"vvv", term.DotHere, "\n",
   139  		" NAVIGATING            Ctrl-H hidden Ctrl-F filter\n", Styles,
   140  		"************           ++++++        ++++++       ",
   141  		" a                        \n", Styles,
   142  		"                          ",
   143  		" e    ", Styles,
   144  		"######",
   145  	)
   146  }
   147  
   148  func TestNavigation_UsesEvalerChdir(t *testing.T) {
   149  	f := setupNav(t)
   150  	afterChdirCalled := false
   151  	f.Evaler.AfterChdir = append(f.Evaler.AfterChdir, func(dir string) {
   152  		afterChdirCalled = true
   153  	})
   154  
   155  	f.TTYCtrl.Inject(term.K('N', ui.Ctrl))
   156  	f.TTYCtrl.Inject(term.K(ui.Down))      // select directory "e"
   157  	f.TTYCtrl.Inject(term.K(ui.Right))     // mode into "e"
   158  	f.TTYCtrl.Inject(term.K('[', ui.Ctrl)) // quit navigation mode
   159  
   160  	f.TestTTY(t,
   161  		filepath.Join("~", "d", "e"), "> ", term.DotHere)
   162  
   163  	if !afterChdirCalled {
   164  		t.Errorf("afterChdir not called")
   165  	}
   166  }
   167  
   168  var testDir = testutil.Dir{
   169  	"d": testutil.Dir{
   170  		"a": "",
   171  		"e": testutil.Dir{},
   172  	},
   173  }
   174  
   175  func setupNav(c testutil.Cleanuper) *fixture {
   176  	f := setup(c)
   177  	lscolors.SetTestLsColors(c)
   178  	testutil.ApplyDir(testDir)
   179  	must.Chdir("d")
   180  	return f
   181  }