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/ctx_functions_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/ctx_functions_spec.lua')
-rw-r--r-- | test/functional/vimscript/ctx_functions_spec.lua | 406 |
1 files changed, 406 insertions, 0 deletions
diff --git a/test/functional/vimscript/ctx_functions_spec.lua b/test/functional/vimscript/ctx_functions_spec.lua new file mode 100644 index 0000000000..f23adbc556 --- /dev/null +++ b/test/functional/vimscript/ctx_functions_spec.lua @@ -0,0 +1,406 @@ +local helpers = require('test.functional.helpers')(after_each) + +local call = helpers.call +local clear = helpers.clear +local command = helpers.command +local eq = helpers.eq +local eval = helpers.eval +local feed = helpers.feed +local map = helpers.tbl_map +local nvim = helpers.nvim +local parse_context = helpers.parse_context +local redir_exec = helpers.redir_exec +local source = helpers.source +local trim = helpers.trim +local write_file = helpers.write_file +local pcall_err = helpers.pcall_err + +describe('context functions', function() + local fname1 = 'Xtest-functional-eval-ctx1' + local fname2 = 'Xtest-functional-eval-ctx2' + local outofbounds = + 'Vim:E475: Invalid value for argument index: out of bounds' + + before_each(function() + clear() + write_file(fname1, "1\n2\n3") + write_file(fname2, "a\nb\nc") + end) + + after_each(function() + os.remove(fname1) + os.remove(fname2) + end) + + describe('ctxpush/ctxpop', function() + it('saves and restores registers properly', function() + local regs = {'1', '2', '3', 'a'} + local vals = {'1', '2', '3', 'hjkl'} + feed('i1<cr>2<cr>3<c-[>ddddddqahjklq') + eq(vals, map(function(r) return trim(call('getreg', r)) end, regs)) + call('ctxpush') + call('ctxpush', {'regs'}) + + map(function(r) call('setreg', r, {}) end, regs) + eq({'', '', '', ''}, + map(function(r) return trim(call('getreg', r)) end, regs)) + + call('ctxpop') + eq(vals, map(function(r) return trim(call('getreg', r)) end, regs)) + + map(function(r) call('setreg', r, {}) end, regs) + eq({'', '', '', ''}, + map(function(r) return trim(call('getreg', r)) end, regs)) + + call('ctxpop') + eq(vals, map(function(r) return trim(call('getreg', r)) end, regs)) + end) + + it('saves and restores jumplist properly', function() + command('edit '..fname1) + feed('G') + feed('gg') + command('edit '..fname2) + local jumplist = call('getjumplist') + call('ctxpush') + call('ctxpush', {'jumps'}) + + command('clearjumps') + eq({{}, 0}, call('getjumplist')) + + call('ctxpop') + eq(jumplist, call('getjumplist')) + + command('clearjumps') + eq({{}, 0}, call('getjumplist')) + + call('ctxpop') + eq(jumplist, call('getjumplist')) + end) + + it('saves and restores buffer list properly', function() + command('edit '..fname1) + command('edit '..fname2) + command('edit TEST') + local bufs = call('map', call('getbufinfo'), 'v:val.name') + call('ctxpush') + call('ctxpush', {'bufs'}) + + command('%bwipeout') + eq({''}, call('map', call('getbufinfo'), 'v:val.name')) + + call('ctxpop') + eq({'', unpack(bufs)}, call('map', call('getbufinfo'), 'v:val.name')) + + command('%bwipeout') + eq({''}, call('map', call('getbufinfo'), 'v:val.name')) + + call('ctxpop') + eq({'', unpack(bufs)}, call('map', call('getbufinfo'), 'v:val.name')) + end) + + it('saves and restores global variables properly', function() + nvim('set_var', 'one', 1) + nvim('set_var', 'Two', 2) + nvim('set_var', 'THREE', 3) + eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]')) + call('ctxpush') + call('ctxpush', {'gvars'}) + + nvim('del_var', 'one') + nvim('del_var', 'Two') + nvim('del_var', 'THREE') + eq('Vim:E121: Undefined variable: g:one', pcall_err(eval, 'g:one')) + eq('Vim:E121: Undefined variable: g:Two', pcall_err(eval, 'g:Two')) + eq('Vim:E121: Undefined variable: g:THREE', pcall_err(eval, 'g:THREE')) + + call('ctxpop') + eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]')) + + nvim('del_var', 'one') + nvim('del_var', 'Two') + nvim('del_var', 'THREE') + eq('Vim:E121: Undefined variable: g:one', pcall_err(eval, 'g:one')) + eq('Vim:E121: Undefined variable: g:Two', pcall_err(eval, 'g:Two')) + eq('Vim:E121: Undefined variable: g:THREE', pcall_err(eval, 'g:THREE')) + + call('ctxpop') + eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]')) + end) + + it('saves and restores script functions properly', function() + source([[ + function s:greet(name) + echom 'Hello, '.a:name.'!' + endfunction + + function s:greet_all(name, ...) + echom 'Hello, '.a:name.'!' + for more in a:000 + echom 'Hello, '.more.'!' + endfor + endfunction + + function Greet(name) + call call('s:greet', [a:name]) + endfunction + + function GreetAll(name, ...) + call call('s:greet_all', extend([a:name], a:000)) + endfunction + + function SaveSFuncs() + call ctxpush(['sfuncs']) + endfunction + + function DeleteSFuncs() + delfunction s:greet + delfunction s:greet_all + endfunction + + function RestoreFuncs() + call ctxpop() + endfunction + ]]) + + eq('\nHello, World!', redir_exec([[call Greet('World')]])) + eq('\nHello, World!'.. + '\nHello, One!'.. + '\nHello, Two!'.. + '\nHello, Three!', + redir_exec([[call GreetAll('World', 'One', 'Two', 'Three')]])) + + call('SaveSFuncs') + call('DeleteSFuncs') + + eq('\nError detected while processing function Greet:'.. + '\nline 1:'.. + '\nE117: Unknown function: s:greet', + redir_exec([[call Greet('World')]])) + eq('\nError detected while processing function GreetAll:'.. + '\nline 1:'.. + '\nE117: Unknown function: s:greet_all', + redir_exec([[call GreetAll('World', 'One', 'Two', 'Three')]])) + + call('RestoreFuncs') + + eq('\nHello, World!', redir_exec([[call Greet('World')]])) + eq('\nHello, World!'.. + '\nHello, One!'.. + '\nHello, Two!'.. + '\nHello, Three!', + redir_exec([[call GreetAll('World', 'One', 'Two', 'Three')]])) + end) + + it('saves and restores functions properly', function() + source([[ + function Greet(name) + echom 'Hello, '.a:name.'!' + endfunction + + function GreetAll(name, ...) + echom 'Hello, '.a:name.'!' + for more in a:000 + echom 'Hello, '.more.'!' + endfor + endfunction + ]]) + + eq('\nHello, World!', redir_exec([[call Greet('World')]])) + eq('\nHello, World!'.. + '\nHello, One!'.. + '\nHello, Two!'.. + '\nHello, Three!', + redir_exec([[call GreetAll('World', 'One', 'Two', 'Three')]])) + + call('ctxpush', {'funcs'}) + command('delfunction Greet') + command('delfunction GreetAll') + + eq('Vim:E117: Unknown function: Greet', pcall_err(call, 'Greet', 'World')) + eq('Vim:E117: Unknown function: GreetAll', + pcall_err(call, 'GreetAll', 'World', 'One', 'Two', 'Three')) + + call('ctxpop') + + eq('\nHello, World!', redir_exec([[call Greet('World')]])) + eq('\nHello, World!'.. + '\nHello, One!'.. + '\nHello, Two!'.. + '\nHello, Three!', + redir_exec([[call GreetAll('World', 'One', 'Two', 'Three')]])) + end) + + it('errors out when context stack is empty', function() + local err = 'Vim:Context stack is empty' + eq(err, pcall_err(call, 'ctxpop')) + eq(err, pcall_err(call, 'ctxpop')) + call('ctxpush') + call('ctxpush') + call('ctxpop') + call('ctxpop') + eq(err, pcall_err(call, 'ctxpop')) + end) + end) + + describe('ctxsize()', function() + it('returns context stack size', function() + eq(0, call('ctxsize')) + call('ctxpush') + eq(1, call('ctxsize')) + call('ctxpush') + eq(2, call('ctxsize')) + call('ctxpush') + eq(3, call('ctxsize')) + call('ctxpop') + eq(2, call('ctxsize')) + call('ctxpop') + eq(1, call('ctxsize')) + call('ctxpop') + eq(0, call('ctxsize')) + end) + end) + + describe('ctxget()', function() + it('errors out when index is out of bounds', function() + eq(outofbounds, pcall_err(call, 'ctxget')) + call('ctxpush') + eq(outofbounds, pcall_err(call, 'ctxget', 1)) + call('ctxpop') + eq(outofbounds, pcall_err(call, 'ctxget', 0)) + end) + + it('returns context dictionary at index in context stack', function() + feed('i1<cr>2<cr>3<c-[>ddddddqahjklq') + command('edit! '..fname1) + feed('G') + feed('gg') + command('edit '..fname2) + nvim('set_var', 'one', 1) + nvim('set_var', 'Two', 2) + nvim('set_var', 'THREE', 3) + + local with_regs = { + ['regs'] = { + {['rt'] = 1, ['rc'] = {'1'}, ['n'] = 49, ['ru'] = true}, + {['rt'] = 1, ['rc'] = {'2'}, ['n'] = 50}, + {['rt'] = 1, ['rc'] = {'3'}, ['n'] = 51}, + {['rc'] = {'hjkl'}, ['n'] = 97}, + } + } + + local with_jumps = { + ['jumps'] = eval(([[ + filter(map(getjumplist()[0], 'filter( + { "f": expand("#".v:val.bufnr.":p"), "l": v:val.lnum }, + { k, v -> k != "l" || v != 1 })'), '!empty(v:val.f)') + ]]):gsub('\n', '')) + } + + local with_bufs = { + ['bufs'] = eval([[ + filter(map(getbufinfo(), '{ "f": v:val.name }'), '!empty(v:val.f)') + ]]) + } + + local with_gvars = { + ['gvars'] = {{'one', 1}, {'Two', 2}, {'THREE', 3}} + } + + local with_all = { + ['regs'] = with_regs['regs'], + ['jumps'] = with_jumps['jumps'], + ['bufs'] = with_bufs['bufs'], + ['gvars'] = with_gvars['gvars'], + } + + call('ctxpush') + eq(with_all, parse_context(call('ctxget'))) + eq(with_all, parse_context(call('ctxget', 0))) + + call('ctxpush', {'gvars'}) + eq(with_gvars, parse_context(call('ctxget'))) + eq(with_gvars, parse_context(call('ctxget', 0))) + eq(with_all, parse_context(call('ctxget', 1))) + + call('ctxpush', {'bufs'}) + eq(with_bufs, parse_context(call('ctxget'))) + eq(with_bufs, parse_context(call('ctxget', 0))) + eq(with_gvars, parse_context(call('ctxget', 1))) + eq(with_all, parse_context(call('ctxget', 2))) + + call('ctxpush', {'jumps'}) + eq(with_jumps, parse_context(call('ctxget'))) + eq(with_jumps, parse_context(call('ctxget', 0))) + eq(with_bufs, parse_context(call('ctxget', 1))) + eq(with_gvars, parse_context(call('ctxget', 2))) + eq(with_all, parse_context(call('ctxget', 3))) + + call('ctxpush', {'regs'}) + eq(with_regs, parse_context(call('ctxget'))) + eq(with_regs, parse_context(call('ctxget', 0))) + eq(with_jumps, parse_context(call('ctxget', 1))) + eq(with_bufs, parse_context(call('ctxget', 2))) + eq(with_gvars, parse_context(call('ctxget', 3))) + eq(with_all, parse_context(call('ctxget', 4))) + + call('ctxpop') + eq(with_jumps, parse_context(call('ctxget'))) + eq(with_jumps, parse_context(call('ctxget', 0))) + eq(with_bufs, parse_context(call('ctxget', 1))) + eq(with_gvars, parse_context(call('ctxget', 2))) + eq(with_all, parse_context(call('ctxget', 3))) + + call('ctxpop') + eq(with_bufs, parse_context(call('ctxget'))) + eq(with_bufs, parse_context(call('ctxget', 0))) + eq(with_gvars, parse_context(call('ctxget', 1))) + eq(with_all, parse_context(call('ctxget', 2))) + + call('ctxpop') + eq(with_gvars, parse_context(call('ctxget'))) + eq(with_gvars, parse_context(call('ctxget', 0))) + eq(with_all, parse_context(call('ctxget', 1))) + + call('ctxpop') + eq(with_all, parse_context(call('ctxget'))) + eq(with_all, parse_context(call('ctxget', 0))) + end) + end) + + describe('ctxset()', function() + it('errors out when index is out of bounds', function() + eq(outofbounds, pcall_err(call, 'ctxset', {dummy = 1})) + call('ctxpush') + eq(outofbounds, pcall_err(call, 'ctxset', {dummy = 1}, 1)) + call('ctxpop') + eq(outofbounds, pcall_err(call, 'ctxset', {dummy = 1}, 0)) + end) + + it('sets context dictionary at index in context stack', function() + nvim('set_var', 'one', 1) + nvim('set_var', 'Two', 2) + nvim('set_var', 'THREE', 3) + call('ctxpush') + local ctx1 = call('ctxget') + nvim('set_var', 'one', 'a') + nvim('set_var', 'Two', 'b') + nvim('set_var', 'THREE', 'c') + call('ctxpush') + call('ctxpush') + local ctx2 = call('ctxget') + + eq({'a', 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]')) + call('ctxset', ctx1) + call('ctxset', ctx2, 2) + call('ctxpop') + eq({1, 2 ,3}, eval('[g:one, g:Two, g:THREE]')) + call('ctxpop') + eq({'a', 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]')) + nvim('set_var', 'one', 1.5) + eq({1.5, 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]')) + call('ctxpop') + eq({'a', 'b' ,'c'}, eval('[g:one, g:Two, g:THREE]')) + end) + end) +end) |