mirror of
https://github.com/neovim/neovim.git
synced 2025-09-15 07:48:18 +00:00
Merge PR #1296 'Use the lua client to run functional tests'
This commit is contained in:
@@ -1,32 +0,0 @@
|
||||
. "$CI_SCRIPTS/common.sh"
|
||||
|
||||
set_environment /opt/neovim-deps/64
|
||||
|
||||
sudo apt-get install expect valgrind
|
||||
|
||||
$MAKE_CMD
|
||||
|
||||
git clone --depth=1 -b master git://github.com/neovim/python-client
|
||||
cd python-client
|
||||
sudo pip install .
|
||||
sudo pip install nose
|
||||
# We run the tests twice:
|
||||
# - First by connecting with an nvim instance spawned by "expect"
|
||||
# - Second by starting nvim in embedded mode through the python client
|
||||
# This is required until nvim is mature enough to always run in embedded mode
|
||||
test_cmd="nosetests --verbosity=2 --nologcapture"
|
||||
nvim_cmd="valgrind -q --track-origins=yes --leak-check=yes --suppressions=$suppressions --log-file=$tmpdir/valgrind-%p.log ../build/bin/nvim -u NONE"
|
||||
if ! ../scripts/run-api-tests.exp "$test_cmd" "$nvim_cmd"; then
|
||||
valgrind_check "$tmpdir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
valgrind_check "$tmpdir"
|
||||
|
||||
export NVIM_SPAWN_ARGV="[\"valgrind\", \"-q\", \"--track-origins=yes\", \"--leak-check=yes\", \"--suppressions=$suppressions\", \"--log-file=$tmpdir/valgrind-%p.log\", \"../build/bin/nvim\", \"-u\", \"NONE\", \"--embed\"]"
|
||||
if ! nosetests --verbosity=2 --nologcapture; then
|
||||
valgrind_check "$tmpdir"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
valgrind_check "$tmpdir"
|
@@ -11,7 +11,6 @@ env:
|
||||
- CI_TARGET=gcc
|
||||
- CI_TARGET=gcc-32
|
||||
- CI_TARGET=clint
|
||||
- CI_TARGET=api-python
|
||||
- CI_TARGET=coverity
|
||||
before_install:
|
||||
# Adds user to a dummy group.
|
||||
|
@@ -228,17 +228,9 @@ if(BUSTED_PRG)
|
||||
-P ${CMAKE_MODULE_PATH}/RunTests.cmake
|
||||
DEPENDS nvim-test unittest-headers)
|
||||
|
||||
# For the functional tests we need the full path to the real busted script,
|
||||
# which will be included by run-functional-tests.py.
|
||||
get_filename_component(LUA_PRG_DIR ${LUA_PRG} PATH)
|
||||
get_filename_component(LUA_PREFIX_DIR ${LUA_PRG_DIR} PATH)
|
||||
file(GLOB_RECURSE BUSTED_REAL_PRG
|
||||
${LUA_PREFIX_DIR}/lib/luarocks/rocks/busted/*busted)
|
||||
|
||||
add_custom_target(test
|
||||
COMMAND ${CMAKE_COMMAND}
|
||||
-DBUSTED_PRG=${PROJECT_SOURCE_DIR}/scripts/run-functional-tests.py
|
||||
-DBUSTED_REAL_PRG=${BUSTED_REAL_PRG}
|
||||
-DBUSTED_PRG=${BUSTED_PRG}
|
||||
-DWORKING_DIR=${CMAKE_CURRENT_SOURCE_DIR}
|
||||
-DBUSTED_OUTPUT_TYPE=${BUSTED_OUTPUT_TYPE}
|
||||
-DTEST_DIR=${CMAKE_CURRENT_SOURCE_DIR}/test
|
||||
|
@@ -6,8 +6,8 @@ endif()
|
||||
|
||||
if(TEST_TYPE STREQUAL "functional")
|
||||
execute_process(
|
||||
COMMAND python ${BUSTED_PRG} ${BUSTED_REAL_PRG} -v -o
|
||||
${BUSTED_OUTPUT_TYPE} --lpath=${BUILD_DIR}/?.lua ${TEST_DIR}/functional
|
||||
COMMAND ${BUSTED_PRG} -v -o ${BUSTED_OUTPUT_TYPE}
|
||||
--lpath=${BUILD_DIR}/?.lua ${TEST_DIR}/functional
|
||||
WORKING_DIRECTORY ${WORKING_DIR}
|
||||
RESULT_VARIABLE res)
|
||||
else()
|
||||
|
@@ -1,93 +0,0 @@
|
||||
# Run functional tests using lua, busted and the python client
|
||||
|
||||
import os
|
||||
import sys
|
||||
import textwrap
|
||||
|
||||
from lupa import LuaRuntime, as_attrgetter
|
||||
from neovim import Nvim, spawn_session
|
||||
|
||||
|
||||
# Extract arguments
|
||||
busted_script = sys.argv[1]
|
||||
busted_argv = sys.argv[2:]
|
||||
|
||||
# Setup a lua state for running busted
|
||||
lua = LuaRuntime(unpack_returned_tuples=True)
|
||||
lua_globals = lua.globals()
|
||||
|
||||
# helper to transform iterables into lua tables
|
||||
list_to_table = lua.eval('''
|
||||
function(l)
|
||||
local t = {}
|
||||
for i, item in python.enumerate(l) do t[i + 1] = item end
|
||||
return t
|
||||
end
|
||||
''')
|
||||
|
||||
dict_to_table = lua.eval('''
|
||||
function(d)
|
||||
local t = {}
|
||||
for k, v in python.iterex(d.items()) do t[k] = v end
|
||||
return t
|
||||
end
|
||||
''')
|
||||
|
||||
def to_table(obj):
|
||||
if type(obj) in [tuple, list]:
|
||||
return list_to_table(list(to_table(e) for e in obj))
|
||||
if type(obj) is dict:
|
||||
return dict_to_table(as_attrgetter(
|
||||
dict((k, to_table(v)) for k, v in obj.items())))
|
||||
return obj
|
||||
|
||||
nvim_prog = os.environ.get('NVIM_PROG', 'build/bin/nvim')
|
||||
nvim_argv = [nvim_prog, '-u', 'NONE', '--embed']
|
||||
|
||||
if 'VALGRIND' in os.environ:
|
||||
log_file = os.environ.get('VALGRIND_LOG', 'valgrind-%p.log')
|
||||
valgrind_argv = ['valgrind', '-q', '--tool=memcheck', '--leak-check=yes',
|
||||
'--track-origins=yes', '--suppressions=.valgrind.supp',
|
||||
'--log-file={0}'.format(log_file)]
|
||||
if 'VALGRIND_GDB' in os.environ:
|
||||
valgrind_argv += ['--vgdb=yes', '--vgdb-error=0']
|
||||
nvim_argv = valgrind_argv + nvim_argv
|
||||
|
||||
session = spawn_session(nvim_argv)
|
||||
nvim = Nvim.from_session(session)
|
||||
|
||||
def nvim_command(cmd):
|
||||
nvim.command(cmd)
|
||||
|
||||
def nvim_eval(expr):
|
||||
return to_table(nvim.eval(expr))
|
||||
|
||||
def nvim_feed(input, mode=''):
|
||||
nvim.feedkeys(input)
|
||||
|
||||
def buffer_slice(start=None, stop=None, buffer_idx=None):
|
||||
rv = '\n'.join(nvim.buffers[buffer_idx or 0][start:stop])
|
||||
return rv
|
||||
|
||||
def nvim_replace_termcodes(input, *opts):
|
||||
return nvim.replace_termcodes(input, *opts)
|
||||
|
||||
expose = [
|
||||
nvim_command,
|
||||
nvim_eval,
|
||||
nvim_feed,
|
||||
nvim_replace_termcodes,
|
||||
buffer_slice,
|
||||
textwrap.dedent,
|
||||
]
|
||||
|
||||
for fn in expose:
|
||||
lua_globals[fn.__name__] = fn
|
||||
|
||||
# Set 'arg' global to let busted parse arguments
|
||||
lua_globals['arg'] = list_to_table(busted_argv)
|
||||
|
||||
# Read the busted script and execute in the lua state
|
||||
with open(busted_script) as f:
|
||||
busted_setup = f.read()
|
||||
lua.execute(busted_setup)
|
118
test/functional/api/buffer_spec.lua
Normal file
118
test/functional/api/buffer_spec.lua
Normal file
@@ -0,0 +1,118 @@
|
||||
-- Sanity checks for buffer_* API calls via msgpack-rpc
|
||||
local helpers = require('test.functional.helpers')
|
||||
local clear, nvim, buffer, curbuf, curwin, eq, ok =
|
||||
helpers.clear, helpers.nvim, helpers.buffer, helpers.curbuf, helpers.curwin,
|
||||
helpers.eq, helpers.ok
|
||||
|
||||
describe('buffer_* functions', function()
|
||||
before_each(clear)
|
||||
|
||||
describe('line_count, insert and del_line', function()
|
||||
it('works', function()
|
||||
eq(1, curbuf('line_count'))
|
||||
curbuf('insert', -1, {'line'})
|
||||
eq(2, curbuf('line_count'))
|
||||
curbuf('insert', -1, {'line'})
|
||||
eq(3, curbuf('line_count'))
|
||||
curbuf('del_line', -1)
|
||||
eq(2, curbuf('line_count'))
|
||||
curbuf('del_line', -1)
|
||||
curbuf('del_line', -1)
|
||||
-- There's always at least one line
|
||||
eq(1, curbuf('line_count'))
|
||||
end)
|
||||
end)
|
||||
|
||||
|
||||
describe('{get,set,del}_line', function()
|
||||
it('works', function()
|
||||
eq('', curbuf('get_line', 0))
|
||||
curbuf('set_line', 0, 'line1')
|
||||
eq('line1', curbuf('get_line', 0))
|
||||
curbuf('set_line', 0, 'line2')
|
||||
eq('line2', curbuf('get_line', 0))
|
||||
curbuf('del_line', 0)
|
||||
eq('', curbuf('get_line', 0))
|
||||
end)
|
||||
end)
|
||||
|
||||
|
||||
describe('{get,set}_line_slice', function()
|
||||
it('works', function()
|
||||
eq({''}, curbuf('get_line_slice', 0, -1, true, true))
|
||||
-- Replace buffer
|
||||
curbuf('set_line_slice', 0, -1, true, true, {'a', 'b', 'c'})
|
||||
eq({'a', 'b', 'c'}, curbuf('get_line_slice', 0, -1, true, true))
|
||||
eq({'b', 'c'}, curbuf('get_line_slice', 1, -1, true, true))
|
||||
eq({'b'}, curbuf('get_line_slice', 1, 2, true, false))
|
||||
eq({}, curbuf('get_line_slice', 1, 1, true, false))
|
||||
eq({'a', 'b'}, curbuf('get_line_slice', 0, -1, true, false))
|
||||
eq({'b'}, curbuf('get_line_slice', 1, -1, true, false))
|
||||
eq({'b', 'c'}, curbuf('get_line_slice', -2, -1, true, true))
|
||||
curbuf('set_line_slice', 1, 2, true, false, {'a', 'b', 'c'})
|
||||
eq({'a', 'a', 'b', 'c', 'c'}, curbuf('get_line_slice', 0, -1, true, true))
|
||||
curbuf('set_line_slice', -1, -1, true, true, {'a', 'b', 'c'})
|
||||
eq({'a', 'a', 'b', 'c', 'a', 'b', 'c'},
|
||||
curbuf('get_line_slice', 0, -1, true, true))
|
||||
curbuf('set_line_slice', 0, -3, true, false, {})
|
||||
eq({'a', 'b', 'c'}, curbuf('get_line_slice', 0, -1, true, true))
|
||||
curbuf('set_line_slice', 0, -1, true, true, {})
|
||||
eq({''}, curbuf('get_line_slice', 0, -1, true, true))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('{get,set}_var', function()
|
||||
it('works', function()
|
||||
curbuf('set_var', 'lua', {1, 2, {['3'] = 1}})
|
||||
eq({1, 2, {['3'] = 1}}, curbuf('get_var', 'lua'))
|
||||
eq({1, 2, {['3'] = 1}}, nvim('eval', 'b:lua'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('{get,set}_option', function()
|
||||
it('works', function()
|
||||
eq(8, curbuf('get_option', 'shiftwidth'))
|
||||
curbuf('set_option', 'shiftwidth', 4)
|
||||
eq(4, curbuf('get_option', 'shiftwidth'))
|
||||
-- global-local option
|
||||
curbuf('set_option', 'define', 'test')
|
||||
eq('test', curbuf('get_option', 'define'))
|
||||
-- Doesn't change the global value
|
||||
eq([[^\s*#\s*define]], nvim('get_option', 'define'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('{get,set}_name', function()
|
||||
it('works', function()
|
||||
nvim('command', 'new')
|
||||
eq('', curbuf('get_name'))
|
||||
local new_name = nvim('eval', 'resolve(tempname())')
|
||||
curbuf('set_name', new_name)
|
||||
eq(new_name, curbuf('get_name'))
|
||||
nvim('command', 'w!')
|
||||
local f = io.open(new_name)
|
||||
ok(f ~= nil)
|
||||
f:close()
|
||||
os.remove(new_name)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('is_valid', function()
|
||||
it('works', function()
|
||||
nvim('command', 'new')
|
||||
local b = nvim('get_current_buffer')
|
||||
ok(buffer('is_valid', b))
|
||||
nvim('command', 'bw!')
|
||||
ok(not buffer('is_valid', b))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('get_mark', function()
|
||||
it('works', function()
|
||||
curbuf('insert', -1, {'a', 'bit of', 'text'})
|
||||
curwin('set_cursor', {3, 4})
|
||||
nvim('command', 'mark V')
|
||||
eq({3, 0}, curbuf('get_mark', 'V'))
|
||||
end)
|
||||
end)
|
||||
end)
|
40
test/functional/api/server_notifications_spec.lua
Normal file
40
test/functional/api/server_notifications_spec.lua
Normal file
@@ -0,0 +1,40 @@
|
||||
-- Tests for nvim notifications
|
||||
local helpers = require('test.functional.helpers')
|
||||
local eq, clear, eval, execute, nvim, next_message =
|
||||
helpers.eq, helpers.clear, helpers.eval, helpers.execute, helpers.nvim,
|
||||
helpers.next_message
|
||||
|
||||
describe('notify', function()
|
||||
local channel
|
||||
|
||||
before_each(function()
|
||||
clear()
|
||||
channel = nvim('get_api_info')[1]
|
||||
end)
|
||||
|
||||
describe('passing a valid channel id', function()
|
||||
it('sends the notification/args to the corresponding channel', function()
|
||||
eval('rpcnotify('..channel..', "test-event", 1, 2, 3)')
|
||||
eq({'notification', 'test-event', {1, 2, 3}}, next_message())
|
||||
execute('au FileType lua call rpcnotify('..channel..', "lua!")')
|
||||
execute('set filetype=lua')
|
||||
eq({'notification', 'lua!', {}}, next_message())
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('passing 0 as the channel id', function()
|
||||
it('sends the notification/args to all subscribed channels', function()
|
||||
nvim('subscribe', 'event2')
|
||||
eval('rpcnotify(0, "event1", 1, 2, 3)')
|
||||
eval('rpcnotify(0, "event2", 4, 5, 6)')
|
||||
eval('rpcnotify(0, "event2", 7, 8, 9)')
|
||||
eq({'notification', 'event2', {4, 5, 6}}, next_message())
|
||||
eq({'notification', 'event2', {7, 8, 9}}, next_message())
|
||||
nvim('unsubscribe', 'event2')
|
||||
nvim('subscribe', 'event1')
|
||||
eval('rpcnotify(0, "event2", 10, 11, 12)')
|
||||
eval('rpcnotify(0, "event1", 13, 14, 15)')
|
||||
eq({'notification', 'event1', {13, 14, 15}}, next_message())
|
||||
end)
|
||||
end)
|
||||
end)
|
68
test/functional/api/server_requests_spec.lua
Normal file
68
test/functional/api/server_requests_spec.lua
Normal file
@@ -0,0 +1,68 @@
|
||||
-- Tests for some server->client RPC scenarios. Note that unlike with
|
||||
-- `rpcnotify`, to evaluate `rpcrequest` calls we need the client event loop to
|
||||
-- be running.
|
||||
local helpers = require('test.functional.helpers')
|
||||
local clear, nvim, eval, eq, run, stop = helpers.clear, helpers.nvim,
|
||||
helpers.eval, helpers.eq, helpers.run, helpers.stop
|
||||
|
||||
|
||||
describe('server -> client', function()
|
||||
local cid
|
||||
|
||||
before_each(function()
|
||||
clear()
|
||||
cid = nvim('get_api_info')[1]
|
||||
end)
|
||||
|
||||
describe('simple call', function()
|
||||
it('works', function()
|
||||
local function on_setup()
|
||||
eq({4, 5, 6}, eval('rpcrequest('..cid..', "scall", 1, 2, 3)'))
|
||||
stop()
|
||||
end
|
||||
|
||||
local function on_request(method, args)
|
||||
eq('scall', method)
|
||||
eq({1, 2, 3}, args)
|
||||
nvim('command', 'let g:result = [4, 5, 6]')
|
||||
return eval('g:result')
|
||||
end
|
||||
run(on_request, nil, on_setup)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('recursive call', function()
|
||||
it('works', function()
|
||||
local function on_setup()
|
||||
nvim('set_var', 'result1', 0)
|
||||
nvim('set_var', 'result2', 0)
|
||||
nvim('set_var', 'result3', 0)
|
||||
nvim('set_var', 'result4', 0)
|
||||
nvim('command', 'let g:result1 = rpcrequest('..cid..', "rcall", 2)')
|
||||
eq(4, nvim('get_var', 'result1'))
|
||||
eq(8, nvim('get_var', 'result2'))
|
||||
eq(16, nvim('get_var', 'result3'))
|
||||
eq(32, nvim('get_var', 'result4'))
|
||||
stop()
|
||||
end
|
||||
|
||||
local function on_request(method, args)
|
||||
eq('rcall', method)
|
||||
local n = unpack(args) * 2
|
||||
if n <= 16 then
|
||||
local cmd
|
||||
if n == 4 then
|
||||
cmd = 'let g:result2 = rpcrequest('..cid..', "rcall", '..n..')'
|
||||
elseif n == 8 then
|
||||
cmd = 'let g:result3 = rpcrequest('..cid..', "rcall", '..n..')'
|
||||
elseif n == 16 then
|
||||
cmd = 'let g:result4 = rpcrequest('..cid..', "rcall", '..n..')'
|
||||
end
|
||||
nvim('command', cmd)
|
||||
end
|
||||
return n
|
||||
end
|
||||
run(on_request, nil, on_setup)
|
||||
end)
|
||||
end)
|
||||
end)
|
42
test/functional/api/tabpage_spec.lua
Normal file
42
test/functional/api/tabpage_spec.lua
Normal file
@@ -0,0 +1,42 @@
|
||||
-- Sanity checks for tabpage_* API calls via msgpack-rpc
|
||||
local helpers = require('test.functional.helpers')
|
||||
local clear, nvim, tabpage, curtab, eq, ok =
|
||||
helpers.clear, helpers.nvim, helpers.tabpage, helpers.curtab, helpers.eq,
|
||||
helpers.ok
|
||||
|
||||
describe('tabpage_* functions', function()
|
||||
before_each(clear)
|
||||
|
||||
describe('get_windows and get_window', function()
|
||||
it('works', function()
|
||||
nvim('command', 'tabnew')
|
||||
nvim('command', 'vsplit')
|
||||
local tab1, tab2 = unpack(nvim('get_tabpages'))
|
||||
local win1, win2, win3 = unpack(nvim('get_windows'))
|
||||
eq({win1}, tabpage('get_windows', tab1))
|
||||
eq({win2, win3}, tabpage('get_windows', tab2))
|
||||
eq(win2, tabpage('get_window', tab2))
|
||||
nvim('set_current_window', win3)
|
||||
eq(win3, tabpage('get_window', tab2))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('{get,set}_var', function()
|
||||
it('works', function()
|
||||
curtab('set_var', 'lua', {1, 2, {['3'] = 1}})
|
||||
eq({1, 2, {['3'] = 1}}, curtab('get_var', 'lua'))
|
||||
eq({1, 2, {['3'] = 1}}, nvim('eval', 't:lua'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('is_valid', function()
|
||||
it('works', function()
|
||||
nvim('command', 'tabnew')
|
||||
local tab = nvim('get_tabpages')[2]
|
||||
nvim('set_current_tabpage', tab)
|
||||
ok(tabpage('is_valid', tab))
|
||||
nvim('command', 'tabclose')
|
||||
ok(not tabpage('is_valid', tab))
|
||||
end)
|
||||
end)
|
||||
end)
|
108
test/functional/api/vim_spec.lua
Normal file
108
test/functional/api/vim_spec.lua
Normal file
@@ -0,0 +1,108 @@
|
||||
-- Sanity checks for vim_* API calls via msgpack-rpc
|
||||
local helpers = require('test.functional.helpers')
|
||||
local clear, nvim, eq, ok = helpers.clear, helpers.nvim, helpers.eq, helpers.ok
|
||||
|
||||
|
||||
describe('vim_* functions', function()
|
||||
before_each(clear)
|
||||
|
||||
describe('command', function()
|
||||
it('works', function()
|
||||
local fname = os.tmpname()
|
||||
nvim('command', 'new')
|
||||
nvim('command', 'edit '..fname)
|
||||
nvim('command', 'normal itesting\napi')
|
||||
nvim('command', 'w')
|
||||
local f = io.open(fname)
|
||||
ok(f ~= nil)
|
||||
eq('testing\napi\n', f:read('*a'))
|
||||
f:close()
|
||||
os.remove(fname)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('eval', function()
|
||||
it('works', function()
|
||||
nvim('command', 'let g:v1 = "a"')
|
||||
nvim('command', 'let g:v2 = [1, 2, {"v3": 3}]')
|
||||
eq({v1 = 'a', v2 = {1, 2, {v3 = 3}}}, nvim('eval', 'g:'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('strwidth', function()
|
||||
it('works', function()
|
||||
eq(3, nvim('strwidth', 'abc'))
|
||||
-- 6 + (neovim)
|
||||
-- 19 * 2 (each japanese character occupies two cells)
|
||||
eq(44, nvim('strwidth', 'neovimのデザインかなりまともなのになってる。'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('{get,set}_current_line', function()
|
||||
it('works', function()
|
||||
eq('', nvim('get_current_line'))
|
||||
nvim('set_current_line', 'abc')
|
||||
eq('abc', nvim('get_current_line'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('{get,set}_var', function()
|
||||
it('works', function()
|
||||
nvim('set_var', 'lua', {1, 2, {['3'] = 1}})
|
||||
eq({1, 2, {['3'] = 1}}, nvim('get_var', 'lua'))
|
||||
eq({1, 2, {['3'] = 1}}, nvim('eval', 'g:lua'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('{get,set}_option', function()
|
||||
it('works', function()
|
||||
ok(nvim('get_option', 'equalalways'))
|
||||
nvim('set_option', 'equalalways', false)
|
||||
ok(not nvim('get_option', 'equalalways'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('{get,set}_current_buffer and get_buffers', function()
|
||||
it('works', function()
|
||||
eq(1, #nvim('get_buffers'))
|
||||
eq(nvim('get_buffers')[1], nvim('get_current_buffer'))
|
||||
nvim('command', 'new')
|
||||
eq(2, #nvim('get_buffers'))
|
||||
eq(nvim('get_buffers')[2], nvim('get_current_buffer'))
|
||||
nvim('set_current_buffer', nvim('get_buffers')[1])
|
||||
eq(nvim('get_buffers')[1], nvim('get_current_buffer'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('{get,set}_current_window and get_windows', function()
|
||||
it('works', function()
|
||||
eq(1, #nvim('get_windows'))
|
||||
eq(nvim('get_windows')[1], nvim('get_current_window'))
|
||||
nvim('command', 'vsplit')
|
||||
nvim('command', 'split')
|
||||
eq(3, #nvim('get_windows'))
|
||||
eq(nvim('get_windows')[1], nvim('get_current_window'))
|
||||
nvim('set_current_window', nvim('get_windows')[2])
|
||||
eq(nvim('get_windows')[2], nvim('get_current_window'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('{get,set}_current_tabpage and get_tabpages', function()
|
||||
it('works', function()
|
||||
eq(1, #nvim('get_tabpages'))
|
||||
eq(nvim('get_tabpages')[1], nvim('get_current_tabpage'))
|
||||
nvim('command', 'tabnew')
|
||||
eq(2, #nvim('get_tabpages'))
|
||||
eq(2, #nvim('get_windows'))
|
||||
eq(nvim('get_windows')[2], nvim('get_current_window'))
|
||||
eq(nvim('get_tabpages')[2], nvim('get_current_tabpage'))
|
||||
nvim('set_current_window', nvim('get_windows')[1])
|
||||
-- Switching window also switches tabpages if necessary
|
||||
eq(nvim('get_tabpages')[1], nvim('get_current_tabpage'))
|
||||
eq(nvim('get_windows')[1], nvim('get_current_window'))
|
||||
nvim('set_current_tabpage', nvim('get_tabpages')[2])
|
||||
eq(nvim('get_tabpages')[2], nvim('get_current_tabpage'))
|
||||
eq(nvim('get_windows')[2], nvim('get_current_window'))
|
||||
end)
|
||||
end)
|
||||
end)
|
124
test/functional/api/window_spec.lua
Normal file
124
test/functional/api/window_spec.lua
Normal file
@@ -0,0 +1,124 @@
|
||||
-- Sanity checks for window_* API calls via msgpack-rpc
|
||||
local helpers = require('test.functional.helpers')
|
||||
local clear, nvim, buffer, curbuf, curbuf_contents, window, curwin, eq, neq,
|
||||
ok = helpers.clear, helpers.nvim, helpers.buffer, helpers.curbuf,
|
||||
helpers.curbuf_contents, helpers.window, helpers.curwin, helpers.eq,
|
||||
helpers.neq, helpers.ok
|
||||
|
||||
describe('window_* functions', function()
|
||||
before_each(clear)
|
||||
|
||||
describe('get_buffer', function()
|
||||
it('works', function()
|
||||
eq(curbuf(), window('get_buffer', nvim('get_windows')[1]))
|
||||
nvim('command', 'new')
|
||||
nvim('set_current_window', nvim('get_windows')[2])
|
||||
eq(curbuf(), window('get_buffer', nvim('get_windows')[2]))
|
||||
neq(window('get_buffer', nvim('get_windows')[1]),
|
||||
window('get_buffer', nvim('get_windows')[2]))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('{get,set}_cursor', function()
|
||||
it('works', function()
|
||||
eq({1, 0}, curwin('get_cursor'))
|
||||
nvim('command', 'normal ityping\027o some text')
|
||||
eq('typing\n some text', curbuf_contents())
|
||||
eq({2, 10}, curwin('get_cursor'))
|
||||
curwin('set_cursor', {2, 6})
|
||||
nvim('command', 'normal i dumb')
|
||||
eq('typing\n some dumb text', curbuf_contents())
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('{get,set}_height', function()
|
||||
it('works', function()
|
||||
nvim('command', 'vsplit')
|
||||
eq(window('get_height', nvim('get_windows')[2]),
|
||||
window('get_height', nvim('get_windows')[1]))
|
||||
nvim('set_current_window', nvim('get_windows')[2])
|
||||
nvim('command', 'split')
|
||||
eq(window('get_height', nvim('get_windows')[2]),
|
||||
window('get_height', nvim('get_windows')[1]) / 2)
|
||||
window('set_height', nvim('get_windows')[2], 2)
|
||||
eq(2, window('get_height', nvim('get_windows')[2]))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('{get,set}_width', function()
|
||||
it('works', function()
|
||||
nvim('command', 'split')
|
||||
eq(window('get_width', nvim('get_windows')[2]),
|
||||
window('get_width', nvim('get_windows')[1]))
|
||||
nvim('set_current_window', nvim('get_windows')[2])
|
||||
nvim('command', 'vsplit')
|
||||
eq(window('get_width', nvim('get_windows')[2]),
|
||||
window('get_width', nvim('get_windows')[1]) / 2)
|
||||
window('set_width', nvim('get_windows')[2], 2)
|
||||
eq(2, window('get_width', nvim('get_windows')[2]))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('{get,set}_var', function()
|
||||
it('works', function()
|
||||
curwin('set_var', 'lua', {1, 2, {['3'] = 1}})
|
||||
eq({1, 2, {['3'] = 1}}, curwin('get_var', 'lua'))
|
||||
eq({1, 2, {['3'] = 1}}, nvim('eval', 'w:lua'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('{get,set}_option', function()
|
||||
it('works', function()
|
||||
curwin('set_option', 'colorcolumn', '4,3')
|
||||
eq('4,3', curwin('get_option', 'colorcolumn'))
|
||||
-- global-local option
|
||||
curwin('set_option', 'statusline', 'window-status')
|
||||
eq('window-status', curwin('get_option', 'statusline'))
|
||||
eq('', nvim('get_option', 'statusline'))
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('get_position', function()
|
||||
it('works', function()
|
||||
local height = window('get_height', nvim('get_windows')[1])
|
||||
local width = window('get_width', nvim('get_windows')[1])
|
||||
nvim('command', 'split')
|
||||
nvim('command', 'vsplit')
|
||||
eq({0, 0}, window('get_position', nvim('get_windows')[1]))
|
||||
local vsplit_pos = math.floor(width / 2)
|
||||
local split_pos = math.floor(height / 2)
|
||||
local win2row, win2col =
|
||||
unpack(window('get_position', nvim('get_windows')[2]))
|
||||
local win3row, win3col =
|
||||
unpack(window('get_position', nvim('get_windows')[3]))
|
||||
eq(0, win2row)
|
||||
eq(0, win3col)
|
||||
ok(vsplit_pos - 1 <= win2col and win2col <= vsplit_pos + 1)
|
||||
ok(split_pos - 1 <= win3row and win3row <= split_pos + 1)
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('get_position', function()
|
||||
it('works', function()
|
||||
nvim('command', 'tabnew')
|
||||
nvim('command', 'vsplit')
|
||||
eq(window('get_tabpage',
|
||||
nvim('get_windows')[1]), nvim('get_tabpages')[1])
|
||||
eq(window('get_tabpage',
|
||||
nvim('get_windows')[2]), nvim('get_tabpages')[2])
|
||||
eq(window('get_tabpage',
|
||||
nvim('get_windows')[3]), nvim('get_tabpages')[2])
|
||||
end)
|
||||
end)
|
||||
|
||||
describe('is_valid', function()
|
||||
it('works', function()
|
||||
nvim('command', 'split')
|
||||
local win = nvim('get_windows')[2]
|
||||
nvim('set_current_window', win)
|
||||
ok(window('is_valid', win))
|
||||
nvim('command', 'close')
|
||||
ok(not window('is_valid', win))
|
||||
end)
|
||||
end)
|
||||
end)
|
@@ -1,3 +1,110 @@
|
||||
local Loop = require('nvim.loop')
|
||||
local MsgpackStream = require('nvim.msgpack_stream')
|
||||
local AsyncSession = require('nvim.async_session')
|
||||
local Session = require('nvim.session')
|
||||
|
||||
local nvim_prog = os.getenv('NVIM_PROG') or 'build/bin/nvim'
|
||||
local nvim_argv = {nvim_prog, '-u', 'NONE', '-N', '--embed'}
|
||||
|
||||
if os.getenv('VALGRIND') then
|
||||
local log_file = os.getenv('VALGRIND_LOG') or 'valgrind-%p.log'
|
||||
local valgrind_argv = {'valgrind', '-q', '--tool=memcheck',
|
||||
'--leak-check=yes', '--track-origins=yes',
|
||||
'--suppressions=.valgrind.supp',
|
||||
'--log-file='..log_file}
|
||||
if os.getenv('VALGRIND_GDB') then
|
||||
table.insert(valgrind_argv, '--vgdb=yes')
|
||||
table.insert(valgrind_argv, '--vgdb-error=0')
|
||||
end
|
||||
local len = #valgrind_argv
|
||||
for i = 1, #nvim_argv do
|
||||
valgrind_argv[i + len] = nvim_argv[i]
|
||||
end
|
||||
nvim_argv = valgrind_argv
|
||||
end
|
||||
|
||||
local session
|
||||
|
||||
local function restart()
|
||||
local loop = Loop.new()
|
||||
local msgpack_stream = MsgpackStream.new(loop)
|
||||
local async_session = AsyncSession.new(msgpack_stream)
|
||||
session = Session.new(async_session)
|
||||
loop:spawn(nvim_argv)
|
||||
end
|
||||
restart()
|
||||
|
||||
local function request(method, ...)
|
||||
local status, rv = session:request(method, ...)
|
||||
if not status then
|
||||
error(rv[2])
|
||||
end
|
||||
return rv
|
||||
end
|
||||
|
||||
local function next_message()
|
||||
return session:next_message()
|
||||
end
|
||||
|
||||
local function run(request_cb, notification_cb, setup_cb)
|
||||
session:run(request_cb, notification_cb, setup_cb)
|
||||
end
|
||||
|
||||
local function stop()
|
||||
session:stop()
|
||||
end
|
||||
|
||||
local function nvim_command(cmd)
|
||||
request('vim_command', cmd)
|
||||
end
|
||||
|
||||
local function nvim_eval(expr)
|
||||
return request('vim_eval', expr)
|
||||
end
|
||||
|
||||
local function nvim_feed(input, mode)
|
||||
mode = mode or ''
|
||||
request('vim_feedkeys', input, mode)
|
||||
end
|
||||
|
||||
local function buffer_slice(start, stop, buffer_idx)
|
||||
local include_end = false
|
||||
if not stop then
|
||||
stop = -1
|
||||
include_end = true
|
||||
end
|
||||
local buffer = request('vim_get_buffers')[buffer_idx or 1]
|
||||
local slice = request('buffer_get_line_slice', buffer, start or 0, stop,
|
||||
true, include_end)
|
||||
return table.concat(slice, '\n')
|
||||
end
|
||||
|
||||
local function nvim_replace_termcodes(input)
|
||||
return request('vim_replace_termcodes', input, false, true, true )
|
||||
end
|
||||
|
||||
local function dedent(str)
|
||||
-- find minimum common indent across lines
|
||||
local indent = nil
|
||||
for line in str:gmatch('[^\n]+') do
|
||||
local line_indent = line:match('^%s+') or ''
|
||||
if indent == nil or #line_indent < #indent then
|
||||
indent = line_indent
|
||||
end
|
||||
end
|
||||
if #indent == 0 then
|
||||
-- no minimum common indent
|
||||
return str
|
||||
end
|
||||
-- create a pattern for the indent
|
||||
indent = indent:gsub('%s', '%%s')
|
||||
-- strip it from the first line
|
||||
str = str:gsub('^'..indent, '')
|
||||
-- strip it from the remaining lines
|
||||
str = str:gsub('[\n]'..indent, '\n')
|
||||
return str
|
||||
end
|
||||
|
||||
local function clear()
|
||||
nvim_command('call BeforeEachTest()')
|
||||
end
|
||||
@@ -48,7 +155,7 @@ local function neq(expected, actual)
|
||||
end
|
||||
|
||||
local function expect(contents, first, last, buffer_index)
|
||||
return eq(dedent(contents), buffer_slice(first, last, buffer_idx))
|
||||
return eq(dedent(contents), buffer_slice(first, last, buffer_index))
|
||||
end
|
||||
|
||||
rawfeed([[:function BeforeEachTest()
|
||||
@@ -89,14 +196,77 @@ rawfeed([[:function BeforeEachTest()
|
||||
endfunction
|
||||
]])
|
||||
|
||||
|
||||
local function ok(expr)
|
||||
assert.is_true(expr)
|
||||
end
|
||||
|
||||
local function nvim(method, ...)
|
||||
return request('vim_'..method, ...)
|
||||
end
|
||||
|
||||
local function buffer(method, ...)
|
||||
return request('buffer_'..method, ...)
|
||||
end
|
||||
|
||||
local function window(method, ...)
|
||||
return request('window_'..method, ...)
|
||||
end
|
||||
|
||||
local function tabpage(method, ...)
|
||||
return request('tabpage_'..method, ...)
|
||||
end
|
||||
|
||||
local function curbuf(method, ...)
|
||||
local buf = nvim('get_current_buffer')
|
||||
if not method then
|
||||
return buf
|
||||
end
|
||||
return buffer(method, buf, ...)
|
||||
end
|
||||
|
||||
local function curbuf_contents()
|
||||
return table.concat(curbuf('get_line_slice', 0, -1, true, true), '\n')
|
||||
end
|
||||
|
||||
local function curwin(method, ...)
|
||||
local win = nvim('get_current_window')
|
||||
if not method then
|
||||
return win
|
||||
end
|
||||
return window(method, win, ...)
|
||||
end
|
||||
|
||||
local function curtab(method, ...)
|
||||
local tab = nvim('get_current_tabpage')
|
||||
if not method then
|
||||
return tab
|
||||
end
|
||||
return tabpage(method, tab, ...)
|
||||
end
|
||||
|
||||
return {
|
||||
clear = clear,
|
||||
restart = restart,
|
||||
rawfeed = rawfeed,
|
||||
insert = insert,
|
||||
feed = feed,
|
||||
execute = execute,
|
||||
eval = eval,
|
||||
request = request,
|
||||
next_message = next_message,
|
||||
run = run,
|
||||
stop = stop,
|
||||
eq = eq,
|
||||
neq = neq,
|
||||
expect = expect
|
||||
expect = expect,
|
||||
ok = ok,
|
||||
nvim = nvim,
|
||||
buffer = buffer,
|
||||
window = window,
|
||||
tabpage = tabpage,
|
||||
curbuf = curbuf,
|
||||
curwin = curwin,
|
||||
curtab = curtab,
|
||||
curbuf_contents = curbuf_contents
|
||||
}
|
||||
|
9
third-party/CMakeLists.txt
vendored
9
third-party/CMakeLists.txt
vendored
@@ -189,7 +189,14 @@ if(USE_BUNDLED_LUAROCKS)
|
||||
add_custom_target(lpeg
|
||||
DEPENDS ${DEPS_LIB_DIR}/luarocks/rocks/lpeg)
|
||||
|
||||
list(APPEND THIRD_PARTY_DEPS busted lua-messagepack lpeg)
|
||||
add_custom_command(OUTPUT ${DEPS_LIB_DIR}/luarocks/rocks/nvim-client
|
||||
COMMAND ${DEPS_BIN_DIR}/luarocks
|
||||
ARGS build https://raw.githubusercontent.com/neovim/lua-client/master/nvim-client-0.0.1-1.rockspec CC=${DEPS_C_COMPILER} LD=${DEPS_C_COMPILER} LIBUV_DIR=${DEPS_INSTALL_DIR}
|
||||
DEPENDS lpeg libuv)
|
||||
add_custom_target(nvim-client
|
||||
DEPENDS ${DEPS_LIB_DIR}/luarocks/rocks/nvim-client)
|
||||
|
||||
list(APPEND THIRD_PARTY_DEPS busted lua-messagepack lpeg nvim-client)
|
||||
endif()
|
||||
|
||||
add_custom_target(third-party ALL
|
||||
|
Reference in New Issue
Block a user