aboutsummaryrefslogtreecommitdiff
path: root/test/functional/provider
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional/provider')
-rw-r--r--test/functional/provider/define_spec.lua365
-rw-r--r--test/functional/provider/python3_spec.lua77
-rw-r--r--test/functional/provider/python_spec.lua77
3 files changed, 519 insertions, 0 deletions
diff --git a/test/functional/provider/define_spec.lua b/test/functional/provider/define_spec.lua
new file mode 100644
index 0000000000..9b97ed84d9
--- /dev/null
+++ b/test/functional/provider/define_spec.lua
@@ -0,0 +1,365 @@
+local helpers = require('test.functional.helpers')
+local eval, command, nvim = helpers.eval, helpers.command, helpers.nvim
+local eq, run, stop = helpers.eq, helpers.run, helpers.stop
+local clear, feed = helpers.clear, helpers.feed
+
+
+local function get_prefix(sync)
+ if sync then
+ return 'sync'
+ end
+ return 'async'
+end
+
+
+local function call(fn, args)
+ command('call '..fn..'('..args..')')
+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/helpers.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)
+
+ describe('without options', function()
+ it('ok', 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)
+ end)
+
+ describe('with nargs', function()
+ it('ok', function()
+ call(fn, args..', {"nargs": "*"}')
+ local function on_setup()
+ command('RpcCommand arg1 arg2 arg3')
+ end
+
+ local function handler(method, args)
+ eq('test-handler', method)
+ eq({'arg1', 'arg2', 'arg3'}, args[1])
+ return ''
+ end
+
+ runx(sync, handler, on_setup)
+ end)
+ end)
+
+ describe('with range', function()
+ it('ok', function()
+ call(fn,args..', {"range": ""}')
+ local function on_setup()
+ command('1,1RpcCommand')
+ end
+
+ local function handler(method, args)
+ eq('test-handler', method)
+ eq({1, 1}, args[1])
+ return ''
+ end
+
+ runx(sync, handler, on_setup)
+ end)
+ end)
+
+ describe('with nargs/range', function()
+ it('ok', function()
+ call(fn, args..', {"nargs": "1", "range": ""}')
+ local function on_setup()
+ command('1,1RpcCommand arg')
+ end
+
+ local function handler(method, args)
+ eq('test-handler', method)
+ eq({'arg'}, args[1])
+ eq({1, 1}, args[2])
+ return ''
+ end
+
+ runx(sync, handler, on_setup)
+ end)
+ end)
+
+ describe('with nargs/count', function()
+ it('ok', function()
+ call(fn, args..', {"nargs": "1", "range": "5"}')
+ local function on_setup()
+ command('5RpcCommand arg')
+ end
+
+ local function handler(method, args)
+ eq('test-handler', method)
+ eq({'arg'}, args[1])
+ eq(5, args[2])
+ return ''
+ end
+
+ runx(sync, handler, on_setup)
+ end)
+ end)
+
+ describe('with nargs/count/bang', function()
+ it('ok', function()
+ call(fn, args..', {"nargs": "1", "range": "5", "bang": ""}')
+ local function on_setup()
+ command('5RpcCommand! arg')
+ end
+
+ local function handler(method, args)
+ eq('test-handler', method)
+ eq({'arg'}, args[1])
+ eq(5, args[2])
+ eq(1, args[3])
+ return ''
+ end
+
+ runx(sync, handler, on_setup)
+ end)
+ end)
+
+ describe('with nargs/count/bang/register', function()
+ it('ok', function()
+ call(fn, args..', {"nargs": "1", "range": "5", "bang": "",'..
+ ' "register": ""}')
+ local function on_setup()
+ command('5RpcCommand! b arg')
+ end
+
+ local function handler(method, args)
+ eq('test-handler', method)
+ eq({'arg'}, args[1])
+ eq(5, args[2])
+ eq(1, args[3])
+ eq('b', args[4])
+ return ''
+ end
+
+ runx(sync, handler, on_setup)
+ end)
+ end)
+
+ describe('with nargs/count/bang/register/eval', function()
+ it('ok', function()
+ call(fn, args..', {"nargs": "1", "range": "5", "bang": "",'..
+ ' "register": "", "eval": "@<reg>"}')
+ local function on_setup()
+ command('let @b = "regb"')
+ command('5RpcCommand! b arg')
+ end
+
+ local function handler(method, args)
+ eq('test-handler', method)
+ eq({'arg'}, args[1])
+ eq(5, args[2])
+ eq(1, args[3])
+ eq('b', args[4])
+ eq('regb', args[5])
+ return ''
+ end
+
+ runx(sync, handler, on_setup)
+ end)
+ 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)
+
+ describe('without options', function()
+ it('ok', function()
+ call(fn, args..', {}')
+ local function on_setup()
+ command('doautocmd BufEnter x.c')
+ end
+
+ local function handler(method, args)
+ eq('test-handler', method)
+ return ''
+ end
+
+ runx(sync, handler, on_setup)
+ end)
+ end)
+
+ describe('with eval', function()
+ it('ok', function()
+ call(fn, args..[[, {'eval': 'expand("<afile>")'}]])
+ local function on_setup()
+ command('doautocmd BufEnter x.c')
+ end
+
+ local function handler(method, args)
+ eq('test-handler', method)
+ eq('x.c', args[1])
+ return ''
+ end
+
+ runx(sync, handler, on_setup)
+ end)
+ 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)
+
+ describe('without options', function()
+ it('ok', 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, args)
+ eq('test-handler', method)
+ eq({{1, 'a', {'b', 'c'}}}, args)
+ return 'rv'
+ end
+
+ runx(sync, handler, on_setup)
+ end)
+ end)
+
+ describe('with eval', function()
+ it('ok', 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, args)
+ eq('test-handler', method)
+ eq({{1, 'a', {'b', 'c'}}, 4}, args)
+ return 'rv'
+ end
+
+ runx(sync, handler, on_setup)
+ end)
+ end)
+ end)
+ end)
+end
+
+local function channel()
+ return nvim('get_api_info')[1]
+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)
diff --git a/test/functional/provider/python3_spec.lua b/test/functional/provider/python3_spec.lua
new file mode 100644
index 0000000000..5be5390370
--- /dev/null
+++ b/test/functional/provider/python3_spec.lua
@@ -0,0 +1,77 @@
+do
+ local proc = io.popen(
+ [[python3 -c 'import neovim, sys; sys.stdout.write("ok")' 2> /dev/null]])
+ if proc:read() ~= 'ok' then
+ pending(
+ 'python3 (or the python3 neovim module) is broken or missing',
+ function() end)
+ return
+ end
+end
+
+local helpers = require('test.functional.helpers')
+local eval, command, feed = helpers.eval, helpers.command, helpers.feed
+local eq, clear, insert = helpers.eq, helpers.clear, helpers.insert
+local expect, write_file = helpers.expect, helpers.write_file
+
+describe('python3 commands and functions', function()
+ before_each(function()
+ clear()
+ command('python3 import vim')
+ end)
+
+ it('feature test', function()
+ eq(1, eval('has("python3")'))
+ end)
+
+ it('python3_execute', function()
+ command('python3 vim.vars["set_by_python3"] = [100, 0]')
+ eq({100, 0}, eval('g:set_by_python3'))
+ end)
+
+ it('python3_execute with nested commands', function()
+ command([[python3 vim.command('python3 vim.command("python3 vim.command(\'let set_by_nested_python3 = 555\')")')]])
+ eq(555, eval('g:set_by_nested_python3'))
+ end)
+
+ it('python3_execute with range', function()
+ insert([[
+ line1
+ line2
+ line3
+ line4]])
+ feed('ggjvj:python3 vim.vars["range"] = vim.current.range[:]<CR>')
+ eq({'line2', 'line3'}, eval('g:range'))
+ end)
+
+ it('py3file', function()
+ local fname = 'py3file.py'
+ write_file(fname, 'vim.command("let set_by_py3file = 123")')
+ command('py3file py3file.py')
+ eq(123, eval('g:set_by_py3file'))
+ os.remove(fname)
+ end)
+
+ it('py3do', function()
+ -- :pydo3 42 returns None for all lines,
+ -- the buffer should not be changed
+ command('normal :py3do 42')
+ eq(0, eval('&mod'))
+ -- insert some text
+ insert('abc\ndef\nghi')
+ expect([[
+ abc
+ def
+ ghi]])
+ -- go to top and select and replace the first two lines
+ feed('ggvj:py3do return str(linenr)<CR>')
+ expect([[
+ 1
+ 2
+ ghi]])
+ end)
+
+ it('py3eval', function()
+ eq({1, 2, {['key'] = 'val'}}, eval([[py3eval('[1, 2, {"key": "val"}]')]]))
+ end)
+end)
diff --git a/test/functional/provider/python_spec.lua b/test/functional/provider/python_spec.lua
new file mode 100644
index 0000000000..ec1a853546
--- /dev/null
+++ b/test/functional/provider/python_spec.lua
@@ -0,0 +1,77 @@
+do
+ local proc = io.popen(
+ [[python -c 'import neovim, sys; sys.stdout.write("ok")' 2> /dev/null]])
+ if proc:read() ~= 'ok' then
+ pending(
+ 'python (or the python neovim module) is broken or missing',
+ function() end)
+ return
+ end
+end
+
+local helpers = require('test.functional.helpers')
+local eval, command, feed = helpers.eval, helpers.command, helpers.feed
+local eq, clear, insert = helpers.eq, helpers.clear, helpers.insert
+local expect, write_file = helpers.expect, helpers.write_file
+
+describe('python commands and functions', function()
+ before_each(function()
+ clear()
+ command('python import vim')
+ end)
+
+ it('feature test', function()
+ eq(1, eval('has("python")'))
+ end)
+
+ it('python_execute', function()
+ command('python vim.vars["set_by_python"] = [100, 0]')
+ eq({100, 0}, eval('g:set_by_python'))
+ end)
+
+ it('python_execute with nested commands', function()
+ command([[python vim.command('python vim.command("python vim.command(\'let set_by_nested_python = 555\')")')]])
+ eq(555, eval('g:set_by_nested_python'))
+ end)
+
+ it('python_execute with range', function()
+ insert([[
+ line1
+ line2
+ line3
+ line4]])
+ feed('ggjvj:python vim.vars["range"] = vim.current.range[:]<CR>')
+ eq({'line2', 'line3'}, eval('g:range'))
+ end)
+
+ it('pyfile', function()
+ local fname = 'pyfile.py'
+ write_file(fname, 'vim.command("let set_by_pyfile = 123")')
+ command('pyfile pyfile.py')
+ eq(123, eval('g:set_by_pyfile'))
+ os.remove(fname)
+ end)
+
+ it('pydo', function()
+ -- :pydo 42 returns None for all lines,
+ -- the buffer should not be changed
+ command('normal :pydo 42')
+ eq(0, eval('&mod'))
+ -- insert some text
+ insert('abc\ndef\nghi')
+ expect([[
+ abc
+ def
+ ghi]])
+ -- go to top and select and replace the first two lines
+ feed('ggvj:pydo return str(linenr)<CR>')
+ expect([[
+ 1
+ 2
+ ghi]])
+ end)
+
+ it('pyeval', function()
+ eq({1, 2, {['key'] = 'val'}}, eval([[pyeval('[1, 2, {"key": "val"}]')]]))
+ end)
+end)