aboutsummaryrefslogtreecommitdiff
path: root/test/unit
diff options
context:
space:
mode:
Diffstat (limited to 'test/unit')
-rw-r--r--test/unit/buffer_spec.lua108
-rw-r--r--test/unit/eval/decode_spec.lua142
-rw-r--r--test/unit/eval/encode_spec.lua100
-rw-r--r--test/unit/eval/helpers.lua72
-rw-r--r--test/unit/eval/tricks_spec.lua43
-rw-r--r--test/unit/fileio_spec.lua1
-rw-r--r--test/unit/formatc.lua14
-rw-r--r--test/unit/garray_spec.lua19
-rw-r--r--test/unit/helpers.lua28
-rw-r--r--test/unit/mbyte_spec.lua276
-rw-r--r--test/unit/os/env_spec.lua12
-rw-r--r--test/unit/os/fs_spec.lua53
-rw-r--r--test/unit/os/shell_spec.lua77
-rw-r--r--test/unit/os/users_spec.lua8
-rw-r--r--test/unit/path_spec.lua80
-rw-r--r--test/unit/preprocess.lua4
-rw-r--r--test/unit/profile_spec.lua26
-rw-r--r--test/unit/set.lua2
-rw-r--r--test/unit/strings_spec.lua68
-rw-r--r--test/unit/tempfile_spec.lua5
20 files changed, 988 insertions, 150 deletions
diff --git a/test/unit/buffer_spec.lua b/test/unit/buffer_spec.lua
index e0e2b827e9..b7f82064d7 100644
--- a/test/unit/buffer_spec.lua
+++ b/test/unit/buffer_spec.lua
@@ -1,11 +1,14 @@
+
+local assert = require("luassert")
local helpers = require("test.unit.helpers")
local to_cstr = helpers.to_cstr
local eq = helpers.eq
+local neq = helpers.neq
+local NULL = helpers.NULL
+local globals = helpers.cimport("./src/nvim/globals.h")
local buffer = helpers.cimport("./src/nvim/buffer.h")
-local window = helpers.cimport("./src/nvim/window.h")
-local option = helpers.cimport("./src/nvim/option.h")
describe('buffer functions', function()
@@ -38,13 +41,13 @@ describe('buffer functions', function()
describe('buf_valid', function()
it('should view NULL as an invalid buffer', function()
- eq(0, buffer.buf_valid(NULL))
+ eq(false, buffer.buf_valid(NULL))
end)
it('should view an open buffer as valid', function()
local buf = buflist_new(path1, buffer.BLN_LISTED)
- eq(1, buffer.buf_valid(buf))
+ eq(true, buffer.buf_valid(buf))
end)
it('should view a closed and hidden buffer as valid', function()
@@ -52,7 +55,7 @@ describe('buffer functions', function()
close_buffer(NULL, buf, 0, 0)
- eq(1, buffer.buf_valid(buf))
+ eq(true, buffer.buf_valid(buf))
end)
it('should view a closed and unloaded buffer as valid', function()
@@ -60,7 +63,7 @@ describe('buffer functions', function()
close_buffer(NULL, buf, buffer.DOBUF_UNLOAD, 0)
- eq(1, buffer.buf_valid(buf))
+ eq(true, buffer.buf_valid(buf))
end)
it('should view a closed and wiped buffer as invalid', function()
@@ -68,7 +71,7 @@ describe('buffer functions', function()
close_buffer(NULL, buf, buffer.DOBUF_WIPE, 0)
- eq(0, buffer.buf_valid(buf))
+ eq(false, buffer.buf_valid(buf))
end)
end)
@@ -206,4 +209,95 @@ describe('buffer functions', function()
close_buffer(NULL, buf2, buffer.DOBUF_WIPE, 0)
end)
end)
+
+ describe('build_stl_str_hl', function()
+
+ local output_buffer = to_cstr(string.rep(" ", 100))
+
+ local build_stl_str_hl = function(pat)
+ return buffer.build_stl_str_hl(globals.curwin,
+ output_buffer,
+ 100,
+ to_cstr(pat),
+ false,
+ 32,
+ 80,
+ NULL,
+ NULL)
+ end
+
+ it('should copy plain text', function()
+ local width = build_stl_str_hl("this is a test")
+
+ eq(14, width)
+ eq("this is a test", helpers.ffi.string(output_buffer, width))
+
+ end)
+
+ it('should print no file name', function()
+ local width = build_stl_str_hl("%f")
+
+ eq(9, width)
+ eq("[No Name]", helpers.ffi.string(output_buffer, width))
+
+ end)
+
+ it('should print the relative file name', function()
+ buffer.setfname(globals.curbuf, to_cstr("Makefile"), NULL, 1)
+ local width = build_stl_str_hl("%f")
+
+ eq(8, width)
+ eq("Makefile", helpers.ffi.string(output_buffer, width))
+
+ end)
+
+ it('should print the full file name', function()
+ buffer.setfname(globals.curbuf, to_cstr("Makefile"), NULL, 1)
+
+ local width = build_stl_str_hl("%F")
+
+ assert.is_true(8 < width)
+ neq(NULL, string.find(helpers.ffi.string(output_buffer, width), "Makefile"))
+
+ end)
+
+ it('should print the tail file name', function()
+ buffer.setfname(globals.curbuf, to_cstr("src/nvim/buffer.c"), NULL, 1)
+
+ local width = build_stl_str_hl("%t")
+
+ eq(8, width)
+ eq("buffer.c", helpers.ffi.string(output_buffer, width))
+
+ end)
+
+ it('should print the buffer number', function()
+ buffer.setfname(globals.curbuf, to_cstr("src/nvim/buffer.c"), NULL, 1)
+
+ local width = build_stl_str_hl("%n")
+
+ eq(1, width)
+ eq("1", helpers.ffi.string(output_buffer, width))
+ end)
+
+ it('should print the current line number in the buffer', function()
+ buffer.setfname(globals.curbuf, to_cstr("test/unit/buffer_spec.lua"), NULL, 1)
+
+ local width = build_stl_str_hl("%l")
+
+ eq(1, width)
+ eq("0", helpers.ffi.string(output_buffer, width))
+
+ end)
+
+ it('should print the number of lines in the buffer', function()
+ buffer.setfname(globals.curbuf, to_cstr("test/unit/buffer_spec.lua"), NULL, 1)
+
+ local width = build_stl_str_hl("%L")
+
+ eq(1, width)
+ eq("1", helpers.ffi.string(output_buffer, width))
+
+ end)
+ end)
end)
diff --git a/test/unit/eval/decode_spec.lua b/test/unit/eval/decode_spec.lua
new file mode 100644
index 0000000000..d94d809c14
--- /dev/null
+++ b/test/unit/eval/decode_spec.lua
@@ -0,0 +1,142 @@
+local helpers = require('test.unit.helpers')
+
+local cimport = helpers.cimport
+local to_cstr = helpers.to_cstr
+local eq = helpers.eq
+local neq = helpers.neq
+local ffi = helpers.ffi
+
+local decode = cimport('./src/nvim/eval/decode.h', './src/nvim/eval_defs.h',
+ './src/nvim/globals.h', './src/nvim/memory.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
+
+ it('does not overflow when running with `n…`, `t…`, `f…`', function()
+ local rettv = ffi.new('typval_T', {v_type=decode.VAR_UNKNOWN})
+ decode.emsg_silent = 1
+ -- This will not crash, but if `len` argument will be ignored it will parse
+ -- `null` as `null` and if not it will parse `null` as `n`.
+ eq(0, decode.json_decode_string('null', 1, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ eq(0, decode.json_decode_string('true', 1, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ eq(0, decode.json_decode_string('false', 1, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ eq(0, decode.json_decode_string('null', 2, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ eq(0, decode.json_decode_string('true', 2, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ eq(0, decode.json_decode_string('false', 2, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ eq(0, decode.json_decode_string('null', 3, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ eq(0, decode.json_decode_string('true', 3, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ eq(0, decode.json_decode_string('false', 3, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ eq(0, decode.json_decode_string('false', 4, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ end)
+
+ it('does not overflow and crash when running with `n`, `t`, `f`', function()
+ local rettv = ffi.new('typval_T', {v_type=decode.VAR_UNKNOWN})
+ decode.emsg_silent = 1
+ eq(0, decode.json_decode_string(char('n'), 1, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ eq(0, decode.json_decode_string(char('t'), 1, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ eq(0, decode.json_decode_string(char('f'), 1, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ end)
+
+ it('does not overflow when running with `"…`', function()
+ local rettv = ffi.new('typval_T', {v_type=decode.VAR_UNKNOWN})
+ decode.emsg_silent = 1
+ eq(0, decode.json_decode_string('"t"', 2, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ eq(0, decode.json_decode_string('""', 1, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ end)
+
+ local check_failure = function(s, len, msg)
+ local rettv = ffi.new('typval_T', {v_type=decode.VAR_UNKNOWN})
+ eq(0, decode.json_decode_string(s, len, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ neq(nil, decode.last_msg_hist)
+ eq(msg, ffi.string(decode.last_msg_hist.msg))
+ end
+
+ it('does not overflow in error messages', function()
+ check_failure(']test', 1, 'E474: No container to close: ]')
+ check_failure('[}test', 2, 'E474: Closing list with curly bracket: }')
+ check_failure('{]test', 2,
+ 'E474: Closing dictionary with square bracket: ]')
+ check_failure('[1,]test', 4, 'E474: Trailing comma: ]')
+ check_failure('{"1":}test', 6, 'E474: Expected value after colon: }')
+ check_failure('{"1"}test', 5, 'E474: Expected value: }')
+ check_failure(',test', 1, 'E474: Comma not inside container: ,')
+ check_failure('[1,,1]test', 6, 'E474: Duplicate comma: ,1]')
+ check_failure('{"1":,}test', 7, 'E474: Comma after colon: ,}')
+ check_failure('{"1",}test', 6, 'E474: Using comma in place of colon: ,}')
+ check_failure('{,}test', 3, 'E474: Leading comma: ,}')
+ check_failure('[,]test', 3, 'E474: Leading comma: ,]')
+ check_failure(':test', 1, 'E474: Colon not inside container: :')
+ check_failure('[:]test', 3, 'E474: Using colon not in dictionary: :]')
+ check_failure('{:}test', 3, 'E474: Unexpected colon: :}')
+ check_failure('{"1"::1}test', 8, 'E474: Duplicate colon: :1}')
+ check_failure('ntest', 1, 'E474: Expected null: n')
+ check_failure('ttest', 1, 'E474: Expected true: t')
+ check_failure('ftest', 1, 'E474: Expected false: f')
+ check_failure('"\\test', 2, 'E474: Unfinished escape sequence: "\\')
+ check_failure('"\\u"test', 4,
+ 'E474: Unfinished unicode escape sequence: "\\u"')
+ check_failure('"\\uXXXX"est', 8,
+ 'E474: Expected four hex digits after \\u: \\uXXXX"')
+ check_failure('"\\?"test', 4, 'E474: Unknown escape sequence: \\?"')
+ check_failure(
+ '"\t"test', 3,
+ 'E474: ASCII control characters cannot be present inside string: \t"')
+ check_failure('"\194"test', 3, 'E474: Only UTF-8 strings allowed: \194"')
+ check_failure('"\252\144\128\128\128\128"test', 8, 'E474: Only UTF-8 code points up to U+10FFFF are allowed to appear unescaped: \252\144\128\128\128\128"')
+ check_failure('"test', 1, 'E474: Expected string end: "')
+ decode.p_enc = to_cstr('latin1')
+ check_failure('"\\uABCD"test', 8,
+ 'E474: Failed to convert string "ꯍ" from UTF-8')
+ decode.p_enc = saved_p_enc
+ check_failure('-test', 1, 'E474: Missing number after minus sign: -')
+ check_failure('-1.test', 3, 'E474: Missing number after decimal dot: -1.')
+ check_failure('-1.0etest', 5, 'E474: Missing exponent: -1.0e')
+ check_failure('?test', 1, 'E474: Unidentified byte: ?')
+ check_failure('1?test', 2, 'E474: Trailing characters: ?')
+ check_failure('[1test', 2, 'E474: Unexpected end of input: [1')
+ end)
+
+ it('does not overflow with `-`', function()
+ check_failure('-0', 1, 'E474: Missing number after minus sign: -')
+ end)
+
+ it('does not overflow and crash when running with `"`', function()
+ local rettv = ffi.new('typval_T', {v_type=decode.VAR_UNKNOWN})
+ decode.emsg_silent = 1
+ eq(0, decode.json_decode_string(char('"'), 1, rettv))
+ eq(decode.VAR_UNKNOWN, rettv.v_type)
+ end)
+end)
diff --git a/test/unit/eval/encode_spec.lua b/test/unit/eval/encode_spec.lua
new file mode 100644
index 0000000000..f151a191fb
--- /dev/null
+++ b/test/unit/eval/encode_spec.lua
@@ -0,0 +1,100 @@
+local helpers = require('test.unit.helpers')
+local eval_helpers = require('test.unit.eval.helpers')
+
+local cimport = helpers.cimport
+local to_cstr = helpers.to_cstr
+local eq = helpers.eq
+
+local list = eval_helpers.list
+local lst2tbl = eval_helpers.lst2tbl
+local type_key = eval_helpers.type_key
+local list_type = eval_helpers.list_type
+local null_string = eval_helpers.null_string
+
+local encode = cimport('./src/nvim/eval/encode.h')
+
+describe('encode_list_write()', function()
+ local encode_list_write = function(l, s)
+ return encode.encode_list_write(l, to_cstr(s), #s)
+ end
+
+ it('writes empty string', function()
+ local l = list()
+ eq(0, encode_list_write(l, ''))
+ eq({[type_key]=list_type}, lst2tbl(l))
+ end)
+
+ it('writes ASCII string literal with printable characters', function()
+ local l = list()
+ eq(0, encode_list_write(l, 'abc'))
+ eq({[type_key]=list_type, 'abc'}, lst2tbl(l))
+ end)
+
+ it('writes string starting with NL', function()
+ local l = list()
+ eq(0, encode_list_write(l, '\nabc'))
+ eq({[type_key]=list_type, null_string, 'abc'}, lst2tbl(l))
+ end)
+
+ it('writes string starting with NL twice', function()
+ local l = list()
+ eq(0, encode_list_write(l, '\nabc'))
+ eq({[type_key]=list_type, null_string, 'abc'}, lst2tbl(l))
+ eq(0, encode_list_write(l, '\nabc'))
+ eq({[type_key]=list_type, null_string, 'abc', 'abc'}, lst2tbl(l))
+ end)
+
+ it('writes string ending with NL', function()
+ local l = list()
+ eq(0, encode_list_write(l, 'abc\n'))
+ eq({[type_key]=list_type, 'abc', null_string}, lst2tbl(l))
+ end)
+
+ it('writes string ending with NL twice', function()
+ local l = list()
+ eq(0, encode_list_write(l, 'abc\n'))
+ eq({[type_key]=list_type, 'abc', null_string}, lst2tbl(l))
+ eq(0, encode_list_write(l, 'abc\n'))
+ eq({[type_key]=list_type, 'abc', 'abc', null_string}, lst2tbl(l))
+ end)
+
+ it('writes string starting, ending and containing NL twice', function()
+ local l = list()
+ eq(0, encode_list_write(l, '\na\nb\n'))
+ eq({[type_key]=list_type, null_string, 'a', 'b', null_string}, lst2tbl(l))
+ eq(0, encode_list_write(l, '\na\nb\n'))
+ eq({[type_key]=list_type, null_string, 'a', 'b', null_string, 'a', 'b', null_string}, lst2tbl(l))
+ end)
+
+ it('writes string starting, ending and containing NUL with NL between twice', function()
+ local l = list()
+ eq(0, encode_list_write(l, '\0\n\0\n\0'))
+ eq({[type_key]=list_type, '\n', '\n', '\n'}, lst2tbl(l))
+ eq(0, encode_list_write(l, '\0\n\0\n\0'))
+ eq({[type_key]=list_type, '\n', '\n', '\n\n', '\n', '\n'}, lst2tbl(l))
+ end)
+
+ it('writes string starting, ending and containing NL with NUL between twice', function()
+ local l = list()
+ eq(0, encode_list_write(l, '\n\0\n\0\n'))
+ eq({[type_key]=list_type, null_string, '\n', '\n', null_string}, lst2tbl(l))
+ eq(0, encode_list_write(l, '\n\0\n\0\n'))
+ eq({[type_key]=list_type, null_string, '\n', '\n', null_string, '\n', '\n', null_string}, lst2tbl(l))
+ end)
+
+ it('writes string containing a single NL twice', function()
+ local l = list()
+ eq(0, encode_list_write(l, '\n'))
+ eq({[type_key]=list_type, null_string, null_string}, lst2tbl(l))
+ eq(0, encode_list_write(l, '\n'))
+ eq({[type_key]=list_type, null_string, null_string, null_string}, lst2tbl(l))
+ end)
+
+ it('writes string containing a few NLs twice', function()
+ local l = list()
+ eq(0, encode_list_write(l, '\n\n\n'))
+ eq({[type_key]=list_type, null_string, null_string, null_string, null_string}, lst2tbl(l))
+ eq(0, encode_list_write(l, '\n\n\n'))
+ eq({[type_key]=list_type, null_string, null_string, null_string, null_string, null_string, null_string, null_string}, lst2tbl(l))
+ end)
+end)
diff --git a/test/unit/eval/helpers.lua b/test/unit/eval/helpers.lua
new file mode 100644
index 0000000000..2367f03e0d
--- /dev/null
+++ b/test/unit/eval/helpers.lua
@@ -0,0 +1,72 @@
+local helpers = require('test.unit.helpers')
+
+local cimport = helpers.cimport
+local to_cstr = helpers.to_cstr
+local ffi = helpers.ffi
+local eq = helpers.eq
+
+local eval = cimport('./src/nvim/eval.h', './src/nvim/eval_defs.h')
+
+local null_string = {[true]='NULL string'}
+local null_list = {[true]='NULL list'}
+local type_key = {[true]='type key'}
+local list_type = {[true]='list type'}
+
+local function list(...)
+ local ret = ffi.gc(eval.list_alloc(), eval.list_unref)
+ eq(0, ret.lv_refcount)
+ ret.lv_refcount = 1
+ for i = 1, select('#', ...) do
+ local val = select(i, ...)
+ local typ = type(val)
+ if typ == 'string' then
+ eval.list_append_string(ret, to_cstr(val))
+ elseif typ == 'table' and val == null_string then
+ eval.list_append_string(ret, nil)
+ elseif typ == 'table' and val == null_list then
+ eval.list_append_list(ret, nil)
+ elseif typ == 'table' and val[type_key] == list_type then
+ local itemlist = ffi.gc(list(table.unpack(val)), nil)
+ eq(1, itemlist.lv_refcount)
+ itemlist.lv_refcount = 0
+ eval.list_append_list(ret, itemlist)
+ else
+ assert(false, 'Not implemented yet')
+ end
+ end
+ return ret
+end
+
+local lst2tbl = function(l)
+ local ret = {[type_key]=list_type}
+ if l == nil then
+ return ret
+ end
+ local li = l.lv_first
+ -- (listitem_T *) NULL is equal to nil, but yet it is not false.
+ while li ~= nil do
+ local typ = li.li_tv.v_type
+ if typ == eval.VAR_STRING then
+ local str = li.li_tv.vval.v_string
+ if str == nil then
+ ret[#ret + 1] = null_string
+ else
+ ret[#ret + 1] = ffi.string(str)
+ end
+ else
+ assert(false, 'Not implemented yet')
+ end
+ li = li.li_next
+ end
+ return ret
+end
+
+return {
+ null_string=null_string,
+ null_list=null_list,
+ list_type=list_type,
+ type_key=type_key,
+
+ list=list,
+ lst2tbl=lst2tbl,
+}
diff --git a/test/unit/eval/tricks_spec.lua b/test/unit/eval/tricks_spec.lua
new file mode 100644
index 0000000000..4c5184995c
--- /dev/null
+++ b/test/unit/eval/tricks_spec.lua
@@ -0,0 +1,43 @@
+local helpers = require('test.unit.helpers')
+
+local cimport = helpers.cimport
+local to_cstr = helpers.to_cstr
+local ffi = helpers.ffi
+local eq = helpers.eq
+
+local eval = cimport('./src/nvim/eval.h', './src/nvim/memory.h')
+
+local eval_expr = function(expr)
+ return ffi.gc(eval.eval_expr(to_cstr(expr), nil), function(tv)
+ eval.clear_tv(tv)
+ eval.xfree(tv)
+ end)
+end
+
+describe('NULL typval_T', function()
+ it('is produced by $XXX_UNEXISTENT_VAR_XXX', function()
+ -- Required for various tests which need to check whether typval_T with NULL
+ -- string works correctly. This test checks that unexistent environment
+ -- variable produces NULL string, not that some specific environment
+ -- variable does not exist. Last bit is left for the test writers.
+ local unexistent_env = 'XXX_UNEXISTENT_VAR_XXX'
+ while os.getenv(unexistent_env) ~= nil do
+ unexistent_env = unexistent_env .. '_XXX'
+ end
+ local rettv = eval_expr('$' .. unexistent_env)
+ eq(eval.VAR_STRING, rettv.v_type)
+ eq(nil, rettv.vval.v_string)
+ end)
+
+ it('is produced by v:_null_list', function()
+ local rettv = eval_expr('v:_null_list')
+ eq(eval.VAR_LIST, rettv.v_type)
+ eq(nil, rettv.vval.v_list)
+ end)
+
+ it('is produced by v:_null_dict', function()
+ local rettv = eval_expr('v:_null_dict')
+ eq(eval.VAR_DICT, rettv.v_type)
+ eq(nil, rettv.vval.v_dict)
+ end)
+end)
diff --git a/test/unit/fileio_spec.lua b/test/unit/fileio_spec.lua
index 180fc3c184..3e3c36617d 100644
--- a/test/unit/fileio_spec.lua
+++ b/test/unit/fileio_spec.lua
@@ -4,6 +4,7 @@ local helpers = require("test.unit.helpers")
local eq = helpers.eq
local ffi = helpers.ffi
local to_cstr = helpers.to_cstr
+local NULL = helpers.NULL
local fileio = helpers.cimport("./src/nvim/fileio.h")
diff --git a/test/unit/formatc.lua b/test/unit/formatc.lua
index f9397eaec6..00637e0b8d 100644
--- a/test/unit/formatc.lua
+++ b/test/unit/formatc.lua
@@ -124,13 +124,13 @@ end
local function set(t)
local s = {}
- for i, v in ipairs(t) do
+ for _, v in ipairs(t) do
s[v] = true
end
return s
end
-local C_keywords = set {
+local C_keywords = set { -- luacheck: ignore
"break", "case", "char", "const", "continue", "default", "do", "double",
"else", "enum", "extern", "float", "for", "goto", "if", "int", "long",
"register", "return", "short", "signed", "sizeof", "static", "struct",
@@ -154,13 +154,13 @@ local C_keywords = set {
-- The first one will have a lot of false positives (the line '{' for
-- example), the second one is more unique.
local function formatc(str)
- local tokens = TokeniseC(str)
+ local toks = TokeniseC(str)
local result = {}
local block_level = 0
local allow_one_nl = false
local end_at_brace = false
- for i, token in ipairs(tokens) do
+ for _, token in ipairs(toks) do
local typ = token[2]
if typ == '{' then
block_level = block_level + 1
@@ -213,8 +213,8 @@ local function formatc(str)
end
-- standalone operation (very handy for debugging)
-local function standalone(...)
- Preprocess = require("preprocess")
+local function standalone(...) -- luacheck: ignore
+ local Preprocess = require("preprocess")
Preprocess.add_to_include_path('./../../src')
Preprocess.add_to_include_path('./../../build/include')
Preprocess.add_to_include_path('./../../.deps/usr/include')
@@ -238,7 +238,7 @@ local function standalone(...)
end
-- uncomment this line (and comment the `return`) for standalone debugging
-- example usage:
--- ../../.deps/usr/bin/luajit formatc.lua ../../include/tempfile.h.generated.h
+-- ../../.deps/usr/bin/luajit formatc.lua ../../include/fileio.h.generated.h
-- ../../.deps/usr/bin/luajit formatc.lua /usr/include/malloc.h
-- standalone(...)
return formatc
diff --git a/test/unit/garray_spec.lua b/test/unit/garray_spec.lua
index e779cab8a7..9694e3c427 100644
--- a/test/unit/garray_spec.lua
+++ b/test/unit/garray_spec.lua
@@ -5,8 +5,6 @@ local internalize = helpers.internalize
local eq = helpers.eq
local neq = helpers.neq
local ffi = helpers.ffi
-local lib = helpers.lib
-local cstr = helpers.cstr
local to_cstr = helpers.to_cstr
local NULL = helpers.NULL
@@ -48,7 +46,7 @@ local ga_size = function(garr)
return ga_len(garr) * ga_itemsize(garr)
end
-local ga_maxsize = function(garr)
+local ga_maxsize = function(garr) -- luacheck: ignore
return ga_maxlen(garr) * ga_itemsize(garr)
end
@@ -65,8 +63,8 @@ local ga_data_as_ints = function(garr)
end
-- garray manipulation
-local ga_init = function(garr, itemsize, growsize)
- return garray.ga_init(garr, itemsize, growsize)
+local ga_init = function(garr, itemsize_, growsize_)
+ return garray.ga_init(garr, itemsize_, growsize_)
end
local ga_clear = function(garr)
@@ -113,7 +111,7 @@ local ga_set_len = function(garr, len)
end
local ga_inc_len = function(garr, by)
- return ga_set_len(garr, ga_len(garr) + 1)
+ return ga_set_len(garr, ga_len(garr) + by)
end
-- custom append functions
@@ -197,10 +195,9 @@ describe('garray', function()
end)
describe('ga_grow', function()
- local new_and_grow
- function new_and_grow(itemsize, growsize, req)
+ local function new_and_grow(itemsize_, growsize_, req)
local garr = new_garray()
- ga_init(garr, itemsize, growsize)
+ ga_init(garr, itemsize_, growsize_)
eq(0, ga_size(garr)) -- should be 0 at first
eq(NULL, ga_data(garr)) -- should be NULL
ga_grow(garr, req) -- add space for `req` items
@@ -306,7 +303,7 @@ describe('garray', function()
ga_init(garr, ffi.sizeof("char"), 1)
local str = "ohwell●●"
local loop = 5
- for i = 1, loop do
+ for _ = 1, loop do
ga_concat(garr, str)
end
@@ -321,7 +318,7 @@ describe('garray', function()
end)
end)
- function test_concat_fn(input, fn, sep)
+ local function test_concat_fn(input, fn, sep)
local garr = new_string_garray()
ga_append_strings(garr, unpack(input))
if sep == nil then
diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua
index 5bcc661226..426ae2d9e0 100644
--- a/test/unit/helpers.lua
+++ b/test/unit/helpers.lua
@@ -18,17 +18,9 @@ local function trim(s)
end
-- a Set that keeps around the lines we've already seen
-if cdefs == nil then
- cdefs = Set:new()
-end
-
-if imported == nil then
- imported = Set:new()
-end
-
-if pragma_pack_id == nil then
- pragma_pack_id = 1
-end
+local cdefs = Set:new()
+local imported = Set:new()
+local pragma_pack_id = 1
-- some things are just too complex for the LuaJIT C parser to digest. We
-- usually don't need them anyway.
@@ -36,8 +28,10 @@ local function filter_complex_blocks(body)
local result = {}
for line in body:gmatch("[^\r\n]+") do
- if not (string.find(line, "(^)", 1, true) ~= nil or
- string.find(line, "_ISwupper", 1, true)) then
+ if not (string.find(line, "(^)", 1, true) ~= nil
+ or string.find(line, "_ISwupper", 1, true)
+ or string.find(line, "msgpack_zone_push_finalizer")
+ or string.find(line, "msgpack_unpacker_reserve_buffer")) then
result[#result + 1] = line
end
end
@@ -67,7 +61,7 @@ local function cimport(...)
end
local body = nil
- for i=1, 10 do
+ for _ = 1, 10 do
local stream = Preprocess.preprocess_stream(unpack(paths))
body = stream:read("*a")
stream:close()
@@ -111,6 +105,11 @@ local function cimport(...)
-- request a sorted version of the new lines (same relative order as the
-- original preprocessed file) and feed that to the LuaJIT ffi
local new_lines = new_cdefs:to_table()
+ if os.getenv('NVIM_TEST_PRINT_CDEF') == '1' then
+ for lnum, line in ipairs(new_lines) do
+ print(lnum, line)
+ end
+ end
ffi.cdef(table.concat(new_lines, "\n"))
return libnvim
@@ -141,6 +140,7 @@ do
local time = cimport('./src/nvim/os/time.h')
time.time_init()
main.early_init()
+ main.event_init()
end
-- C constants.
diff --git a/test/unit/mbyte_spec.lua b/test/unit/mbyte_spec.lua
new file mode 100644
index 0000000000..9b2415a93f
--- /dev/null
+++ b/test/unit/mbyte_spec.lua
@@ -0,0 +1,276 @@
+local helpers = require("test.unit.helpers")
+
+local ffi = helpers.ffi
+local eq = helpers.eq
+
+local mbyte = helpers.cimport("./src/nvim/mbyte.h")
+
+describe('mbyte', function()
+
+ -- Array for composing characters
+ local intp = ffi.typeof('int[?]')
+ local function to_intp()
+ -- how to get MAX_MCO from globals.h?
+ return intp(7, 1)
+ end
+
+ -- Convert from bytes to string
+ local function to_string(bytes)
+ local s = {}
+ for i = 1, #bytes do
+ s[i] = string.char(bytes[i])
+ end
+ return table.concat(s)
+ end
+
+ before_each(function()
+ end)
+
+ it('utf_ptr2char', function()
+ -- For strings with length 1 the first byte is returned.
+ for c = 0, 255 do
+ eq(c, mbyte.utf_ptr2char(to_string({c, 0})))
+ end
+
+ -- Some ill formed byte sequences that should not be recognized as UTF-8
+ -- First byte: 0xc0 or 0xc1
+ -- Second byte: 0x80 .. 0xbf
+ --eq(0x00c0, mbyte.utf_ptr2char(to_string({0xc0, 0x80})))
+ --eq(0x00c1, mbyte.utf_ptr2char(to_string({0xc1, 0xbf})))
+ --
+ -- Sequences with more than four bytes
+ end)
+
+
+ describe('utfc_ptr2char_len', function()
+
+ it('1-byte sequences', function()
+ local pcc = to_intp()
+ for c = 0, 255 do
+ eq(c, mbyte.utfc_ptr2char_len(to_string({c}), pcc, 1))
+ eq(0, pcc[0])
+ end
+ end)
+
+ it('2-byte sequences', function()
+ local pcc = to_intp()
+ -- No combining characters
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string({0x7f, 0x7f}), pcc, 2))
+ eq(0, pcc[0])
+ -- No combining characters
+ pcc = to_intp()
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string({0x7f, 0x80}), pcc, 2))
+ eq(0, pcc[0])
+
+ -- No UTF-8 sequence
+ pcc = to_intp()
+ eq(0x00c2, mbyte.utfc_ptr2char_len(to_string({0xc2, 0x7f}), pcc, 2))
+ eq(0, pcc[0])
+ -- One UTF-8 character
+ pcc = to_intp()
+ eq(0x0080, mbyte.utfc_ptr2char_len(to_string({0xc2, 0x80}), pcc, 2))
+ eq(0, pcc[0])
+ -- No UTF-8 sequence
+ pcc = to_intp()
+ eq(0x00c2, mbyte.utfc_ptr2char_len(to_string({0xc2, 0xc0}), pcc, 2))
+ eq(0, pcc[0])
+ end)
+
+ it('3-byte sequences', function()
+ local pcc = to_intp()
+
+ -- No second UTF-8 character
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string({0x7f, 0x80, 0x80}), pcc, 3))
+ eq(0, pcc[0])
+ -- No combining character
+ pcc = to_intp()
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string({0x7f, 0xc2, 0x80}), pcc, 3))
+ eq(0, pcc[0])
+
+ -- Combining character is U+0300
+ pcc = to_intp()
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string({0x7f, 0xcc, 0x80}), pcc, 3))
+ eq(0x0300, pcc[0])
+ eq(0x0000, pcc[1])
+
+ -- No UTF-8 sequence
+ pcc = to_intp()
+ eq(0x00c2, mbyte.utfc_ptr2char_len(to_string({0xc2, 0x7f, 0xcc}), pcc, 3))
+ eq(0, pcc[0])
+ -- Incomplete combining character
+ pcc = to_intp()
+ eq(0x0080, mbyte.utfc_ptr2char_len(to_string({0xc2, 0x80, 0xcc}), pcc, 3))
+ eq(0, pcc[0])
+
+ -- One UTF-8 character
+ pcc = to_intp()
+ eq(0x20d0, mbyte.utfc_ptr2char_len(to_string({0xe2, 0x83, 0x90}), pcc, 3))
+ eq(0, pcc[0])
+ end)
+
+ it('4-byte sequences', function()
+ local pcc = to_intp()
+
+ -- No following combining character
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string({0x7f, 0x7f, 0xcc, 0x80}), pcc, 4))
+ eq(0, pcc[0])
+ -- No second UTF-8 character
+ pcc = to_intp()
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string({0x7f, 0xc2, 0xcc, 0x80}), pcc, 4))
+ eq(0, pcc[0])
+
+ -- Combining character U+0300
+ pcc = to_intp()
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string({0x7f, 0xcc, 0x80, 0xcc}), pcc, 4))
+ eq(0x0300, pcc[0])
+ eq(0x0000, pcc[1])
+
+ -- No UTF-8 sequence
+ pcc = to_intp()
+ eq(0x00c2, mbyte.utfc_ptr2char_len(to_string({0xc2, 0x7f, 0xcc, 0x80}), pcc, 4))
+ eq(0, pcc[0])
+ -- No following UTF-8 character
+ pcc = to_intp()
+ eq(0x0080, mbyte.utfc_ptr2char_len(to_string({0xc2, 0x80, 0xcc, 0xcc}), pcc, 4))
+ eq(0, pcc[0])
+ -- Combining character U+0301
+ pcc = to_intp()
+ eq(0x0080, mbyte.utfc_ptr2char_len(to_string({0xc2, 0x80, 0xcc, 0x81}), pcc, 4))
+ eq(0x0301, pcc[0])
+ eq(0x0000, pcc[1])
+
+ -- One UTF-8 character
+ pcc = to_intp()
+ eq(0x100000, mbyte.utfc_ptr2char_len(to_string({0xf4, 0x80, 0x80, 0x80}), pcc, 4))
+ eq(0, pcc[0])
+ end)
+
+ it('5+-byte sequences', function()
+ local pcc = to_intp()
+
+ -- No following combining character
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string({0x7f, 0x7f, 0xcc, 0x80, 0x80}), pcc, 5))
+ eq(0, pcc[0])
+ -- No second UTF-8 character
+ pcc = to_intp()
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string({0x7f, 0xc2, 0xcc, 0x80, 0x80}), pcc, 5))
+ eq(0, pcc[0])
+
+ -- Combining character U+0300
+ pcc = to_intp()
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string({0x7f, 0xcc, 0x80, 0xcc}), pcc, 5))
+ eq(0x0300, pcc[0])
+ eq(0x0000, pcc[1])
+
+ -- Combining characters U+0300 and U+0301
+ pcc = to_intp()
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string({0x7f, 0xcc, 0x80, 0xcc, 0x81}), pcc, 5))
+ eq(0x0300, pcc[0])
+ eq(0x0301, pcc[1])
+ eq(0x0000, pcc[2])
+ -- Combining characters U+0300, U+0301, U+0302
+ pcc = to_intp()
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string({0x7f, 0xcc, 0x80, 0xcc, 0x81, 0xcc, 0x82}), pcc, 7))
+ eq(0x0300, pcc[0])
+ eq(0x0301, pcc[1])
+ eq(0x0302, pcc[2])
+ eq(0x0000, pcc[3])
+ -- Combining characters U+0300, U+0301, U+0302, U+0303
+ pcc = to_intp()
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string({0x7f, 0xcc, 0x80, 0xcc, 0x81, 0xcc, 0x82, 0xcc, 0x83}), pcc, 9))
+ eq(0x0300, pcc[0])
+ eq(0x0301, pcc[1])
+ eq(0x0302, pcc[2])
+ eq(0x0303, pcc[3])
+ eq(0x0000, pcc[4])
+ -- Combining characters U+0300, U+0301, U+0302, U+0303, U+0304
+ pcc = to_intp()
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string(
+ {0x7f, 0xcc, 0x80, 0xcc, 0x81, 0xcc, 0x82, 0xcc, 0x83, 0xcc, 0x84}), pcc, 11))
+ eq(0x0300, pcc[0])
+ eq(0x0301, pcc[1])
+ eq(0x0302, pcc[2])
+ eq(0x0303, pcc[3])
+ eq(0x0304, pcc[4])
+ eq(0x0000, pcc[5])
+ -- Combining characters U+0300, U+0301, U+0302, U+0303, U+0304,
+ -- U+0305
+ pcc = to_intp()
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string(
+ {0x7f, 0xcc, 0x80, 0xcc, 0x81, 0xcc, 0x82, 0xcc, 0x83, 0xcc, 0x84, 0xcc, 0x85}), pcc, 13))
+ eq(0x0300, pcc[0])
+ eq(0x0301, pcc[1])
+ eq(0x0302, pcc[2])
+ eq(0x0303, pcc[3])
+ eq(0x0304, pcc[4])
+ eq(0x0305, pcc[5])
+ eq(1, pcc[6])
+
+ -- Combining characters U+0300, U+0301, U+0302, U+0303, U+0304,
+ -- U+0305, U+0306, but only save six (= MAX_MCO).
+ pcc = to_intp()
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string(
+ {0x7f, 0xcc, 0x80, 0xcc, 0x81, 0xcc, 0x82, 0xcc, 0x83, 0xcc, 0x84, 0xcc, 0x85, 0xcc, 0x86}), pcc, 15))
+ eq(0x0300, pcc[0])
+ eq(0x0301, pcc[1])
+ eq(0x0302, pcc[2])
+ eq(0x0303, pcc[3])
+ eq(0x0304, pcc[4])
+ eq(0x0305, pcc[5])
+ eq(0x0001, pcc[6])
+
+ -- Only three following combining characters U+0300, U+0301, U+0302
+ pcc = to_intp()
+ eq(0x007f, mbyte.utfc_ptr2char_len(to_string(
+ {0x7f, 0xcc, 0x80, 0xcc, 0x81, 0xcc, 0x82, 0xc2, 0x80, 0xcc, 0x84, 0xcc, 0x85}), pcc, 13))
+ eq(0x0300, pcc[0])
+ eq(0x0301, pcc[1])
+ eq(0x0302, pcc[2])
+ eq(0x0000, pcc[3])
+
+
+ -- No UTF-8 sequence
+ pcc = to_intp()
+ eq(0x00c2, mbyte.utfc_ptr2char_len(to_string({0xc2, 0x7f, 0xcc, 0x80, 0x80}), pcc, 5))
+ eq(0, pcc[0])
+ -- No following UTF-8 character
+ pcc = to_intp()
+ eq(0x0080, mbyte.utfc_ptr2char_len(to_string({0xc2, 0x80, 0xcc, 0xcc, 0x80}), pcc, 5))
+ eq(0, pcc[0])
+ -- Combining character U+0301
+ pcc = to_intp()
+ eq(0x0080, mbyte.utfc_ptr2char_len(to_string({0xc2, 0x80, 0xcc, 0x81, 0x7f}), pcc, 5))
+ eq(0x0301, pcc[0])
+ eq(0x0000, pcc[1])
+ -- Combining character U+0301
+ pcc = to_intp()
+ eq(0x0080, mbyte.utfc_ptr2char_len(to_string({0xc2, 0x80, 0xcc, 0x81, 0xcc}), pcc, 5))
+ eq(0x0301, pcc[0])
+ eq(0x0000, pcc[1])
+
+ -- One UTF-8 character
+ pcc = to_intp()
+ eq(0x100000, mbyte.utfc_ptr2char_len(to_string({0xf4, 0x80, 0x80, 0x80, 0x7f}), pcc, 5))
+ eq(0, pcc[0])
+
+ -- One UTF-8 character
+ pcc = to_intp()
+ eq(0x100000, mbyte.utfc_ptr2char_len(to_string({0xf4, 0x80, 0x80, 0x80, 0x80}), pcc, 5))
+ eq(0, pcc[0])
+ -- One UTF-8 character
+ pcc = to_intp()
+ eq(0x100000, mbyte.utfc_ptr2char_len(to_string({0xf4, 0x80, 0x80, 0x80, 0xcc}), pcc, 5))
+ eq(0, pcc[0])
+
+ -- Combining characters U+1AB0 and U+0301
+ pcc = to_intp()
+ eq(0x100000, mbyte.utfc_ptr2char_len(to_string(
+ {0xf4, 0x80, 0x80, 0x80, 0xe1, 0xaa, 0xb0, 0xcc, 0x81}), pcc, 9))
+ eq(0x1ab0, pcc[0])
+ eq(0x0301, pcc[1])
+ eq(0x0000, pcc[2])
+ end)
+
+ end)
+
+end)
diff --git a/test/unit/os/env_spec.lua b/test/unit/os/env_spec.lua
index 8e18c599d9..9e00a3e8f8 100644
--- a/test/unit/os/env_spec.lua
+++ b/test/unit/os/env_spec.lua
@@ -1,11 +1,9 @@
local helpers = require('test.unit.helpers')
local cimport = helpers.cimport
-local internalize = helpers.internalize
local eq = helpers.eq
local neq = helpers.neq
local ffi = helpers.ffi
-local lib = helpers.lib
local cstr = helpers.cstr
local to_cstr = helpers.to_cstr
local NULL = helpers.NULL
@@ -15,15 +13,15 @@ require('lfs')
local env = cimport('./src/nvim/os/os.h')
describe('env function', function()
- function os_setenv(name, value, override)
+ local function os_setenv(name, value, override)
return env.os_setenv((to_cstr(name)), (to_cstr(value)), override)
end
- function os_unsetenv(name, value, override)
+ local function os_unsetenv(name, _, _)
return env.os_unsetenv((to_cstr(name)))
end
- function os_getenv(name)
+ local function os_getenv(name)
local rval = env.os_getenv((to_cstr(name)))
if rval ~= NULL then
return ffi.string(rval)
@@ -150,8 +148,8 @@ describe('env function', function()
local name = 'NEOVIM_UNIT_TEST_EXPAND_ENV_ESCN'
local value = 'NEOVIM_UNIT_TEST_EXPAND_ENV_ESCV'
os_setenv(name, value, 1)
- -- TODO(bobtwinkles) This only tests UNIX expansions. There should be a
- -- test for windows as well
+ -- TODO(bobtwinkles) This only tests Unix expansions. There should be a
+ -- test for Windows as well
local input1 = to_cstr('$NEOVIM_UNIT_TEST_EXPAND_ENV_ESCN/test')
local input2 = to_cstr('${NEOVIM_UNIT_TEST_EXPAND_ENV_ESCN}/test')
local output_buff1 = cstr(255, '')
diff --git a/test/unit/os/fs_spec.lua b/test/unit/os/fs_spec.lua
index c7a1f55b5d..71b5e7f576 100644
--- a/test/unit/os/fs_spec.lua
+++ b/test/unit/os/fs_spec.lua
@@ -1,3 +1,6 @@
+local lfs = require('lfs')
+local bit = require('bit')
+
local helpers = require('test.unit.helpers')
local cimport = helpers.cimport
@@ -6,16 +9,12 @@ local internalize = helpers.internalize
local eq = helpers.eq
local neq = helpers.neq
local ffi = helpers.ffi
-local lib = helpers.lib
local cstr = helpers.cstr
local to_cstr = helpers.to_cstr
local OK = helpers.OK
local FAIL = helpers.FAIL
local NULL = helpers.NULL
-require('lfs')
-require('bit')
-
cimport('unistd.h')
cimport('./src/nvim/os/shell.h')
cimport('./src/nvim/option_defs.h')
@@ -23,11 +22,10 @@ cimport('./src/nvim/main.h')
cimport('./src/nvim/fileio.h')
local fs = cimport('./src/nvim/os/os.h')
cppimport('sys/stat.h')
-cppimport('sys/fcntl.h')
-cppimport('sys/errno.h')
+cppimport('fcntl.h')
+cppimport('uv-errno.h')
-local len = 0
-local buf = ""
+local buffer = ""
local directory = nil
local absolute_executable = nil
local executable_name = nil
@@ -85,24 +83,26 @@ describe('fs function', function()
end)
describe('os_dirname', function()
+ local length
+
local function os_dirname(buf, len)
return fs.os_dirname(buf, len)
end
before_each(function()
- len = (string.len(lfs.currentdir())) + 1
- buf = cstr(len, '')
+ length = (string.len(lfs.currentdir())) + 1
+ buffer = cstr(length, '')
end)
it('returns OK and writes current directory into the buffer if it is large\n enough', function()
- eq(OK, (os_dirname(buf, len)))
- eq(lfs.currentdir(), (ffi.string(buf)))
+ eq(OK, (os_dirname(buffer, length)))
+ eq(lfs.currentdir(), (ffi.string(buffer)))
end)
-- What kind of other failing cases are possible?
it('returns FAIL if the buffer is too small', function()
- local buf = cstr((len - 1), '')
- eq(FAIL, (os_dirname(buf, (len - 1))))
+ local buf = cstr((length - 1), '')
+ eq(FAIL, (os_dirname(buf, (length - 1))))
end)
end)
@@ -148,7 +148,7 @@ describe('fs function', function()
local function os_can_exe(name)
local buf = ffi.new('char *[1]')
buf[0] = NULL
- local ok = fs.os_can_exe(to_cstr(name), buf)
+ local ok = fs.os_can_exe(to_cstr(name), buf, true)
-- When os_can_exe returns true, it must set the path.
-- When it returns false, the path must be NULL.
@@ -213,15 +213,6 @@ describe('fs function', function()
os_setperm('unit-test-directory/test.file', orig_test_file_perm)
end)
- local function os_getperm(filename)
- local perm = fs.os_getperm((to_cstr(filename)))
- return tonumber(perm)
- end
-
- local function os_setperm(filename, perm)
- return fs.os_setperm((to_cstr(filename)), 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)
@@ -242,8 +233,8 @@ describe('fs function', function()
end
describe('os_getperm', function()
- it('returns -1 when the given file does not exist', function()
- eq(-1, (os_getperm('non-existing-file')))
+ it('returns UV_ENOENT when the given file does not exist', function()
+ eq(ffi.C.UV_ENOENT, (os_getperm('non-existing-file')))
end)
it('returns a perm > 0 when given an existing file', function()
@@ -454,8 +445,8 @@ describe('fs function', function()
local new_file = 'test_new_file'
local existing_file = 'unit-test-directory/test_existing.file'
- it('returns -ENOENT for O_RDWR on a non-existing file', function()
- eq(-ffi.C.kENOENT, (os_open('non-existing-file', ffi.C.kO_RDWR, 0)))
+ it('returns UV_ENOENT for O_RDWR on a non-existing file', function()
+ eq(ffi.C.UV_ENOENT, (os_open('non-existing-file', ffi.C.kO_RDWR, 0)))
end)
it('returns non-negative for O_CREAT on a non-existing file', function()
@@ -468,9 +459,9 @@ describe('fs function', function()
assert.is_true(0 <= (os_open(existing_file, ffi.C.kO_CREAT, 0)))
end)
- it('returns -EEXIST for O_CREAT|O_EXCL on a existing file', function()
+ it('returns UV_EEXIST for O_CREAT|O_EXCL on a existing file', function()
assert_file_exists(existing_file)
- eq(-ffi.C.kEEXIST, (os_open(existing_file, (bit.bor(ffi.C.kO_CREAT, ffi.C.kO_EXCL)), 0)))
+ eq(ffi.C.kUV_EEXIST, (os_open(existing_file, (bit.bor(ffi.C.kO_CREAT, ffi.C.kO_EXCL)), 0)))
end)
it('sets `rwx` permissions for O_CREAT 700', function()
@@ -611,7 +602,7 @@ describe('fs function', function()
it('removes the given directory and returns 0', function()
lfs.mkdir('unit-test-directory/new-dir')
- eq(0, (os_rmdir('unit-test-directory/new-dir', mode)))
+ eq(0, os_rmdir('unit-test-directory/new-dir'))
eq(false, (os_isdir('unit-test-directory/new-dir')))
end)
end)
diff --git a/test/unit/os/shell_spec.lua b/test/unit/os/shell_spec.lua
index 20cfc17950..93103e4e8c 100644
--- a/test/unit/os/shell_spec.lua
+++ b/test/unit/os/shell_spec.lua
@@ -11,29 +11,46 @@ if allowed_os[jit.os] ~= true then
end
local helpers = require('test.unit.helpers')
-local shell = helpers.cimport(
+local cimported = helpers.cimport(
'./src/nvim/os/shell.h',
'./src/nvim/option_defs.h',
'./src/nvim/main.h',
- './src/nvim/misc1.h'
+ './src/nvim/misc1.h',
+ './src/nvim/memory.h'
)
-local ffi, eq, neq = helpers.ffi, helpers.eq, helpers.neq
+local ffi, eq = helpers.ffi, helpers.eq
local intern = helpers.internalize
local to_cstr = helpers.to_cstr
local NULL = ffi.cast('void *', 0)
describe('shell functions', function()
setup(function()
- shell.event_init()
-- os_system() can't work when the p_sh and p_shcf variables are unset
- shell.p_sh = to_cstr('/bin/bash')
- shell.p_shcf = to_cstr('-c')
+ cimported.p_sh = to_cstr('/bin/bash')
+ cimported.p_shcf = to_cstr('-c')
end)
teardown(function()
- shell.event_teardown()
+ cimported.event_teardown()
end)
+ local function shell_build_argv(cmd, extra_args)
+ local res = cimported.shell_build_argv(
+ cmd and to_cstr(cmd),
+ extra_args and to_cstr(extra_args))
+ local argc = 0
+ local ret = {}
+ -- Explicitly free everything, so if it is not in allocated memory it will
+ -- crash.
+ while res[argc] ~= nil do
+ ret[#ret + 1] = ffi.string(res[argc])
+ cimported.xfree(res[argc])
+ argc = argc + 1
+ end
+ cimported.xfree(res)
+ return ret
+ end
+
local function os_system(cmd, input)
local input_or = input and to_cstr(input) or NULL
local input_len = (input ~= nil) and string.len(input) or 0
@@ -41,8 +58,8 @@ describe('shell functions', function()
local nread = ffi.new('size_t[1]')
local argv = ffi.cast('char**',
- shell.shell_build_argv(to_cstr(cmd), nil))
- local status = shell.os_system(argv, input_or, input_len, output, nread)
+ cimported.shell_build_argv(to_cstr(cmd), nil))
+ local status = cimported.os_system(argv, input_or, input_len, output, nread)
return status, intern(output[0], nread[0])
end
@@ -70,8 +87,48 @@ describe('shell functions', function()
end)
it ('returns non-zero exit code', function()
- local status, output = os_system('exit 2')
+ 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)
+
+ it('works with NULL arguments', function()
+ eq({'/bin/bash'}, shell_build_argv(nil, nil))
+ end)
+
+ it('works with cmd', function()
+ eq({'/bin/bash', '-c', 'abc def'}, shell_build_argv('abc def', nil))
+ end)
+
+ it('works with extra_args', function()
+ eq({'/bin/bash', 'ghi jkl'}, shell_build_argv(nil, 'ghi jkl'))
+ end)
+
+ it('works with cmd and extra_args', function()
+ eq({'/bin/bash', 'ghi jkl', '-c', 'abc def'}, shell_build_argv('abc def', 'ghi jkl'))
+ end)
+
+ it('splits and unquotes &shell and &shellcmdflag', function()
+ cimported.p_sh = to_cstr('/Program" "Files/zsh -f')
+ cimported.p_shcf = to_cstr('-x -o "sh word split" "-"c')
+ eq({'/Program Files/zsh', '-f',
+ 'ghi jkl',
+ '-x', '-o', 'sh word split',
+ '-c', 'abc def'},
+ shell_build_argv('abc def', 'ghi jkl'))
+ end)
+ end)
end)
diff --git a/test/unit/os/users_spec.lua b/test/unit/os/users_spec.lua
index df5d2365c6..236481e9e7 100644
--- a/test/unit/os/users_spec.lua
+++ b/test/unit/os/users_spec.lua
@@ -1,26 +1,24 @@
local helpers = require('test.unit.helpers')
local cimport = helpers.cimport
-local internalize = helpers.internalize
local eq = helpers.eq
local ffi = helpers.ffi
local lib = helpers.lib
-local cstr = helpers.cstr
local NULL = helpers.NULL
local OK = helpers.OK
local FAIL = helpers.FAIL
local users = cimport('./src/nvim/os/os.h', 'unistd.h')
-function garray_new()
+local function garray_new()
return ffi.new('garray_T[1]')
end
-function garray_get_len(array)
+local function garray_get_len(array)
return array[0].ga_len
end
-function garray_get_item(array, index)
+local function garray_get_item(array, index)
return (ffi.cast('void **', array[0].ga_data))[index]
end
diff --git a/test/unit/path_spec.lua b/test/unit/path_spec.lua
index 239a255151..9b76834383 100644
--- a/test/unit/path_spec.lua
+++ b/test/unit/path_spec.lua
@@ -1,18 +1,16 @@
+local lfs = require('lfs')
local helpers = require('test.unit.helpers')
local cimport = helpers.cimport
-local internalize = helpers.internalize
local eq = helpers.eq
local neq = helpers.neq
local ffi = helpers.ffi
-local lib = helpers.lib
local cstr = helpers.cstr
local to_cstr = helpers.to_cstr
local NULL = helpers.NULL
local OK = helpers.OK
local FAIL = helpers.FAIL
-require('lfs')
cimport('string.h')
local path = cimport('./src/nvim/path.h')
@@ -23,7 +21,7 @@ local kBothFilesMissing = path.kBothFilesMissing
local kOneFileMissing = path.kOneFileMissing
local kEqualFileNames = path.kEqualFileNames
-local len = 0
+local length = 0
local buffer = nil
describe('path function', function()
@@ -36,19 +34,19 @@ describe('path function', function()
lfs.rmdir('unit-test-directory')
end)
- function path_full_dir_name(directory, buffer, len)
+ local function path_full_dir_name(directory, buf, len)
directory = to_cstr(directory)
- return path.path_full_dir_name(directory, buffer, len)
+ return path.path_full_dir_name(directory, buf, len)
end
before_each(function()
-- Create empty string buffer which will contain the resulting path.
- len = (string.len(lfs.currentdir())) + 22
- buffer = cstr(len, '')
+ length = string.len(lfs.currentdir()) + 22
+ buffer = cstr(length, '')
end)
it('returns the absolute directory name of a given relative one', function()
- local result = path_full_dir_name('..', buffer, len)
+ local result = path_full_dir_name('..', buffer, length)
eq(OK, result)
local old_dir = lfs.currentdir()
lfs.chdir('..')
@@ -58,23 +56,23 @@ describe('path function', function()
end)
it('returns the current directory name if the given string is empty', function()
- eq(OK, (path_full_dir_name('', buffer, len)))
+ eq(OK, (path_full_dir_name('', buffer, length)))
eq(lfs.currentdir(), (ffi.string(buffer)))
end)
it('fails if the given directory does not exist', function()
- eq(FAIL, path_full_dir_name('does_not_exist', buffer, len))
+ eq(FAIL, path_full_dir_name('does_not_exist', buffer, length))
end)
it('works with a normal relative dir', function()
- local result = path_full_dir_name('unit-test-directory', buffer, len)
+ local result = path_full_dir_name('unit-test-directory', buffer, length)
eq(lfs.currentdir() .. '/unit-test-directory', (ffi.string(buffer)))
eq(OK, result)
end)
end)
describe('path_full_compare', function()
- function path_full_compare(s1, s2, cn)
+ local function path_full_compare(s1, s2, cn)
s1 = to_cstr(s1)
s2 = to_cstr(s2)
return path.path_full_compare(s1, s2, cn or 0)
@@ -117,7 +115,7 @@ describe('path function', function()
end)
describe('path_tail', function()
- function path_tail(file)
+ local function path_tail(file)
local res = path.path_tail((to_cstr(file)))
neq(NULL, res)
return ffi.string(res)
@@ -133,7 +131,7 @@ describe('path function', function()
end)
describe('path_tail_with_sep', function()
- function path_tail_with_sep(file)
+ local function path_tail_with_sep(file)
local res = path.path_tail_with_sep((to_cstr(file)))
neq(NULL, res)
return ffi.string(res)
@@ -165,7 +163,7 @@ describe('path function', function()
-- Returns the path tail and length (out param) of the tail.
-- Does not convert the tail from C-pointer to lua string for use with
-- strcmp.
- function invocation_path_tail(invk)
+ local function invocation_path_tail(invk)
local plen = ffi.new('size_t[?]', 1)
local ptail = path.invocation_path_tail((to_cstr(invk)), plen)
neq(NULL, ptail)
@@ -178,7 +176,7 @@ describe('path function', function()
end
-- This test mimics the intended use in C.
- function compare(base, pinvk, len)
+ local function compare(base, pinvk, len)
return eq(0, (ffi.C.strncmp((to_cstr(base)), pinvk, len)))
end
@@ -207,7 +205,7 @@ describe('path function', function()
end)
it('only accepts whitespace as a terminator for the executable name', function()
- local invk, len = invocation_path_tail('exe-a+b_c[]()|#!@$%^&*')
+ local invk, _ = invocation_path_tail('exe-a+b_c[]()|#!@$%^&*')
eq('exe-a+b_c[]()|#!@$%^&*', (ffi.string(invk)))
end)
@@ -215,20 +213,20 @@ describe('path function', function()
local ptail = path.path_tail(to_cstr("a/b/c x y z"))
neq(NULL, ptail)
local tail = ffi.string(ptail)
- local invk, len = invocation_path_tail("a/b/c x y z")
+ local invk, _ = invocation_path_tail("a/b/c x y z")
eq(tail, ffi.string(invk))
end)
it('is not equivalent to path_tail when args contain a path separator', function()
local ptail = path.path_tail(to_cstr("a/b/c x y/z"))
neq(NULL, ptail)
- local invk, len = invocation_path_tail("a/b/c x y/z")
+ local invk, _ = invocation_path_tail("a/b/c x y/z")
neq((ffi.string(ptail)), (ffi.string(invk)))
end)
end)
describe('path_next_component', function()
- function path_next_component(file)
+ local function path_next_component(file)
local res = path.path_next_component((to_cstr(file)))
neq(NULL, res)
return ffi.string(res)
@@ -308,11 +306,11 @@ describe('more path function', function()
-- Since the tests are executed, they are called by an executable. We use
-- that executable for several asserts.
- absolute_executable = arg[0]
+ local absolute_executable = arg[0]
-- Split absolute_executable into a directory and the actual file name for
-- later usage.
- directory, executable_name = string.match(absolute_executable, '^(.*)/(.*)$')
+ local directory, executable_name = string.match(absolute_executable, '^(.*)/(.*)$') -- luacheck: ignore
end)
teardown(function()
@@ -321,27 +319,27 @@ describe('more path function', function()
end)
describe('vim_FullName', function()
- function vim_FullName(filename, buffer, length, force)
+ local function vim_FullName(filename, buf, len, force)
filename = to_cstr(filename)
- return path.vim_FullName(filename, buffer, length, force)
+ return path.vim_FullName(filename, buf, len, force)
end
before_each(function()
-- Create empty string buffer which will contain the resulting path.
- len = (string.len(lfs.currentdir())) + 33
- buffer = cstr(len, '')
+ length = (string.len(lfs.currentdir())) + 33
+ buffer = cstr(length, '')
end)
it('fails if given filename is NULL', function()
local force_expansion = 1
- local result = path.vim_FullName(NULL, buffer, len, force_expansion)
+ local result = path.vim_FullName(NULL, buffer, length, force_expansion)
eq(FAIL, result)
end)
it('uses the filename if the filename is a URL', function()
local force_expansion = 1
local filename = 'http://www.neovim.org'
- local result = vim_FullName(filename, buffer, len, force_expansion)
+ local result = vim_FullName(filename, buffer, length, force_expansion)
eq(filename, (ffi.string(buffer)))
eq(OK, result)
end)
@@ -349,14 +347,14 @@ describe('more path function', function()
it('fails and uses filename if given filename contains non-existing directory', function()
local force_expansion = 1
local filename = 'non_existing_dir/test.file'
- local result = vim_FullName(filename, buffer, len, force_expansion)
+ local result = vim_FullName(filename, buffer, length, force_expansion)
eq(filename, (ffi.string(buffer)))
eq(FAIL, result)
end)
it('concatenates given filename if it does not contain a slash', function()
local force_expansion = 1
- local result = vim_FullName('test.file', buffer, len, force_expansion)
+ local result = vim_FullName('test.file', buffer, length, force_expansion)
local expected = lfs.currentdir() .. '/test.file'
eq(expected, (ffi.string(buffer)))
eq(OK, result)
@@ -364,7 +362,7 @@ describe('more path function', function()
it('concatenates given filename if it is a directory but does not contain a\n slash', function()
local force_expansion = 1
- local result = vim_FullName('..', buffer, len, force_expansion)
+ local result = vim_FullName('..', buffer, length, force_expansion)
local expected = lfs.currentdir() .. '/..'
eq(expected, (ffi.string(buffer)))
eq(OK, result)
@@ -374,7 +372,7 @@ describe('more path function', function()
-- the unit tests? Which other directory would be better?
it('enters given directory (instead of just concatenating the strings) if possible and if path contains a slash', function()
local force_expansion = 1
- local result = vim_FullName('../test.file', buffer, len, force_expansion)
+ local result = vim_FullName('../test.file', buffer, length, force_expansion)
local old_dir = lfs.currentdir()
lfs.chdir('..')
local expected = lfs.currentdir() .. '/test.file'
@@ -386,7 +384,7 @@ describe('more path function', function()
it('just copies the path if it is already absolute and force=0', function()
local force_expansion = 0
local absolute_path = '/absolute/path'
- local result = vim_FullName(absolute_path, buffer, len, force_expansion)
+ local result = vim_FullName(absolute_path, buffer, length, force_expansion)
eq(absolute_path, (ffi.string(buffer)))
eq(OK, result)
end)
@@ -394,14 +392,14 @@ describe('more path function', function()
it('fails and uses filename when the path is relative to HOME', function()
local force_expansion = 1
local absolute_path = '~/home.file'
- local result = vim_FullName(absolute_path, buffer, len, force_expansion)
+ local result = vim_FullName(absolute_path, buffer, length, force_expansion)
eq(absolute_path, (ffi.string(buffer)))
eq(FAIL, result)
end)
it('works with some "normal" relative path with directories', function()
local force_expansion = 1
- local result = vim_FullName('unit-test-directory/test.file', buffer, len, force_expansion)
+ local result = vim_FullName('unit-test-directory/test.file', buffer, length, force_expansion)
eq(OK, result)
eq(lfs.currentdir() .. '/unit-test-directory/test.file', (ffi.string(buffer)))
end)
@@ -411,7 +409,7 @@ describe('more path function', function()
local filename = to_cstr('unit-test-directory/test.file')
-- Don't use the wrapper here but pass a cstring directly to the c
-- function.
- local result = path.vim_FullName(filename, buffer, len, force_expansion)
+ local result = path.vim_FullName(filename, buffer, length, force_expansion)
eq(lfs.currentdir() .. '/unit-test-directory/test.file', (ffi.string(buffer)))
eq('unit-test-directory/test.file', (ffi.string(filename)))
eq(OK, result)
@@ -420,15 +418,15 @@ describe('more path function', function()
it('works with directories that have one path component', function()
local force_expansion = 1
local filename = to_cstr('/tmp')
- local result = path.vim_FullName(filename, buffer, len, force_expansion)
+ local result = path.vim_FullName(filename, buffer, length, force_expansion)
eq('/tmp', ffi.string(buffer))
eq(OK, result)
end)
end)
describe('path_fix_case', function()
- function fix_case(file)
- c_file = to_cstr(file)
+ local function fix_case(file)
+ local c_file = to_cstr(file)
path.path_fix_case(c_file)
return ffi.string(c_file)
end
@@ -493,7 +491,7 @@ describe('more path function', function()
end)
describe('path_is_absolute_path', function()
- function path_is_absolute_path(filename)
+ local function path_is_absolute_path(filename)
filename = to_cstr(filename)
return path.path_is_absolute_path(filename)
end
diff --git a/test/unit/preprocess.lua b/test/unit/preprocess.lua
index d4c2e088a4..e5c838b13b 100644
--- a/test/unit/preprocess.lua
+++ b/test/unit/preprocess.lua
@@ -169,8 +169,8 @@ local type_to_class = {
-- find the best cc. If os.exec causes problems on windows (like popping up
-- a console window) we might consider using something like this:
-- http://scite-ru.googlecode.com/svn/trunk/pack/tools/LuaLib/shell.html#exec
-local function find_best_cc(ccs)
- for _, meta in pairs(ccs) do
+local function find_best_cc(compilers)
+ for _, meta in pairs(compilers) do
local version = io.popen(tostring(meta.path) .. " -v 2>&1")
version:close()
if version then
diff --git a/test/unit/profile_spec.lua b/test/unit/profile_spec.lua
index 2b006a0768..852475fe2c 100644
--- a/test/unit/profile_spec.lua
+++ b/test/unit/profile_spec.lua
@@ -36,20 +36,20 @@ local function cmp_assert(v1, v2, op, opstr)
assert.is_true(res)
end
-local function lt(v1, v2)
- cmp_assert(v1, v2, function(v1, v2) return v1 < v2 end, "<")
+local function lt(a, b) -- luacheck: ignore
+ cmp_assert(a, b, function(x, y) return x < y end, "<")
end
-local function lte(v1, v2)
- cmp_assert(v1, v2, function(v1, v2) return v1 <= v2 end, "<=")
+local function lte(a, b) -- luacheck: ignore
+ cmp_assert(a, b, function(x, y) return x <= y end, "<=")
end
-local function gt(v1, v2)
- cmp_assert(v1, v2, function(v1, v2) return v1 > v2 end, ">")
+local function gt(a, b) -- luacheck: ignore
+ cmp_assert(a, b, function(x, y) return x > y end, ">")
end
-local function gte(v1, v2)
- cmp_assert(v1, v2, function(v1, v2) return v1 >= v2 end, ">=")
+local function gte(a, b)
+ cmp_assert(a, b, function(x, y) return x >= y end, ">=")
end
-- missing functions:
@@ -70,7 +70,7 @@ describe('profiling related functions', function()
local function profile_equal(t1, t2) return prof.profile_equal(t1, t2) end
local function profile_msg(t) return ffi.string(prof.profile_msg(t)) end
- local function toseconds(t)
+ local function toseconds(t) -- luacheck: ignore
local str = trim(profile_msg(t))
local spl = split(str, ".")
local s, us = spl[1], spl[2]
@@ -122,7 +122,7 @@ describe('profiling related functions', function()
local divided = profile_divide(start, divisor)
local res = divided
- for i = 1, divisor - 1 do
+ for _ = 1, divisor - 1 do
res = profile_add(res, divided)
end
@@ -143,7 +143,7 @@ describe('profiling related functions', function()
describe('profile_start', function()
it('increases', function()
local last = profile_start()
- for i=1,100 do
+ for _ = 1, 100 do
local curr = profile_start()
gte(curr, last)
last = curr
@@ -157,7 +157,7 @@ describe('profiling related functions', function()
end)
it('outer elapsed >= inner elapsed', function()
- for i = 1, 100 do
+ for _ = 1, 100 do
local start_outer = profile_start()
local start_inner = profile_start()
local elapsed_inner = profile_end(start_inner)
@@ -238,7 +238,7 @@ describe('profiling related functions', function()
-- t2 >= t1 => profile_cmp(t1, t2) >= 0
assert.is_true(cmp >= 0)
- local cmp = profile_cmp(profile_sub(start3, start1), profile_sub(start2, start1))
+ cmp = profile_cmp(profile_sub(start3, start1), profile_sub(start2, start1))
-- t2 <= t1 => profile_cmp(t1, t2) <= 0
assert.is_true(cmp <= 0)
end)
diff --git a/test/unit/set.lua b/test/unit/set.lua
index bfb6b8c41c..4e66546f32 100644
--- a/test/unit/set.lua
+++ b/test/unit/set.lua
@@ -35,7 +35,7 @@ end
-- adds the argument table to this Set
function Set:union_table(t)
- for k, v in pairs(t) do
+ for _, v in pairs(t) do
self:add(v)
end
end
diff --git a/test/unit/strings_spec.lua b/test/unit/strings_spec.lua
new file mode 100644
index 0000000000..e935d2af6a
--- /dev/null
+++ b/test/unit/strings_spec.lua
@@ -0,0 +1,68 @@
+local helpers = require("test.unit.helpers")
+
+local cimport = helpers.cimport
+local eq = helpers.eq
+local ffi = helpers.ffi
+local to_cstr = helpers.to_cstr
+
+local strings = cimport('stdlib.h', './src/nvim/strings.h',
+ './src/nvim/memory.h')
+
+describe('vim_strnsave_unquoted()', function()
+ local vim_strnsave_unquoted = function(s, len)
+ local res = strings.vim_strnsave_unquoted(to_cstr(s), len or #s)
+ local ret = ffi.string(res)
+ -- Explicitly free memory so we are sure it is allocated: if it was not it
+ -- will crash.
+ strings.xfree(res)
+ return ret
+ end
+
+ it('copies unquoted strings as-is', function()
+ eq('-c', vim_strnsave_unquoted('-c'))
+ eq('', vim_strnsave_unquoted(''))
+ end)
+
+ it('respects length argument', function()
+ eq('', vim_strnsave_unquoted('-c', 0))
+ eq('-', vim_strnsave_unquoted('-c', 1))
+ eq('-', vim_strnsave_unquoted('"-c', 2))
+ end)
+
+ it('unquotes fully quoted word', function()
+ eq('/bin/sh', vim_strnsave_unquoted('"/bin/sh"'))
+ end)
+
+ it('unquotes partially quoted word', function()
+ eq('/Program Files/sh', vim_strnsave_unquoted('/Program" "Files/sh'))
+ end)
+
+ it('removes ""', function()
+ eq('/Program Files/sh', vim_strnsave_unquoted('/""Program" "Files/sh'))
+ end)
+
+ it('performs unescaping of "', function()
+ eq('/"Program Files"/sh', vim_strnsave_unquoted('/"\\""Program Files"\\""/sh'))
+ end)
+
+ it('performs unescaping of \\', function()
+ eq('/\\Program Files\\foo/sh', vim_strnsave_unquoted('/"\\\\"Program Files"\\\\foo"/sh'))
+ end)
+
+ it('strips quote when there is no pair to it', function()
+ eq('/Program Files/sh', vim_strnsave_unquoted('/Program" Files/sh'))
+ eq('', vim_strnsave_unquoted('"'))
+ end)
+
+ it('allows string to end with one backslash unescaped', function()
+ eq('/Program Files/sh\\', vim_strnsave_unquoted('/Program" Files/sh\\'))
+ end)
+
+ it('does not perform unescaping out of quotes', function()
+ eq('/Program\\ Files/sh\\', vim_strnsave_unquoted('/Program\\ Files/sh\\'))
+ end)
+
+ it('does not unescape \\n', function()
+ eq('/Program\\nFiles/sh', vim_strnsave_unquoted('/Program"\\n"Files/sh'))
+ end)
+end)
diff --git a/test/unit/tempfile_spec.lua b/test/unit/tempfile_spec.lua
index e558ff04c8..7975d11aed 100644
--- a/test/unit/tempfile_spec.lua
+++ b/test/unit/tempfile_spec.lua
@@ -2,9 +2,12 @@ local lfs = require 'lfs'
local helpers = require 'test.unit.helpers'
local os = helpers.cimport './src/nvim/os/os.h'
-local tempfile = helpers.cimport './src/nvim/tempfile.h'
+local tempfile = helpers.cimport './src/nvim/fileio.h'
describe('tempfile related functions', function()
+ before_each(function()
+ tempfile.vim_deltempdir()
+ end)
after_each(function()
tempfile.vim_deltempdir()
end)