diff options
Diffstat (limited to 'test/functional/api')
-rw-r--r-- | test/functional/api/buffer_spec.lua | 96 | ||||
-rw-r--r-- | test/functional/api/buffer_updates_spec.lua | 4 | ||||
-rw-r--r-- | test/functional/api/menu_spec.lua | 8 | ||||
-rw-r--r-- | test/functional/api/server_notifications_spec.lua | 7 | ||||
-rw-r--r-- | test/functional/api/server_requests_spec.lua | 7 | ||||
-rw-r--r-- | test/functional/api/tabpage_spec.lua | 2 | ||||
-rw-r--r-- | test/functional/api/version_spec.lua | 74 | ||||
-rw-r--r-- | test/functional/api/vim_spec.lua | 79 | ||||
-rw-r--r-- | test/functional/api/window_spec.lua | 2 |
9 files changed, 212 insertions, 67 deletions
diff --git a/test/functional/api/buffer_spec.lua b/test/functional/api/buffer_spec.lua index 823c134ebd..d9412f0f13 100644 --- a/test/functional/api/buffer_spec.lua +++ b/test/functional/api/buffer_spec.lua @@ -35,8 +35,37 @@ describe('api/buf', function() -- There's always at least one line eq(1, curbuf_depr('line_count')) end) - end) + it('line_count has defined behaviour for unloaded buffers', function() + -- we'll need to know our bufnr for when it gets unloaded + local bufnr = curbuf('get_number') + -- replace the buffer contents with these three lines + request('nvim_buf_set_lines', bufnr, 0, -1, 1, {"line1", "line2", "line3", "line4"}) + -- check the line count is correct + eq(4, request('nvim_buf_line_count', bufnr)) + -- force unload the buffer (this will discard changes) + command('new') + command('bunload! '..bufnr) + -- line count for an unloaded buffer should always be 0 + eq(0, request('nvim_buf_line_count', bufnr)) + end) + + it('get_lines has defined behaviour for unloaded buffers', function() + -- we'll need to know our bufnr for when it gets unloaded + local bufnr = curbuf('get_number') + -- replace the buffer contents with these three lines + buffer('set_lines', bufnr, 0, -1, 1, {"line1", "line2", "line3", "line4"}) + -- confirm that getting lines works + eq({"line2", "line3"}, buffer('get_lines', bufnr, 1, 3, 1)) + -- force unload the buffer (this will discard changes) + command('new') + command('bunload! '..bufnr) + -- attempting to get lines now always gives empty list + eq({}, buffer('get_lines', bufnr, 1, 3, 1)) + -- it's impossible to get out-of-bounds errors for an unloaded buffer + eq({}, buffer('get_lines', bufnr, 8888, 9999, 1)) + end) + end) describe('{get,set,del}_line', function() it('works', function() @@ -70,7 +99,6 @@ describe('api/buf', function() end) end) - describe('{get,set}_line_slice', function() it('get_line_slice: out-of-bounds returns empty array', function() curbuf_depr('set_line_slice', 0, 0, true, true, {'a', 'b', 'c'}) @@ -273,6 +301,43 @@ describe('api/buf', function() end) end) + describe('get_offset', function() + local get_offset = curbufmeths.get_offset + it('works', function() + curbufmeths.set_lines(0,-1,true,{'Some\r','exa\000mple', '', 'buf\rfer', 'text'}) + eq(5, curbufmeths.line_count()) + eq(0, get_offset(0)) + eq(6, get_offset(1)) + eq(15, get_offset(2)) + eq(16, get_offset(3)) + eq(24, get_offset(4)) + eq(29, get_offset(5)) + eq({false,'Index out of bounds'}, meth_pcall(get_offset, 6)) + eq({false,'Index out of bounds'}, meth_pcall(get_offset, -1)) + + curbufmeths.set_option('eol', false) + curbufmeths.set_option('fixeol', false) + eq(28, get_offset(5)) + + -- fileformat is ignored + curbufmeths.set_option('fileformat', 'dos') + eq(0, get_offset(0)) + eq(6, get_offset(1)) + eq(15, get_offset(2)) + eq(16, get_offset(3)) + eq(24, get_offset(4)) + eq(28, get_offset(5)) + curbufmeths.set_option('eol', true) + eq(29, get_offset(5)) + + command("set hidden") + command("enew") + eq(6, bufmeths.get_offset(1,1)) + command("bunload! 1") + eq(-1, bufmeths.get_offset(1,1)) + end) + end) + describe('{get,set,del}_var', function() it('works', function() curbuf('set_var', 'lua', {1, 2, {['3'] = 1}}) @@ -281,7 +346,7 @@ describe('api/buf', function() eq(1, funcs.exists('b:lua')) curbufmeths.del_var('lua') eq(0, funcs.exists('b:lua')) - eq({false, 'Key does not exist: lua'}, meth_pcall(curbufmeths.del_var, 'lua')) + eq({false, 'Key not found: lua'}, meth_pcall(curbufmeths.del_var, 'lua')) curbufmeths.set_var('lua', 1) command('lockvar b:lua') eq({false, 'Key is locked: lua'}, meth_pcall(curbufmeths.del_var, 'lua')) @@ -345,6 +410,31 @@ describe('api/buf', function() end) end) + describe('is_loaded', function() + it('works', function() + -- record our buffer number for when we unload it + local bufnr = curbuf('get_number') + -- api should report that the buffer is loaded + ok(buffer('is_loaded', bufnr)) + -- hide the current buffer by switching to a new empty buffer + -- Careful! we need to modify the buffer first or vim will just reuse it + buffer('set_lines', bufnr, 0, -1, 1, {'line1'}) + command('hide enew') + -- confirm the buffer is hidden, but still loaded + local infolist = nvim('eval', 'getbufinfo('..bufnr..')') + eq(1, #infolist) + eq(1, infolist[1].hidden) + eq(1, infolist[1].loaded) + -- now force unload the buffer + command('bunload! '..bufnr) + -- confirm the buffer is unloaded + infolist = nvim('eval', 'getbufinfo('..bufnr..')') + eq(0, infolist[1].loaded) + -- nvim_buf_is_loaded() should also report the buffer as unloaded + eq(false, buffer('is_loaded', bufnr)) + end) + end) + describe('is_valid', function() it('works', function() nvim('command', 'new') diff --git a/test/functional/api/buffer_updates_spec.lua b/test/functional/api/buffer_updates_spec.lua index e5cc747f8a..b54d9e1f6e 100644 --- a/test/functional/api/buffer_updates_spec.lua +++ b/test/functional/api/buffer_updates_spec.lua @@ -538,10 +538,6 @@ describe('API: buffer events:', function() end) it('works with :diffput and :diffget', function() - if os.getenv("APPVEYOR") then - pending("Fails on appveyor for some reason.", function() end) - end - local b1, tick1 = editoriginal(true, {"AAA", "BBB"}) local channel = nvim('get_api_info')[1] command('diffthis') diff --git a/test/functional/api/menu_spec.lua b/test/functional/api/menu_spec.lua index d55b7b118a..2cfa0e3e47 100644 --- a/test/functional/api/menu_spec.lua +++ b/test/functional/api/menu_spec.lua @@ -20,15 +20,15 @@ describe("update_menu notification", function() end) local function expect_sent(expected) - screen:wait(function() + screen:expect{condition=function() if screen.update_menu ~= expected then if expected then - return 'update_menu was expected but not sent' + error('update_menu was expected but not sent') else - return 'update_menu was sent unexpectedly' + error('update_menu was sent unexpectedly') end end - end) + end, unchanged=(not expected)} end it("should be sent when adding a menu", function() diff --git a/test/functional/api/server_notifications_spec.lua b/test/functional/api/server_notifications_spec.lua index 1d64ae7103..29cd38ef0d 100644 --- a/test/functional/api/server_notifications_spec.lua +++ b/test/functional/api/server_notifications_spec.lua @@ -65,4 +65,11 @@ describe('notify', function() eq(nest_level, act_nest_level) end) end) + + it('unsubscribe non-existing event #8745', function() + nvim('subscribe', 'event1') + nvim('unsubscribe', 'doesnotexist') + nvim('unsubscribe', 'event1') + eq(2, eval('1+1')) -- Still alive? + end) end) diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua index 856e5ca4d2..4d25ba0819 100644 --- a/test/functional/api/server_requests_spec.lua +++ b/test/functional/api/server_requests_spec.lua @@ -9,7 +9,7 @@ local nvim_prog, command, funcs = helpers.nvim_prog, helpers.command, helpers.fu local source, next_msg = helpers.source, helpers.next_msg local ok = helpers.ok local meths = helpers.meths -local spawn, nvim_argv = helpers.spawn, helpers.nvim_argv +local spawn, merge_args = helpers.spawn, helpers.merge_args local set_session = helpers.set_session local expect_err = helpers.expect_err @@ -23,7 +23,7 @@ describe('server -> client', function() it('handles unexpected closed stream while preparing RPC response', function() source([[ - let g:_nvim_args = [v:progpath, '--embed', '-n', '-u', 'NONE', '-i', 'NONE', ] + let g:_nvim_args = [v:progpath, '--embed', '--headless', '-n', '-u', 'NONE', '-i', 'NONE', ] let ch1 = jobstart(g:_nvim_args, {'rpc': v:true}) let child1_ch = rpcrequest(ch1, "nvim_get_api_info")[0] call rpcnotify(ch1, 'nvim_eval', 'rpcrequest('.child1_ch.', "nvim_get_api_info")') @@ -189,7 +189,7 @@ describe('server -> client', function() end before_each(function() - command("let vim = rpcstart('"..nvim_prog.."', ['-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--embed'])") + command("let vim = rpcstart('"..nvim_prog.."', ['-u', 'NONE', '-i', 'NONE', '--cmd', 'set noswapfile', '--embed', '--headless'])") neq(0, eval('vim')) end) @@ -268,6 +268,7 @@ describe('server -> client', function() end) describe('connecting to another (peer) nvim', function() + local nvim_argv = merge_args(helpers.nvim_argv, {'--headless'}) local function connect_test(server, mode, address) local serverpid = funcs.getpid() local client = spawn(nvim_argv) diff --git a/test/functional/api/tabpage_spec.lua b/test/functional/api/tabpage_spec.lua index 260a91a80c..c49091db02 100644 --- a/test/functional/api/tabpage_spec.lua +++ b/test/functional/api/tabpage_spec.lua @@ -34,7 +34,7 @@ describe('api/tabpage', function() eq(1, funcs.exists('t:lua')) curtabmeths.del_var('lua') eq(0, funcs.exists('t:lua')) - eq({false, 'Key does not exist: lua'}, meth_pcall(curtabmeths.del_var, 'lua')) + eq({false, 'Key not found: lua'}, meth_pcall(curtabmeths.del_var, 'lua')) curtabmeths.set_var('lua', 1) command('lockvar t:lua') eq({false, 'Key is locked: lua'}, meth_pcall(curtabmeths.del_var, 'lua')) diff --git a/test/functional/api/version_spec.lua b/test/functional/api/version_spec.lua index 7bf54c0d1e..b4ae17d963 100644 --- a/test/functional/api/version_spec.lua +++ b/test/functional/api/version_spec.lua @@ -46,12 +46,12 @@ end) describe("api functions", function() before_each(clear) - local function func_table(metadata) - local functions = {} - for _,f in ipairs(metadata.functions) do - functions[f.name] = f + local function name_table(entries) + local by_name = {} + for _,e in ipairs(entries) do + by_name[e.name] = e end - return functions + return by_name end -- Remove metadata that is not essential to backwards-compatibility. @@ -67,6 +67,15 @@ describe("api functions", function() return f end + local function check_ui_event_compatible(old_e, new_e) + -- check types of existing params are the same + -- adding parameters is ok, but removing params is not (gives nil error) + eq(old_e.since, new_e.since, old_e.name) + for i,p in ipairs(old_e.parameters) do + eq(new_e.parameters[i][1], p[1], old_e.name) + end + end + -- Level 0 represents methods from 0.1.5 and earlier, when 'since' was not -- yet defined, and metadata was not filtered of internal keys like 'async'. local function clean_level_0(metadata) @@ -89,8 +98,10 @@ describe("api functions", function() stable = api_level end - local funcs_new = func_table(api) + local funcs_new = name_table(api.functions) + local ui_events_new = name_table(api.ui_events) local funcs_compat = {} + local ui_events_compat = {} for level = compat, stable do local path = ('test/functional/fixtures/api_level_'.. tostring(level)..'.mpack') @@ -119,8 +130,18 @@ describe("api functions", function() filter_function_metadata(funcs_new[f.name])) end end - - funcs_compat[level] = func_table(old_api) + funcs_compat[level] = name_table(old_api.functions) + + -- UI events were formalized in level 3 + if level >= 3 then + for _,e in ipairs(old_api.ui_events) do + local new_e = ui_events_new[e.name] + if new_e ~= nil then + check_ui_event_compatible(e, new_e) + end + end + ui_events_compat[level] = name_table(old_api.ui_events) + end end for _,f in ipairs(api.functions) do @@ -140,9 +161,38 @@ describe("api functions", function() end end elseif f.since > api_level then - error("function "..f.name.." has since value > api_level. ".. - "Please bump NVIM_API_CURRENT and set ".. - "NVIM_API_PRERELEASE to true in CMakeLists.txt.") + if api.version.api_prerelease then + error("New function "..f.name.." should use since value ".. + api_level) + else + error("function "..f.name.." has since value > api_level. ".. + "Bump NVIM_API_CURRENT and set ".. + "NVIM_API_PRERELEASE to true in CMakeLists.txt.") + end + end + end + + for _,e in ipairs(api.ui_events) do + if e.since <= stable then + local e_old = ui_events_compat[e.since][e.name] + if e_old == nil then + local errstr = ("UI event "..e.name.." has too low since value. ".. + "For new events set it to "..(stable+1)..".") + if not api.version.api_prerelease then + errstr = (errstr.." Also bump NVIM_API_CURRENT and set ".. + "NVIM_API_PRERELEASE to true in CMakeLists.txt.") + end + error(errstr) + end + elseif e.since > api_level then + if api.version.api_prerelease then + error("New UI event "..e.name.." should use since value ".. + api_level) + else + error("UI event "..e.name.." has since value > api_level. ".. + "Bump NVIM_API_CURRENT and set ".. + "NVIM_API_PRERELEASE to true in CMakeLists.txt.") + end end end end) @@ -156,6 +206,6 @@ describe("ui_options in metadata", function() local api = helpers.call('api_info') local options = api.ui_options eq({'rgb', 'ext_cmdline', 'ext_popupmenu', - 'ext_tabline', 'ext_wildmenu'}, options) + 'ext_tabline', 'ext_wildmenu', 'ext_linegrid', 'ext_hlstate'}, options) end) end) diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua index e4b343c123..a9d137391e 100644 --- a/test/functional/api/vim_spec.lua +++ b/test/functional/api/vim_spec.lua @@ -24,13 +24,25 @@ describe('API', function() before_each(clear) it('validates requests', function() - expect_err('Invalid method: bogus', + -- RPC + expect_err('Invalid method: bogus$', request, 'bogus') - expect_err('Invalid method: … の り 。…', + expect_err('Invalid method: … の り 。…$', request, '… の り 。…') - expect_err('Invalid method: <empty>', + expect_err('Invalid method: <empty>$', request, '') - expect_err("can't serialize object", + + -- Non-RPC: rpcrequest(v:servername) uses internal channel. + expect_err('Invalid method: … の り 。…$', + request, 'nvim_eval', + [=[rpcrequest(sockconnect('pipe', v:servername, {'rpc':1}), '… の り 。…')]=]) + expect_err('Invalid method: bogus$', + request, 'nvim_eval', + [=[rpcrequest(sockconnect('pipe', v:servername, {'rpc':1}), 'bogus')]=]) + + -- XXX: This must be the last one, else next one will fail: + -- "Packer instance already working. Use another Packer ..." + expect_err("can't serialize object$", request, nil) end) @@ -158,7 +170,7 @@ describe('API', function() end) it("VimL error: returns error details, does NOT update v:errmsg", function() - expect_err('E121: Undefined variable: bogus', request, + expect_err('E121: Undefined variable: bogus$', request, 'nvim_eval', 'bogus expression') eq('', eval('v:errmsg')) -- v:errmsg was not updated. end) @@ -173,7 +185,7 @@ describe('API', function() end) it("VimL validation error: returns specific error, does NOT update v:errmsg", function() - expect_err('E117: Unknown function: bogus function', request, + expect_err('E117: Unknown function: bogus function$', request, 'nvim_call_function', 'bogus function', {'arg1'}) expect_err('E119: Not enough arguments for function: atan', request, 'nvim_call_function', 'atan', {}) @@ -182,11 +194,11 @@ describe('API', function() end) it("VimL error: returns error details, does NOT update v:errmsg", function() - expect_err('E808: Number or Float required', request, + expect_err('E808: Number or Float required$', request, 'nvim_call_function', 'atan', {'foo'}) - expect_err('Invalid channel stream "xxx"', request, + expect_err('Invalid channel stream "xxx"$', request, 'nvim_call_function', 'chanclose', {999, 'xxx'}) - expect_err('E900: Invalid channel id', request, + expect_err('E900: Invalid channel id$', request, 'nvim_call_function', 'chansend', {999, 'foo'}) eq('', eval('v:exception')) eq('', eval('v:errmsg')) -- v:errmsg was not updated. @@ -198,7 +210,7 @@ describe('API', function() throw 'wtf' endfunction ]]) - expect_err('wtf', request, + expect_err('wtf$', request, 'nvim_call_function', 'Foo', {}) eq('', eval('v:exception')) eq('', eval('v:errmsg')) -- v:errmsg was not updated. @@ -212,7 +224,7 @@ describe('API', function() endfunction ]]) -- E740 - expect_err('Function called with too many arguments', request, + expect_err('Function called with too many arguments$', request, 'nvim_call_function', 'Foo', too_many_args) end) end) @@ -248,23 +260,23 @@ describe('API', function() it('validates args', function() command('let g:d={"baz":"zub","meep":[]}') - expect_err('Not found: bogus', request, + expect_err('Not found: bogus$', request, 'nvim_call_dict_function', 'g:d', 'bogus', {1,2}) - expect_err('Not a function: baz', request, + expect_err('Not a function: baz$', request, 'nvim_call_dict_function', 'g:d', 'baz', {1,2}) - expect_err('Not a function: meep', request, + expect_err('Not a function: meep$', request, 'nvim_call_dict_function', 'g:d', 'meep', {1,2}) - expect_err('E117: Unknown function: f', request, + expect_err('E117: Unknown function: f$', request, 'nvim_call_dict_function', { f = '' }, 'f', {1,2}) - expect_err('Not a function: f', request, + expect_err('Not a function: f$', request, 'nvim_call_dict_function', "{ 'f': '' }", 'f', {1,2}) - expect_err('dict argument type must be String or Dictionary', request, + expect_err('dict argument type must be String or Dictionary$', request, 'nvim_call_dict_function', 42, 'f', {1,2}) - expect_err('Failed to evaluate dict expression', request, + expect_err('Failed to evaluate dict expression$', request, 'nvim_call_dict_function', 'foo', 'f', {1,2}) - expect_err('dict not found', request, + expect_err('dict not found$', request, 'nvim_call_dict_function', '42', 'f', {1,2}) - expect_err('Invalid %(empty%) function name', request, + expect_err('Invalid %(empty%) function name$', request, 'nvim_call_dict_function', "{ 'f': '' }", '', {1,2}) end) end) @@ -337,7 +349,7 @@ describe('API', function() eq(1, funcs.exists('g:lua')) meths.del_var('lua') eq(0, funcs.exists('g:lua')) - eq({false, 'Key does not exist: lua'}, meth_pcall(meths.del_var, 'lua')) + eq({false, "Key not found: lua"}, meth_pcall(meths.del_var, 'lua')) meths.set_var('lua', 1) command('lockvar lua') eq({false, 'Key is locked: lua'}, meth_pcall(meths.del_var, 'lua')) @@ -829,10 +841,6 @@ describe('API', function() end) it('works for job channel', function() - if iswin() and os.getenv('APPVEYOR') ~= nil then - pending("jobstart(['cat']) unreliable on appveyor") - return - end eq(3, eval("jobstart(['cat'], {'rpc': v:true})")) local info = { stream='job', @@ -948,7 +956,7 @@ describe('API', function() } local status, err = pcall(meths.call_atomic, req) eq(false, status) - ok(err:match(' All items in calls array must be arrays of size 2') ~= nil) + ok(err:match('Items in calls array must be arrays of size 2') ~= nil) -- call before was done, but not after eq(1, meths.get_var('avar')) @@ -958,7 +966,7 @@ describe('API', function() } status, err = pcall(meths.call_atomic, req) eq(false, status) - ok(err:match('All items in calls array must be arrays') ~= nil) + ok(err:match('Items in calls array must be arrays') ~= nil) eq({2,3}, meths.get_var('bvar')) req = { @@ -1242,6 +1250,8 @@ describe('API', function() ext_popupmenu = false, ext_tabline = false, ext_wildmenu = false, + ext_linegrid = screen._options.ext_linegrid or false, + ext_hlstate=false, height = 4, rgb = true, width = 20, @@ -1252,18 +1262,9 @@ describe('API', function() screen:detach() screen = Screen.new(44, 99) screen:attach({ rgb = false }) - expected = { - { - chan = 1, - ext_cmdline = false, - ext_popupmenu = false, - ext_tabline = false, - ext_wildmenu = false, - height = 99, - rgb = false, - width = 44, - } - } + expected[1].rgb = false + expected[1].width = 44 + expected[1].height = 99 eq(expected, nvim("list_uis")) end) end) diff --git a/test/functional/api/window_spec.lua b/test/functional/api/window_spec.lua index d404ef5426..27d7aa11b4 100644 --- a/test/functional/api/window_spec.lua +++ b/test/functional/api/window_spec.lua @@ -169,7 +169,7 @@ describe('api/win', function() eq(1, funcs.exists('w:lua')) curwinmeths.del_var('lua') eq(0, funcs.exists('w:lua')) - eq({false, 'Key does not exist: lua'}, meth_pcall(curwinmeths.del_var, 'lua')) + eq({false, 'Key not found: lua'}, meth_pcall(curwinmeths.del_var, 'lua')) curwinmeths.set_var('lua', 1) command('lockvar w:lua') eq({false, 'Key is locked: lua'}, meth_pcall(curwinmeths.del_var, 'lua')) |