aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/api/keymap_spec.lua246
-rw-r--r--test/functional/api/server_requests_spec.lua73
-rw-r--r--test/functional/eval/map_functions_spec.lua120
-rw-r--r--test/functional/eval/server_spec.lua47
-rw-r--r--test/functional/helpers.lua5
-rw-r--r--test/functional/options/pastetoggle_spec.lua35
6 files changed, 502 insertions, 24 deletions
diff --git a/test/functional/api/keymap_spec.lua b/test/functional/api/keymap_spec.lua
new file mode 100644
index 0000000000..833e0d2f3c
--- /dev/null
+++ b/test/functional/api/keymap_spec.lua
@@ -0,0 +1,246 @@
+
+local helpers = require('test.functional.helpers')(after_each)
+local clear = helpers.clear
+local command = helpers.command
+local curbufmeths = helpers.curbufmeths
+local eq = helpers.eq
+local funcs = helpers.funcs
+local meths = helpers.meths
+local source = helpers.source
+
+local function local_copy(t)
+ local copy = {}
+ for k,v in pairs(t) do
+ copy[k] = v
+ end
+ return copy
+end
+
+describe('get_keymap', function()
+ before_each(clear)
+
+ -- Basic mapping and table to be used to describe results
+ local foo_bar_string = 'nnoremap foo bar'
+ local foo_bar_map_table = {
+ lhs='foo',
+ silent=0,
+ rhs='bar',
+ expr=0,
+ sid=0,
+ buffer=0,
+ nowait=0,
+ mode='n',
+ noremap=1,
+ }
+
+ it('returns empty list when no map', function()
+ eq({}, meths.get_keymap('n'))
+ end)
+
+ it('returns list of all applicable mappings', function()
+ command(foo_bar_string)
+ -- Only one mapping available
+ -- Should be the same as the dictionary we supplied earlier
+ -- and the dictionary you would get from maparg
+ -- since this is a global map, and not script local
+ eq({foo_bar_map_table}, meths.get_keymap('n'))
+ eq({funcs.maparg('foo', 'n', false, true)},
+ meths.get_keymap('n')
+ )
+
+ -- Add another mapping
+ command('nnoremap foo_longer bar_longer')
+ local foolong_bar_map_table = local_copy(foo_bar_map_table)
+ foolong_bar_map_table['lhs'] = 'foo_longer'
+ foolong_bar_map_table['rhs'] = 'bar_longer'
+
+ eq({foolong_bar_map_table, foo_bar_map_table},
+ meths.get_keymap('n')
+ )
+
+ -- Remove a mapping
+ command('unmap foo_longer')
+ eq({foo_bar_map_table},
+ meths.get_keymap('n')
+ )
+ end)
+
+ it('works for other modes', function()
+ -- Add two mappings, one in insert and one normal
+ -- We'll only check the insert mode one
+ command('nnoremap not_going to_check')
+
+ command('inoremap foo bar')
+ -- The table will be the same except for the mode
+ local insert_table = local_copy(foo_bar_map_table)
+ insert_table['mode'] = 'i'
+
+ eq({insert_table}, meths.get_keymap('i'))
+ end)
+
+ it('considers scope', function()
+ -- change the map slightly
+ command('nnoremap foo_longer bar_longer')
+ local foolong_bar_map_table = local_copy(foo_bar_map_table)
+ foolong_bar_map_table['lhs'] = 'foo_longer'
+ foolong_bar_map_table['rhs'] = 'bar_longer'
+
+ local buffer_table = local_copy(foo_bar_map_table)
+ buffer_table['buffer'] = 1
+
+ command('nnoremap <buffer> foo bar')
+
+ -- The buffer mapping should not show up
+ eq({foolong_bar_map_table}, meths.get_keymap('n'))
+ eq({buffer_table}, curbufmeths.get_keymap('n'))
+ end)
+
+ it('considers scope for overlapping maps', function()
+ command('nnoremap foo bar')
+
+ local buffer_table = local_copy(foo_bar_map_table)
+ buffer_table['buffer'] = 1
+
+ command('nnoremap <buffer> foo bar')
+
+ eq({foo_bar_map_table}, meths.get_keymap('n'))
+ eq({buffer_table}, curbufmeths.get_keymap('n'))
+ end)
+
+ it('can retrieve mapping for different buffers', function()
+ local original_buffer = curbufmeths.get_number()
+ -- Place something in each of the buffers to make sure they stick around
+ -- and set hidden so we can leave them
+ command('set hidden')
+ command('new')
+ command('normal! ihello 2')
+ command('new')
+ command('normal! ihello 3')
+
+ local final_buffer = curbufmeths.get_number()
+
+ command('nnoremap <buffer> foo bar')
+ -- Final buffer will have buffer mappings
+ local buffer_table = local_copy(foo_bar_map_table)
+ buffer_table['buffer'] = final_buffer
+ eq({buffer_table}, meths.buf_get_keymap(final_buffer, 'n'))
+ eq({buffer_table}, meths.buf_get_keymap(0, 'n'))
+
+ command('buffer ' .. original_buffer)
+ eq(original_buffer, curbufmeths.get_number())
+ -- Original buffer won't have any mappings
+ eq({}, meths.get_keymap('n'))
+ eq({}, curbufmeths.get_keymap('n'))
+ eq({buffer_table}, meths.buf_get_keymap(final_buffer, 'n'))
+ end)
+
+ -- Test toggle switches for basic options
+ -- @param option The key represented in the `maparg()` result dict
+ local function global_and_buffer_test(map,
+ option,
+ option_token,
+ global_on_result,
+ buffer_on_result,
+ global_off_result,
+ buffer_off_result,
+ new_windows)
+
+ local function make_new_windows(number_of_windows)
+ if new_windows == nil then
+ return nil
+ end
+
+ for _=1,number_of_windows do
+ command('new')
+ end
+ end
+
+ local mode = string.sub(map, 1,1)
+ -- Don't run this for the <buffer> mapping, since it doesn't make sense
+ if option_token ~= '<buffer>' then
+ it(string.format( 'returns %d for the key "%s" when %s is used globally with %s (%s)',
+ global_on_result, option, option_token, map, mode), function()
+ make_new_windows(new_windows)
+ command(map .. ' ' .. option_token .. ' foo bar')
+ local result = meths.get_keymap(mode)[1][option]
+ eq(global_on_result, result)
+ end)
+ end
+
+ it(string.format('returns %d for the key "%s" when %s is used for buffers with %s (%s)',
+ buffer_on_result, option, option_token, map, mode), function()
+ make_new_windows(new_windows)
+ command(map .. ' <buffer> ' .. option_token .. ' foo bar')
+ local result = curbufmeths.get_keymap(mode)[1][option]
+ eq(buffer_on_result, result)
+ end)
+
+ -- Don't run these for the <buffer> mapping, since it doesn't make sense
+ if option_token ~= '<buffer>' then
+ it(string.format('returns %d for the key "%s" when %s is not used globally with %s (%s)',
+ global_off_result, option, option_token, map, mode), function()
+ make_new_windows(new_windows)
+ command(map .. ' baz bat')
+ local result = meths.get_keymap(mode)[1][option]
+ eq(global_off_result, result)
+ end)
+
+ it(string.format('returns %d for the key "%s" when %s is not used for buffers with %s (%s)',
+ buffer_off_result, option, option_token, map, mode), function()
+ make_new_windows(new_windows)
+ command(map .. ' <buffer> foo bar')
+
+ local result = curbufmeths.get_keymap(mode)[1][option]
+ eq(buffer_off_result, result)
+ end)
+ end
+ end
+
+ -- Standard modes and returns the same values in the dictionary as maparg()
+ local mode_list = {'nnoremap', 'nmap', 'imap', 'inoremap', 'cnoremap'}
+ for mode in pairs(mode_list) do
+ global_and_buffer_test(mode_list[mode], 'silent', '<silent>', 1, 1, 0, 0)
+ global_and_buffer_test(mode_list[mode], 'nowait', '<nowait>', 1, 1, 0, 0)
+ global_and_buffer_test(mode_list[mode], 'expr', '<expr>', 1, 1, 0, 0)
+ end
+
+ -- noremap will now be 2 if script was used, which is not the same as maparg()
+ global_and_buffer_test('nmap', 'noremap', '<script>', 2, 2, 0, 0)
+ global_and_buffer_test('nnoremap', 'noremap', '<script>', 2, 2, 1, 1)
+
+ -- buffer will return the buffer ID, which is not the same as maparg()
+ -- Three of these tests won't run
+ global_and_buffer_test('nnoremap', 'buffer', '<buffer>', nil, 3, nil, nil, 2)
+
+ it('returns script numbers for global maps', function()
+ source([[
+ function! s:maparg_test_function() abort
+ return 'testing'
+ endfunction
+
+ nnoremap fizz :call <SID>maparg_test_function()<CR>
+ ]])
+ local sid_result = meths.get_keymap('n')[1]['sid']
+ eq(1, sid_result)
+ eq('testing', meths.call_function('<SNR>' .. sid_result .. '_maparg_test_function', {}))
+ end)
+
+ it('returns script numbers for buffer maps', function()
+ source([[
+ function! s:maparg_test_function() abort
+ return 'testing'
+ endfunction
+
+ nnoremap <buffer> fizz :call <SID>maparg_test_function()<CR>
+ ]])
+ local sid_result = curbufmeths.get_keymap('n')[1]['sid']
+ eq(1, sid_result)
+ eq('testing', meths.call_function('<SNR>' .. sid_result .. '_maparg_test_function', {}))
+ end)
+
+ it('works with <F12> and others', function()
+ command('nnoremap <F12> :let g:maparg_test_var = 1<CR>')
+ eq('<F12>', meths.get_keymap('n')[1]['lhs'])
+ eq(':let g:maparg_test_var = 1<CR>', meths.get_keymap('n')[1]['rhs'])
+ end)
+end)
diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua
index 658077b112..cf15062325 100644
--- a/test/functional/api/server_requests_spec.lua
+++ b/test/functional/api/server_requests_spec.lua
@@ -9,6 +9,8 @@ local nvim_prog, command, funcs = helpers.nvim_prog, helpers.command, helpers.fu
local source, next_message = helpers.source, helpers.next_message
local ok = helpers.ok
local meths = helpers.meths
+local spawn, nvim_argv = helpers.spawn, helpers.nvim_argv
+local set_session = helpers.set_session
describe('server -> client', function()
local cid
@@ -225,4 +227,75 @@ describe('server -> client', function()
end)
end)
+ describe('when connecting to another nvim instance', function()
+ local function connect_test(server, mode, address)
+ local serverpid = funcs.getpid()
+ local client = spawn(nvim_argv)
+ set_session(client, true)
+ local clientpid = funcs.getpid()
+ neq(serverpid, clientpid)
+ local id = funcs.sockconnect(mode, address, {rpc=true})
+ ok(id > 0)
+
+ funcs.rpcrequest(id, 'nvim_set_current_line', 'hello')
+ local client_id = funcs.rpcrequest(id, 'nvim_get_api_info')[1]
+
+ set_session(server, true)
+ eq(serverpid, funcs.getpid())
+ eq('hello', meths.get_current_line())
+
+ -- method calls work both ways
+ funcs.rpcrequest(client_id, 'nvim_set_current_line', 'howdy!')
+ eq(id, funcs.rpcrequest(client_id, 'nvim_get_api_info')[1])
+
+ set_session(client, true)
+ eq(clientpid, funcs.getpid())
+ eq('howdy!', meths.get_current_line())
+
+ server:close()
+ client:close()
+ end
+
+ it('over a named pipe', function()
+ local server = spawn(nvim_argv)
+ set_session(server)
+ local address = funcs.serverlist()[1]
+ local first = string.sub(address,1,1)
+ ok(first == '/' or first == '\\')
+ connect_test(server, 'pipe', address)
+ end)
+
+ it('to an ip adress', function()
+ local server = spawn(nvim_argv)
+ set_session(server)
+ local address = funcs.serverstart("127.0.0.1:")
+ eq('127.0.0.1:', string.sub(address,1,10))
+ connect_test(server, 'tcp', address)
+ end)
+
+ it('to a hostname', function()
+ local server = spawn(nvim_argv)
+ set_session(server)
+ local address = funcs.serverstart("localhost:")
+ eq('localhost:', string.sub(address,1,10))
+ connect_test(server, 'tcp', address)
+ end)
+ end)
+
+ describe('when connecting to its own pipe adress', function()
+ it('it does not deadlock', function()
+ local address = funcs.serverlist()[1]
+ local first = string.sub(address,1,1)
+ ok(first == '/' or first == '\\')
+ local serverpid = funcs.getpid()
+
+ local id = funcs.sockconnect('pipe', address, {rpc=true})
+
+ funcs.rpcrequest(id, 'nvim_set_current_line', 'hello')
+ eq('hello', meths.get_current_line())
+ eq(serverpid, funcs.rpcrequest(id, "nvim_eval", "getpid()"))
+
+ eq(id, funcs.rpcrequest(id, 'nvim_get_api_info')[1])
+ end)
+ end)
end)
diff --git a/test/functional/eval/map_functions_spec.lua b/test/functional/eval/map_functions_spec.lua
new file mode 100644
index 0000000000..a260522aa3
--- /dev/null
+++ b/test/functional/eval/map_functions_spec.lua
@@ -0,0 +1,120 @@
+
+local helpers = require('test.functional.helpers')(after_each)
+local clear = helpers.clear
+local eq = helpers.eq
+local eval = helpers.eval
+local funcs = helpers.funcs
+local nvim = helpers.nvim
+local source = helpers.source
+
+describe('maparg()', function()
+ before_each(clear)
+
+ local foo_bar_map_table = {
+ lhs='foo',
+ silent=0,
+ rhs='bar',
+ expr=0,
+ sid=0,
+ buffer=0,
+ nowait=0,
+ mode='n',
+ noremap=1,
+ }
+
+ it('returns a dictionary', function()
+ nvim('command', 'nnoremap foo bar')
+ eq('bar', funcs.maparg('foo'))
+ eq(foo_bar_map_table, funcs.maparg('foo', 'n', false, true))
+ end)
+
+ it('returns 1 for silent when <silent> is used', function()
+ nvim('command', 'nnoremap <silent> foo bar')
+ eq(1, funcs.maparg('foo', 'n', false, true)['silent'])
+
+ nvim('command', 'nnoremap baz bat')
+ eq(0, funcs.maparg('baz', 'n', false, true)['silent'])
+ end)
+
+ it('returns an empty string when no map is present', function()
+ eq('', funcs.maparg('not a mapping'))
+ end)
+
+ it('returns an empty dictionary when no map is present and dict is requested', function()
+ eq({}, funcs.maparg('not a mapping', 'n', false, true))
+ end)
+
+ it('returns the same value for noremap and <script>', function()
+ nvim('command', 'inoremap <script> hello world')
+ nvim('command', 'inoremap this that')
+ eq(
+ funcs.maparg('hello', 'i', false, true)['noremap'],
+ funcs.maparg('this', 'i', false, true)['noremap']
+ )
+ end)
+
+ it('returns a boolean for buffer', function()
+ -- Open enough windows to know we aren't on buffer number 1
+ nvim('command', 'new')
+ nvim('command', 'new')
+ nvim('command', 'new')
+ nvim('command', 'cnoremap <buffer> this that')
+ eq(1, funcs.maparg('this', 'c', false, true)['buffer'])
+
+ -- Global will return 0 always
+ nvim('command', 'nnoremap other another')
+ eq(0, funcs.maparg('other', 'n', false, true)['buffer'])
+ end)
+
+ it('returns script numbers', function()
+ source([[
+ function! s:maparg_test_function() abort
+ return 'testing'
+ endfunction
+
+ nnoremap fizz :call <SID>maparg_test_function()<CR>
+ ]])
+ eq(1, funcs.maparg('fizz', 'n', false, true)['sid'])
+ eq('testing', nvim('call_function', '<SNR>1_maparg_test_function', {}))
+ end)
+
+ it('works with <F12> and others', function()
+ source([[
+ let g:maparg_test_var = 0
+
+ nnoremap <F12> :let g:maparg_test_var = 1<CR>
+ ]])
+ eq(0, eval('g:maparg_test_var'))
+ source([[
+ call feedkeys("\<F12>")
+ ]])
+ eq(1, eval('g:maparg_test_var'))
+
+ eq(':let g:maparg_test_var = 1<CR>', funcs.maparg('<F12>', 'n', false, true)['rhs'])
+ end)
+
+ it('works with <expr>', function()
+ source([[
+ let counter = 0
+ inoremap <expr> <C-L> ListItem()
+ inoremap <expr> <C-R> ListReset()
+
+ func ListItem()
+ let g:counter += 1
+ return g:counter . '. '
+ endfunc
+
+ func ListReset()
+ let g:counter = 0
+ return ''
+ endfunc
+
+ call feedkeys("i\<C-L>")
+ ]])
+ eq(1, eval('g:counter'))
+
+ local map_dict = funcs.maparg('<C-L>', 'i', false, true)
+ eq(1, map_dict['expr'])
+ eq('i', map_dict['mode'])
+ end)
+end)
diff --git a/test/functional/eval/server_spec.lua b/test/functional/eval/server_spec.lua
index 420aea04aa..115114c3c3 100644
--- a/test/functional/eval/server_spec.lua
+++ b/test/functional/eval/server_spec.lua
@@ -1,20 +1,27 @@
local helpers = require('test.functional.helpers')(after_each)
-local nvim, eq, neq, eval = helpers.nvim, helpers.eq, helpers.neq, helpers.eval
+local eq, neq, eval = helpers.eq, helpers.neq, helpers.eval
+local command = helpers.command
local clear, funcs, meths = helpers.clear, helpers.funcs, helpers.meths
local os_name = helpers.os_name
+local function clear_serverlist()
+ for _, server in pairs(funcs.serverlist()) do
+ funcs.serverstop(server)
+ end
+end
+
describe('serverstart(), serverstop()', function()
before_each(clear)
it('sets $NVIM_LISTEN_ADDRESS on first invocation', function()
-- Unset $NVIM_LISTEN_ADDRESS
- nvim('command', 'let $NVIM_LISTEN_ADDRESS = ""')
+ command('let $NVIM_LISTEN_ADDRESS = ""')
local s = eval('serverstart()')
assert(s ~= nil and s:len() > 0, "serverstart() returned empty")
eq(s, eval('$NVIM_LISTEN_ADDRESS'))
- nvim('command', "call serverstop('"..s.."')")
+ command("call serverstop('"..s.."')")
eq('', eval('$NVIM_LISTEN_ADDRESS'))
end)
@@ -47,10 +54,38 @@ describe('serverstart(), serverstop()', function()
end)
it('serverstop() ignores invalid input', function()
- nvim('command', "call serverstop('')")
- nvim('command', "call serverstop('bogus-socket-name')")
+ command("call serverstop('')")
+ command("call serverstop('bogus-socket-name')")
end)
+ it('parses endpoints correctly', function()
+ clear_serverlist()
+ eq({}, funcs.serverlist())
+
+ local s = funcs.serverstart('127.0.0.1:0') -- assign random port
+ assert(string.match(s, '127.0.0.1:%d+'))
+ eq(s, funcs.serverlist()[1])
+ clear_serverlist()
+
+ s = funcs.serverstart('127.0.0.1:') -- assign random port
+ assert(string.match(s, '127.0.0.1:%d+'))
+ eq(s, funcs.serverlist()[1])
+ clear_serverlist()
+
+ funcs.serverstart('127.0.0.1:12345')
+ funcs.serverstart('127.0.0.1:12345') -- exists already; ignore
+ funcs.serverstart('::1:12345')
+ funcs.serverstart('::1:12345') -- exists already; ignore
+ local expected = {
+ '127.0.0.1:12345',
+ '::1:12345',
+ }
+ eq(expected, funcs.serverlist())
+ clear_serverlist()
+
+ funcs.serverstart('127.0.0.1:65536') -- invalid port
+ eq({}, funcs.serverlist())
+ end)
end)
describe('serverlist()', function()
@@ -75,7 +110,7 @@ describe('serverlist()', function()
-- The new servers should be at the end of the list.
for i = 1, #servs do
eq(servs[i], new_servs[i + n])
- nvim('command', "call serverstop('"..servs[i].."')")
+ command("call serverstop('"..servs[i].."')")
end
-- After serverstop() the servers should NOT be in the list.
eq(n, eval('len(serverlist())'))
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index b03840b3fe..62b0ce1200 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -76,8 +76,8 @@ end
local session, loop_running, last_error
-local function set_session(s)
- if session then
+local function set_session(s, keep)
+ if session and not keep then
session:close()
end
session = s
@@ -609,6 +609,7 @@ local module = {
nvim = nvim,
nvim_async = nvim_async,
nvim_prog = nvim_prog,
+ nvim_argv = nvim_argv,
nvim_set = nvim_set,
nvim_dir = nvim_dir,
buffer = buffer,
diff --git a/test/functional/options/pastetoggle_spec.lua b/test/functional/options/pastetoggle_spec.lua
index ec3c60fe37..a1f86f73ff 100644
--- a/test/functional/options/pastetoggle_spec.lua
+++ b/test/functional/options/pastetoggle_spec.lua
@@ -6,32 +6,35 @@ local command = helpers.command
local eq = helpers.eq
local eval = helpers.eval
local sleep = helpers.sleep
+local expect = helpers.expect
describe("'pastetoggle' option", function()
before_each(function()
clear()
command('set nopaste')
- command('set pastetoggle=a')
end)
+
it("toggles 'paste'", function()
- eq(eval('&paste'), 0)
+ command('set pastetoggle=a')
+ eq(0, eval('&paste'))
feed('a')
-- Need another key so that the vgetorpeek() function returns.
feed('j')
- eq(eval('&paste'), 1)
+ eq(1, eval('&paste'))
end)
- it("multiple key 'pastetoggle' is waited for", function()
- eq(eval('&paste'), 0)
- local pastetoggle = 'lllll'
- command('set pastetoggle=' .. pastetoggle)
- command('set timeoutlen=1 ttimeoutlen=10000')
- feed(pastetoggle:sub(0, 2))
- -- sleep() for long enough that vgetorpeek() is gotten into, but short
- -- enough that ttimeoutlen is not reached.
- sleep(200)
- feed(pastetoggle:sub(3, -1))
- -- Need another key so that the vgetorpeek() function returns.
- feed('j')
- eq(eval('&paste'), 1)
+
+
+ it('does not wait for timeout', function()
+ command('set pastetoggle=abc')
+ command('set ttimeoutlen=9999999')
+ eq(0, eval('&paste'))
+ -- n.b. need <esc> to return from vgetorpeek()
+ feed('abc<esc>')
+ eq(1, eval('&paste'))
+ feed('ab')
+ sleep(10)
+ feed('c<esc>')
+ expect('bc')
+ eq(1, eval('&paste'))
end)
end)