src.elv.sh@v0.21.0-dev.0.20240515223629-06979efb9a2a/pkg/cli/modes/histlist_test.go (about)

     1  package modes
     2  
     3  import (
     4  	"regexp"
     5  	"testing"
     6  
     7  	"src.elv.sh/pkg/cli"
     8  	. "src.elv.sh/pkg/cli/clitest"
     9  	"src.elv.sh/pkg/cli/histutil"
    10  	"src.elv.sh/pkg/cli/term"
    11  	"src.elv.sh/pkg/store/storedefs"
    12  	"src.elv.sh/pkg/ui"
    13  )
    14  
    15  func TestNewHistlist_NoStore(t *testing.T) {
    16  	f := Setup()
    17  	defer f.Stop()
    18  
    19  	_, err := NewHistlist(f.App, HistlistSpec{})
    20  	if err != errNoHistoryStore {
    21  		t.Errorf("want errNoHistoryStore")
    22  	}
    23  }
    24  
    25  func TestNewHistlist_FocusedWidgetNotCodeArea(t *testing.T) {
    26  	testFocusedWidgetNotCodeArea(t, func(app cli.App) error {
    27  		st := histutil.NewMemStore("foo")
    28  		_, err := NewHistlist(app, HistlistSpec{AllCmds: st.AllCmds})
    29  		return err
    30  	})
    31  }
    32  
    33  type faultyStore struct{}
    34  
    35  func (s faultyStore) AllCmds() ([]storedefs.Cmd, error) { return nil, errMock }
    36  
    37  func TestNewHistlist_StoreError(t *testing.T) {
    38  	f := Setup()
    39  	defer f.Stop()
    40  
    41  	_, err := NewHistlist(f.App, HistlistSpec{AllCmds: faultyStore{}.AllCmds})
    42  	if err.Error() != "db error: mock error" {
    43  		t.Errorf("want db error")
    44  	}
    45  }
    46  
    47  func TestHistlist(t *testing.T) {
    48  	f := Setup()
    49  	defer f.Stop()
    50  
    51  	st := histutil.NewMemStore(
    52  		// 0    1      2
    53  		"foo", "bar", "baz")
    54  	startHistlist(f.App, HistlistSpec{AllCmds: st.AllCmds})
    55  
    56  	// Test initial UI - last item selected
    57  	f.TestTTY(t,
    58  		"\n",
    59  		" HISTORY (dedup on)  ", Styles,
    60  		"******************** ", term.DotHere, "\n",
    61  		"   0 foo\n",
    62  		"   1 bar\n",
    63  		"   2 baz                                          ", Styles,
    64  		"++++++++++++++++++++++++++++++++++++++++++++++++++")
    65  
    66  	// Test filtering.
    67  	f.TTY.Inject(term.K('b'))
    68  	f.TestTTY(t,
    69  		"\n",
    70  		" HISTORY (dedup on)  b", Styles,
    71  		"********************  ", term.DotHere, "\n",
    72  		"   1 bar\n",
    73  		"   2 baz                                          ", Styles,
    74  		"++++++++++++++++++++++++++++++++++++++++++++++++++")
    75  
    76  	// Test accepting.
    77  	f.TTY.Inject(term.K(ui.Enter))
    78  	f.TestTTY(t, "baz", term.DotHere)
    79  
    80  	// Test accepting when there is already some text.
    81  	st.AddCmd(storedefs.Cmd{Text: "baz2"})
    82  	startHistlist(f.App, HistlistSpec{AllCmds: st.AllCmds})
    83  	f.TTY.Inject(term.K(ui.Enter))
    84  	f.TestTTY(t, "baz",
    85  		// codearea now contains newly inserted entry on a separate line
    86  		"\n", "baz2", term.DotHere)
    87  }
    88  
    89  func TestHistlist_Dedup(t *testing.T) {
    90  	f := Setup()
    91  	defer f.Stop()
    92  
    93  	st := histutil.NewMemStore(
    94  		// 0    1      2
    95  		"ls", "echo", "ls")
    96  
    97  	// No dedup
    98  	startHistlist(f.App,
    99  		HistlistSpec{AllCmds: st.AllCmds, Dedup: func() bool { return false }})
   100  	f.TestTTY(t,
   101  		"\n",
   102  		" HISTORY  ", Styles,
   103  		"********* ", term.DotHere, "\n",
   104  		"   0 ls\n",
   105  		"   1 echo\n",
   106  		"   2 ls                                           ", Styles,
   107  		"++++++++++++++++++++++++++++++++++++++++++++++++++")
   108  
   109  	f.App.PopAddon()
   110  
   111  	// With dedup
   112  	startHistlist(f.App,
   113  		HistlistSpec{AllCmds: st.AllCmds, Dedup: func() bool { return true }})
   114  	f.TestTTY(t,
   115  		"\n",
   116  		" HISTORY (dedup on)  ", Styles,
   117  		"******************** ", term.DotHere, "\n",
   118  		"   1 echo\n",
   119  		"   2 ls                                           ", Styles,
   120  		"++++++++++++++++++++++++++++++++++++++++++++++++++")
   121  }
   122  
   123  func TestHistlist_CustomFilter(t *testing.T) {
   124  	f := Setup()
   125  	defer f.Stop()
   126  
   127  	st := histutil.NewMemStore(
   128  		// 0   1         2
   129  		"vi", "elvish", "nvi")
   130  
   131  	startHistlist(f.App, HistlistSpec{
   132  		AllCmds: st.AllCmds,
   133  		Filter: FilterSpec{
   134  			Maker: func(p string) func(string) bool {
   135  				re, _ := regexp.Compile(p)
   136  				return func(s string) bool {
   137  					return re != nil && re.MatchString(s)
   138  				}
   139  			},
   140  			Highlighter: func(p string) (ui.Text, []ui.Text) {
   141  				return ui.T(p, ui.Inverse), nil
   142  			},
   143  		},
   144  	})
   145  	f.TTY.Inject(term.K('v'), term.K('i'), term.K('$'))
   146  	f.TestTTY(t,
   147  		"\n",
   148  		" HISTORY (dedup on)  vi$", Styles,
   149  		"******************** +++", term.DotHere, "\n",
   150  		"   0 vi\n",
   151  		"   2 nvi                                          ", Styles,
   152  		"++++++++++++++++++++++++++++++++++++++++++++++++++")
   153  }
   154  
   155  func startHistlist(app cli.App, spec HistlistSpec) {
   156  	w, err := NewHistlist(app, spec)
   157  	startMode(app, w, err)
   158  }