diff options
author | ZyX <kp-pav@yandex.ru> | 2017-03-11 16:02:47 +0300 |
---|---|---|
committer | ZyX <kp-pav@yandex.ru> | 2017-03-11 23:23:49 +0300 |
commit | e2a578f40dbd4836330402a44844c7ef8a0df5c5 (patch) | |
tree | ab2b04b6d0228e7d5a4ef6d611971f063a17be17 | |
parent | 9400466282918396c814ef456d0f65dca51b8889 (diff) | |
download | rneovim-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.lua | 79 | ||||
-rw-r--r-- | test/unit/eval/decode_spec.lua | 14 | ||||
-rw-r--r-- | test/unit/eval/helpers.lua | 162 | ||||
-rw-r--r-- | test/unit/garray_spec.lua | 4 | ||||
-rw-r--r-- | test/unit/helpers.lua | 238 | ||||
-rw-r--r-- | test/unit/multiqueue_spec.lua | 12 | ||||
-rw-r--r-- | test/unit/os/fs_spec.lua | 13 | ||||
-rw-r--r-- | test/unit/os/shell_spec.lua | 15 | ||||
-rw-r--r-- | test/unit/path_spec.lua | 21 | ||||
-rw-r--r-- | test/unit/profile_spec.lua | 6 | ||||
-rw-r--r-- | test/unit/rbuffer_spec.lua | 71 | ||||
-rw-r--r-- | test/unit/tempfile_spec.lua | 35 |
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() |