github.com/markusbkk/elvish@v0.0.0-20231204143114-91dc52438621/pkg/edit/listing_test.go (about) 1 package edit 2 3 import ( 4 "testing" 5 6 "github.com/markusbkk/elvish/pkg/cli/term" 7 "github.com/markusbkk/elvish/pkg/store/storedefs" 8 "github.com/markusbkk/elvish/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, "\n", 88 " 2 echo\n", 89 " 3 ls\n", 90 " 4 LS ", Styles, 91 "++++++++++++++++++++++++++++++++++++++++++++++++++", 92 ) 93 94 evals(f.Evaler, `edit:histlist:toggle-dedup`) 95 f.TestTTY(t, 96 "~> \n", 97 " HISTORY ", Styles, 98 "********* ", term.DotHere, "\n", 99 " 1 ls\n", 100 " 2 echo\n", 101 " 3 ls\n", 102 " 4 LS ", Styles, 103 "++++++++++++++++++++++++++++++++++++++++++++++++++", 104 ) 105 106 evals(f.Evaler, `edit:histlist:toggle-dedup`) 107 108 // Filtering is case-insensitive when filter is all lower case. 109 f.TTYCtrl.Inject(term.K('l')) 110 f.TestTTY(t, 111 "~> \n", 112 " HISTORY (dedup on) l", Styles, 113 "******************** ", term.DotHere, "\n", 114 " 3 ls\n", 115 " 4 LS ", Styles, 116 "++++++++++++++++++++++++++++++++++++++++++++++++++", 117 ) 118 119 // Filtering is case-sensitive when filter is not all lower case. 120 f.TTYCtrl.Inject(term.K(ui.Backspace), term.K('L')) 121 f.TestTTY(t, 122 "~> \n", 123 " HISTORY (dedup on) L", Styles, 124 "******************** ", term.DotHere, "\n", 125 " 4 LS ", Styles, 126 "++++++++++++++++++++++++++++++++++++++++++++++++++", 127 ) 128 } 129 130 func TestLastCmdAddon(t *testing.T) { 131 f := setup(t, storeOp(func(s storedefs.Store) { 132 s.AddCmd("echo hello world") 133 })) 134 135 f.TTYCtrl.Inject(term.K(',', ui.Alt)) 136 f.TestTTY(t, 137 "~> \n", 138 " LASTCMD ", Styles, 139 "********* ", term.DotHere, "\n", 140 " echo hello world \n", Styles, 141 "++++++++++++++++++++++++++++++++++++++++++++++++++", 142 " 0 echo\n", 143 " 1 hello\n", 144 " 2 world", 145 ) 146 } 147 148 func TestCustomListing_PassingList(t *testing.T) { 149 f := setup(t) 150 151 evals(f.Evaler, 152 `var items = [[&to-filter=1 &to-accept=echo &to-show=echo] 153 [&to-filter=2 &to-accept=put &to-show=(styled put green)]]`, 154 `edit:listing:start-custom $items &accept=$edit:insert-at-dot~ &caption=A`) 155 f.TestTTY(t, 156 "~> \n", 157 "A ", Styles, 158 "* ", term.DotHere, "\n", 159 "echo \n", Styles, 160 "++++++++++++++++++++++++++++++++++++++++++++++++++", 161 "put ", Styles, 162 "vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv", 163 ) 164 // Filter - "put" will be selected. 165 f.TTYCtrl.Inject(term.K('2')) 166 // Accept. 167 f.TTYCtrl.Inject(term.K('\n')) 168 f.TestTTY(t, 169 "~> put", Styles, 170 " vvv", term.DotHere, 171 ) 172 } 173 174 func TestCustomListing_PassingValueCallback(t *testing.T) { 175 f := setup(t) 176 177 evals(f.Evaler, 178 `var f = {|q| put [&to-accept='q '$q &to-show=(styled 'q '$q blue)] }`, 179 `edit:listing:start-custom $f &caption=A`) 180 // Query. 181 f.TTYCtrl.Inject(term.K('x')) 182 f.TestTTY(t, 183 "~> \n", 184 "A x", Styles, 185 "* ", term.DotHere, "\n", 186 "q x ", Styles, 187 "##################################################", 188 ) 189 // No-op accept. 190 f.TTYCtrl.Inject(term.K('\n')) 191 f.TestTTY(t, "~> ", term.DotHere) 192 } 193 194 func TestCustomListing_PassingBytesCallback(t *testing.T) { 195 f := setup(t) 196 197 evals(f.Evaler, 198 `var f = {|q| echo '# '$q }`, 199 `edit:listing:start-custom $f &accept=$edit:insert-at-dot~ &caption=A `+ 200 `&binding=(edit:binding-table [&Ctrl-X=$edit:listing:accept~])`) 201 // Test that the query function is used to generate candidates. Also test 202 // the caption. 203 f.TTYCtrl.Inject(term.K('x')) 204 f.TestTTY(t, 205 "~> \n", 206 "A x", Styles, 207 "* ", term.DotHere, "\n", 208 "# x ", Styles, 209 "++++++++++++++++++++++++++++++++++++++++++++++++++", 210 ) 211 // Test both the binding and the accept callback. 212 f.TTYCtrl.Inject(term.K('X', ui.Ctrl)) 213 f.TestTTY(t, 214 "~> # x", Styles, 215 " ccc", term.DotHere) 216 }