local t = require('test.testutil') local n = require('test.functional.testnvim')() local eval, command = n.eval, n.command local eq, run, stop = t.eq, n.run, n.stop local clear = n.clear local api = n.api local function get_prefix(sync) if sync then return 'sync' end return 'async' end local function call(fn, arguments) command('call ' .. fn .. '(' .. arguments .. ')') end local function clear_and_init(init) return function() clear() if init then init() end end end local function runx(sync, handler, on_setup) local function setup_cb(...) on_setup(...) -- need to stop on setup callback because there's two session:request -- calls in `request/testnvim.lua`. The second call will always return -- after pending notification/request callbacks are processed stop() end local function handler_cb(...) return handler(...) end if sync then run(handler_cb, nil, setup_cb) else run(nil, handler_cb, setup_cb) end end local function command_specs_for(fn, sync, first_arg_factory, init) local prefix = get_prefix(sync) describe(prefix .. ' command created by', function() before_each(clear_and_init(init)) describe(fn, function() local args before_each(function() args = first_arg_factory() .. ', "test-handler", ' if sync then args = args .. '1' else args = args .. '0' end args = args .. ', "RpcCommand"' end) it('without options', function() call(fn, args .. ', {}') local function on_setup() command('RpcCommand') end local function handler(method) eq('test-handler', method) return '' end runx(sync, handler, on_setup) end) it('with nargs', function() call(fn, args .. ', {"nargs": "*"}') local function on_setup() command('RpcCommand arg1 arg2 arg3') end local function handler(method, arguments) eq('test-handler', method) eq({ 'arg1', 'arg2', 'arg3' }, arguments[1]) return '' end runx(sync, handler, on_setup) end) it('with nargs/double-quote', function() call(fn, args .. ', {"nargs": "*"}') local function on_setup() command('RpcCommand "arg1" "arg2" "arg3"') end local function handler(method, arguments) eq('test-handler', method) eq({ '"arg1"', '"arg2"', '"arg3"' }, arguments[1]) return '' end runx(sync, handler, on_setup) end) it('with range', function() call(fn, args .. ', {"range": ""}') local function on_setup() command('1,1RpcCommand') end local function handler(method, arguments) eq('test-handler', method) eq({ 1, 1 }, arguments[1]) return '' end runx(sync, handler, on_setup) end) it('with nargs/range', function() call(fn, args .. ', {"nargs": "1", "range": ""}') local function on_setup() command('1,1RpcCommand arg') end local function handler(method, arguments) eq('test-handler', method) eq({ 'arg' }, arguments[1]) eq({ 1, 1 }, arguments[2]) return '' end runx(sync, handler, on_setup) end) it('with nargs/count', function() call(fn, args .. ', {"nargs": "1", "count": "5"}') local function on_setup() command('5RpcCommand arg') end local function handler(method, arguments) eq('test-handler', method) eq({ 'arg' }, arguments[1]) eq(5, arguments[2]) return '' end runx(sync, handler, on_setup) end) it('with nargs/count/bang', function() call(fn, args .. ', {"nargs": "1", "count": "5", "bang": ""}') local function on_setup() command('5RpcCommand! arg') end local function handler(method, arguments) eq('test-handler', method) eq({ 'arg' }, arguments[1]) eq(5, arguments[2]) eq(1, arguments[3]) return '' end runx(sync, handler, on_setup) end) it('with nargs/count/bang/register', function() call(fn, args .. ', {"nargs": "1", "count": "5", "bang": "",' .. ' "register": ""}') local function on_setup() command('5RpcCommand! b arg') end local function handler(method, arguments) eq('test-handler', method) eq({ 'arg' }, arguments[1]) eq(5, arguments[2]) eq(1, arguments[3]) eq('b', arguments[4]) return '' end runx(sync, handler, on_setup) end) it('with nargs/count/bang/register/eval', function() call( fn, args .. ', {"nargs": "1", "count": "5", "bang": "",' .. ' "register": "", "eval": "@"}' ) local function on_setup() command('let @b = "regb"') command('5RpcCommand! b arg') end local function handler(method, arguments) eq('test-handler', method) eq({ 'arg' }, arguments[1]) eq(5, arguments[2]) eq(1, arguments[3]) eq('b', arguments[4]) eq('regb', arguments[5]) return '' end runx(sync, handler, on_setup) end) end) end) end local function autocmd_specs_for(fn, sync, first_arg_factory, init) local prefix = get_prefix(sync) describe(prefix .. ' autocmd created by', function() before_each(clear_and_init(init)) describe(fn, function() local args before_each(function() args = first_arg_factory() .. ', "test-handler", ' if sync then args = args .. '1' else args = args .. '0' end args = args .. ', "BufEnter"' end) it('without options', function() call(fn, args .. ', {}') local function on_setup() command('doautocmd BufEnter x.c') end local function handler(method) eq('test-handler', method) return '' end runx(sync, handler, on_setup) end) it('with eval', function() call(fn, args .. [[, {'eval': 'expand("")'}]]) local function on_setup() command('doautocmd BufEnter x.c') end local function handler(method, arguments) eq('test-handler', method) eq('x.c', arguments[1]) return '' end runx(sync, handler, on_setup) end) end) end) end local function function_specs_for(fn, sync, first_arg_factory, init) local prefix = get_prefix(sync) describe(prefix .. ' function created by', function() before_each(clear_and_init(init)) describe(fn, function() local args before_each(function() args = first_arg_factory() .. ', "test-handler", ' if sync then args = args .. '1' else args = args .. '0' end args = args .. ', "TestFunction"' end) it('without options', function() call(fn, args .. ', {}') local function on_setup() if sync then eq('rv', eval('TestFunction(1, "a", ["b", "c"])')) else eq(1, eval('TestFunction(1, "a", ["b", "c"])')) end end local function handler(method, arguments) eq('test-handler', method) eq({ { 1, 'a', { 'b', 'c' } } }, arguments) return 'rv' end runx(sync, handler, on_setup) end) it('with eval', function() call(fn, args .. [[, {'eval': '2 + 2'}]]) local function on_setup() if sync then eq('rv', eval('TestFunction(1, "a", ["b", "c"])')) else eq(1, eval('TestFunction(1, "a", ["b", "c"])')) end end local function handler(method, arguments) eq('test-handler', method) eq({ { 1, 'a', { 'b', 'c' } }, 4 }, arguments) return 'rv' end runx(sync, handler, on_setup) end) it('with range', function() n.insert([[ foo bar baz zub]]) call(fn, args .. [[, {'range': ''}]]) local function on_setup() command('2,3call TestFunction(1, "a", ["b", "c"])') end local function handler(method, arguments) eq('test-handler', method) eq({ { 1, 'a', { 'b', 'c' } }, { 2, 3 } }, arguments) return 'rv' end runx(sync, handler, on_setup) end) it('with eval/range', function() call(fn, args .. [[, {'eval': '4', 'range': ''}]]) local function on_setup() command('%call TestFunction(1, "a", ["b", "c"])') end local function handler(method, arguments) eq('test-handler', method) eq({ { 1, 'a', { 'b', 'c' } }, { 1, 1 }, 4 }, arguments) return 'rv' end runx(sync, handler, on_setup) end) end) end) end local function channel() return api.nvim_get_chan_info(0).id end local function host() return '"busted"' end local function register() eval('remote#host#Register("busted", "busted", ' .. channel() .. ')') end command_specs_for('remote#define#CommandOnChannel', true, channel) command_specs_for('remote#define#CommandOnChannel', false, channel) command_specs_for('remote#define#CommandOnHost', true, host, register) command_specs_for('remote#define#CommandOnHost', false, host, register) autocmd_specs_for('remote#define#AutocmdOnChannel', true, channel) autocmd_specs_for('remote#define#AutocmdOnChannel', false, channel) autocmd_specs_for('remote#define#AutocmdOnHost', true, host, register) autocmd_specs_for('remote#define#AutocmdOnHost', false, host, register) function_specs_for('remote#define#FunctionOnChannel', true, channel) function_specs_for('remote#define#FunctionOnChannel', false, channel) function_specs_for('remote#define#FunctionOnHost', true, host, register) function_specs_for('remote#define#FunctionOnHost', false, host, register)