diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2021-09-17 09:16:40 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-09-17 09:16:40 -0700 |
commit | d8de4eb685e35646c7d541e9a75bdc296127b7e2 (patch) | |
tree | 4bb05ec713856715ac9ba57e5d116eed344511b9 /test/functional/vimscript/input_spec.lua | |
parent | d56002f7b722facd97b0958e141c8ed2d01495f7 (diff) | |
download | rneovim-d8de4eb685e35646c7d541e9a75bdc296127b7e2.tar.gz rneovim-d8de4eb685e35646c7d541e9a75bdc296127b7e2.tar.bz2 rneovim-d8de4eb685e35646c7d541e9a75bdc296127b7e2.zip |
test: reorg #15698
Problem:
Subdirectories like "visual", "insert", "normal" encourage people to
separate *related* tests for no good reason. Typically the _mode_ is
not the relevant topic of a test (and when it is, _then_ create
an appropriate describe() or it()).
Solution:
- Delete the various `test/functional/<mode>/` subdirectories, move
their tests to more meaningful topics.
- Rename `…/normal/` to `…/editor/`.
- Move or merge `…/visual/*` and `…/insert/*` tests into here where
appropriate.
- Rename `…/eval/` to `…/vimscript/`.
- Move `…/viml/*` into here also.
* test(reorg): insert/* => editor/mode_insert_spec.lua
* test(reorg): cmdline/* => editor/mode_cmdline_spec.lua
* test(reorg): eval core tests => eval_spec.lua
Diffstat (limited to 'test/functional/vimscript/input_spec.lua')
-rw-r--r-- | test/functional/vimscript/input_spec.lua | 483 |
1 files changed, 483 insertions, 0 deletions
diff --git a/test/functional/vimscript/input_spec.lua b/test/functional/vimscript/input_spec.lua new file mode 100644 index 0000000000..14c02f9eb2 --- /dev/null +++ b/test/functional/vimscript/input_spec.lua @@ -0,0 +1,483 @@ +local helpers = require('test.functional.helpers')(after_each) +local Screen = require('test.functional.ui.screen') + +local eq = helpers.eq +local feed = helpers.feed +local meths = helpers.meths +local clear = helpers.clear +local source = helpers.source +local command = helpers.command +local exc_exec = helpers.exc_exec +local nvim_async = helpers.nvim_async + +local screen + +before_each(function() + clear() + screen = Screen.new(25, 5) + screen:attach() + source([[ + hi Test ctermfg=Red guifg=Red term=bold + function CustomCompl(...) + return 'TEST' + endfunction + function CustomListCompl(...) + return ['FOO'] + endfunction + + highlight RBP1 guibg=Red + highlight RBP2 guibg=Yellow + highlight RBP3 guibg=Green + highlight RBP4 guibg=Blue + let g:NUM_LVLS = 4 + function Redraw() + redraw! + return '' + endfunction + cnoremap <expr> {REDRAW} Redraw() + function RainBowParens(cmdline) + let ret = [] + let i = 0 + let lvl = 0 + while i < len(a:cmdline) + if a:cmdline[i] is# '(' + call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)]) + let lvl += 1 + elseif a:cmdline[i] is# ')' + let lvl -= 1 + call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)]) + endif + let i += 1 + endwhile + return ret + endfunction + ]]) + screen:set_default_attr_ids({ + EOB={bold = true, foreground = Screen.colors.Blue1}, + T={foreground=Screen.colors.Red}, + RBP1={background=Screen.colors.Red}, + RBP2={background=Screen.colors.Yellow}, + RBP3={background=Screen.colors.Green}, + RBP4={background=Screen.colors.Blue}, + SEP={bold = true, reverse = true}, + CONFIRM={bold = true, foreground = Screen.colors.SeaGreen4}, + }) +end) + +describe('input()', function() + it('works with multiline prompts', function() + feed([[:call input("Test\nFoo")<CR>]]) + screen:expect([[ + | + {EOB:~ }| + {SEP: }| + Test | + Foo^ | + ]]) + end) + it('works with multiline prompts and :echohl', function() + feed([[:echohl Test | call input("Test\nFoo")<CR>]]) + screen:expect([[ + | + {EOB:~ }| + {SEP: }| + {T:Test} | + {T:Foo}^ | + ]]) + command('redraw!') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:Foo}^ | + ]]) + end) + it('allows unequal numeric arguments when using multiple args', function() + command('echohl Test') + feed([[:call input(1, 2)<CR>]]) + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:1}2^ | + ]]) + feed('<BS>') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:1}^ | + ]]) + end) + it('allows unequal numeric values when using {opts} dictionary', function() + command('echohl Test') + meths.set_var('opts', {prompt=1, default=2, cancelreturn=3}) + feed([[:echo input(opts)<CR>]]) + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:1}2^ | + ]]) + feed('<BS>') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:1}^ | + ]]) + feed('<Esc>') + screen:expect([[ + ^ | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:3} | + ]]) + end) + it('works with redraw', function() + command('echohl Test') + meths.set_var('opts', {prompt='Foo>', default='Bar'}) + feed([[:echo inputdialog(opts)<CR>]]) + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:Foo>}Bar^ | + ]]) + command('mode') + screen:expect{grid=[[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:Foo>}Bar^ | + ]], reset=true} + feed('<BS>') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:Foo>}Ba^ | + ]]) + command('mode') + screen:expect{grid=[[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:Foo>}Ba^ | + ]], reset=true} + end) + it('allows omitting everything with dictionary argument', function() + command('echohl Test') + feed([[:call input({})<CR>]]) + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + ^ | + ]]) + end) + it('supports completion', function() + feed(':let var = input("", "", "custom,CustomCompl")<CR>') + feed('<Tab><CR>') + eq('TEST', meths.get_var('var')) + + feed(':let var = input({"completion": "customlist,CustomListCompl"})<CR>') + feed('<Tab><CR>') + eq('FOO', meths.get_var('var')) + end) + it('supports cancelreturn', function() + feed(':let var = input({"cancelreturn": "BAR"})<CR>') + feed('<Esc>') + eq('BAR', meths.get_var('var')) + end) + it('supports default string', function() + feed(':let var = input("", "DEF1")<CR>') + feed('<CR>') + eq('DEF1', meths.get_var('var')) + + feed(':let var = input({"default": "DEF2"})<CR>') + feed('<CR>') + eq('DEF2', meths.get_var('var')) + end) + it('errors out on invalid inputs', function() + eq('Vim(call):E730: using List as a String', + exc_exec('call input([])')) + eq('Vim(call):E730: using List as a String', + exc_exec('call input("", [])')) + eq('Vim(call):E730: using List as a String', + exc_exec('call input("", "", [])')) + eq('Vim(call):E730: using List as a String', + exc_exec('call input({"prompt": []})')) + eq('Vim(call):E730: using List as a String', + exc_exec('call input({"cancelreturn": []})')) + eq('Vim(call):E730: using List as a String', + exc_exec('call input({"default": []})')) + eq('Vim(call):E730: using List as a String', + exc_exec('call input({"completion": []})')) + eq('Vim(call):E5050: {opts} must be the only argument', + exc_exec('call input({}, "default")')) + eq('Vim(call):E118: Too many arguments for function: input', + exc_exec('call input("prompt> ", "default", "file", "extra")')) + end) + it('supports highlighting', function() + command('nnoremap <expr> X input({"highlight": "RainBowParens"})[-1]') + feed([[X]]) + feed('(())') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {RBP1:(}{RBP2:()}{RBP1:)}^ | + ]]) + end) + it('is not hidden by :silent', function() + feed([[:silent call input('Foo: ')<CR>]]) + screen:expect([[ + | + {EOB:~ }| + {SEP: }| + Foo: ^ | + | + ]]) + feed('Bar') + screen:expect([[ + | + {EOB:~ }| + {SEP: }| + Foo: Bar^ | + | + ]]) + feed('<CR>') + end) +end) +describe('inputdialog()', function() + it('works with multiline prompts', function() + feed([[:call inputdialog("Test\nFoo")<CR>]]) + screen:expect([[ + | + {EOB:~ }| + {SEP: }| + Test | + Foo^ | + ]]) + end) + it('works with multiline prompts and :echohl', function() + feed([[:echohl Test | call inputdialog("Test\nFoo")<CR>]]) + screen:expect([[ + | + {EOB:~ }| + {SEP: }| + {T:Test} | + {T:Foo}^ | + ]]) + command('redraw!') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:Foo}^ | + ]]) + end) + it('allows unequal numeric arguments when using multiple args', function() + command('echohl Test') + feed([[:call inputdialog(1, 2)<CR>]]) + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:1}2^ | + ]]) + feed('<BS>') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:1}^ | + ]]) + end) + it('allows unequal numeric values when using {opts} dictionary', function() + command('echohl Test') + meths.set_var('opts', {prompt=1, default=2, cancelreturn=3}) + feed([[:echo input(opts)<CR>]]) + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:1}2^ | + ]]) + feed('<BS>') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:1}^ | + ]]) + feed('<Esc>') + screen:expect([[ + ^ | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:3} | + ]]) + end) + it('works with redraw', function() + command('echohl Test') + meths.set_var('opts', {prompt='Foo>', default='Bar'}) + feed([[:echo input(opts)<CR>]]) + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:Foo>}Bar^ | + ]]) + command('mode') + screen:expect{grid=[[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:Foo>}Bar^ | + ]], reset=true} + feed('<BS>') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:Foo>}Ba^ | + ]]) + command('mode') + screen:expect{grid=[[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {T:Foo>}Ba^ | + ]], reset=true} + end) + it('allows omitting everything with dictionary argument', function() + command('echohl Test') + feed(':echo inputdialog({})<CR>') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + ^ | + ]]) + end) + it('supports completion', function() + feed(':let var = inputdialog({"completion": "customlist,CustomListCompl"})<CR>') + feed('<Tab><CR>') + eq('FOO', meths.get_var('var')) + end) + it('supports cancelreturn', function() + feed(':let var = inputdialog("", "", "CR1")<CR>') + feed('<Esc>') + eq('CR1', meths.get_var('var')) + + feed(':let var = inputdialog({"cancelreturn": "BAR"})<CR>') + feed('<Esc>') + eq('BAR', meths.get_var('var')) + end) + it('supports default string', function() + feed(':let var = inputdialog("", "DEF1")<CR>') + feed('<CR>') + eq('DEF1', meths.get_var('var')) + + feed(':let var = inputdialog({"default": "DEF2"})<CR>') + feed('<CR>') + eq('DEF2', meths.get_var('var')) + end) + it('errors out on invalid inputs', function() + eq('Vim(call):E730: using List as a String', + exc_exec('call inputdialog([])')) + eq('Vim(call):E730: using List as a String', + exc_exec('call inputdialog("", [])')) + eq('Vim(call):E730: using List as a String', + exc_exec('call inputdialog("", "", [])')) + eq('Vim(call):E730: using List as a String', + exc_exec('call inputdialog({"prompt": []})')) + eq('Vim(call):E730: using List as a String', + exc_exec('call inputdialog({"cancelreturn": []})')) + eq('Vim(call):E730: using List as a String', + exc_exec('call inputdialog({"default": []})')) + eq('Vim(call):E730: using List as a String', + exc_exec('call inputdialog({"completion": []})')) + eq('Vim(call):E5050: {opts} must be the only argument', + exc_exec('call inputdialog({}, "default")')) + eq('Vim(call):E118: Too many arguments for function: inputdialog', + exc_exec('call inputdialog("prompt> ", "default", "file", "extra")')) + end) + it('supports highlighting', function() + command('nnoremap <expr> X inputdialog({"highlight": "RainBowParens"})[-1]') + feed([[X]]) + feed('(())') + screen:expect([[ + | + {EOB:~ }| + {EOB:~ }| + {EOB:~ }| + {RBP1:(}{RBP2:()}{RBP1:)}^ | + ]]) + end) +end) + +describe('confirm()', function() + it("shows dialog even if :silent #8788", function() + command("autocmd BufNewFile * call confirm('test')") + + local function check_and_clear(edit_line) + screen:expect([[ + | + {SEP: }| + ]]..edit_line..[[ + {CONFIRM:test} | + {CONFIRM:[O]k: }^ | + ]]) + feed('<cr>') + command('redraw') + command('bdelete!') + end + + -- With shortmess-=F + command('set shortmess-=F') + feed(':edit foo<cr>') + check_and_clear('"foo" [New] |\n') + + -- With shortmess+=F + command('set shortmess+=F') + feed(':edit foo<cr>') + check_and_clear(':edit foo |\n') + + -- With :silent + feed(':silent edit foo<cr>') + check_and_clear(':silent edit foo |\n') + + -- With API (via eval/VimL) call and shortmess+=F + feed(':call nvim_command("edit x")<cr>') + check_and_clear(':call nvim_command("edit |\n') + + nvim_async('command', 'edit x') + check_and_clear(' |\n') + end) +end) |