aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/api/server_requests_spec.lua4
-rw-r--r--test/functional/autocmd/bufenter_spec.lua35
-rw-r--r--test/functional/autocmd/tabnew_spec.lua9
-rw-r--r--test/functional/autocmd/tabnewentered_spec.lua8
-rw-r--r--test/functional/core/job_partial_spec.lua13
-rw-r--r--test/functional/core/job_spec.lua18
-rw-r--r--test/functional/eval/execute_spec.lua91
-rw-r--r--test/functional/eval/server_spec.lua17
-rw-r--r--test/functional/eval/setpos_spec.lua64
-rw-r--r--test/functional/eval/system_spec.lua101
-rw-r--r--test/functional/ex_cmds/dict_notifications_spec.lua17
-rw-r--r--test/functional/fixtures/CMakeLists.txt1
-rw-r--r--test/functional/fixtures/printargs-test.c9
-rw-r--r--test/functional/helpers.lua9
-rw-r--r--test/functional/options/defaults_spec.lua35
-rw-r--r--test/functional/shada/buffers_spec.lua2
-rw-r--r--test/functional/shada/marks_spec.lua15
-rw-r--r--test/functional/shada/shada_spec.lua6
-rw-r--r--test/functional/ui/inccommand_spec.lua71
-rw-r--r--test/unit/eval/helpers.lua85
-rw-r--r--test/unit/eval/tv_clear_spec.lua127
-rw-r--r--test/unit/helpers.lua76
-rw-r--r--test/unit/preprocess.lua1
23 files changed, 720 insertions, 94 deletions
diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua
index 3245e1b52d..aa91cd1396 100644
--- a/test/functional/api/server_requests_spec.lua
+++ b/test/functional/api/server_requests_spec.lua
@@ -8,8 +8,6 @@ local nvim_prog, command, funcs = helpers.nvim_prog, helpers.command, helpers.fu
local source, next_message = helpers.source, helpers.next_message
local meths = helpers.meths
-if helpers.pending_win32(pending) then return end
-
describe('server -> client', function()
local cid
@@ -212,6 +210,8 @@ describe('server -> client', function()
funcs.jobstop(jobid)
end)
+ if helpers.pending_win32(pending) then return end
+
it('rpc and text stderr can be combined', function()
eq("ok",funcs.rpcrequest(jobid, "poll"))
funcs.rpcnotify(jobid, "ping")
diff --git a/test/functional/autocmd/bufenter_spec.lua b/test/functional/autocmd/bufenter_spec.lua
new file mode 100644
index 0000000000..ccbcdf5c5e
--- /dev/null
+++ b/test/functional/autocmd/bufenter_spec.lua
@@ -0,0 +1,35 @@
+local helpers = require('test.functional.helpers')(after_each)
+
+local clear = helpers.clear
+local command = helpers.command
+local eq = helpers.eq
+local eval = helpers.eval
+local execute = helpers.execute
+local request = helpers.request
+local source = helpers.source
+
+describe('autocmd BufEnter', function()
+ before_each(clear)
+
+ it("triggered by nvim_command('edit <dir>')", function()
+ command("autocmd BufEnter * if isdirectory(expand('<afile>')) | let g:dir_bufenter = 1 | endif")
+ request("nvim_command", "split .")
+ eq(1, eval("exists('g:dir_bufenter')")) -- Did BufEnter for the directory.
+ eq(2, eval("bufnr('%')")) -- Switched to the dir buffer.
+ end)
+
+ it('triggered by "try|:split <dir>|endtry" in a function', function()
+ command("autocmd BufEnter * if isdirectory(expand('<afile>')) | let g:dir_bufenter = 1 | endif")
+ source([[
+ function! Test()
+ try
+ exe 'split .'
+ catch
+ endtry
+ endfunction
+ ]])
+ execute("call Test()")
+ eq(1, eval("exists('g:dir_bufenter')")) -- Did BufEnter for the directory.
+ eq(2, eval("bufnr('%')")) -- Switched to the dir buffer.
+ end)
+end)
diff --git a/test/functional/autocmd/tabnew_spec.lua b/test/functional/autocmd/tabnew_spec.lua
index 2148b21832..ad40954f76 100644
--- a/test/functional/autocmd/tabnew_spec.lua
+++ b/test/functional/autocmd/tabnew_spec.lua
@@ -5,8 +5,6 @@ local command = helpers.command
local eq = helpers.eq
local eval = helpers.eval
-if helpers.pending_win32(pending) then return end
-
describe('autocmd TabNew', function()
before_each(clear)
@@ -19,12 +17,11 @@ describe('autocmd TabNew', function()
end)
it('matches when opening a new tab for FILE', function()
- local tmp_path = helpers.funcs.tempname()
command('let g:test = "foo"')
- command('autocmd! TabNew ' .. tmp_path .. ' let g:test = "bar"')
- command('tabnew ' .. tmp_path ..'X')
+ command('autocmd! TabNew Xtest-tabnew let g:test = "bar"')
+ command('tabnew Xtest-tabnewX')
eq('foo', eval('g:test'))
- command('tabnew ' .. tmp_path)
+ command('tabnew Xtest-tabnew')
eq('bar', eval('g:test'))
end)
end)
diff --git a/test/functional/autocmd/tabnewentered_spec.lua b/test/functional/autocmd/tabnewentered_spec.lua
index f033bd5fe4..bdbe677132 100644
--- a/test/functional/autocmd/tabnewentered_spec.lua
+++ b/test/functional/autocmd/tabnewentered_spec.lua
@@ -1,8 +1,6 @@
local helpers = require('test.functional.helpers')(after_each)
local clear, nvim, eq = helpers.clear, helpers.nvim, helpers.eq
-if helpers.pending_win32(pending) then return end
-
describe('TabNewEntered', function()
describe('au TabNewEntered', function()
describe('with * as <afile>', function()
@@ -15,9 +13,9 @@ describe('TabNewEntered', function()
end)
describe('with FILE as <afile>', function()
it('matches when opening a new tab for FILE', function()
- local tmp_path = nvim('eval', 'tempname()')
- nvim('command', 'au! TabNewEntered '..tmp_path..' echom "tabnewentered:match"')
- eq("\n\""..tmp_path.."\" [New File]\ntabnewentered:4:4\ntabnewentered:match", nvim('command_output', 'tabnew '..tmp_path))
+ nvim('command', 'au! TabNewEntered Xtest-tabnewentered echom "tabnewentered:match"')
+ eq('\n"Xtest-tabnewentered" [New File]\ntabnewentered:4:4\ntabnewentered:match',
+ nvim('command_output', 'tabnew Xtest-tabnewentered'))
end)
end)
describe('with CTRL-W T', function()
diff --git a/test/functional/core/job_partial_spec.lua b/test/functional/core/job_partial_spec.lua
index b60f239db9..7643b283c4 100644
--- a/test/functional/core/job_partial_spec.lua
+++ b/test/functional/core/job_partial_spec.lua
@@ -2,13 +2,14 @@ local helpers = require('test.functional.helpers')(after_each)
local clear, eq, next_msg, nvim, source = helpers.clear, helpers.eq,
helpers.next_message, helpers.nvim, helpers.source
-if helpers.pending_win32(pending) then return end
-
describe('jobs with partials', function()
local channel
before_each(function()
clear()
+ if helpers.os_name() == 'windows' then
+ helpers.set_shell_powershell()
+ end
channel = nvim('get_api_info')[1]
nvim('set_var', 'channel', channel)
end)
@@ -16,12 +17,14 @@ describe('jobs with partials', function()
it('works correctly', function()
source([[
function PrintArgs(a1, a2, id, data, event)
- call rpcnotify(g:channel, '1', a:a1, a:a2, a:data, a:event)
+ " Windows: Remove ^M char.
+ let normalized = map(a:data, 'substitute(v:val, "\r", "", "g")')
+ call rpcnotify(g:channel, '1', a:a1, a:a2, normalized, a:event)
endfunction
let Callback = function('PrintArgs', ["foo", "bar"])
let g:job_opts = {'on_stdout': Callback}
- call jobstart(['echo'], g:job_opts)
+ call jobstart('echo "some text"', g:job_opts)
]])
- eq({'notification', '1', {'foo', 'bar', {'', ''}, 'stdout'}}, next_msg())
+ eq({'notification', '1', {'foo', 'bar', {'some text', ''}, 'stdout'}}, next_msg())
end)
end)
diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua
index 75b50aad0a..48a4689545 100644
--- a/test/functional/core/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -312,6 +312,24 @@ describe('jobs', function()
end)
end)
+ it('does not repeat output with slow output handlers', function()
+ source([[
+ let d = {'data': []}
+ function! d.on_stdout(job, data, event) dict
+ call add(self.data, a:data)
+ sleep 200m
+ endfunction
+ if has('win32')
+ let cmd = '1,2,3,4,5 | foreach-object -process {echo $_; sleep 0.1}'
+ else
+ let cmd = ['sh', '-c', 'for i in $(seq 1 5); do echo $i; sleep 0.1; done']
+ endif
+ call jobwait([jobstart(cmd, d)])
+ call rpcnotify(g:channel, 'data', d.data)
+ ]])
+ eq({'notification', 'data', {{{'1', ''}, {'2', ''}, {'3', ''}, {'4', ''}, {'5', ''}}}}, next_msg())
+ end)
+
describe('jobwait', function()
it('returns a list of status codes', function()
source([[
diff --git a/test/functional/eval/execute_spec.lua b/test/functional/eval/execute_spec.lua
index fc13c0a72b..cc9b61b842 100644
--- a/test/functional/eval/execute_spec.lua
+++ b/test/functional/eval/execute_spec.lua
@@ -7,7 +7,7 @@ local redir_exec = helpers.redir_exec
local exc_exec = helpers.exc_exec
local funcs = helpers.funcs
local Screen = require('test.functional.ui.screen')
-local feed = helpers.feed
+local command = helpers.command
describe('execute()', function()
before_each(clear)
@@ -62,11 +62,11 @@ describe('execute()', function()
ret = exc_exec('call execute(function("tr"))')
eq('Vim(call):E729: using Funcref as a String', ret)
ret = exc_exec('call execute(["echo 42", 0.0, "echo 44"])')
- eq('Vim(call):E806: using Float as a String', ret)
+ eq('Vim:E806: using Float as a String', ret)
ret = exc_exec('call execute(["echo 42", v:_null_dict, "echo 44"])')
- eq('Vim(call):E731: using Dictionary as a String', ret)
+ eq('Vim:E731: using Dictionary as a String', ret)
ret = exc_exec('call execute(["echo 42", function("tr"), "echo 44"])')
- eq('Vim(call):E729: using Funcref as a String', ret)
+ eq('Vim:E729: using Funcref as a String', ret)
end)
-- This matches Vim behavior.
@@ -74,18 +74,75 @@ describe('execute()', function()
eq('\n:!echo "foo"\13\n', funcs.execute('!echo "foo"'))
end)
- it('silences command run inside', function()
- local screen = Screen.new(40, 5)
- screen:attach()
- screen:set_default_attr_ids( {[0] = {bold=true, foreground=255}} )
- feed(':let g:mes = execute("echon 42")<CR>')
- screen:expect([[
- ^ |
- {0:~ }|
- {0:~ }|
- {0:~ }|
- :let g:mes = execute("echon 42") |
- ]])
- eq('42', eval('g:mes'))
+ describe('{silent} argument', function()
+ it('captures & displays output for ""', function()
+ local screen = Screen.new(40, 5)
+ screen:attach()
+ command('let g:mes = execute("echon 42", "")')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ 42 |
+ ]])
+ eq('42', eval('g:mes'))
+ end)
+
+ it('captures but does not display output for "silent"', function()
+ local screen = Screen.new(40, 5)
+ screen:attach()
+ command('let g:mes = execute("echon 42")')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]])
+ eq('42', eval('g:mes'))
+
+ command('let g:mes = execute("echon 13", "silent")')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]])
+ eq('13', eval('g:mes'))
+ end)
+
+ it('suppresses errors for "silent!"', function()
+ eq(0, exc_exec('let g:mes = execute(0.0, "silent!")'))
+ eq('', eval('g:mes'))
+
+ eq(0, exc_exec('let g:mes = execute("echon add(1, 1)", "silent!")'))
+ eq('1', eval('g:mes'))
+
+ eq(0, exc_exec('let g:mes = execute(["echon 42", "echon add(1, 1)"], "silent!")'))
+ eq('421', eval('g:mes'))
+ end)
+
+ it('propagates errors for "" and "silent"', function()
+ local ret
+ ret = exc_exec('call execute(0.0, "")')
+ eq('Vim(call):E806: using Float as a String', ret)
+
+ ret = exc_exec('call execute(v:_null_dict, "silent")')
+ eq('Vim(call):E731: using Dictionary as a String', ret)
+
+ ret = exc_exec('call execute("echo add(1, 1)", "")')
+ eq('Vim(echo):E714: List required', ret)
+
+ ret = exc_exec('call execute(["echon 42", "echo add(1, 1)"], "")')
+ eq('Vim(echo):E714: List required', ret)
+
+ ret = exc_exec('call execute("echo add(1, 1)", "silent")')
+ eq('Vim(echo):E714: List required', ret)
+
+ ret = exc_exec('call execute(["echon 42", "echo add(1, 1)"], "silent")')
+ eq('Vim(echo):E714: List required', ret)
+ end)
end)
end)
diff --git a/test/functional/eval/server_spec.lua b/test/functional/eval/server_spec.lua
index d2c985e894..420aea04aa 100644
--- a/test/functional/eval/server_spec.lua
+++ b/test/functional/eval/server_spec.lua
@@ -4,8 +4,6 @@ local nvim, eq, neq, eval = helpers.nvim, helpers.eq, helpers.neq, helpers.eval
local clear, funcs, meths = helpers.clear, helpers.funcs, helpers.meths
local os_name = helpers.os_name
-if helpers.pending_win32(pending) then return end
-
describe('serverstart(), serverstop()', function()
before_each(clear)
@@ -42,8 +40,8 @@ describe('serverstart(), serverstop()', function()
-- v:servername will take the next available server.
local servername = (os_name() == 'windows'
- and [[\\.\pipe\Xtest-functional-server-server-pipe]]
- or 'Xtest-functional-server-server-socket')
+ and [[\\.\pipe\Xtest-functional-server-pipe]]
+ or 'Xtest-functional-server-socket')
funcs.serverstart(servername)
eq(servername, meths.get_vvar('servername'))
end)
@@ -63,9 +61,11 @@ describe('serverlist()', function()
local n = eval('len(serverlist())')
-- Add a few
- local servs = {'should-not-exist', 'another-one-that-shouldnt'}
+ local servs = (os_name() == 'windows'
+ and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] }
+ or { [[Xtest-pipe0934]], [[Xtest-pipe4324]] })
for _, s in ipairs(servs) do
- eq(s, eval('serverstart("'..s..'")'))
+ eq(s, eval("serverstart('"..s.."')"))
end
local new_servs = eval('serverlist()')
@@ -75,10 +75,9 @@ describe('serverlist()', function()
-- The new servers should be at the end of the list.
for i = 1, #servs do
eq(servs[i], new_servs[i + n])
- nvim('command', 'call serverstop("'..servs[i]..'")')
+ nvim('command', "call serverstop('"..servs[i].."')")
end
- -- After calling serverstop() on the new servers, they should no longer be
- -- in the list.
+ -- After serverstop() the servers should NOT be in the list.
eq(n, eval('len(serverlist())'))
end)
end)
diff --git a/test/functional/eval/setpos_spec.lua b/test/functional/eval/setpos_spec.lua
new file mode 100644
index 0000000000..2e27cd8ac0
--- /dev/null
+++ b/test/functional/eval/setpos_spec.lua
@@ -0,0 +1,64 @@
+local helpers = require('test.functional.helpers')(after_each)
+local setpos = helpers.funcs.setpos
+local getpos = helpers.funcs.getpos
+local insert = helpers.insert
+local clear = helpers.clear
+local execute = helpers.execute
+local eval = helpers.eval
+local eq = helpers.eq
+local exc_exec = helpers.exc_exec
+
+
+describe('setpos() function', function()
+ before_each(function()
+ clear()
+ insert([[
+ First line of text
+ Second line of text
+ Third line of text]])
+ execute('new')
+ insert([[
+ Line of text 1
+ Line of text 2
+ Line of text 3]])
+ end)
+ it('can set the current cursor position', function()
+ setpos(".", {0, 2, 1, 0})
+ eq(getpos("."), {0, 2, 1, 0})
+ setpos(".", {2, 1, 1, 0})
+ eq(getpos("."), {0, 1, 1, 0})
+ -- Ensure get an error attempting to set position to another buffer
+ local ret = exc_exec('call setpos(".", [1, 1, 1, 0])')
+ eq('Vim(call):E474: Invalid argument', ret)
+ end)
+ it('can set lowercase marks in the current buffer', function()
+ setpos("'d", {0, 2, 1, 0})
+ eq(getpos("'d"), {0, 2, 1, 0})
+ execute('undo', 'call setpos("\'d", [2, 3, 1, 0])')
+ eq(getpos("'d"), {0, 3, 1, 0})
+ end)
+ it('can set lowercase marks in other buffers', function()
+ local retval = setpos("'d", {1, 2, 1, 0})
+ eq(0, retval)
+ setpos("'d", {1, 2, 1, 0})
+ eq(getpos("'d"), {0, 0, 0, 0})
+ execute('wincmd w')
+ eq(eval('bufnr("%")'), 1)
+ eq(getpos("'d"), {0, 2, 1, 0})
+ end)
+ it("fails when setting a mark in a buffer that doesn't exist", function()
+ local retval = setpos("'d", {3, 2, 1, 0})
+ eq(-1, retval)
+ eq(getpos("'d"), {0, 0, 0, 0})
+ retval = setpos("'D", {3, 2, 1, 0})
+ eq(-1, retval)
+ eq(getpos("'D"), {0, 0, 0, 0})
+ end)
+ it('can set uppercase marks', function()
+ setpos("'D", {2, 2, 3, 0})
+ eq(getpos("'D"), {2, 2, 3, 0})
+ -- Can set a mark in another buffer
+ setpos("'D", {1, 2, 2, 0})
+ eq(getpos("'D"), {1, 2, 2, 0})
+ end)
+end)
diff --git a/test/functional/eval/system_spec.lua b/test/functional/eval/system_spec.lua
index 6393477260..d5845132dd 100644
--- a/test/functional/eval/system_spec.lua
+++ b/test/functional/eval/system_spec.lua
@@ -1,12 +1,10 @@
local helpers = require('test.functional.helpers')(after_each)
-local eq, clear, eval, execute, feed, nvim =
- helpers.eq, helpers.clear, helpers.eval, helpers.execute, helpers.feed,
- helpers.nvim
+local eq, call, clear, eval, execute, feed, nvim =
+ helpers.eq, helpers.call, helpers.clear, helpers.eval, helpers.execute,
+ helpers.feed, helpers.nvim
local Screen = require('test.functional.ui.screen')
-if helpers.pending_win32(pending) then return end
-
local function create_file_with_nuls(name)
return function()
feed('ipart1<C-V>000part2<C-V>000part3<ESC>:w '..name..'<CR>')
@@ -31,7 +29,70 @@ end
describe('system()', function()
before_each(clear)
- it('sets the v:shell_error variable', function()
+ describe('command passed as a List', function()
+ local printargs_path = helpers.nvim_dir..'/printargs-test'
+ .. (helpers.os_name() == 'windows' and '.exe' or '')
+
+ it('sets v:shell_error if cmd[0] is not executable', function()
+ call('system', { 'this-should-not-exist' })
+ eq(-1, eval('v:shell_error'))
+ end)
+
+ it('parameter validation does NOT modify v:shell_error', function()
+ -- 1. Call system() with invalid parameters.
+ -- 2. Assert that v:shell_error was NOT set.
+ execute('call system({})')
+ eq('E475: Invalid argument: expected String or List', eval('v:errmsg'))
+ eq(0, eval('v:shell_error'))
+ execute('call system([])')
+ eq('E474: Invalid argument', eval('v:errmsg'))
+ eq(0, eval('v:shell_error'))
+
+ -- Provoke a non-zero v:shell_error.
+ call('system', { 'this-should-not-exist' })
+ local old_val = eval('v:shell_error')
+ eq(-1, old_val)
+
+ -- 1. Call system() with invalid parameters.
+ -- 2. Assert that v:shell_error was NOT modified.
+ execute('call system({})')
+ eq(old_val, eval('v:shell_error'))
+ execute('call system([])')
+ eq(old_val, eval('v:shell_error'))
+ end)
+
+ it('quotes arguments correctly #5280', function()
+ local out = call('system',
+ { printargs_path, [[1]], [[2 "3]], [[4 ' 5]], [[6 ' 7']] })
+
+ eq(0, eval('v:shell_error'))
+ eq([[arg1=1;arg2=2 "3;arg3=4 ' 5;arg4=6 ' 7';]], out)
+
+ out = call('system', { printargs_path, [['1]], [[2 "3]] })
+ eq(0, eval('v:shell_error'))
+ eq([[arg1='1;arg2=2 "3;]], out)
+
+ out = call('system', { printargs_path, "A\nB" })
+ eq(0, eval('v:shell_error'))
+ eq("arg1=A\nB;", out)
+ end)
+
+ it('calls executable in $PATH', function()
+ if 0 == eval("executable('python')") then pending("missing `python`") end
+ eq("foo\n", eval([[system(['python', '-c', 'print("foo")'])]]))
+ eq(0, eval('v:shell_error'))
+ end)
+
+ it('does NOT run in shell', function()
+ if helpers.os_name() ~= 'windows' then
+ eq("* $PATH %PATH%\n", eval("system(['echo', '*', '$PATH', '%PATH%'])"))
+ end
+ end)
+ end)
+
+ if helpers.pending_win32(pending) then return end
+
+ it('sets v:shell_error', function()
eval([[system("sh -c 'exit'")]])
eq(0, eval('v:shell_error'))
eval([[system("sh -c 'exit 1'")]])
@@ -158,7 +219,7 @@ describe('system()', function()
end)
end)
- describe('passing number as input', function()
+ describe('input passed as Number', function()
it('stringifies the input', function()
eq('1', eval('system("cat", 1)'))
end)
@@ -175,8 +236,8 @@ describe('system()', function()
end)
end)
- describe('passing list as input', function()
- it('joins list items with linefeed characters', function()
+ describe('input passed as List', function()
+ it('joins List items with linefeed characters', function()
eq('line1\nline2\nline3',
eval("system('cat -', ['line1', 'line2', 'line3'])"))
end)
@@ -185,7 +246,7 @@ describe('system()', function()
-- is inconsistent and is a good reason for the existence of the
-- `systemlist()` function, where input and output map to the same
-- characters(see the following tests with `systemlist()` below)
- describe('with linefeed characters inside list items', function()
+ describe('with linefeed characters inside List items', function()
it('converts linefeed characters to NULs', function()
eq('l1\001p2\nline2\001a\001b\nl3',
eval([[system('cat -', ["l1\np2", "line2\na\nb", 'l3'])]]))
@@ -202,7 +263,7 @@ describe('system()', function()
describe("with a program that doesn't close stdout", function()
if not xclip then
- pending('skipped (missing xclip)', function() end)
+ pending('missing `xclip`', function() end)
else
it('will exit properly after passing input', function()
eq('', eval([[system('xclip -i -selection clipboard', 'clip-data')]]))
@@ -210,18 +271,12 @@ describe('system()', function()
end)
end
end)
-
- describe('command passed as a list', function()
- it('does not execute &shell', function()
- eq('* $NOTHING ~/file',
- eval("system(['echo', '-n', '*', '$NOTHING', '~/file'])"))
- end)
- end)
end)
+if helpers.pending_win32(pending) then return end
+
describe('systemlist()', function()
- -- behavior is similar to `system()` but it returns a list instead of a
- -- string.
+ -- Similar to `system()`, but returns List instead of String.
before_each(clear)
it('sets the v:shell_error variable', function()
@@ -334,14 +389,14 @@ describe('systemlist()', function()
end)
end)
- describe('passing list as input', function()
+ describe('input passed as List', function()
it('joins list items with linefeed characters', function()
eq({'line1', 'line2', 'line3'},
eval("systemlist('cat -', ['line1', 'line2', 'line3'])"))
end)
-- Unlike `system()` which uses SOH to represent NULs, with `systemlist()`
- -- input and ouput are the same
+ -- input and ouput are the same.
describe('with linefeed characters inside list items', function()
it('converts linefeed characters to NULs', function()
eq({'l1\np2', 'line2\na\nb', 'l3'},
@@ -381,7 +436,7 @@ describe('systemlist()', function()
describe("with a program that doesn't close stdout", function()
if not xclip then
- pending('skipped (missing xclip)', function() end)
+ pending('missing `xclip`', function() end)
else
it('will exit properly after passing input', function()
eq({}, eval(
diff --git a/test/functional/ex_cmds/dict_notifications_spec.lua b/test/functional/ex_cmds/dict_notifications_spec.lua
index e6f7609016..5e89986c0f 100644
--- a/test/functional/ex_cmds/dict_notifications_spec.lua
+++ b/test/functional/ex_cmds/dict_notifications_spec.lua
@@ -3,6 +3,7 @@ local clear, nvim, source = helpers.clear, helpers.nvim, helpers.source
local eq, next_msg = helpers.eq, helpers.next_message
local exc_exec = helpers.exc_exec
local command = helpers.command
+local eval = helpers.eval
describe('dictionary change notifications', function()
@@ -255,5 +256,21 @@ describe('dictionary change notifications', function()
eq({'notification', '2b', {'key', {old = 'v2', new = 'value'}}}, next_msg())
end)
+
+ it('does not crash when freeing a watched dictionary', function()
+ source([[
+ function! Watcher(dict, key, value)
+ echo a:key string(a:value)
+ endfunction
+
+ function! MakeWatch()
+ let d = {'foo': 'bar'}
+ call dictwatcheradd(d, 'foo', function('Watcher'))
+ endfunction
+ ]])
+
+ command('call MakeWatch()')
+ eq(2, eval('1+1')) -- Still alive?
+ end)
end)
end)
diff --git a/test/functional/fixtures/CMakeLists.txt b/test/functional/fixtures/CMakeLists.txt
index 70aee6efa9..8537ea390f 100644
--- a/test/functional/fixtures/CMakeLists.txt
+++ b/test/functional/fixtures/CMakeLists.txt
@@ -2,3 +2,4 @@ add_executable(tty-test tty-test.c)
target_link_libraries(tty-test ${LIBUV_LIBRARIES})
add_executable(shell-test shell-test.c)
+add_executable(printargs-test printargs-test.c)
diff --git a/test/functional/fixtures/printargs-test.c b/test/functional/fixtures/printargs-test.c
new file mode 100644
index 0000000000..2c25cf8447
--- /dev/null
+++ b/test/functional/fixtures/printargs-test.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ for (int i=1; i<argc; i++) {
+ printf("arg%d=%s;", i, argv[i]);
+ }
+ return 0;
+}
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index 5eec3afe65..2939184d2c 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -346,6 +346,14 @@ local function source(code)
return fname
end
+local function set_shell_powershell()
+ source([[
+ set shell=powershell shellquote=\" shellpipe=\| shellredir=>
+ set shellcmdflag=\ -ExecutionPolicy\ RemoteSigned\ -Command
+ let &shellxquote=' '
+ ]])
+end
+
local function nvim(method, ...)
return request('nvim_'..method, ...)
end
@@ -590,6 +598,7 @@ return function(after_each)
curtabmeths = curtabmeths,
pending_win32 = pending_win32,
skip_fragile = skip_fragile,
+ set_shell_powershell = set_shell_powershell,
tmpname = tmpname,
NIL = mpack.NIL,
}
diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua
index 1ae855f26c..caeca5e4e2 100644
--- a/test/functional/options/defaults_spec.lua
+++ b/test/functional/options/defaults_spec.lua
@@ -9,8 +9,6 @@ local eval = helpers.eval
local eq = helpers.eq
local neq = helpers.neq
-if helpers.pending_win32(pending) then return end
-
local function init_session(...)
local args = { helpers.nvim_prog, '-i', 'NONE', '--embed',
'--cmd', 'set shortmess+=I background=light noswapfile noautoindent',
@@ -24,6 +22,8 @@ end
describe('startup defaults', function()
describe(':filetype', function()
+ if helpers.pending_win32(pending) then return end
+
local function expect_filetype(expected)
local screen = Screen.new(48, 4)
screen:attach()
@@ -99,8 +99,37 @@ describe('startup defaults', function()
end)
describe('XDG-based defaults', function()
- -- Need to be in separate describe() block to not run clear() twice.
+ -- Need separate describe() blocks to not run clear() twice.
-- Do not put before_each() here for the same reasons.
+
+ describe('with empty/broken environment', function()
+ it('sets correct defaults', function()
+ clear({env={
+ XDG_CONFIG_HOME=nil,
+ XDG_DATA_HOME=nil,
+ XDG_CACHE_HOME=nil,
+ XDG_RUNTIME_DIR=nil,
+ XDG_CONFIG_DIRS=nil,
+ XDG_DATA_DIRS=nil,
+ LOCALAPPDATA=nil,
+ HOMEPATH=nil,
+ HOMEDRIVE=nil,
+ HOME=nil,
+ TEMP=nil,
+ VIMRUNTIME=nil,
+ USER=nil,
+ }})
+
+ eq('.', meths.get_option('backupdir'))
+ eq('.', meths.get_option('viewdir'))
+ eq('.', meths.get_option('directory'))
+ eq('.', meths.get_option('undodir'))
+ end)
+ end)
+
+ -- TODO(jkeyes): tests below fail on win32 because of path separator.
+ if helpers.pending_win32(pending) then return end
+
describe('with too long XDG variables', function()
before_each(function()
clear({env={
diff --git a/test/functional/shada/buffers_spec.lua b/test/functional/shada/buffers_spec.lua
index 7e6338897a..a4746c2205 100644
--- a/test/functional/shada/buffers_spec.lua
+++ b/test/functional/shada/buffers_spec.lua
@@ -8,8 +8,6 @@ local reset, set_additional_cmd, clear =
shada_helpers.reset, shada_helpers.set_additional_cmd,
shada_helpers.clear
-if helpers.pending_win32(pending) then return end
-
describe('ShaDa support code', function()
local testfilename = 'Xtestfile-functional-shada-buffers'
local testfilename_2 = 'Xtestfile-functional-shada-buffers-2'
diff --git a/test/functional/shada/marks_spec.lua b/test/functional/shada/marks_spec.lua
index b7c0f61f57..fa760ceb5b 100644
--- a/test/functional/shada/marks_spec.lua
+++ b/test/functional/shada/marks_spec.lua
@@ -14,8 +14,6 @@ local nvim_current_line = function()
return curwinmeths.get_cursor()[1]
end
-if helpers.pending_win32(pending) then return end
-
describe('ShaDa support code', function()
local testfilename = 'Xtestfile-functional-shada-marks'
local testfilename_2 = 'Xtestfile-functional-shada-marks-2'
@@ -153,6 +151,19 @@ describe('ShaDa support code', function()
eq(saved, redir_exec('jumps'))
end)
+ it('when dumping jump list also dumps current position', function()
+ nvim_command('edit ' .. testfilename)
+ nvim_command('normal! G')
+ nvim_command('split ' .. testfilename_2)
+ nvim_command('normal! G')
+ nvim_command('wshada')
+ nvim_command('quit')
+ nvim_command('rshada')
+ nvim_command('normal! \15') -- <C-o>
+ eq(testfilename_2, funcs.bufname('%'))
+ eq({2, 0}, curwinmeths.get_cursor())
+ end)
+
it('is able to dump and restore jump list with different times (slow!)',
function()
nvim_command('edit ' .. testfilename_2)
diff --git a/test/functional/shada/shada_spec.lua b/test/functional/shada/shada_spec.lua
index f845f6f93b..32598fc399 100644
--- a/test/functional/shada/shada_spec.lua
+++ b/test/functional/shada/shada_spec.lua
@@ -23,8 +23,6 @@ local wshada, _, shada_fname, clean =
local dirname = 'Xtest-functional-shada-shada.d'
local dirshada = dirname .. '/main.shada'
-if helpers.pending_win32(pending) then return end
-
describe('ShaDa support code', function()
before_each(reset)
after_each(function()
@@ -173,6 +171,7 @@ describe('ShaDa support code', function()
end
it('correctly uses shada-r option', function()
+ nvim_command('set shellslash')
meths.set_var('__home', paths.test_source_path)
nvim_command('let $HOME = __home')
nvim_command('unlet __home')
@@ -196,6 +195,7 @@ describe('ShaDa support code', function()
end)
it('correctly ignores case with shada-r option', function()
+ nvim_command('set shellslash')
local pwd = funcs.getcwd()
local relfname = 'абв/test'
local fname = pwd .. '/' .. relfname
@@ -240,6 +240,8 @@ describe('ShaDa support code', function()
end)
it('does not crash when ShaDa file directory is not writable', function()
+ if helpers.pending_win32(pending) then return end
+
funcs.mkdir(dirname, '', 0)
eq(0, funcs.filewritable(dirname))
set_additional_cmd('set shada=')
diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua
index 35aeb6e67c..41ebfd2334 100644
--- a/test/functional/ui/inccommand_spec.lua
+++ b/test/functional/ui/inccommand_spec.lua
@@ -42,6 +42,7 @@ local function common_setup(screen, inccommand, text)
[14] = {foreground = Screen.colors.White, background = Screen.colors.Red},
[15] = {bold=true, foreground=Screen.colors.Blue},
[16] = {background=Screen.colors.Grey90}, -- cursorline
+ vis = {background=Screen.colors.LightGrey}
})
end
@@ -207,6 +208,42 @@ describe(":substitute, 'inccommand' preserves", function()
end)
end
+ for _, case in pairs{"", "split", "nosplit"} do
+ it("visual selection for non-previewable command (inccommand="..case..") #5888", function()
+ local screen = Screen.new(30,10)
+ common_setup(screen, case, default_text)
+ feed('1G2V')
+
+ feed(':s')
+ screen:expect([[
+ {vis:Inc substitution on} |
+ t{vis:wo lines} |
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ :'<,'>s^ |
+ ]])
+
+ feed('o')
+ screen:expect([[
+ {vis:Inc substitution on} |
+ t{vis:wo lines} |
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ :'<,'>so^ |
+ ]])
+ end)
+ end
+
end)
describe(":substitute, 'inccommand' preserves undo", function()
@@ -1201,6 +1238,40 @@ describe(":substitute, 'inccommand' with a failing expression", function()
end
end)
+ it('in the range does not error #5912', function()
+ for _, case in pairs(cases) do
+ refresh(case)
+ feed(':100s/')
+
+ screen:expect([[
+ Inc substitution on |
+ two lines |
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ :100s/^ |
+ ]])
+
+ feed('<enter>')
+ screen:expect([[
+ Inc substitution on |
+ two lines |
+ ^ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {14:E16: Invalid range} |
+ ]])
+ end
+ end)
+
end)
describe("'inccommand' and :cnoremap", function()
diff --git a/test/unit/eval/helpers.lua b/test/unit/eval/helpers.lua
index 712530a0aa..c3c27e4fed 100644
--- a/test/unit/eval/helpers.lua
+++ b/test/unit/eval/helpers.lua
@@ -5,7 +5,8 @@ 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 eval = cimport('./src/nvim/eval.h', './src/nvim/eval_defs.h',
+ './src/nvim/hashtab.h')
local null_string = {[true]='NULL string'}
local null_list = {[true]='NULL list'}
@@ -122,6 +123,32 @@ typvalt2lua = function(t, processed)
end)(t, processed or {}))
end
+local function list_iter(l)
+ local init_s = {
+ idx=0,
+ li=l.lv_first,
+ }
+ local function f(s, _)
+ -- (listitem_T *) NULL is equal to nil, but yet it is not false.
+ if s.li == nil then
+ return nil
+ end
+ local ret_li = s.li
+ s.li = s.li.li_next
+ s.idx = s.idx + 1
+ return s.idx, ret_li
+ end
+ return f, init_s, nil
+end
+
+local function list_items(l)
+ local ret = {}
+ for i, li in list_iter(l) do
+ ret[i] = li
+ end
+ return ret
+end
+
lst2tbl = function(l, processed)
if l == nil then
return null_list
@@ -133,11 +160,8 @@ lst2tbl = function(l, processed)
end
local ret = {[type_key]=list_type}
processed[p_key] = ret
- local li = l.lv_first
- -- (listitem_T *) NULL is equal to nil, but yet it is not false.
- while li ~= nil do
- ret[#ret + 1] = typvalt2lua(li.li_tv, processed)
- li = li.li_next
+ for i, li in list_iter(l) do
+ ret[i] = typvalt2lua(li.li_tv, processed)
end
if ret[1] then
ret[type_key] = nil
@@ -145,7 +169,9 @@ lst2tbl = function(l, processed)
return ret
end
-local function dict_iter(d)
+local hi_key_removed = eval._hash_key_removed()
+
+local function dict_iter(d, return_hi)
local init_s = {
todo=d.dv_hashtab.ht_used,
hi=d.dv_hashtab.ht_array,
@@ -153,13 +179,18 @@ local function dict_iter(d)
local function f(s, _)
if s.todo == 0 then return nil end
while s.todo > 0 do
- if s.hi.hi_key ~= nil and s.hi ~= eval.hash_removed then
+ if s.hi.hi_key ~= nil and s.hi.hi_key ~= hi_key_removed then
local key = ffi.string(s.hi.hi_key)
- local di = ffi.cast('dictitem_T*',
- s.hi.hi_key - ffi.offsetof('dictitem_T', 'di_key'))
+ local ret
+ if return_hi then
+ ret = s.hi
+ else
+ ret = ffi.cast('dictitem_T*',
+ s.hi.hi_key - ffi.offsetof('dictitem_T', 'di_key'))
+ end
s.todo = s.todo - 1
s.hi = s.hi + 1
- return key, di
+ return key, ret
end
s.hi = s.hi + 1
end
@@ -172,6 +203,16 @@ local function first_di(d)
return select(2, f(init_s, v))
end
+local function dict_items(d)
+ local ret = {[0]=0}
+ for k, hi in dict_iter(d) do
+ ret[k] = hi
+ ret[0] = ret[0] + 1
+ ret[ret[0]] = hi
+ end
+ return ret
+end
+
dct2tbl = function(d, processed)
if d == nil then
return null_dict
@@ -324,6 +365,22 @@ lua2typvalt = function(l, processed)
end
end
+local function void(ptr)
+ return ffi.cast('void*', ptr)
+end
+
+local alloc_logging_helpers = {
+ list = function(l) return {func='calloc', args={1, ffi.sizeof('list_T')}, ret=void(l)} end,
+ li = function(li) return {func='malloc', args={ffi.sizeof('listitem_T')}, ret=void(li)} end,
+ dict = function(d) return {func='malloc', args={ffi.sizeof('dict_T')}, ret=void(d)} end,
+ di = function(di, size)
+ return {func='malloc', args={ffi.offsetof('dictitem_T', 'di_key') + size + 1}, ret=void(di)}
+ end,
+ str = function(s, size) return {func='malloc', args={size + 1}, ret=void(s)} end,
+
+ freed = function(p) return {func='free', args={p and void(p)}} end,
+}
+
return {
null_string=null_string,
null_list=null_list,
@@ -350,5 +407,11 @@ return {
li_alloc=li_alloc,
dict_iter=dict_iter,
+ list_iter=list_iter,
first_di=first_di,
+
+ alloc_logging_helpers=alloc_logging_helpers,
+
+ list_items=list_items,
+ dict_items=dict_items,
}
diff --git a/test/unit/eval/tv_clear_spec.lua b/test/unit/eval/tv_clear_spec.lua
new file mode 100644
index 0000000000..96eccdbd71
--- /dev/null
+++ b/test/unit/eval/tv_clear_spec.lua
@@ -0,0 +1,127 @@
+local helpers = require('test.unit.helpers')
+local eval_helpers = require('test.unit.eval.helpers')
+
+local alloc_log_new = helpers.alloc_log_new
+local cimport = helpers.cimport
+local ffi = helpers.ffi
+local eq = helpers.eq
+
+local a = eval_helpers.alloc_logging_helpers
+local type_key = eval_helpers.type_key
+local list_type = eval_helpers.list_type
+local list_items = eval_helpers.list_items
+local dict_items = eval_helpers.dict_items
+local lua2typvalt = eval_helpers.lua2typvalt
+
+local lib = cimport('./src/nvim/eval_defs.h', './src/nvim/eval.h')
+
+local alloc_log = alloc_log_new()
+
+before_each(function()
+ alloc_log:before_each()
+end)
+
+after_each(function()
+ alloc_log:after_each()
+end)
+
+describe('clear_tv()', function()
+ it('successfully frees all lists in [&l [1], *l, *l]', function()
+ local l_inner = {1}
+ local list = {l_inner, l_inner, l_inner}
+ local list_tv = ffi.gc(lua2typvalt(list), nil)
+ local list_p = list_tv.vval.v_list
+ local lis = list_items(list_p)
+ local list_inner_p = lis[1].li_tv.vval.v_list
+ local lis_inner = list_items(list_inner_p)
+ alloc_log:check({
+ a.list(list_p),
+ a.list(list_inner_p),
+ a.li(lis_inner[1]),
+ a.li(lis[1]),
+ a.li(lis[2]),
+ a.li(lis[3]),
+ })
+ eq(3, list_inner_p.lv_refcount)
+ lib.clear_tv(list_tv)
+ alloc_log:check({
+ a.freed(lis_inner[1]),
+ a.freed(list_inner_p),
+ a.freed(lis[1]),
+ a.freed(lis[2]),
+ a.freed(lis[3]),
+ a.freed(list_p),
+ })
+ end)
+ it('successfully frees all lists in [&l [], *l, *l]', function()
+ local l_inner = {[type_key]=list_type}
+ local list = {l_inner, l_inner, l_inner}
+ local list_tv = ffi.gc(lua2typvalt(list), nil)
+ local list_p = list_tv.vval.v_list
+ local lis = list_items(list_p)
+ local list_inner_p = lis[1].li_tv.vval.v_list
+ alloc_log:check({
+ a.list(list_p),
+ a.list(list_inner_p),
+ a.li(lis[1]),
+ a.li(lis[2]),
+ a.li(lis[3]),
+ })
+ eq(3, list_inner_p.lv_refcount)
+ lib.clear_tv(list_tv)
+ alloc_log:check({
+ a.freed(list_inner_p),
+ a.freed(lis[1]),
+ a.freed(lis[2]),
+ a.freed(lis[3]),
+ a.freed(list_p),
+ })
+ end)
+ it('successfully frees all dictionaries in [&d {}, *d]', function()
+ local d_inner = {}
+ local list = {d_inner, d_inner}
+ local list_tv = ffi.gc(lua2typvalt(list), nil)
+ local list_p = list_tv.vval.v_list
+ local lis = list_items(list_p)
+ local dict_inner_p = lis[1].li_tv.vval.v_dict
+ alloc_log:check({
+ a.list(list_p),
+ a.dict(dict_inner_p),
+ a.li(lis[1]),
+ a.li(lis[2]),
+ })
+ eq(2, dict_inner_p.dv_refcount)
+ lib.clear_tv(list_tv)
+ alloc_log:check({
+ a.freed(dict_inner_p),
+ a.freed(lis[1]),
+ a.freed(lis[2]),
+ a.freed(list_p),
+ })
+ end)
+ it('successfully frees all dictionaries in [&d {a: 1}, *d]', function()
+ local d_inner = {a=1}
+ local list = {d_inner, d_inner}
+ local list_tv = ffi.gc(lua2typvalt(list), nil)
+ local list_p = list_tv.vval.v_list
+ local lis = list_items(list_p)
+ local dict_inner_p = lis[1].li_tv.vval.v_dict
+ local dis = dict_items(dict_inner_p)
+ alloc_log:check({
+ a.list(list_p),
+ a.dict(dict_inner_p),
+ a.di(dis.a, 1),
+ a.li(lis[1]),
+ a.li(lis[2]),
+ })
+ eq(2, dict_inner_p.dv_refcount)
+ lib.clear_tv(list_tv)
+ alloc_log:check({
+ a.freed(dis.a),
+ a.freed(dict_inner_p),
+ a.freed(lis[1]),
+ a.freed(lis[2]),
+ a.freed(list_p),
+ })
+ end)
+end)
diff --git a/test/unit/helpers.lua b/test/unit/helpers.lua
index 45bbaaeb10..1bfdd32739 100644
--- a/test/unit/helpers.lua
+++ b/test/unit/helpers.lua
@@ -9,6 +9,12 @@ local neq = global_helpers.neq
local eq = global_helpers.eq
local ok = global_helpers.ok
+-- C constants.
+local NULL = ffi.cast('void*', 0)
+
+local OK = 1
+local FAIL = 0
+
-- add some standard header locations
for _, p in ipairs(Paths.include_paths) do
Preprocess.add_to_include_path(p)
@@ -118,6 +124,67 @@ local function cppimport(path)
return cimport(Paths.test_include_path .. '/' .. path)
end
+local function alloc_log_new()
+ local log = {
+ log={},
+ lib=cimport('./src/nvim/memory.h'),
+ original_functions={},
+ null={['\0:is_null']=true},
+ }
+ 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]
+ end
+ end
+ function log:set_mocks()
+ for _, k in ipairs(allocator_functions) do
+ do
+ local kk = k
+ self.lib['mem_' .. k] = function(...)
+ local log_entry = {func=kk, args={...}}
+ self.log[#self.log + 1] = log_entry
+ if kk == 'free' then
+ self.original_functions[kk](...)
+ else
+ log_entry.ret = self.original_functions[kk](...)
+ end
+ for i, v in ipairs(log_entry.args) do
+ if v == nil then
+ -- XXX This thing thinks that {NULL} ~= {NULL}.
+ log_entry.args[i] = self.null
+ end
+ end
+ if self.hook then self:hook(log_entry) end
+ if log_entry.ret then
+ return log_entry.ret
+ end
+ end
+ end
+ end
+ end
+ function log:clear()
+ self.log = {}
+ end
+ function log:check(exp)
+ eq(exp, self.log)
+ self:clear()
+ end
+ function log:restore_original_functions()
+ for k, v in pairs(self.original_functions) do
+ self.lib['mem_' .. k] = v
+ end
+ end
+ function log:before_each()
+ log:save_original_functions()
+ log:set_mocks()
+ end
+ function log:after_each()
+ log:restore_original_functions()
+ end
+ return log
+end
+
cimport('./src/nvim/types.h')
-- take a pointer to a C-allocated string and return an interned
@@ -142,12 +209,6 @@ do
main.event_init()
end
--- C constants.
-local NULL = ffi.cast('void*', 0)
-
-local OK = 1
-local FAIL = 0
-
return {
cimport = cimport,
cppimport = cppimport,
@@ -161,5 +222,6 @@ return {
to_cstr = to_cstr,
NULL = NULL,
OK = OK,
- FAIL = FAIL
+ FAIL = FAIL,
+ alloc_log_new = alloc_log_new,
}
diff --git a/test/unit/preprocess.lua b/test/unit/preprocess.lua
index 8c2a5c73e5..1c9b290462 100644
--- a/test/unit/preprocess.lua
+++ b/test/unit/preprocess.lua
@@ -123,6 +123,7 @@ function Gcc:init_defines()
self:define('INIT', {'...'}, '')
self:define('_GNU_SOURCE')
self:define('INCLUDE_GENERATED_DECLARATIONS')
+ self:define('UNIT_TESTING')
-- Needed for FreeBSD
self:define('_Thread_local', nil, '')
-- Needed for macOS Sierra