Merge #9301 'runtime/lua'

This commit is contained in:
Justin M. Keyes 2019-05-18 21:50:57 +02:00 committed by GitHub
commit 1cbe014569
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 173 additions and 161 deletions

View File

@ -0,0 +1,73 @@
--- Shared functions
-- - Used by Nvim and tests
-- - Can run in vanilla Lua (do not require a running instance of Nvim)
-- Checks if a list-like (vector) table contains `value`.
local function tbl_contains(t, value)
if type(t) ~= 'table' then
error('t must be a table')
end
for _,v in ipairs(t) do
if v == value then
return true
end
end
return false
end
--- Merges two or more map-like tables.
--
--@see |extend()|
--
-- behavior: Decides what to do if a key is found in more than one map:
-- "error": raise an error
-- "keep": use value from the leftmost map
-- "force": use value from the rightmost map
local function tbl_extend(behavior, ...)
if (behavior ~= 'error' and behavior ~= 'keep' and behavior ~= 'force') then
error('invalid "behavior": '..tostring(behavior))
end
local ret = {}
for i = 1, select('#', ...) do
local tbl = select(i, ...)
if tbl then
for k, v in pairs(tbl) do
if behavior ~= 'force' and ret[k] ~= nil then
if behavior == 'error' then
error('key found in more than one map: '..k)
end -- Else behavior is "keep".
else
ret[k] = v
end
end
end
end
return ret
end
-- Flattens a list-like table: unrolls and appends nested tables to table `t`.
local function tbl_flatten(t)
-- From https://github.com/premake/premake-core/blob/master/src/base/table.lua
local result = {}
local function _tbl_flatten(_t)
local n = #_t
for i = 1, n do
local v = _t[i]
if type(v) == "table" then
_tbl_flatten(v)
elseif v then
table.insert(result, v)
end
end
end
_tbl_flatten(t)
return result
end
local module = {
tbl_contains = tbl_contains,
tbl_extend = tbl_extend,
tbl_flatten = tbl_flatten,
}
return module

View File

@ -1,3 +1,39 @@
-- Nvim-Lua stdlib: the `vim` module (:help lua-stdlib)
--
-- Lua code lives in one of three places:
-- 1. The runtime (`runtime/lua/vim/`). For "nice to have" features, e.g.
-- the `inspect` and `lpeg` modules.
-- 2. The `vim.shared` module: code shared between Nvim and its test-suite.
-- 3. Compiled-into Nvim itself (`src/nvim/lua/`).
--
-- Guideline: "If in doubt, put it in the runtime".
--
-- Most functions should live directly on `vim.`, not sub-modules. The only
-- "forbidden" names are those claimed by legacy `if_lua`:
-- $ vim
-- :lua for k,v in pairs(vim) do print(k) end
-- buffer
-- open
-- window
-- lastline
-- firstline
-- type
-- line
-- eval
-- dict
-- beep
-- list
-- command
--
-- Reference (#6580):
-- - https://github.com/luafun/luafun
-- - https://github.com/rxi/lume
-- - http://leafo.net/lapis/reference/utilities.html
-- - https://github.com/torch/paths
-- - https://github.com/bakpakin/Fennel (pretty print, repl)
-- - https://github.com/howl-editor/howl/tree/master/lib/howl/util
-- Internal-only until comments in #8107 are addressed.
-- Returns:
-- {errcode}, {output}
@ -187,10 +223,14 @@ deepcopy = function(orig)
return deepcopy_funcs[type(orig)](orig)
end
local function __index(table, key)
if key == "inspect" then
table.inspect = require("vim.inspect")
return table.inspect
local function __index(t, key)
if key == 'inspect' then
t.inspect = require('vim.inspect')
return t.inspect
elseif require('vim.shared')[key] ~= nil then
-- Expose all `vim.shared` functions on the `vim` module.
t[key] = require('vim.shared')[key]
return t[key]
end
end

View File

@ -1,3 +1,5 @@
" Also used by: test/functional/helpers.lua
function! s:load_factor() abort
let timeout = 200
let times = []
@ -23,8 +25,8 @@ function! s:load_factor() abort
endfunction
" Compute load factor only once.
let s:load_factor = s:load_factor()
let g:test_load_factor = s:load_factor()
function! LoadAdjust(num) abort
return float2nr(ceil(a:num * s:load_factor))
return float2nr(ceil(a:num * g:test_load_factor))
endfunction

View File

@ -15,17 +15,13 @@ func MyHandlerWithLists(lists, timer)
let x = string(a:lists)
endfunc
func s:assert_inrange(lower, upper, actual)
return assert_inrange(a:lower, LoadAdjust(a:upper), a:actual)
endfunc
func Test_oneshot()
let g:val = 0
let timer = timer_start(50, 'MyHandler')
let slept = WaitFor('g:val == 1')
call assert_equal(1, g:val)
if has('reltime')
call s:assert_inrange(40, 120, slept)
call assert_inrange(40, LoadAdjust(120), slept)
else
call assert_inrange(20, 120, slept)
endif
@ -37,7 +33,7 @@ func Test_repeat_three()
let slept = WaitFor('g:val == 3')
call assert_equal(3, g:val)
if has('reltime')
call s:assert_inrange(120, 250, slept)
call assert_inrange(120, LoadAdjust(250), slept)
else
call assert_inrange(80, 200, slept)
endif
@ -52,7 +48,7 @@ func Test_repeat_many()
endif
sleep 200m
call timer_stop(timer)
call s:assert_inrange((has('mac') ? 1 : 2), 4, g:val)
call assert_inrange((has('mac') ? 1 : 2), LoadAdjust(4), g:val)
endfunc
func Test_with_partial_callback()
@ -66,7 +62,7 @@ func Test_with_partial_callback()
let slept = WaitFor('g:val == 1')
call assert_equal(1, g:val)
if has('reltime')
call s:assert_inrange(40, 130, slept)
call assert_inrange(40, LoadAdjust(130), slept)
else
call assert_inrange(20, 100, slept)
endif
@ -129,7 +125,7 @@ func Test_paused()
let slept = WaitFor('g:val == 1')
call assert_equal(1, g:val)
if has('reltime')
call s:assert_inrange(0, 140, slept)
call assert_inrange(0, LoadAdjust(140), slept)
else
call assert_inrange(0, 10, slept)
endif

View File

@ -1,5 +1,4 @@
local helpers = require('test.functional.helpers')(after_each)
local global_helpers = require('test.helpers')
local bufmeths = helpers.bufmeths
local clear = helpers.clear
@ -12,8 +11,8 @@ local funcs = helpers.funcs
local meths = helpers.meths
local source = helpers.source
local shallowcopy = global_helpers.shallowcopy
local sleep = global_helpers.sleep
local shallowcopy = helpers.shallowcopy
local sleep = helpers.sleep
describe('nvim_get_keymap', function()
before_each(clear)

View File

@ -1,7 +1,6 @@
-- Test server -> client RPC scenarios. Note: unlike `rpcnotify`, to evaluate
-- `rpcrequest` calls we need the client event loop to be running.
local helpers = require('test.functional.helpers')(after_each)
local Paths = require('test.config.paths')
local clear, nvim, eval = helpers.clear, helpers.nvim, helpers.eval
local eq, neq, run, stop = helpers.eq, helpers.neq, helpers.run, helpers.stop
@ -243,8 +242,8 @@ describe('server -> client', function()
\ 'rpc': v:true
\ }
]])
local lua_prog = Paths.test_lua_prg
meths.set_var("args", {lua_prog, 'test/functional/api/rpc_fixture.lua'})
meths.set_var("args", {helpers.test_lua_prg,
'test/functional/api/rpc_fixture.lua'})
jobid = eval("jobstart(g:args, g:job_opts)")
neq(0, 'jobid')
end)

View File

@ -1,6 +1,5 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local global_helpers = require('test.helpers')
local NIL = helpers.NIL
local clear, nvim, eq, neq = helpers.clear, helpers.nvim, helpers.eq, helpers.neq
@ -16,10 +15,10 @@ local request = helpers.request
local source = helpers.source
local next_msg = helpers.next_msg
local expect_err = global_helpers.expect_err
local format_string = global_helpers.format_string
local intchar2lua = global_helpers.intchar2lua
local mergedicts_copy = global_helpers.mergedicts_copy
local expect_err = helpers.expect_err
local format_string = helpers.format_string
local intchar2lua = helpers.intchar2lua
local mergedicts_copy = helpers.mergedicts_copy
describe('API', function()
before_each(clear)

View File

@ -1,7 +1,5 @@
local global_helpers = require('test.helpers')
local uname = global_helpers.uname
local helpers = require('test.functional.helpers')(after_each)
local uname = helpers.uname
local clear, eq, eval, next_msg, ok, source = helpers.clear, helpers.eq,
helpers.eval, helpers.next_msg, helpers.ok, helpers.source
local command, funcs, meths = helpers.command, helpers.funcs, helpers.meths

View File

@ -59,7 +59,7 @@ describe(':let', function()
end)
it("multibyte env var to child process #8398 #9267", function()
if (not helpers.iswin()) and require('test.helpers').isCI() then
if (not helpers.iswin()) and helpers.isCI() then
-- Fails on non-Windows CI. Buffering/timing issue?
pending('fails on unix CI', function() end)
end

View File

@ -8,23 +8,14 @@ local Session = require('nvim.session')
local TcpStream = require('nvim.tcp_stream')
local SocketStream = require('nvim.socket_stream')
local ChildProcessStream = require('nvim.child_process_stream')
local Paths = require('test.config.paths')
local check_cores = global_helpers.check_cores
local check_logs = global_helpers.check_logs
local dedent = global_helpers.dedent
local eq = global_helpers.eq
local expect_err = global_helpers.expect_err
local filter = global_helpers.filter
local map = global_helpers.map
local matches = global_helpers.matches
local near = global_helpers.near
local neq = global_helpers.neq
local ok = global_helpers.ok
local read_file = global_helpers.read_file
local sleep = global_helpers.sleep
local table_contains = global_helpers.table_contains
local table_flatten = global_helpers.table_flatten
local tbl_contains = global_helpers.tbl_contains
local write_file = global_helpers.write_file
local start_dir = lfs.currentdir()
@ -32,7 +23,7 @@ local start_dir = lfs.currentdir()
local nvim_prog = (
os.getenv('NVIM_PROG')
or os.getenv('NVIM_PRG')
or Paths.test_build_dir .. '/bin/nvim'
or global_helpers.test_build_dir .. '/bin/nvim'
)
-- Default settings for the test session.
local nvim_set = 'set shortmess+=I background=light noswapfile noautoindent'
@ -174,7 +165,7 @@ local function expect_msg_seq(...)
error(cat_err(final_error,
string.format('got %d messages (ignored %d), expected %d',
#actual_seq, nr_ignored, #expected_seq)))
elseif table_contains(ignore, msg_type) then
elseif tbl_contains(ignore, msg_type) then
nr_ignored = nr_ignored + 1
else
table.insert(actual_seq, msg)
@ -348,9 +339,9 @@ local function remove_args(args, args_rm)
end
local last = ''
for _, arg in ipairs(args) do
if table_contains(skip_following, last) then
if tbl_contains(skip_following, last) then
last = ''
elseif table_contains(args_rm, arg) then
elseif tbl_contains(args_rm, arg) then
last = arg
else
table.insert(new_args, arg)
@ -747,41 +738,14 @@ local function alter_slashes(obj)
end
end
local function compute_load_factor()
local timeout = 200
local times = {}
clear()
for _ = 1, 5 do
source([[
let g:val = 0
call timer_start(200, {-> nvim_set_var('val', 1)})
let start = reltime()
while 1
sleep 10m
if g:val == 1
let g:waited_in_ms = float2nr(reltimefloat(reltime(start)) * 1000)
break
endif
endwhile
]])
table.insert(times, nvim_eval('g:waited_in_ms'))
end
session:close()
session = nil
local longest = math.max(unpack(times))
local factor = (longest + 50.0) / timeout
return factor
end
-- Compute load factor only once.
local load_factor = compute_load_factor()
local load_factor = nil
local function load_adjust(num)
if load_factor == nil then -- Compute load factor only once.
clear()
request('nvim_command', 'source src/nvim/testdir/load.vim')
load_factor = request('nvim_eval', 'g:test_load_factor')
end
return math.ceil(num * load_factor)
end
@ -802,33 +766,25 @@ local module = {
curtabmeths = curtabmeths,
curwin = curwin,
curwinmeths = curwinmeths,
dedent = dedent,
eq = eq,
eval = nvim_eval,
exc_exec = exc_exec,
expect = expect,
expect_any = expect_any,
expect_err = expect_err,
expect_msg_seq = expect_msg_seq,
expect_twostreams = expect_twostreams,
feed = feed,
feed_command = feed_command,
filter = filter,
funcs = funcs,
get_pathsep = get_pathsep,
get_session = get_session,
insert = insert,
iswin = iswin,
map = map,
matches = matches,
merge_args = merge_args,
meth_pcall = meth_pcall,
meths = meths,
missing_provider = missing_provider,
mkdir = lfs.mkdir,
load_adjust = load_adjust,
near = near,
neq = neq,
new_pipename = new_pipename,
next_msg = next_msg,
nvim = nvim,
@ -838,13 +794,11 @@ local module = {
nvim_prog = nvim_prog,
nvim_prog_abs = nvim_prog_abs,
nvim_set = nvim_set,
ok = ok,
os_name = os_name,
pathroot = pathroot,
pending_win32 = pending_win32,
prepend_argv = prepend_argv,
rawfeed = rawfeed,
read_file = read_file,
redir_exec = redir_exec,
request = request,
retry = retry,
@ -854,20 +808,17 @@ local module = {
set_session = set_session,
set_shell_powershell = set_shell_powershell,
skip_fragile = skip_fragile,
sleep = sleep,
source = source,
spawn = spawn,
stop = stop,
table_flatten = table_flatten,
tabmeths = tabmeths,
tabpage = tabpage,
tmpname = tmpname,
uimeths = uimeths,
wait = wait,
window = window,
winmeths = winmeths,
write_file = write_file,
}
module = global_helpers.tbl_extend('error', module, global_helpers)
return function(after_each)
if after_each then

View File

@ -1,5 +1,4 @@
local helpers = require('test.functional.helpers')(after_each)
local global_helpers = require('test.helpers')
local Screen = require('test.functional.ui.screen')
@ -16,7 +15,7 @@ local neq = helpers.neq
local mkdir = helpers.mkdir
local rmdir = helpers.rmdir
local alter_slashes = helpers.alter_slashes
local table_contains = global_helpers.table_contains
local tbl_contains = helpers.tbl_contains
describe('startup defaults', function()
describe(':filetype', function()
@ -262,7 +261,7 @@ describe('XDG-based defaults', function()
for _,v in ipairs(rtp) do
local m = string.match(v, [=[[/\]nvim[^/\]*[/\]site.*$]=])
if m and not table_contains(rv, m) then
if m and not tbl_contains(rv, m) then
table.insert(rv, m)
end
end

View File

@ -1,8 +1,7 @@
-- TUI acceptance tests.
-- Uses :terminal as a way to send keys and assert screen state.
local global_helpers = require('test.helpers')
local uname = global_helpers.uname
local helpers = require('test.functional.helpers')(after_each)
local uname = helpers.uname
local thelpers = require('test.functional.terminal.helpers')
local Screen = require('test.functional.ui.screen')
local eq = helpers.eq

View File

@ -1,10 +1,9 @@
local global_helpers = require('test.helpers')
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear = helpers.clear
local command = helpers.command
local eq = helpers.eq
local shallowcopy = global_helpers.shallowcopy
local shallowcopy = helpers.shallowcopy
describe('ui receives option updates', function()
local screen

View File

@ -71,11 +71,10 @@
-- To help write screen tests, see Screen:snapshot_util().
-- To debug screen tests, see Screen:redraw_debug().
local global_helpers = require('test.helpers')
local deepcopy = global_helpers.deepcopy
local shallowcopy = global_helpers.shallowcopy
local concat_tables = global_helpers.concat_tables
local helpers = require('test.functional.helpers')(nil)
local deepcopy = helpers.deepcopy
local shallowcopy = helpers.shallowcopy
local concat_tables = helpers.concat_tables
local request, run_session = helpers.request, helpers.run_session
local eq = helpers.eq
local dedent = helpers.dedent

View File

@ -1,7 +1,6 @@
local global_helpers = require('test.helpers')
local shallowcopy = global_helpers.shallowcopy
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local shallowcopy = helpers.shallowcopy
local clear, feed, command = helpers.clear, helpers.feed, helpers.command
local iswin = helpers.iswin
local funcs = helpers.funcs

View File

@ -1,8 +1,10 @@
require('vim.compat')
local shared = require('vim.shared')
local assert = require('luassert')
local luv = require('luv')
local lfs = require('lfs')
local relpath = require('pl.path').relpath
local Paths = require('test.config.paths')
local quote_me = '[^.%w%+%-%@%_%/]' -- complement (needn't quote)
local function shell_quote(str)
@ -420,6 +422,7 @@ local function updated(d, d2)
return d
end
-- Concat list-like tables.
local function concat_tables(...)
local ret = {}
for i = 1, select('#', ...) do
@ -609,37 +612,6 @@ local function fixtbl_rec(tbl)
return fixtbl(tbl)
end
-- From https://github.com/premake/premake-core/blob/master/src/base/table.lua
local function table_flatten(arr)
local result = {}
local function _table_flatten(_arr)
local n = #_arr
for i = 1, n do
local v = _arr[i]
if type(v) == "table" then
_table_flatten(v)
elseif v then
table.insert(result, v)
end
end
end
_table_flatten(arr)
return result
end
-- Checks if a list-like (vector) table contains `value`.
local function table_contains(t, value)
if type(t) ~= 'table' then
error('t must be a table')
end
for _,v in ipairs(t) do
if v == value then
return true
end
end
return false
end
local function hexdump(str)
local len = string.len(str)
local dump = ""
@ -784,13 +756,12 @@ local module = {
repeated_read_cmd = repeated_read_cmd,
shallowcopy = shallowcopy,
sleep = sleep,
table_contains = table_contains,
table_flatten = table_flatten,
tmpname = tmpname,
uname = uname,
updated = updated,
which = which,
write_file = write_file,
}
module = shared.tbl_extend('error', module, Paths, shared)
return module

View File

@ -1,7 +1,6 @@
local bit = require('bit')
local helpers = require('test.unit.helpers')(after_each)
local eval_helpers = require('test.unit.eval.helpers')
local global_helpers = require('test.helpers')
local itp = helpers.gen_itp(it)
@ -14,6 +13,8 @@ local NULL = helpers.NULL
local cimport = helpers.cimport
local to_cstr = helpers.to_cstr
local alloc_log_new = helpers.alloc_log_new
local concat_tables = helpers.concat_tables
local map = helpers.map
local a = eval_helpers.alloc_logging_helpers
local int = eval_helpers.int
@ -40,9 +41,6 @@ local callback2tbl = eval_helpers.callback2tbl
local tbl2callback = eval_helpers.tbl2callback
local dict_watchers = eval_helpers.dict_watchers
local concat_tables = global_helpers.concat_tables
local map = global_helpers.map
local lib = cimport('./src/nvim/eval/typval.h', './src/nvim/memory.h',
'./src/nvim/mbyte.h', './src/nvim/garray.h',
'./src/nvim/eval.h', './src/nvim/vim.h',

View File

@ -15,7 +15,6 @@ local dedent = global_helpers.dedent
local neq = global_helpers.neq
local map = global_helpers.map
local eq = global_helpers.eq
local ok = global_helpers.ok
-- C constants.
local NULL = ffi.cast('void*', 0)
@ -842,9 +841,6 @@ local module = {
cimport = cimport,
cppimport = cppimport,
internalize = internalize,
ok = ok,
eq = eq,
neq = neq,
ffi = ffi,
lib = lib,
cstr = cstr,
@ -869,6 +865,7 @@ local module = {
ptr2key = ptr2key,
debug_log = debug_log,
}
module = global_helpers.tbl_extend('error', module, global_helpers)
return function()
return module
end

View File

@ -2,9 +2,7 @@ local helpers = require('test.unit.helpers')(after_each)
local itp = helpers.gen_itp(it)
local lfs = require('lfs')
local child_call_once = helpers.child_call_once
local global_helpers = require('test.helpers')
local sleep = global_helpers.sleep
local sleep = helpers.sleep
local ffi = helpers.ffi
local cimport = helpers.cimport
@ -156,12 +154,12 @@ describe('u_write_undo', function()
local file_contents = "testing permissions"
-- Write a text file where the undofile should go
local correct_name = ffi.string(undo.u_get_undo_file_name(file_buffer.b_ffname, false))
global_helpers.write_file(correct_name, file_contents, true, false)
helpers.write_file(correct_name, file_contents, true, false)
-- Call with `forceit`.
u_write_undo(correct_name, true, file_buffer, buffer_hash)
local undo_file_contents = global_helpers.read_file(correct_name)
local undo_file_contents = helpers.read_file(correct_name)
neq(file_contents, undo_file_contents)
local success, deletion_err = os.remove(correct_name) -- delete the file now that we're done with it.

View File

@ -1,5 +1,4 @@
local helpers = require('test.unit.helpers')(after_each)
local global_helpers = require('test.helpers')
local itp = helpers.gen_itp(it)
local viml_helpers = require('test.unit.viml.helpers')
@ -8,6 +7,8 @@ local conv_enum = helpers.conv_enum
local cimport = helpers.cimport
local ffi = helpers.ffi
local eq = helpers.eq
local shallowcopy = helpers.shallowcopy
local intchar2lua = helpers.intchar2lua
local conv_ccs = viml_helpers.conv_ccs
local new_pstate = viml_helpers.new_pstate
@ -15,9 +16,6 @@ local conv_cmp_type = viml_helpers.conv_cmp_type
local pstate_set_str = viml_helpers.pstate_set_str
local conv_expr_asgn_type = viml_helpers.conv_expr_asgn_type
local shallowcopy = global_helpers.shallowcopy
local intchar2lua = global_helpers.intchar2lua
local lib = cimport('./src/nvim/viml/parser/expressions.h')
local eltkn_type_tab, eltkn_mul_type_tab, eltkn_opt_scope_tab

View File

@ -1,5 +1,4 @@
local helpers = require('test.unit.helpers')(after_each)
local global_helpers = require('test.helpers')
local itp = helpers.gen_itp(it)
local viml_helpers = require('test.unit.viml.helpers')
@ -14,6 +13,11 @@ local cimport = helpers.cimport
local ffi = helpers.ffi
local neq = helpers.neq
local eq = helpers.eq
local mergedicts_copy = helpers.mergedicts_copy
local format_string = helpers.format_string
local format_luav = helpers.format_luav
local intchar2lua = helpers.intchar2lua
local dictdiff = helpers.dictdiff
local conv_ccs = viml_helpers.conv_ccs
local new_pstate = viml_helpers.new_pstate
@ -21,12 +25,6 @@ local conv_cmp_type = viml_helpers.conv_cmp_type
local pstate_set_str = viml_helpers.pstate_set_str
local conv_expr_asgn_type = viml_helpers.conv_expr_asgn_type
local mergedicts_copy = global_helpers.mergedicts_copy
local format_string = global_helpers.format_string
local format_luav = global_helpers.format_luav
local intchar2lua = global_helpers.intchar2lua
local dictdiff = global_helpers.dictdiff
local lib = cimport('./src/nvim/viml/parser/expressions.h',
'./src/nvim/syntax.h')