ui_spec.lua (6956B)
1 local t = require('test.testutil') 2 local n = require('test.functional.testnvim')() 3 4 local eq = t.eq 5 local ok = t.ok 6 local exec_lua = n.exec_lua 7 local clear = n.clear 8 local feed = n.feed 9 local eval = n.eval 10 local is_ci = t.is_ci 11 local is_os = t.is_os 12 local poke_eventloop = n.poke_eventloop 13 14 describe('vim.ui', function() 15 before_each(function() 16 clear({ args_rm = { '-u' }, args = { '--clean' } }) 17 end) 18 19 describe('select()', function() 20 it('can select an item', function() 21 local result = exec_lua [[ 22 local items = { 23 { name = 'Item 1' }, 24 { name = 'Item 2' }, 25 } 26 local opts = { 27 format_item = function(entry) 28 return entry.name 29 end 30 } 31 local selected 32 local cb = function(item) 33 selected = item 34 end 35 -- inputlist would require input and block the test; 36 local choices 37 vim.fn.inputlist = function(x) 38 choices = x 39 return 1 40 end 41 vim.ui.select(items, opts, cb) 42 vim.wait(100, function() return selected ~= nil end) 43 return {selected, choices} 44 ]] 45 eq({ name = 'Item 1' }, result[1]) 46 eq({ 47 'Select one of:', 48 '1: Item 1', 49 '2: Item 2', 50 }, result[2]) 51 end) 52 end) 53 54 describe('input()', function() 55 it('can input text', function() 56 local result = exec_lua [[ 57 local opts = { 58 prompt = 'Input: ', 59 } 60 local input 61 local cb = function(item) 62 input = item 63 end 64 -- input would require input and block the test; 65 local prompt 66 vim.fn.input = function(opts) 67 prompt = opts.prompt 68 return "Inputted text" 69 end 70 vim.ui.input(opts, cb) 71 vim.wait(100, function() return input ~= nil end) 72 return {input, prompt} 73 ]] 74 eq('Inputted text', result[1]) 75 eq('Input: ', result[2]) 76 end) 77 78 it('can input text on nil opt', function() 79 feed(':lua vim.ui.input(nil, function(input) result = input end)<cr>') 80 eq('', eval('v:errmsg')) 81 feed('Inputted text<cr>') 82 eq('Inputted text', exec_lua('return result')) 83 end) 84 85 it('can input text on {} opt', function() 86 feed(':lua vim.ui.input({}, function(input) result = input end)<cr>') 87 eq('', eval('v:errmsg')) 88 feed('abcdefg<cr>') 89 eq('abcdefg', exec_lua('return result')) 90 end) 91 92 it('can input empty text #18144', function() 93 feed(':lua vim.ui.input({}, function(input) result = input end)<cr>') 94 feed('<cr>') 95 eq('', exec_lua('return result')) 96 end) 97 98 it('can input empty text with cancelreturn opt #18144', function() 99 feed(':lua vim.ui.input({ cancelreturn = "CANCEL" }, function(input) result = input end)<cr>') 100 feed('<cr>') 101 eq('', exec_lua('return result')) 102 end) 103 104 it('can return nil when aborted with ESC #18144', function() 105 feed(':lua result = "on_confirm not called"<cr>') 106 feed(':lua vim.ui.input({}, function(input) result = input end)<cr>') 107 feed('Inputted Text<esc>') 108 -- Note: When `result == nil`, exec_lua('returns result') returns vim.NIL 109 eq(true, exec_lua('return (nil == result)')) 110 end) 111 112 it('can return opts.cancelreturn when aborted with ESC with cancelreturn opt #18144', function() 113 feed(':lua result = "on_confirm not called"<cr>') 114 feed(':lua vim.ui.input({ cancelreturn = "CANCEL" }, function(input) result = input end)<cr>') 115 feed('Inputted Text<esc>') 116 eq('CANCEL', exec_lua('return result')) 117 end) 118 119 it('can return nil when interrupted with Ctrl-C #18144', function() 120 feed(':lua result = "on_confirm not called"<cr>') 121 feed(':lua vim.ui.input({}, function(input) result = input end)<cr>') 122 poke_eventloop() -- This is needed because Ctrl-C flushes input 123 feed('Inputted Text<c-c>') 124 eq(true, exec_lua('return (nil == result)')) 125 end) 126 127 it( 128 'can return the identical object when an arbitrary opts.cancelreturn object is given', 129 function() 130 feed(':lua fn = function() return 42 end<CR>') 131 eq(42, exec_lua('return fn()')) 132 feed(':lua vim.ui.input({ cancelreturn = fn }, function(input) result = input end)<cr>') 133 feed('cancel<esc>') 134 eq(true, exec_lua('return (result == fn)')) 135 eq(42, exec_lua('return result()')) 136 end 137 ) 138 end) 139 140 describe('open()', function() 141 it('validation', function() 142 if is_os('win') or not is_ci('github') then 143 exec_lua [[vim.system = function() return { wait=function() return { code=3 } end } end]] 144 end 145 if not is_os('bsd') then 146 local rv = exec_lua([[ 147 local cmd, err = vim.ui.open('non-existent-file') 148 if err then return nil end 149 return cmd:wait(100).code 150 ]]) 151 if type(rv) == 'number' then 152 ok(rv ~= 0, 'nonzero exit code', rv) 153 end 154 end 155 156 exec_lua [[ 157 vim.fn.has = function() return 0 end 158 vim.fn.executable = function() return 0 end 159 ]] 160 eq( 161 'vim.ui.open: no handler found (tried: wslview, explorer.exe, xdg-open, lemonade)', 162 exec_lua [[local _, err = vim.ui.open('foo') ; return err]] 163 ) 164 end) 165 166 it('opt.cmd #29490', function() 167 t.matches( 168 'ENOENT: no such file or directory', 169 t.pcall_err(exec_lua, function() 170 vim.ui.open('foo', { cmd = { 'non-existent-tool' } }) 171 end) 172 ) 173 174 eq( 175 { 176 code = 0, 177 signal = 0, 178 stderr = '', 179 stdout = 'arg1=arg1;arg2=https://example.com;', 180 }, 181 exec_lua(function(cmd_) 182 local cmd, err = vim.ui.open('https://example.com', { cmd = cmd_ }) 183 assert(cmd and not err) 184 return cmd:wait() 185 end, { n.testprg('printargs-test'), 'arg1' }) 186 ) 187 end) 188 189 it('gx on a help tag opens URL', function() 190 n.command('helptags $VIMRUNTIME/doc') 191 n.command('help nvim.txt') 192 193 local link_ns = n.api.nvim_create_namespace('nvim.help.urls') 194 local tag = n.api.nvim_buf_get_extmarks(0, link_ns, 0, -1, { 195 limit = 1, 196 details = true, 197 })[1] 198 199 local url = tag[4].url 200 assert(url) 201 202 --- points to the neovim.io site 203 eq(true, vim.startswith(url, 'https://neovim.io/doc')) 204 205 -- tag is URI encoded 206 local param = url:match('%?tag=(.*)') 207 local tagname = 208 n.api.nvim_buf_get_text(0, tag[2], tag[3], tag[4].end_row, tag[4].end_col, {})[1] 209 eq(vim.uri_encode(tagname), param) 210 211 -- non-nvim tags are ignored 212 local buf = n.api.nvim_create_buf(false, false) 213 n.api.nvim_buf_set_lines(buf, 0, 0, false, { 214 '|nonexisting|', 215 }) 216 n.api.nvim_set_option_value('filetype', 'help', { buf = buf, scope = 'local' }) 217 local tags = n.api.nvim_buf_get_extmarks(buf, link_ns, 0, -1, {}) 218 eq(#tags, 0) 219 end) 220 end) 221 end)