aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZyX <kp-pav@yandex.ru>2017-03-11 16:02:47 +0300
committerZyX <kp-pav@yandex.ru>2017-03-11 23:23:49 +0300
commite2a578f40dbd4836330402a44844c7ef8a0df5c5 (patch)
treeab2b04b6d0228e7d5a4ef6d611971f063a17be17
parent9400466282918396c814ef456d0f65dca51b8889 (diff)
downloadrneovim-e2a578f40dbd4836330402a44844c7ef8a0df5c5.tar.gz
rneovim-e2a578f40dbd4836330402a44844c7ef8a0df5c5.tar.bz2
rneovim-e2a578f40dbd4836330402a44844c7ef8a0df5c5.zip
unittests: Do not import libnvim or headers in main process
Slows down unit tests much, but gets rid of as much preserved state as possible.
-rw-r--r--test/unit/api/helpers.lua79
-rw-r--r--test/unit/eval/decode_spec.lua14
-rw-r--r--test/unit/eval/helpers.lua162
-rw-r--r--test/unit/garray_spec.lua4
-rw-r--r--test/unit/helpers.lua238
-rw-r--r--test/unit/multiqueue_spec.lua12
-rw-r--r--test/unit/os/fs_spec.lua13
-rw-r--r--test/unit/os/shell_spec.lua15
-rw-r--r--test/unit/path_spec.lua21
-rw-r--r--test/unit/profile_spec.lua6
-rw-r--r--test/unit/rbuffer_spec.lua71
-rw-r--r--test/unit/tempfile_spec.lua35
12 files changed, 359 insertions, 311 deletions
diff --git a/test/unit/api/helpers.lua b/test/unit/api/helpers.lua
index 750e2f3c77..bbd5e8e4df 100644
--- a/test/unit/api/helpers.lua
+++ b/test/unit/api/helpers.lua
@@ -19,47 +19,46 @@ local api = cimport('./src/nvim/api/private/defs.h',
local obj2lua
-local obj2lua_tab = {
- [tonumber(api.kObjectTypeArray)] = function(obj)
- local ret = {[type_key]=list_type}
- for i = 1,tonumber(obj.data.array.size) do
- ret[i] = obj2lua(obj.data.array.items[i - 1])
- end
- if ret[1] then
- ret[type_key] = nil
- end
- return ret
- end,
- [tonumber(api.kObjectTypeDictionary)] = function(obj)
- local ret = {}
- for i = 1,tonumber(obj.data.dictionary.size) do
- local kv_pair = obj.data.dictionary.items[i - 1]
- ret[ffi.string(kv_pair.key.data, kv_pair.key.size)] = obj2lua(kv_pair.value)
- end
- return ret
- end,
- [tonumber(api.kObjectTypeBoolean)] = function(obj)
- if obj.data.boolean == false then
- return false
- else
- return true
- end
- end,
- [tonumber(api.kObjectTypeNil)] = function(_)
- return nil_value
- end,
- [tonumber(api.kObjectTypeFloat)] = function(obj)
- return tonumber(obj.data.floating)
- end,
- [tonumber(api.kObjectTypeInteger)] = function(obj)
- return {[type_key]=int_type, value=tonumber(obj.data.integer)}
- end,
- [tonumber(api.kObjectTypeString)] = function(obj)
- return ffi.string(obj.data.string.data, obj.data.string.size)
- end,
-}
-
obj2lua = function(obj)
+ local obj2lua_tab = {
+ [tonumber(api.kObjectTypeArray)] = function(obj)
+ local ret = {[type_key]=list_type}
+ for i = 1,tonumber(obj.data.array.size) do
+ ret[i] = obj2lua(obj.data.array.items[i - 1])
+ end
+ if ret[1] then
+ ret[type_key] = nil
+ end
+ return ret
+ end,
+ [tonumber(api.kObjectTypeDictionary)] = function(obj)
+ local ret = {}
+ for i = 1,tonumber(obj.data.dictionary.size) do
+ local kv_pair = obj.data.dictionary.items[i - 1]
+ ret[ffi.string(kv_pair.key.data, kv_pair.key.size)] = obj2lua(kv_pair.value)
+ end
+ return ret
+ end,
+ [tonumber(api.kObjectTypeBoolean)] = function(obj)
+ if obj.data.boolean == false then
+ return false
+ else
+ return true
+ end
+ end,
+ [tonumber(api.kObjectTypeNil)] = function(_)
+ return nil_value
+ end,
+ [tonumber(api.kObjectTypeFloat)] = function(obj)
+ return tonumber(obj.data.floating)
+ end,
+ [tonumber(api.kObjectTypeInteger)] = function(obj)
+ return {[type_key]=int_type, value=tonumber(obj.data.integer)}
+ end,
+ [tonumber(api.kObjectTypeString)] = function(obj)
+ return ffi.string(obj.data.string.data, obj.data.string.size)
+ end,
+ }
return ((obj2lua_tab[tonumber(obj['type'])] or function(obj_inner)
assert(false, 'Converting ' .. tostring(tonumber(obj_inner['type'])) .. ' is not implementing yet')
end)(obj))
diff --git a/test/unit/eval/decode_spec.lua b/test/unit/eval/decode_spec.lua
index a32ecf8ed0..fc38feb084 100644
--- a/test/unit/eval/decode_spec.lua
+++ b/test/unit/eval/decode_spec.lua
@@ -12,20 +12,6 @@ local decode = cimport('./src/nvim/eval/decode.h', './src/nvim/eval_defs.h',
'./src/nvim/message.h')
describe('json_decode_string()', function()
- local saved_p_enc = nil
-
- before_each(function()
- saved_p_enc = decode.p_enc
- end)
-
- after_each(function()
- decode.emsg_silent = 0
- decode.p_enc = saved_p_enc
- while decode.delete_first_msg() == 1 do
- -- Delete all messages
- end
- end)
-
local char = function(c)
return ffi.gc(decode.xmemdup(c, 1), decode.xfree)
end
diff --git a/test/unit/eval/helpers.lua b/test/unit/eval/helpers.lua
index ee9b423eb6..1377d5b501 100644
--- a/test/unit/eval/helpers.lua
+++ b/test/unit/eval/helpers.lua
@@ -46,12 +46,6 @@ local function list(...)
return ret
end
-local special_tab = {
- [eval.kSpecialVarFalse] = false,
- [eval.kSpecialVarNull] = nil_value,
- [eval.kSpecialVarTrue] = true,
-}
-
local ptr2key = function(ptr)
return tostring(ptr)
end
@@ -60,64 +54,74 @@ local lst2tbl
local dct2tbl
local typvalt2lua
-local typvalt2lua_tab
+local typvalt2lua_tab = nil
-typvalt2lua_tab = {
- [tonumber(eval.VAR_SPECIAL)] = function(t)
- return special_tab[t.vval.v_special]
- end,
- [tonumber(eval.VAR_NUMBER)] = function(t)
- return {[type_key]=int_type, value=tonumber(t.vval.v_number)}
- end,
- [tonumber(eval.VAR_FLOAT)] = function(t)
- return tonumber(t.vval.v_float)
- end,
- [tonumber(eval.VAR_STRING)] = function(t)
- local str = t.vval.v_string
- if str == nil then
- return null_string
- else
- return ffi.string(str)
- end
- end,
- [tonumber(eval.VAR_LIST)] = function(t, processed)
- return lst2tbl(t.vval.v_list, processed)
- end,
- [tonumber(eval.VAR_DICT)] = function(t, processed)
- return dct2tbl(t.vval.v_dict, processed)
- end,
- [tonumber(eval.VAR_FUNC)] = function(t, processed)
- return {[type_key]=func_type, value=typvalt2lua_tab[eval.VAR_STRING](t, processed or {})}
- end,
- [tonumber(eval.VAR_PARTIAL)] = function(t, processed)
- local p_key = ptr2key(t)
- if processed[p_key] then
- return processed[p_key]
- end
- local pt = t.vval.v_partial
- local value, auto, dict, argv = nil, nil, nil, nil
- if pt ~= nil then
- value = ffi.string(pt.pt_name)
- auto = pt.pt_auto and true or nil
- argv = {}
- for i = 1, pt.pt_argc do
- argv[i] = typvalt2lua(pt.pt_argv[i - 1], processed)
+local function typvalt2lua_tab_init()
+ if typvalt2lua_tab then
+ return
+ end
+ typvalt2lua_tab = {
+ [tonumber(eval.VAR_SPECIAL)] = function(t)
+ return ({
+ [eval.kSpecialVarFalse] = false,
+ [eval.kSpecialVarNull] = nil_value,
+ [eval.kSpecialVarTrue] = true,
+ })[t.vval.v_special]
+ end,
+ [tonumber(eval.VAR_NUMBER)] = function(t)
+ return {[type_key]=int_type, value=tonumber(t.vval.v_number)}
+ end,
+ [tonumber(eval.VAR_FLOAT)] = function(t)
+ return tonumber(t.vval.v_float)
+ end,
+ [tonumber(eval.VAR_STRING)] = function(t)
+ local str = t.vval.v_string
+ if str == nil then
+ return null_string
+ else
+ return ffi.string(str)
end
- if pt.pt_dict ~= nil then
- dict = dct2tbl(pt.pt_dict)
+ end,
+ [tonumber(eval.VAR_LIST)] = function(t, processed)
+ return lst2tbl(t.vval.v_list, processed)
+ end,
+ [tonumber(eval.VAR_DICT)] = function(t, processed)
+ return dct2tbl(t.vval.v_dict, processed)
+ end,
+ [tonumber(eval.VAR_FUNC)] = function(t, processed)
+ return {[type_key]=func_type, value=typvalt2lua_tab[eval.VAR_STRING](t, processed or {})}
+ end,
+ [tonumber(eval.VAR_PARTIAL)] = function(t, processed)
+ local p_key = ptr2key(t)
+ if processed[p_key] then
+ return processed[p_key]
end
- end
- return {
- [type_key]=func_type,
- value=value,
- auto=auto,
- args=argv,
- dict=dict,
- }
- end,
-}
+ local pt = t.vval.v_partial
+ local value, auto, dict, argv = nil, nil, nil, nil
+ if pt ~= nil then
+ value = ffi.string(pt.pt_name)
+ auto = pt.pt_auto and true or nil
+ argv = {}
+ for i = 1, pt.pt_argc do
+ argv[i] = typvalt2lua(pt.pt_argv[i - 1], processed)
+ end
+ if pt.pt_dict ~= nil then
+ dict = dct2tbl(pt.pt_dict)
+ end
+ end
+ return {
+ [type_key]=func_type,
+ value=value,
+ auto=auto,
+ args=argv,
+ dict=dict,
+ }
+ end,
+ }
+end
typvalt2lua = function(t, processed)
+ typvalt2lua_tab_init()
return ((typvalt2lua_tab[tonumber(t.v_type)] or function(t_inner)
assert(false, 'Converting ' .. tonumber(t_inner.v_type) .. ' was not implemented yet')
end)(t, processed or {}))
@@ -169,9 +173,10 @@ lst2tbl = function(l, processed)
return ret
end
-local hi_key_removed = eval._hash_key_removed()
+local hi_key_removed = nil
local function dict_iter(d, return_hi)
+ hi_key_removed = hi_key_removed or eval._hash_key_removed()
local init_s = {
todo=d.dv_hashtab.ht_used,
hi=d.dv_hashtab.ht_array,
@@ -320,25 +325,28 @@ local lua2typvalt_type_tab = {
end,
}
-local special_vals = {
- [null_string] = {eval.VAR_STRING, {v_string=ffi.cast('char_u*', nil)}},
- [null_list] = {eval.VAR_LIST, {v_list=ffi.cast('list_T*', nil)}},
- [null_dict] = {eval.VAR_DICT, {v_dict=ffi.cast('dict_T*', nil)}},
- [nil_value] = {eval.VAR_SPECIAL, {v_special=eval.kSpecialVarNull}},
- [true] = {eval.VAR_SPECIAL, {v_special=eval.kSpecialVarTrue}},
- [false] = {eval.VAR_SPECIAL, {v_special=eval.kSpecialVarFalse}},
-}
+local special_vals = nil
-for k, v in pairs(special_vals) do
- local tmp = function(typ, vval)
- special_vals[k] = function()
- return typvalt(typ, vval)
+lua2typvalt = function(l, processed)
+ if not special_vals then
+ special_vals = {
+ [null_string] = {'VAR_STRING', {v_string=ffi.cast('char_u*', nil)}},
+ [null_list] = {'VAR_LIST', {v_list=ffi.cast('list_T*', nil)}},
+ [null_dict] = {'VAR_DICT', {v_dict=ffi.cast('dict_T*', nil)}},
+ [nil_value] = {'VAR_SPECIAL', {v_special=eval.kSpecialVarNull}},
+ [true] = {'VAR_SPECIAL', {v_special=eval.kSpecialVarTrue}},
+ [false] = {'VAR_SPECIAL', {v_special=eval.kSpecialVarFalse}},
+ }
+
+ for k, v in pairs(special_vals) do
+ local tmp = function(typ, vval)
+ special_vals[k] = function()
+ return typvalt(eval[typ], vval)
+ end
+ end
+ tmp(v[1], v[2])
end
end
- tmp(v[1], v[2])
-end
-
-lua2typvalt = function(l, processed)
processed = processed or {}
if l == nil or l == nil_value then
return special_vals[nil_value]()
@@ -360,7 +368,7 @@ lua2typvalt = function(l, processed)
return typvalt(eval.VAR_STRING, {v_string=eval.xmemdupz(to_cstr(l), #l)})
elseif type(l) == 'cdata' then
local tv = typvalt(eval.VAR_UNKNOWN)
- eval.tv_copy(l, tv)
+ eval.copy_tv(l, tv)
return tv
end
end
diff --git a/test/unit/garray_spec.lua b/test/unit/garray_spec.lua
index ffa0f15717..28df8a6e3f 100644
--- a/test/unit/garray_spec.lua
+++ b/test/unit/garray_spec.lua
@@ -9,7 +9,7 @@ local ffi = helpers.ffi
local to_cstr = helpers.to_cstr
local NULL = helpers.NULL
-local garray = cimport('stdlib.h', './src/nvim/garray.h')
+local garray = cimport('./src/nvim/garray.h')
local itemsize = 14
local growsize = 95
@@ -157,7 +157,7 @@ local ga_append_ints = function(garr, ...)
end
-- enhanced constructors
-local garray_ctype = ffi.typeof('garray_T[1]')
+local garray_ctype = function(...) return ffi.typeof('garray_T[1]')(...) end
local new_garray = function()
local garr = garray_ctype()
return ffi.gc(garr, ga_clear)
diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua
index b6fcc959ef..93eb01b21b 100644
--- a/test/unit/helpers.lua
+++ b/test/unit/helpers.lua
@@ -13,6 +13,7 @@ local syscall = nil
local check_cores = global_helpers.check_cores
local which = global_helpers.which
local neq = global_helpers.neq
+local map = global_helpers.map
local eq = global_helpers.eq
local ok = global_helpers.ok
@@ -22,13 +23,82 @@ local NULL = ffi.cast('void*', 0)
local OK = 1
local FAIL = 0
+local cimport
+
-- add some standard header locations
for _, p in ipairs(Paths.include_paths) do
Preprocess.add_to_include_path(p)
end
--- load neovim shared library
-local libnvim = ffi.load(Paths.test_libnvim_path)
+local pid = nil
+local function only_separate(func)
+ return function(...)
+ if pid ~= 0 then
+ eq(0, 'This function must be run in a separate process only')
+ end
+ return func(...)
+ end
+end
+local deferred_calls_init = {}
+local deferred_calls_mod = nil
+local function deferred_call(func, ret)
+ return function(...)
+ local deferred_calls = deferred_calls_mod or deferred_calls_init
+ if pid ~= 0 then
+ deferred_calls[#deferred_calls + 1] = {func=func, args={...}}
+ return ret
+ else
+ return func(...)
+ end
+ end
+end
+
+local separate_cleanups_mod = nil
+local function separate_cleanup(func)
+ return function(...)
+ local separate_cleanups = separate_cleanups_mod
+ if pid ~= 0 then
+ separate_cleanups[#separate_cleanups + 1] = {args={...}}
+ else
+ func(...)
+ end
+ end
+end
+
+local libnvim = nil
+
+local lib = setmetatable({}, {
+ __index = only_separate(function(tbl, idx)
+ return libnvim[idx]
+ end),
+ __newindex = deferred_call(function(tbl, idx, val)
+ libnvim[idx] = val
+ end),
+})
+
+local init = only_separate(function()
+ -- load neovim shared library
+ libnvim = ffi.load(Paths.test_libnvim_path)
+ for _, c in ipairs(deferred_calls_init) do
+ c.func(unpack(c.args))
+ end
+ libnvim.time_init()
+ libnvim.early_init()
+ libnvim.event_init()
+ if deferred_calls_mod then
+ for _, c in ipairs(deferred_calls_mod) do
+ c.func(unpack(c.args))
+ end
+ end
+end)
+
+local deinit = only_separate(function()
+ if separate_cleanups_mod then
+ for _, c in ipairs(separate_cleanups_mod) do
+ c.func(unpack(c.args))
+ end
+ end
+end)
local function trim(s)
return s:match('^%s*(.*%S)') or ''
@@ -58,52 +128,74 @@ local function filter_complex_blocks(body)
return table.concat(result, "\n")
end
-local previous_defines = ''
local cdef = ffi.cdef
local cimportstr
+local previous_defines_init = ''
+local preprocess_cache_init = {}
+local previous_defines_mod = ''
+local preprocess_cache_mod = nil
+
-- use this helper to import C files, you can pass multiple paths at once,
-- this helper will return the C namespace of the nvim library.
-local function cimport(...)
- local paths = {}
- local args = {...}
-
- -- filter out paths we've already imported
- for _,path in pairs(args) do
- if path ~= nil and not imported:contains(path) then
- paths[#paths + 1] = path
- end
+cimport = function(...)
+ local previous_defines, preprocess_cache
+ if preprocess_cache_mod then
+ preprocess_cache = preprocess_cache_mod
+ previous_defines = previous_defines_mod
+ else
+ preprocess_cache = preprocess_cache_init
+ previous_defines = previous_defines_init
end
-
- for _,path in pairs(paths) do
- imported:add(path)
+ for _, path in ipairs({...}) do
+ if not (path:sub(1, 1) == '/' or path:sub(1, 1) == '.'
+ or path:sub(2, 2) == ':') then
+ path = './' .. path
+ end
+ local body
+ if preprocess_cache[path] then
+ body = preprocess_cache[path]
+ else
+ body, previous_defines = Preprocess.preprocess(previous_defines, path)
+ -- format it (so that the lines are "unique" statements), also filter out
+ -- Objective-C blocks
+ if os.getenv('NVIM_TEST_PRINT_I') == '1' then
+ local lnum = 0
+ for line in body:gmatch('[^\n]+') do
+ lnum = lnum + 1
+ print(lnum, line)
+ end
+ end
+ body = formatc(body)
+ body = filter_complex_blocks(body)
+ preprocess_cache[path] = body
+ end
+ cimportstr(preprocess_cache, path)
end
+ return lib
+end
- if #paths == 0 then
- return libnvim
+local cimport_immediate = function(...)
+ local saved_pid = pid
+ pid = 0
+ local err, emsg = pcall(cimport, ...)
+ pid = saved_pid
+ if not err then
+ emsg = tostring(emsg)
+ io.stderr:write(emsg .. '\n')
+ assert(false)
+ else
+ return lib
end
-
- local body
- body, previous_defines = Preprocess.preprocess(previous_defines, unpack(paths))
-
- return cimportstr(body)
end
-cimportstr = function(body)
- -- format it (so that the lines are "unique" statements), also filter out
- -- Objective-C blocks
- if os.getenv('NVIM_TEST_PRINT_I') == '1' then
- local lnum = 0
- for line in body:gmatch('[^\n]+') do
- lnum = lnum + 1
- print(lnum, line)
- end
+cimportstr = deferred_call(function(preprocess_cache, path)
+ if imported:contains(path) then
+ return lib
end
- body = formatc(body)
- body = filter_complex_blocks(body)
-
+ local body = preprocess_cache[path]
-- add the formatted lines to a set
local new_cdefs = Set:new()
for line in body:gmatch("[^\r\n]+") do
@@ -126,7 +218,7 @@ cimportstr = function(body)
if new_cdefs:size() == 0 then
-- if there's no new lines, just return
- return libnvim
+ return lib
end
-- request a sorted version of the new lines (same relative order as the
@@ -138,13 +230,10 @@ cimportstr = function(body)
end
end
cdef(table.concat(new_lines, "\n"))
+ imported:add(path)
- return libnvim
-end
-
-local function cppimport(path)
- return cimport(Paths.test_include_path .. '/' .. path)
-end
+ return lib
+end, lib)
local function alloc_log_new()
local log = {
@@ -156,9 +245,12 @@ local function alloc_log_new()
local allocator_functions = {'malloc', 'free', 'calloc', 'realloc'}
function log:save_original_functions()
for _, funcname in ipairs(allocator_functions) do
- self.original_functions[funcname] = self.lib['mem_' .. funcname]
+ if not self.original_functions[funcname] then
+ self.original_functions[funcname] = self.lib['mem_' .. funcname]
+ end
end
end
+ log.save_original_functions = deferred_call(log.save_original_functions)
function log:set_mocks()
for _, k in ipairs(allocator_functions) do
do
@@ -185,6 +277,7 @@ local function alloc_log_new()
end
end
end
+ log.set_mocks = deferred_call(log.set_mocks)
function log:clear()
self.log = {}
end
@@ -193,22 +286,28 @@ local function alloc_log_new()
self:clear()
end
function log:restore_original_functions()
- for k, v in pairs(self.original_functions) do
- self.lib['mem_' .. k] = v
- end
+ -- Do nothing: set mocks live in a separate process
+ return
+ --[[
+ [ for k, v in pairs(self.original_functions) do
+ [ self.lib['mem_' .. k] = v
+ [ end
+ ]]
end
- function log:before_each()
+ function log:setup()
log:save_original_functions()
log:set_mocks()
end
+ function log:before_each()
+ return
+ end
function log:after_each()
log:restore_original_functions()
end
+ log:setup()
return log
end
-cimport('./src/nvim/types.h')
-
-- take a pointer to a C-allocated string and return an interned
-- version while also freeing the memory
local function internalize(cdata, len)
@@ -221,16 +320,6 @@ local function to_cstr(string)
return cstr(#string + 1, string)
end
--- initialize some global variables, this is still necessary to unit test
--- functions that rely on global state.
-do
- local main = cimport('./src/nvim/main.h')
- local time = cimport('./src/nvim/os/time.h')
- time.time_init()
- main.early_init()
- main.event_init()
-end
-
local sc
if posix ~= nil then
@@ -263,7 +352,7 @@ elseif syscall ~= nil then
exit = syscall.exit,
}
else
- cimport('./test/unit/fixtures/posix.h')
+ cimport_immediate('./test/unit/fixtures/posix.h')
sc = {
fork = function()
return tonumber(ffi.C.fork())
@@ -291,7 +380,7 @@ else
len - total_bytes_read))
if bytes_read == -1 then
local err = ffi.errno(0)
- if err ~= libnvim.kPOSIXErrnoEINTR then
+ if err ~= ffi.C.kPOSIXErrnoEINTR then
assert(false, ("read() error: %u: %s"):format(
err, ffi.string(ffi.C.strerror(err))))
end
@@ -314,7 +403,7 @@ else
#s - total_bytes_written))
if bytes_written == -1 then
local err = ffi.errno(0)
- if err ~= libnvim.kPOSIXErrnoEINTR then
+ if err ~= ffi.C.kPOSIXErrnoEINTR then
assert(false, ("write() error: %u: %s"):format(
err, ffi.string(ffi.C.strerror(err))))
end
@@ -330,12 +419,12 @@ else
wait = function(pid)
ffi.errno(0)
while true do
- local r = ffi.C.waitpid(pid, nil, libnvim.kPOSIXWaitWUNTRACED)
+ local r = ffi.C.waitpid(pid, nil, ffi.C.kPOSIXWaitWUNTRACED)
if r == -1 then
local err = ffi.errno(0)
- if err == libnvim.kPOSIXErrnoECHILD then
+ if err == ffi.C.kPOSIXErrnoECHILD then
break
- elseif err ~= libnvim.kPOSIXErrnoEINTR then
+ elseif err ~= ffi.C.kPOSIXErrnoEINTR then
assert(false, ("waitpid() error: %u: %s"):format(
err, ffi.string(ffi.C.strerror(err))))
end
@@ -371,6 +460,10 @@ if os.getenv('NVIM_TEST_PRINT_SYSCALLS') == '1' then
end
local function gen_itp(it)
+ deferred_calls_mod = {}
+ deferred_cleanups_mod = {}
+ preprocess_cache_mod = map(function(v) return v end, preprocess_cache_init)
+ previous_defines_mod = previous_defines_init
local function just_fail(_)
return false
end
@@ -386,8 +479,9 @@ local function gen_itp(it)
end
it(name, function()
local rd, wr = sc.pipe()
- local pid = sc.fork()
+ pid = sc.fork()
if pid == 0 then
+ init()
sc.close(rd)
collectgarbage('stop')
local err, emsg = pcall(func)
@@ -395,16 +489,19 @@ local function gen_itp(it)
emsg = tostring(emsg)
if not err then
sc.write(wr, ('-\n%05u\n%s'):format(#emsg, emsg))
+ deinit()
sc.close(wr)
sc.exit(1)
else
sc.write(wr, '+\n')
+ deinit()
sc.close(wr)
sc.exit(0)
end
else
sc.close(wr)
sc.wait(pid)
+ pid = nil
local function check()
local res = sc.read(rd, 2)
eq(2, #res)
@@ -433,6 +530,12 @@ local function gen_itp(it)
return itp
end
+local function cppimport(path)
+ return cimport(Paths.test_include_path .. '/' .. path)
+end
+
+cimport('./src/nvim/types.h', './src/nvim/main.h', './src/nvim/os/time.h')
+
local module = {
cimport = cimport,
cppimport = cppimport,
@@ -441,7 +544,7 @@ local module = {
eq = eq,
neq = neq,
ffi = ffi,
- lib = libnvim,
+ lib = lib,
cstr = cstr,
to_cstr = to_cstr,
NULL = NULL,
@@ -449,6 +552,9 @@ local module = {
FAIL = FAIL,
alloc_log_new = alloc_log_new,
gen_itp = gen_itp,
+ only_separate = only_separate,
+ deferred_call = deferred_call,
+ separate_cleanup = separate_cleanup,
}
return function(after_each)
if after_each then
diff --git a/test/unit/multiqueue_spec.lua b/test/unit/multiqueue_spec.lua
index b72040a396..bb90728c24 100644
--- a/test/unit/multiqueue_spec.lua
+++ b/test/unit/multiqueue_spec.lua
@@ -1,10 +1,12 @@
local helpers = require("test.unit.helpers")(after_each)
local itp = helpers.gen_itp(it)
-local ffi = helpers.ffi
-local eq = helpers.eq
+local deferred_call = helpers.deferred_call
+local cimport = helpers.cimport
+local ffi = helpers.ffi
+local eq = helpers.eq
-local multiqueue = helpers.cimport("./test/unit/fixtures/multiqueue.h")
+local multiqueue = cimport("./test/unit/fixtures/multiqueue.h")
describe("multiqueue (multi-level event-queue)", function()
local parent, child1, child2, child3
@@ -21,7 +23,7 @@ describe("multiqueue (multi-level event-queue)", function()
multiqueue.multiqueue_free(q)
end
- before_each(function()
+ before_each(deferred_call(function()
parent = multiqueue.multiqueue_new_parent(ffi.NULL, ffi.NULL)
child1 = multiqueue.multiqueue_new_child(parent)
child2 = multiqueue.multiqueue_new_child(parent)
@@ -35,7 +37,7 @@ describe("multiqueue (multi-level event-queue)", function()
put(child2, 'c2i4')
put(child3, 'c3i1')
put(child3, 'c3i2')
- end)
+ end))
itp('keeps count of added events', function()
eq(3, multiqueue.multiqueue_size(child1))
diff --git a/test/unit/os/fs_spec.lua b/test/unit/os/fs_spec.lua
index 1ef7d756dc..860ebfdbcb 100644
--- a/test/unit/os/fs_spec.lua
+++ b/test/unit/os/fs_spec.lua
@@ -16,10 +16,10 @@ local to_cstr = helpers.to_cstr
local OK = helpers.OK
local FAIL = helpers.FAIL
local NULL = helpers.NULL
+
local NODE_NORMAL = 0
local NODE_WRITABLE = 1
-cimport('unistd.h')
cimport('./src/nvim/os/shell.h')
cimport('./src/nvim/option_defs.h')
cimport('./src/nvim/main.h')
@@ -66,13 +66,10 @@ local function os_getperm(filename)
end
describe('fs function', function()
- local orig_test_file_perm
-
- setup(function()
+ before_each(function()
lfs.mkdir('unit-test-directory');
io.open('unit-test-directory/test.file', 'w').close()
- orig_test_file_perm = os_getperm('unit-test-directory/test.file')
io.open('unit-test-directory/test_2.file', 'w').close()
lfs.link('test.file', 'unit-test-directory/test_link.file', true)
@@ -84,7 +81,7 @@ describe('fs function', function()
directory, executable_name = string.match(absolute_executable, '^(.*)/(.*)$')
end)
- teardown(function()
+ after_each(function()
os.remove('unit-test-directory/test.file')
os.remove('unit-test-directory/test_2.file')
os.remove('unit-test-directory/test_link.file')
@@ -217,10 +214,6 @@ describe('fs function', function()
end)
describe('file permissions', function()
- before_each(function()
- os_setperm('unit-test-directory/test.file', orig_test_file_perm)
- end)
-
local function os_fchown(filename, user_id, group_id)
local fd = ffi.C.open(filename, 0)
local res = fs.os_fchown(fd, user_id, group_id)
diff --git a/test/unit/os/shell_spec.lua b/test/unit/os/shell_spec.lua
index de39477b19..e53a510f1f 100644
--- a/test/unit/os/shell_spec.lua
+++ b/test/unit/os/shell_spec.lua
@@ -11,6 +11,7 @@ local ffi, eq = helpers.ffi, helpers.eq
local intern = helpers.internalize
local to_cstr = helpers.to_cstr
local NULL = ffi.cast('void *', 0)
+local deferred_call = deferred_call
describe('shell functions', function()
before_each(function()
@@ -73,25 +74,13 @@ describe('shell functions', function()
eq(0, status)
end)
- it ('returns non-zero exit code', function()
+ itp('returns non-zero exit code', function()
local status = os_system('exit 2')
eq(2, status)
end)
end)
describe('shell_build_argv', function()
- local saved_opts = {}
-
- setup(function()
- saved_opts.p_sh = cimported.p_sh
- saved_opts.p_shcf = cimported.p_shcf
- end)
-
- teardown(function()
- cimported.p_sh = saved_opts.p_sh
- cimported.p_shcf = saved_opts.p_shcf
- end)
-
itp('works with NULL arguments', function()
eq({'/bin/bash'}, shell_build_argv(nil, nil))
end)
diff --git a/test/unit/path_spec.lua b/test/unit/path_spec.lua
index 9663c2c8ec..470f971e68 100644
--- a/test/unit/path_spec.lua
+++ b/test/unit/path_spec.lua
@@ -15,13 +15,6 @@ local FAIL = helpers.FAIL
cimport('string.h')
local path = cimport('./src/nvim/path.h')
--- import constants parsed by ffi
-local kEqualFiles = path.kEqualFiles
-local kDifferentFiles = path.kDifferentFiles
-local kBothFilesMissing = path.kBothFilesMissing
-local kOneFileMissing = path.kOneFileMissing
-local kEqualFileNames = path.kEqualFileNames
-
local length = 0
local buffer = nil
@@ -93,25 +86,25 @@ describe('path function', function()
end)
itp('returns kEqualFiles when passed the same file', function()
- eq(kEqualFiles, (path_full_compare(f1, f1)))
+ eq(path.kEqualFiles, (path_full_compare(f1, f1)))
end)
itp('returns kEqualFileNames when files that dont exist and have same name', function()
- eq(kEqualFileNames, (path_full_compare('null.txt', 'null.txt', true)))
+ eq(path.kEqualFileNames, (path_full_compare('null.txt', 'null.txt', true)))
end)
itp('returns kBothFilesMissing when files that dont exist', function()
- eq(kBothFilesMissing, (path_full_compare('null.txt', 'null.txt')))
+ eq(path.kBothFilesMissing, (path_full_compare('null.txt', 'null.txt')))
end)
itp('returns kDifferentFiles when passed different files', function()
- eq(kDifferentFiles, (path_full_compare(f1, f2)))
- eq(kDifferentFiles, (path_full_compare(f2, f1)))
+ eq(path.kDifferentFiles, (path_full_compare(f1, f2)))
+ eq(path.kDifferentFiles, (path_full_compare(f2, f1)))
end)
itp('returns kOneFileMissing if only one does not exist', function()
- eq(kOneFileMissing, (path_full_compare(f1, 'null.txt')))
- eq(kOneFileMissing, (path_full_compare('null.txt', f1)))
+ eq(path.kOneFileMissing, (path_full_compare(f1, 'null.txt')))
+ eq(path.kOneFileMissing, (path_full_compare('null.txt', f1)))
end)
end)
diff --git a/test/unit/profile_spec.lua b/test/unit/profile_spec.lua
index e70dfa7ba0..08e5cedbab 100644
--- a/test/unit/profile_spec.lua
+++ b/test/unit/profile_spec.lua
@@ -1,11 +1,13 @@
-local helpers = require 'test.unit.helpers'
+local helpers = require('test.unit.helpers')(after_each)
local itp = helpers.gen_itp(it)
-local prof = helpers.cimport './src/nvim/profile.h'
+local cimport = helpers.cimport
local ffi = helpers.ffi
local eq = helpers.eq
local neq = helpers.neq
+local prof = cimport('./src/nvim/profile.h')
+
local function split(inputstr, sep)
if sep == nil then
sep = "%s"
diff --git a/test/unit/rbuffer_spec.lua b/test/unit/rbuffer_spec.lua
index 90ee648e7a..9b5927cae6 100644
--- a/test/unit/rbuffer_spec.lua
+++ b/test/unit/rbuffer_spec.lua
@@ -1,10 +1,11 @@
local helpers = require("test.unit.helpers")(after_each)
local itp = helpers.gen_itp(it)
-local ffi = helpers.ffi
-local eq = helpers.eq
-local cstr = helpers.cstr
+local eq = helpers.eq
+local ffi = helpers.ffi
+local cstr = helpers.cstr
local to_cstr = helpers.to_cstr
+local deferred_call = helpers.deferred_call
local rbuffer = helpers.cimport("./test/unit/fixtures/rbuffer.h")
@@ -31,11 +32,11 @@ describe('rbuffer functions', function()
return ffi.string(rbuffer.rbuffer_get(rbuf, idx), 1)
end
- before_each(function()
+ before_each(deferred_call(function()
rbuf = ffi.gc(rbuffer.rbuffer_new(capacity), rbuffer.rbuffer_free)
-- fill the internal buffer with the character '0' to simplify inspecting
ffi.C.memset(rbuf.start_ptr, string.byte('0'), capacity)
- end)
+ end))
describe('RBUFFER_UNTIL_FULL', function()
local chunks
@@ -58,59 +59,44 @@ describe('rbuffer functions', function()
end)
describe('with partially empty buffer in one contiguous chunk', function()
- before_each(function()
- write('string')
- end)
-
itp('is called once with the empty chunk', function()
+ write('string')
collect_write_chunks()
eq({'0000000000'}, chunks)
end)
end)
describe('with filled buffer in one contiguous chunk', function()
- before_each(function()
- write('abcdefghijklmnopq')
- end)
-
itp('is not called', function()
+ write('abcdefghijklmnopq')
collect_write_chunks()
eq({}, chunks)
end)
end)
describe('with buffer partially empty in two contiguous chunks', function()
- before_each(function()
+ itp('is called twice with each filled chunk', function()
write('1234567890')
read(8)
- end)
-
- itp('is called twice with each filled chunk', function()
collect_write_chunks()
eq({'000000', '12345678'}, chunks)
end)
end)
describe('with buffer empty in two contiguous chunks', function()
- before_each(function()
+ itp('is called twice with each filled chunk', function()
write('12345678')
read(8)
- end)
-
- itp('is called twice with each filled chunk', function()
collect_write_chunks()
eq({'00000000', '12345678'}, chunks)
end)
end)
describe('with buffer filled in two contiguous chunks', function()
- before_each(function()
+ itp('is not called', function()
write('12345678')
read(8)
write('abcdefghijklmnopq')
- end)
-
- itp('is not called', function()
collect_write_chunks()
eq({}, chunks)
end)
@@ -138,48 +124,36 @@ describe('rbuffer functions', function()
end)
describe('with partially filled buffer in one contiguous chunk', function()
- before_each(function()
- write('string')
- end)
-
itp('is called once with the filled chunk', function()
+ write('string')
collect_read_chunks()
eq({'string'}, chunks)
end)
end)
describe('with filled buffer in one contiguous chunk', function()
- before_each(function()
- write('abcdefghijklmnopq')
- end)
-
itp('is called once with the filled chunk', function()
+ write('abcdefghijklmnopq')
collect_read_chunks()
eq({'abcdefghijklmnop'}, chunks)
end)
end)
describe('with buffer partially filled in two contiguous chunks', function()
- before_each(function()
+ itp('is called twice with each filled chunk', function()
write('1234567890')
read(10)
write('long string')
- end)
-
- itp('is called twice with each filled chunk', function()
collect_read_chunks()
eq({'long s', 'tring'}, chunks)
end)
end)
describe('with buffer filled in two contiguous chunks', function()
- before_each(function()
+ itp('is called twice with each filled chunk', function()
write('12345678')
read(8)
write('abcdefghijklmnopq')
- end)
-
- itp('is called twice with each filled chunk', function()
collect_read_chunks()
eq({'abcdefgh', 'ijklmnop'}, chunks)
end)
@@ -206,13 +180,10 @@ describe('rbuffer functions', function()
end)
describe('with buffer filled in two contiguous chunks', function()
- before_each(function()
+ itp('collects each character and index', function()
write('1234567890')
read(10)
write('long string')
- end)
-
- itp('collects each character and index', function()
collect_chars()
eq({{'l', 0}, {'o', 1}, {'n', 2}, {'g', 3}, {' ', 4}, {'s', 5},
{'t', 6}, {'r', 7}, {'i', 8}, {'n', 9}, {'g', 10}}, chars)
@@ -240,13 +211,10 @@ describe('rbuffer functions', function()
end)
describe('with buffer filled in two contiguous chunks', function()
- before_each(function()
+ itp('collects each character and index', function()
write('1234567890')
read(10)
write('long string')
- end)
-
- itp('collects each character and index', function()
collect_chars()
eq({{'g', 10}, {'n', 9}, {'i', 8}, {'r', 7}, {'t', 6}, {'s', 5},
{' ', 4}, {'g', 3}, {'n', 2}, {'o', 1}, {'l', 0}}, chars)
@@ -265,13 +233,10 @@ describe('rbuffer functions', function()
end
describe('with buffer filled in two contiguous chunks', function()
- before_each(function()
+ itp('compares the common longest sequence', function()
write('1234567890')
read(10)
write('long string')
- end)
-
- itp('compares the common longest sequence', function()
eq(0, cmp('long string'))
eq(0, cmp('long strin'))
eq(-1, cmp('long striM'))
diff --git a/test/unit/tempfile_spec.lua b/test/unit/tempfile_spec.lua
index f435c950e9..27bd8729f9 100644
--- a/test/unit/tempfile_spec.lua
+++ b/test/unit/tempfile_spec.lua
@@ -1,20 +1,25 @@
-local lfs = require 'lfs'
-local helpers = require 'test.unit.helpers'
+local lfs = require('lfs')
+local helpers = require('test.unit.helpers')(after_each)
local itp = helpers.gen_itp(it)
-local os = helpers.cimport './src/nvim/os/os.h'
-local tempfile = helpers.cimport './src/nvim/fileio.h'
+local eq = helpers.eq
+local neq = helpers.neq
+local cimport = helpers.cimport
+local deferred_call = helpers.deferred_call
+local separate_cleanup = helpers.separate_cleanup
+
+local lib = cimport('./src/nvim/os/os.h', './src/nvim/fileio.h')
describe('tempfile related functions', function()
- before_each(function()
- tempfile.vim_deltempdir()
- end)
- after_each(function()
- tempfile.vim_deltempdir()
+ before_each(deferred_call(function()
+ lib.vim_deltempdir()
+ end))
+ separate_cleanup(function()
+ lib.vim_deltempdir()
end)
local vim_gettempdir = function()
- return helpers.ffi.string(tempfile.vim_gettempdir())
+ return helpers.ffi.string(lib.vim_gettempdir())
end
describe('vim_gettempdir', function()
@@ -23,7 +28,7 @@ describe('tempfile related functions', function()
assert.True(dir ~= nil and dir:len() > 0)
-- os_file_is_writable returns 2 for a directory which we have rights
-- to write into.
- assert.equals(os.os_file_is_writable(helpers.to_cstr(dir)), 2)
+ eq(lib.os_file_is_writable(helpers.to_cstr(dir)), 2)
for entry in lfs.dir(dir) do
assert.True(entry == '.' or entry == '..')
end
@@ -32,25 +37,25 @@ describe('tempfile related functions', function()
itp('returns the same directory on each call', function()
local dir1 = vim_gettempdir()
local dir2 = vim_gettempdir()
- assert.equals(dir1, dir2)
+ eq(dir1, dir2)
end)
end)
describe('vim_tempname', function()
local vim_tempname = function()
- return helpers.ffi.string(tempfile.vim_tempname())
+ return helpers.ffi.string(lib.vim_tempname())
end
itp('generate name of non-existing file', function()
local file = vim_tempname()
assert.truthy(file)
- assert.False(os.os_path_exists(file))
+ assert.False(lib.os_path_exists(file))
end)
itp('generate different names on each call', function()
local fst = vim_tempname()
local snd = vim_tempname()
- assert.not_equals(fst, snd)
+ neq(fst, snd)
end)
itp('generate file name in Neovim own temp directory', function()