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

     1  package edit
     2  
     3  import (
     4  	"testing"
     5  
     6  	"src.elv.sh/pkg/cli/term"
     7  	"src.elv.sh/pkg/store/storedefs"
     8  	"src.elv.sh/pkg/ui"
     9  )
    10  
    11  func TestListingBuiltins(t *testing.T) {
    12  	// Use the custom listing mode since it doesn't require special setup. The
    13  	// builtins work the same across all listing modes.
    14  
    15  	f := setup(t)
    16  	evals(f.Evaler,
    17  		`fn item {|x| put [&to-show=$x &to-accept=$x &to-filter=$x] }`,
    18  		`edit:listing:start-custom [(item 1) (item 2) (item 3)]`)
    19  	buf1 := f.MakeBuffer(
    20  		"~> \n",
    21  		" LISTING  ", Styles,
    22  		"********* ", term.DotHere, "\n",
    23  		"1                                                 ", Styles,
    24  		"++++++++++++++++++++++++++++++++++++++++++++++++++",
    25  		"2                                                 \n",
    26  		"3                                                 ",
    27  	)
    28  	f.TTYCtrl.TestBuffer(t, buf1)
    29  
    30  	evals(f.Evaler, "edit:listing:down", "edit:redraw")
    31  	buf2 := f.MakeBuffer(
    32  		"~> \n",
    33  		" LISTING  ", Styles,
    34  		"********* ", term.DotHere, "\n",
    35  		"1                                                 \n",
    36  		"2                                                 \n", Styles,
    37  		"++++++++++++++++++++++++++++++++++++++++++++++++++",
    38  		"3                                                 ",
    39  	)
    40  	f.TTYCtrl.TestBuffer(t, buf2)
    41  
    42  	evals(f.Evaler, "edit:listing:down", "edit:redraw")
    43  	buf3 := f.MakeBuffer(
    44  		"~> \n",
    45  		" LISTING  ", Styles,
    46  		"********* ", term.DotHere, "\n",
    47  		"1                                                 \n",
    48  		"2                                                 \n",
    49  		"3                                                 ", Styles,
    50  		"++++++++++++++++++++++++++++++++++++++++++++++++++",
    51  	)
    52  	f.TTYCtrl.TestBuffer(t, buf3)
    53  
    54  	evals(f.Evaler, "edit:listing:down", "edit:redraw")
    55  	f.TTYCtrl.TestBuffer(t, buf3)
    56  
    57  	evals(f.Evaler, "edit:listing:down-cycle", "edit:redraw")
    58  	f.TTYCtrl.TestBuffer(t, buf1)
    59  
    60  	evals(f.Evaler, "edit:listing:up", "edit:redraw")
    61  	f.TTYCtrl.TestBuffer(t, buf1)
    62  
    63  	evals(f.Evaler, "edit:listing:up-cycle", "edit:redraw")
    64  	f.TTYCtrl.TestBuffer(t, buf3)
    65  
    66  	evals(f.Evaler, "edit:listing:page-up", "edit:redraw")
    67  	f.TTYCtrl.TestBuffer(t, buf1)
    68  
    69  	evals(f.Evaler, "edit:listing:page-down", "edit:redraw")
    70  	f.TTYCtrl.TestBuffer(t, buf3)
    71  }
    72  
    73  // Smoke tests for individual addons.
    74  
    75  func TestHistlistAddon(t *testing.T) {
    76  	f := setup(t, storeOp(func(s storedefs.Store) {
    77  		s.AddCmd("ls")
    78  		s.AddCmd("echo")
    79  		s.AddCmd("ls")
    80  		s.AddCmd("LS")
    81  	}))
    82  
    83  	f.TTYCtrl.Inject(term.K('R', ui.Ctrl))
    84  	f.TestTTY(t,
    85  		"~> \n",
    86  		" HISTORY (dedup on)  ", Styles,
    87  		"******************** ", term.DotHere,
    88  		"                 Ctrl-D dedup\n", Styles,
    89  		"                 ++++++      ",
    90  		"   2 echo\n",
    91  		"   3 ls\n",
    92  		"   4 LS                                           ", Styles,
    93  		"++++++++++++++++++++++++++++++++++++++++++++++++++",
    94  	)
    95  
    96  	evals(f.Evaler, `edit:histlist:toggle-dedup`)
    97  	f.TestTTY(t,
    98  		"~> \n",
    99  		" HISTORY  ", Styles,
   100  		"********* ", term.DotHere,
   101  		"                            Ctrl-D dedup\n", Styles,
   102  		"                            ++++++      ",
   103  		"   1 ls\n",
   104  		"   2 echo\n",
   105  		"   3 ls\n",
   106  		"   4 LS                                           ", Styles,
   107  		"++++++++++++++++++++++++++++++++++++++++++++++++++",
   108  	)
   109  
   110  	evals(f.Evaler, `edit:histlist:toggle-dedup`)
   111  
   112  	// Filtering is case-insensitive when filter is all lower case.
   113  	f.TTYCtrl.Inject(term.K('l'))
   114  	f.TestTTY(t,
   115  		"~> \n",
   116  		" HISTORY (dedup on)  l", Styles,
   117  		"********************  ", term.DotHere,
   118  		"                Ctrl-D dedup\n", Styles,
   119  		"                ++++++      ",
   120  		"   3 ls\n",
   121  		"   4 LS                                           ", Styles,
   122  		"++++++++++++++++++++++++++++++++++++++++++++++++++",
   123  	)
   124  
   125  	// Filtering is case-sensitive when filter is not all lower case.
   126  	f.TTYCtrl.Inject(term.K(ui.Backspace), term.K('L'))
   127  	f.TestTTY(t,
   128  		"~> \n",
   129  		" HISTORY (dedup on)  L", Styles,
   130  		"********************  ", term.DotHere,
   131  		"                Ctrl-D dedup\n", Styles,
   132  		"                ++++++      ",
   133  		"   4 LS                                           ", Styles,
   134  		"++++++++++++++++++++++++++++++++++++++++++++++++++",
   135  	)
   136  }
   137  
   138  func TestLastCmdAddon(t *testing.T) {
   139  	f := setup(t, storeOp(func(s storedefs.Store) {
   140  		s.AddCmd("echo hello world")
   141  	}))
   142  
   143  	f.TTYCtrl.Inject(term.K(',', ui.Alt))
   144  	f.TestTTY(t,
   145  		"~> \n",
   146  		" LASTCMD  ", Styles,
   147  		"********* ", term.DotHere, "\n",
   148  		"    echo hello world                              \n", Styles,
   149  		"++++++++++++++++++++++++++++++++++++++++++++++++++",
   150  		"  0 echo\n",
   151  		"  1 hello\n",
   152  		"  2 world",
   153  	)
   154  }
   155  
   156  func TestCustomListing_PassingList(t *testing.T) {
   157  	f := setup(t)
   158  
   159  	evals(f.Evaler,
   160  		`var items = [[&to-filter=1 &to-accept=echo &to-show=echo]
   161  		              [&to-filter=2  &to-accept=put &to-show=(styled put green)]]`,
   162  		`edit:listing:start-custom $items &accept=$edit:insert-at-dot~ &caption=A`)
   163  	f.TestTTY(t,
   164  		"~> \n",
   165  		"A ", Styles,
   166  		"* ", term.DotHere, "\n",
   167  		"echo                                              \n", Styles,
   168  		"++++++++++++++++++++++++++++++++++++++++++++++++++",
   169  		"put                                               ", Styles,
   170  		"vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv",
   171  	)
   172  	// Filter - "put" will be selected.
   173  	f.TTYCtrl.Inject(term.K('2'))
   174  	// Accept.
   175  	f.TTYCtrl.Inject(term.K('\n'))
   176  	f.TestTTY(t,
   177  		"~> put", Styles,
   178  		"   vvv", term.DotHere,
   179  	)
   180  }
   181  
   182  func TestCustomListing_PassingValueCallback(t *testing.T) {
   183  	f := setup(t)
   184  
   185  	evals(f.Evaler,
   186  		`var f = {|q| put [&to-accept='q '$q &to-show=(styled 'q '$q blue)] }`,
   187  		`edit:listing:start-custom $f &caption=A`)
   188  	// Query.
   189  	f.TTYCtrl.Inject(term.K('x'))
   190  	f.TestTTY(t,
   191  		"~> \n",
   192  		"A x", Styles,
   193  		"*  ", term.DotHere, "\n",
   194  		"q x                                               ", Styles,
   195  		"##################################################",
   196  	)
   197  	// No-op accept.
   198  	f.TTYCtrl.Inject(term.K('\n'))
   199  	f.TestTTY(t, "~> ", term.DotHere)
   200  }
   201  
   202  func TestCustomListing_PassingBytesCallback(t *testing.T) {
   203  	f := setup(t)
   204  
   205  	evals(f.Evaler,
   206  		`var f = {|q| echo '# '$q }`,
   207  		`edit:listing:start-custom $f &accept=$edit:insert-at-dot~ &caption=A `+
   208  			`&binding=(edit:binding-table [&Ctrl-X=$edit:listing:accept~])`)
   209  	// Test that the query function is used to generate candidates. Also test
   210  	// the caption.
   211  	f.TTYCtrl.Inject(term.K('x'))
   212  	f.TestTTY(t,
   213  		"~> \n",
   214  		"A x", Styles,
   215  		"*  ", term.DotHere, "\n",
   216  		"# x                                               ", Styles,
   217  		"++++++++++++++++++++++++++++++++++++++++++++++++++",
   218  	)
   219  	// Test both the binding and the accept callback.
   220  	f.TTYCtrl.Inject(term.K('X', ui.Ctrl))
   221  	f.TestTTY(t,
   222  		"~> # x", Styles,
   223  		"   ccc", term.DotHere)
   224  }