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 }