aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/api/highlight_spec.lua9
-rw-r--r--test/functional/api/ui_spec.lua37
-rw-r--r--test/functional/api/vim_spec.lua17
-rw-r--r--test/functional/autocmd/cmdline_spec.lua9
-rw-r--r--test/functional/clipboard/clipboard_provider_spec.lua28
-rw-r--r--test/functional/core/job_spec.lua15
-rw-r--r--test/functional/eval/execute_spec.lua16
-rw-r--r--test/functional/eval/input_spec.lua25
-rw-r--r--test/functional/eval/server_spec.lua76
-rw-r--r--test/functional/eval/system_spec.lua8
-rw-r--r--test/functional/ex_cmds/cmd_map_spec.lua43
-rw-r--r--test/functional/ex_cmds/oldfiles_spec.lua1
-rw-r--r--test/functional/helpers.lua4
-rw-r--r--test/functional/insert/insert_spec.lua41
-rw-r--r--test/functional/insert/last_inserted_spec.lua22
-rw-r--r--test/functional/legacy/077_mf_hash_grow_spec.lua3
-rw-r--r--test/functional/lua/overrides_spec.lua1
-rw-r--r--test/functional/options/defaults_spec.lua276
-rw-r--r--test/functional/options/num_options_spec.lua97
-rw-r--r--test/functional/shada/merging_spec.lua109
-rw-r--r--test/functional/shada/shada_spec.lua6
-rw-r--r--test/functional/terminal/tui_spec.lua14
-rw-r--r--test/functional/ui/cmdline_highlight_spec.lua17
-rw-r--r--test/functional/ui/cursor_spec.lua4
-rw-r--r--test/functional/ui/highlight_spec.lua135
-rw-r--r--test/functional/ui/inccommand_spec.lua1
-rw-r--r--test/functional/ui/input_spec.lua6
-rw-r--r--test/functional/ui/mouse_spec.lua1
-rw-r--r--test/functional/ui/output_spec.lua18
-rw-r--r--test/functional/ui/screen_basic_spec.lua62
-rw-r--r--test/helpers.lua17
31 files changed, 944 insertions, 174 deletions
diff --git a/test/functional/api/highlight_spec.lua b/test/functional/api/highlight_spec.lua
index 2297a0760f..fed53a3dfd 100644
--- a/test/functional/api/highlight_spec.lua
+++ b/test/functional/api/highlight_spec.lua
@@ -99,5 +99,14 @@ describe('highlight api',function()
eq(false, err)
eq('Invalid highlight name: ',
string.match(emsg, 'Invalid.*'))
+
+ -- Test "standout" attribute. #8054
+ eq({ underline = true, },
+ meths.get_hl_by_name('cursorline', 0));
+ command('hi CursorLine cterm=standout,underline term=standout,underline gui=standout,underline')
+ command('set cursorline')
+ eq({ underline = true, standout = true, },
+ meths.get_hl_by_name('cursorline', 0));
+
end)
end)
diff --git a/test/functional/api/ui_spec.lua b/test/functional/api/ui_spec.lua
new file mode 100644
index 0000000000..b028a50b02
--- /dev/null
+++ b/test/functional/api/ui_spec.lua
@@ -0,0 +1,37 @@
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+local clear = helpers.clear
+local eq = helpers.eq
+local eval = helpers.eval
+local expect_err = helpers.expect_err
+local meths = helpers.meths
+local request = helpers.request
+
+describe('nvim_ui_attach()', function()
+ before_each(function()
+ clear()
+ end)
+ it('handles very large width/height #2180', function()
+ local screen = Screen.new(999, 999)
+ screen:attach()
+ eq(999, eval('&lines'))
+ eq(999, eval('&columns'))
+ end)
+ it('invalid option returns error', function()
+ expect_err('No such UI option: foo',
+ meths.ui_attach, 80, 24, { foo={'foo'} })
+ end)
+ it('validates channel arg', function()
+ expect_err('UI not attached to channel: 1',
+ request, 'nvim_ui_try_resize', 40, 10)
+ expect_err('UI not attached to channel: 1',
+ request, 'nvim_ui_set_option', 'rgb', true)
+ expect_err('UI not attached to channel: 1',
+ request, 'nvim_ui_detach')
+
+ local screen = Screen.new()
+ screen:attach({rgb=false})
+ expect_err('UI already attached to channel: 1',
+ request, 'nvim_ui_attach', 40, 10, { rgb=false })
+ end)
+end)
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index bd56161a54..718294d941 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -73,6 +73,8 @@ describe('api', function()
it('captures command output', function()
eq('this is\nspinal tap',
nvim('command_output', [[echo "this is\nspinal tap"]]))
+ eq('no line ending!',
+ nvim('command_output', [[echon "no line ending!"]]))
end)
it('captures empty command output', function()
@@ -579,7 +581,8 @@ describe('api', function()
screen:set_default_attr_ids({
[0] = {bold=true, foreground=Screen.colors.Blue},
[1] = {foreground = Screen.colors.White, background = Screen.colors.Red},
- [2] = {bold = true, foreground = Screen.colors.SeaGreen}
+ [2] = {bold = true, foreground = Screen.colors.SeaGreen},
+ [3] = {bold = true, reverse = true},
})
end)
@@ -600,11 +603,11 @@ describe('api', function()
it('shows return prompt when more than &cmdheight lines', function()
nvim_async('err_write', 'something happened\nvery bad\n')
screen:expect([[
+ |
{0:~ }|
{0:~ }|
{0:~ }|
- {0:~ }|
- {0:~ }|
+ {3: }|
{1:something happened} |
{1:very bad} |
{2:Press ENTER or type command to continue}^ |
@@ -614,9 +617,9 @@ describe('api', function()
it('shows return prompt after all lines are shown', function()
nvim_async('err_write', 'FAILURE\nERROR\nEXCEPTION\nTRACEBACK\n')
screen:expect([[
+ |
{0:~ }|
- {0:~ }|
- {0:~ }|
+ {3: }|
{1:FAILURE} |
{1:ERROR} |
{1:EXCEPTION} |
@@ -644,11 +647,11 @@ describe('api', function()
-- shows up to &cmdheight lines
nvim_async('err_write', 'more fail\ntoo fail\n')
screen:expect([[
+ |
{0:~ }|
{0:~ }|
{0:~ }|
- {0:~ }|
- {0:~ }|
+ {3: }|
{1:more fail} |
{1:too fail} |
{2:Press ENTER or type command to continue}^ |
diff --git a/test/functional/autocmd/cmdline_spec.lua b/test/functional/autocmd/cmdline_spec.lua
index 8ea086fb46..3f0504d02f 100644
--- a/test/functional/autocmd/cmdline_spec.lua
+++ b/test/functional/autocmd/cmdline_spec.lua
@@ -59,24 +59,25 @@ describe('cmdline autocommands', function()
[1] = {bold = true, foreground = Screen.colors.Blue1},
[2] = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
[3] = {bold = true, foreground = Screen.colors.SeaGreen4},
+ [4] = {bold = true, reverse = true},
})
command("autocmd CmdlineEnter * echoerr 'FAIL'")
command("autocmd CmdlineLeave * echoerr 'very error'")
feed(':')
screen:expect([[
+ |
{1:~ }|
{1:~ }|
{1:~ }|
- {1:~ }|
- {1:~ }|
+ {4: }|
: |
{2:E5500: autocmd has thrown an exception: Vim(echoerr):FAIL} |
:^ |
]])
feed("put ='lorem ipsum'<cr>")
screen:expect([[
- {1:~ }|
- {1:~ }|
+ |
+ {4: }|
: |
{2:E5500: autocmd has thrown an exception: Vim(echoerr):FAIL} |
:put ='lorem ipsum' |
diff --git a/test/functional/clipboard/clipboard_provider_spec.lua b/test/functional/clipboard/clipboard_provider_spec.lua
index a3ea3b568f..a40c080a6d 100644
--- a/test/functional/clipboard/clipboard_provider_spec.lua
+++ b/test/functional/clipboard/clipboard_provider_spec.lua
@@ -83,7 +83,14 @@ local function basic_register_test(noblock)
end
describe('clipboard', function()
- before_each(clear)
+ local screen
+
+ before_each(function()
+ clear()
+ screen = Screen.new(72, 4)
+ screen:attach()
+ command("set display-=msgsep")
+ end)
it('unnamed register works without provider', function()
eq('"', eval('v:register'))
@@ -92,8 +99,6 @@ describe('clipboard', function()
it('`:redir @+>` with invalid g:clipboard shows exactly one error #7184',
function()
- local screen = Screen.new(72, 4)
- screen:attach()
command("let g:clipboard = 'bogus'")
feed_command('redir @+> | :silent echo system("cat CONTRIBUTING.md") | redir END')
screen:expect([[
@@ -106,8 +111,6 @@ describe('clipboard', function()
it('`:redir @+>|bogus_cmd|redir END` + invalid g:clipboard must not recurse #7184',
function()
- local screen = Screen.new(72, 4)
- screen:attach()
command("let g:clipboard = 'bogus'")
feed_command('redir @+> | bogus_cmd | redir END')
screen:expect([[
@@ -123,8 +126,6 @@ describe('clipboard', function()
eq('', eval('provider#clipboard#Executable()'))
eq('clipboard: invalid g:clipboard', eval('provider#clipboard#Error()'))
- local screen = Screen.new(72, 4)
- screen:attach()
command("let g:clipboard = 'bogus'")
-- Explicit clipboard attempt, should show a hint message.
feed_command('let @+="foo"')
@@ -493,10 +494,10 @@ describe('clipboard', function()
feed_command("let g:test_clip['+'] = ['such', 'plus', 'stuff']")
feed_command("registers")
screen:expect([[
- ~ |
- ~ |
- ~ |
- ~ |
+ |
+ {0:~ }|
+ {0:~ }|
+ {4: }|
:registers |
{1:--- Registers ---} |
"* some{2:^J}star data{2:^J} |
@@ -504,10 +505,11 @@ describe('clipboard', function()
": let g:test_clip['+'] = ['such', 'plus', 'stuff'] |
{3:Press ENTER or type command to continue}^ |
]], {
+ [0] = {bold = true, foreground = Screen.colors.Blue},
[1] = {bold = true, foreground = Screen.colors.Fuchsia},
[2] = {foreground = Screen.colors.Blue},
- [3] = {bold = true, foreground = Screen.colors.SeaGreen}},
- {{bold = true, foreground = Screen.colors.Blue}})
+ [3] = {bold = true, foreground = Screen.colors.SeaGreen},
+ [4] = {bold = true, reverse = true}})
feed('<cr>') -- clear out of Press ENTER screen
end)
diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua
index 45b739057f..e90339b0cd 100644
--- a/test/functional/core/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -685,6 +685,21 @@ describe('jobs', function()
ok(string.find(err, "E475: Invalid argument: job cannot have both 'pty' and 'rpc' options set") ~= nil)
end)
+ it('does not crash when repeatedly failing to start shell', function()
+ source([[
+ set shell=nosuchshell
+ func! DoIt()
+ call jobstart('true')
+ call jobstart('true')
+ endfunc
+ ]])
+ -- The crash only triggered if both jobs are cleaned up on the same event
+ -- loop tick. This is also prevented by try-block, so feed must be used.
+ feed_command("call DoIt()")
+ feed('<cr>') -- press RETURN
+ eq(2,eval('1+1'))
+ end)
+
it('jobstop() kills entire process tree #6530', function()
-- XXX: Using `nvim` isn't a good test, it reaps its children on exit.
-- local c = 'call jobstart([v:progpath, "-u", "NONE", "-i", "NONE", "--headless"])'
diff --git a/test/functional/eval/execute_spec.lua b/test/functional/eval/execute_spec.lua
index 183884a51e..925e311c7d 100644
--- a/test/functional/eval/execute_spec.lua
+++ b/test/functional/eval/execute_spec.lua
@@ -106,16 +106,22 @@ describe('execute()', function()
end)
it('does not corrupt the command display #5422', function()
- local screen = Screen.new(70, 5)
+ local screen = Screen.new(70, 7)
screen:attach()
feed(':echo execute("hi ErrorMsg")<CR>')
screen:expect([[
- ~ |
- ~ |
+ |
+ {1:~ }|
+ {1:~ }|
+ {2: }|
:echo execute("hi ErrorMsg") |
ErrorMsg xxx ctermfg=15 ctermbg=1 guifg=White guibg=Red |
- Press ENTER or type command to continue^ |
- ]])
+ {3:Press ENTER or type command to continue}^ |
+ ]], {
+ [1] = {bold = true, foreground = Screen.colors.Blue1},
+ [2] = {bold = true, reverse = true},
+ [3] = {bold = true, foreground = Screen.colors.SeaGreen4},
+ })
feed('<CR>')
end)
diff --git a/test/functional/eval/input_spec.lua b/test/functional/eval/input_spec.lua
index 1e6b107c60..777f49462d 100644
--- a/test/functional/eval/input_spec.lua
+++ b/test/functional/eval/input_spec.lua
@@ -58,6 +58,7 @@ before_each(function()
RBP2={background=Screen.colors.Yellow},
RBP3={background=Screen.colors.Green},
RBP4={background=Screen.colors.Blue},
+ SEP={bold = true, reverse = true},
})
end)
@@ -65,9 +66,9 @@ describe('input()', function()
it('works with multiline prompts', function()
feed([[:call input("Test\nFoo")<CR>]])
screen:expect([[
+ |
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {SEP: }|
Test |
Foo^ |
]])
@@ -75,9 +76,9 @@ describe('input()', function()
it('works with multiline prompts and :echohl', function()
feed([[:echohl Test | call input("Test\nFoo")<CR>]])
screen:expect([[
+ |
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {SEP: }|
{T:Test} |
{T:Foo}^ |
]])
@@ -242,17 +243,17 @@ describe('input()', function()
it('is not hidden by :silent', function()
feed([[:silent call input('Foo: ')<CR>]])
screen:expect([[
+ |
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {SEP: }|
Foo: ^ |
|
]])
feed('Bar')
screen:expect([[
+ |
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {SEP: }|
Foo: Bar^ |
|
]])
@@ -263,9 +264,9 @@ describe('inputdialog()', function()
it('works with multiline prompts', function()
feed([[:call inputdialog("Test\nFoo")<CR>]])
screen:expect([[
+ |
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {SEP: }|
Test |
Foo^ |
]])
@@ -273,9 +274,9 @@ describe('inputdialog()', function()
it('works with multiline prompts and :echohl', function()
feed([[:echohl Test | call inputdialog("Test\nFoo")<CR>]])
screen:expect([[
+ |
{EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
+ {SEP: }|
{T:Test} |
{T:Foo}^ |
]])
diff --git a/test/functional/eval/server_spec.lua b/test/functional/eval/server_spec.lua
index 393616838e..4e4aed864b 100644
--- a/test/functional/eval/server_spec.lua
+++ b/test/functional/eval/server_spec.lua
@@ -1,31 +1,40 @@
-
local helpers = require('test.functional.helpers')(after_each)
local eq, neq, eval = helpers.eq, helpers.neq, helpers.eval
local command = helpers.command
local clear, funcs, meths = helpers.clear, helpers.funcs, helpers.meths
-local os_name = helpers.os_name
+local iswin = helpers.iswin
+local ok = helpers.ok
+local matches = helpers.matches
local function clear_serverlist()
- for _, server in pairs(funcs.serverlist()) do
- funcs.serverstop(server)
- end
+ for _, server in pairs(funcs.serverlist()) do
+ funcs.serverstop(server)
+ end
end
-describe('serverstart(), serverstop()', function()
+describe('server', function()
before_each(clear)
- it('sets $NVIM_LISTEN_ADDRESS on first invocation', function()
+ it('serverstart() sets $NVIM_LISTEN_ADDRESS on first invocation', function()
-- Unset $NVIM_LISTEN_ADDRESS
command('let $NVIM_LISTEN_ADDRESS = ""')
local s = eval('serverstart()')
assert(s ~= nil and s:len() > 0, "serverstart() returned empty")
eq(s, eval('$NVIM_LISTEN_ADDRESS'))
- command("call serverstop('"..s.."')")
+ eq(1, eval("serverstop('"..s.."')"))
eq('', eval('$NVIM_LISTEN_ADDRESS'))
end)
- it('sets v:servername _only_ on nvim startup unless all servers are stopped',
+ it('sets new v:servername if $NVIM_LISTEN_ADDRESS is invalid', function()
+ clear({env={NVIM_LISTEN_ADDRESS='.'}})
+ eq('.', eval('$NVIM_LISTEN_ADDRESS'))
+ local servers = funcs.serverlist()
+ eq(1, #servers)
+ ok(string.len(servers[1]) > 4) -- Like /tmp/nvim…/… or \\.\pipe\…
+ end)
+
+ it('sets v:servername at startup or if all servers were stopped',
function()
local initial_server = meths.get_vvar('servername')
assert(initial_server ~= nil and initial_server:len() > 0,
@@ -38,24 +47,23 @@ describe('serverstart(), serverstop()', function()
neq(initial_server, s)
-- serverstop() does _not_ modify v:servername...
- funcs.serverstop(s)
+ eq(1, funcs.serverstop(s))
eq(initial_server, meths.get_vvar('servername'))
-- ...unless we stop _all_ servers.
- funcs.serverstop(funcs.serverlist()[1])
+ eq(1, funcs.serverstop(funcs.serverlist()[1]))
eq('', meths.get_vvar('servername'))
-- v:servername will take the next available server.
- local servername = (os_name() == 'windows'
- and [[\\.\pipe\Xtest-functional-server-pipe]]
- or 'Xtest-functional-server-socket')
+ local servername = (iswin() and [[\\.\pipe\Xtest-functional-server-pipe]]
+ or 'Xtest-functional-server-socket')
funcs.serverstart(servername)
eq(servername, meths.get_vvar('servername'))
end)
- it('serverstop() ignores invalid input', function()
- command("call serverstop('')")
- command("call serverstop('bogus-socket-name')")
+ it('serverstop() returns false for invalid input', function()
+ eq(0, eval("serverstop('')"))
+ eq(0, eval("serverstop('bogus-socket-name')"))
end)
it('parses endpoints correctly', function()
@@ -96,17 +104,13 @@ describe('serverstart(), serverstop()', function()
funcs.serverstart('127.0.0.1:65536') -- invalid port
eq({}, funcs.serverlist())
end)
-end)
-
-describe('serverlist()', function()
- before_each(clear)
- it('returns the list of servers', function()
+ it('serverlist() returns the list of servers', function()
-- There should already be at least one server.
local n = eval('len(serverlist())')
- -- Add a few
- local servs = (os_name() == 'windows'
+ -- Add some servers.
+ local servs = (iswin()
and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] }
or { [[Xtest-pipe0934]], [[Xtest-pipe4324]] })
for _, s in ipairs(servs) do
@@ -120,9 +124,31 @@ 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])
- command("call serverstop('"..servs[i].."')")
+ eq(1, eval("serverstop('"..servs[i].."')"))
end
-- After serverstop() the servers should NOT be in the list.
eq(n, eval('len(serverlist())'))
end)
end)
+
+describe('startup --listen', function()
+ it('validates', function()
+ clear()
+
+ local cmd = { unpack(helpers.nvim_argv) }
+ table.insert(cmd, '--listen')
+ matches('nvim.*: Argument missing after: "%-%-listen"', funcs.system(cmd))
+
+ cmd = { unpack(helpers.nvim_argv) }
+ table.insert(cmd, '--listen2')
+ matches('nvim.*: Garbage after option argument: "%-%-listen2"', funcs.system(cmd))
+ end)
+
+ it('sets v:servername, overrides $NVIM_LISTEN_ADDRESS', function()
+ local addr = (iswin() and [[\\.\pipe\Xtest-listen-pipe]]
+ or 'Xtest-listen-pipe')
+ clear({ env={ NVIM_LISTEN_ADDRESS='Xtest-env-pipe' },
+ args={ '--listen', addr } })
+ eq(addr, meths.get_vvar('servername'))
+ end)
+end)
diff --git a/test/functional/eval/system_spec.lua b/test/functional/eval/system_spec.lua
index 201426c40b..23cea4c038 100644
--- a/test/functional/eval/system_spec.lua
+++ b/test/functional/eval/system_spec.lua
@@ -255,10 +255,8 @@ describe('system()', function()
end
end)
it('to backgrounded command does not crash', function()
- -- cmd.exe doesn't background a command with &
- if iswin() then return end
-- This is indeterminate, just exercise the codepath. May get E5677.
- feed_command('call system("echo -n echoed &")')
+ feed_command('call system(has("win32") ? "start /b /wait cmd /c echo echoed" : "echo -n echoed &")')
local v_errnum = string.match(eval("v:errmsg"), "^E%d*:")
if v_errnum then
eq("E5677:", v_errnum)
@@ -272,10 +270,8 @@ describe('system()', function()
eq("input", eval('system("cat -", "input")'))
end)
it('to backgrounded command does not crash', function()
- -- cmd.exe doesn't background a command with &
- if iswin() then return end
-- This is indeterminate, just exercise the codepath. May get E5677.
- feed_command('call system("cat - &", "input")')
+ feed_command('call system(has("win32") ? "start /b /wait more" : "cat - &", "input")')
local v_errnum = string.match(eval("v:errmsg"), "^E%d*:")
if v_errnum then
eq("E5677:", v_errnum)
diff --git a/test/functional/ex_cmds/cmd_map_spec.lua b/test/functional/ex_cmds/cmd_map_spec.lua
index 5b7f0942b1..77d025dcc7 100644
--- a/test/functional/ex_cmds/cmd_map_spec.lua
+++ b/test/functional/ex_cmds/cmd_map_spec.lua
@@ -27,6 +27,7 @@ describe('mappings with <Cmd>', function()
[4] = {bold = true},
[5] = {background = Screen.colors.LightGrey},
[6] = {foreground = Screen.colors.Blue1},
+ [7] = {bold = true, reverse = true},
})
screen:attach()
@@ -342,11 +343,11 @@ describe('mappings with <Cmd>', function()
-- error doesn't interrupt visual mode
feed('ggvw<F6>')
screen:expect([[
+ {5:some }short lines |
+ of test text |
{1:~ }|
{1:~ }|
- {1:~ }|
- {1:~ }|
- {1:~ }|
+ {7: }|
{2:Error detected while processing :} |
{2:E605: Exception not caught: very error} |
{3:Press ENTER or type command to continue}^ |
@@ -425,11 +426,11 @@ describe('mappings with <Cmd>', function()
-- error doesn't interrupt temporary visual mode
feed('<esc>ggvw<c-g><F6>')
screen:expect([[
+ {5:some }short lines |
+ of test text |
{1:~ }|
{1:~ }|
- {1:~ }|
- {1:~ }|
- {1:~ }|
+ {7: }|
{2:Error detected while processing :} |
{2:E605: Exception not caught: very error} |
{3:Press ENTER or type command to continue}^ |
@@ -453,11 +454,11 @@ describe('mappings with <Cmd>', function()
-- error doesn't interrupt select mode
feed('<esc>ggvw<c-g><F1>')
screen:expect([[
+ {5:some }short lines |
+ of test text |
{1:~ }|
{1:~ }|
- {1:~ }|
- {1:~ }|
- {1:~ }|
+ {7: }|
{2:Error detected while processing :} |
{2:E605: Exception not caught: very error} |
{3:Press ENTER or type command to continue}^ |
@@ -527,11 +528,11 @@ describe('mappings with <Cmd>', function()
-- error aborts operator-pending, operator not performed
feed('d<F6>')
screen:expect([[
+ some short lines |
+ of test text |
{1:~ }|
{1:~ }|
- {1:~ }|
- {1:~ }|
- {1:~ }|
+ {7: }|
{2:Error detected while processing :} |
{2:E605: Exception not caught: very error} |
{3:Press ENTER or type command to continue}^ |
@@ -571,11 +572,11 @@ describe('mappings with <Cmd>', function()
feed('<F6>')
screen:expect([[
+ indeed some short little lines |
+ of test text |
{1:~ }|
{1:~ }|
- {1:~ }|
- {1:~ }|
- {1:~ }|
+ {7: }|
{2:Error detected while processing :} |
{2:E605: Exception not caught: very error} |
{3:Press ENTER or type command to continue}^ |
@@ -675,10 +676,10 @@ describe('mappings with <Cmd>', function()
feed(':echo 2<F6>')
screen:expect([[
+ some short lines |
+ of test text |
{1:~ }|
- {1:~ }|
- {1:~ }|
- {1:~ }|
+ {7: }|
:echo 2 |
{2:Error detected while processing :} |
{2:E605: Exception not caught: very error} |
@@ -689,9 +690,9 @@ describe('mappings with <Cmd>', function()
eq('c', eval('mode(1)'))
feed('+2<cr>')
screen:expect([[
- {1:~ }|
- {1:~ }|
- {1:~ }|
+ some short lines |
+ of test text |
+ {7: }|
:echo 2 |
{2:Error detected while processing :} |
{2:E605: Exception not caught: very error} |
diff --git a/test/functional/ex_cmds/oldfiles_spec.lua b/test/functional/ex_cmds/oldfiles_spec.lua
index 4002855c24..448326cdfb 100644
--- a/test/functional/ex_cmds/oldfiles_spec.lua
+++ b/test/functional/ex_cmds/oldfiles_spec.lua
@@ -29,6 +29,7 @@ describe(':oldfiles', function()
it('shows most recently used files', function()
local screen = Screen.new(100, 5)
screen:attach()
+ feed_command("set display-=msgsep")
feed_command('edit testfile1')
feed_command('edit testfile2')
feed_command('wshada')
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index f2f5a6220c..03c6f3bbaa 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -14,8 +14,10 @@ local check_cores = global_helpers.check_cores
local check_logs = global_helpers.check_logs
local neq = global_helpers.neq
local eq = global_helpers.eq
+local expect_err = global_helpers.expect_err
local ok = global_helpers.ok
local map = global_helpers.map
+local matches = global_helpers.matches
local filter = global_helpers.filter
local dedent = global_helpers.dedent
local table_flatten = global_helpers.table_flatten
@@ -736,6 +738,7 @@ local module = {
exc_exec = exc_exec,
expect = expect,
expect_any = expect_any,
+ expect_err = expect_err,
expect_msg_seq = expect_msg_seq,
expect_twostreams = expect_twostreams,
feed = feed,
@@ -747,6 +750,7 @@ local module = {
insert = insert,
iswin = iswin,
map = map,
+ matches = matches,
merge_args = merge_args,
meth_pcall = meth_pcall,
meths = meths,
diff --git a/test/functional/insert/insert_spec.lua b/test/functional/insert/insert_spec.lua
new file mode 100644
index 0000000000..427954f5a6
--- /dev/null
+++ b/test/functional/insert/insert_spec.lua
@@ -0,0 +1,41 @@
+local helpers = require('test.functional.helpers')(after_each)
+local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
+local command = helpers.command
+local eq = helpers.eq
+local expect = helpers.expect
+local funcs = helpers.funcs
+
+describe('insert-mode', function()
+ before_each(function()
+ clear()
+ end)
+
+ it('CTRL-@', function()
+ -- Inserts last-inserted text, leaves insert-mode.
+ insert('hello')
+ feed('i<C-@>x')
+ expect('hellhello')
+
+ -- C-Space is the same as C-@.
+ -- CTRL-SPC inserts last-inserted text, leaves insert-mode.
+ feed('i<C-Space>x')
+ expect('hellhellhello')
+
+ -- CTRL-A inserts last inserted text
+ feed('i<C-A>x')
+ expect('hellhellhellhelloxo')
+ end)
+
+ it('ALT/META #8213', function()
+ -- Mapped ALT-chord behaves as mapped.
+ command('inoremap <M-l> meta-l')
+ command('inoremap <A-j> alt-j')
+ feed('i<M-l> xxx <A-j><M-h>a<A-h>')
+ expect('meta-l xxx alt-j')
+ eq({ 0, 1, 14, 0, }, funcs.getpos('.'))
+ -- Unmapped ALT-chord behaves as ESC+c.
+ command('iunmap <M-l>')
+ feed('0i<M-l>')
+ eq({ 0, 1, 2, 0, }, funcs.getpos('.'))
+ end)
+end)
diff --git a/test/functional/insert/last_inserted_spec.lua b/test/functional/insert/last_inserted_spec.lua
deleted file mode 100644
index dce23a3790..0000000000
--- a/test/functional/insert/last_inserted_spec.lua
+++ /dev/null
@@ -1,22 +0,0 @@
-local helpers = require('test.functional.helpers')(after_each)
-local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
-local expect = helpers.expect
-
-clear()
-
-describe('insert-mode', function()
- it('CTRL-@ inserts last-inserted text, leaves insert-mode', function()
- insert('hello')
- feed('i<C-@>x')
- expect('hellhello')
- end)
- -- C-Space is the same as C-@
- it('CTRL-SPC inserts last-inserted text, leaves insert-mode', function()
- feed('i<C-Space>x')
- expect('hellhellhello')
- end)
- it('CTRL-A inserts last inserted text', function()
- feed('i<C-A>x')
- expect('hellhellhellhelloxo')
- end)
-end)
diff --git a/test/functional/legacy/077_mf_hash_grow_spec.lua b/test/functional/legacy/077_mf_hash_grow_spec.lua
index c692127213..4719a3ecbf 100644
--- a/test/functional/legacy/077_mf_hash_grow_spec.lua
+++ b/test/functional/legacy/077_mf_hash_grow_spec.lua
@@ -18,7 +18,8 @@ describe('mf_hash_grow()', function()
setup(clear)
-- Check to see if cksum exists, otherwise skip the test
- if os.execute('which cksum 2>&1 > /dev/null') ~= 0 then
+ local null = helpers.iswin() and 'nul' or '/dev/null'
+ if os.execute('cksum --help >' .. null .. ' 2>&1') ~= 0 then
pending('was not tested because cksum was not found', function() end)
else
it('is working', function()
diff --git a/test/functional/lua/overrides_spec.lua b/test/functional/lua/overrides_spec.lua
index 8ca5fe57ba..007d40874f 100644
--- a/test/functional/lua/overrides_spec.lua
+++ b/test/functional/lua/overrides_spec.lua
@@ -87,6 +87,7 @@ describe('debug.debug', function()
E = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
cr = {bold = true, foreground = Screen.colors.SeaGreen4},
})
+ command("set display-=msgsep")
end)
it('works', function()
command([[lua
diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua
index 9e29baba2d..f452cafd22 100644
--- a/test/functional/options/defaults_spec.lua
+++ b/test/functional/options/defaults_spec.lua
@@ -5,12 +5,15 @@ local Screen = require('test.functional.ui.screen')
local meths = helpers.meths
local command = helpers.command
local clear = helpers.clear
+local exc_exec = helpers.exc_exec
local eval = helpers.eval
local eq = helpers.eq
+local funcs = helpers.funcs
local insert = helpers.insert
local neq = helpers.neq
local mkdir = helpers.mkdir
local rmdir = helpers.rmdir
+local alter_slashes = helpers.alter_slashes
describe('startup defaults', function()
describe(':filetype', function()
@@ -422,3 +425,276 @@ describe('XDG-based defaults', function()
end)
end)
end)
+
+
+describe('stdpath()', function()
+ context('returns a String', function()
+ describe('with "config"' , function ()
+ it('knows XDG_CONFIG_HOME', function()
+ clear({env={
+ XDG_CONFIG_HOME=alter_slashes('/home/docwhat/.config'),
+ }})
+ eq(alter_slashes('/home/docwhat/.config/nvim'), funcs.stdpath('config'))
+ end)
+
+ it('handles changes during runtime', function()
+ clear({env={
+ XDG_CONFIG_HOME=alter_slashes('/home/original'),
+ }})
+ eq(alter_slashes('/home/original/nvim'), funcs.stdpath('config'))
+ command("let $XDG_CONFIG_HOME='"..alter_slashes('/home/new').."'")
+ eq(alter_slashes('/home/new/nvim'), funcs.stdpath('config'))
+ end)
+
+ it("doesn't expand $VARIABLES", function()
+ clear({env={
+ XDG_CONFIG_HOME='$VARIABLES',
+ VARIABLES='this-should-not-happen',
+ }})
+ eq(alter_slashes('$VARIABLES/nvim'), funcs.stdpath('config'))
+ end)
+
+ it("doesn't expand ~/", function()
+ clear({env={
+ XDG_CONFIG_HOME=alter_slashes('~/frobnitz'),
+ }})
+ eq(alter_slashes('~/frobnitz/nvim'), funcs.stdpath('config'))
+ end)
+ end)
+
+ describe('with "data"' , function ()
+ local appended_dir
+ setup(function()
+ -- Windows appends 'nvim-data' instead of just 'nvim' to
+ -- prevent collisions due to XDG_CONFIG_HOME and XDG_DATA_HOME
+ -- being the same.
+ if helpers.iswin() then
+ appended_dir = '/nvim-data'
+ else
+ appended_dir = '/nvim'
+ end
+ end)
+
+ it('knows XDG_DATA_HOME', function()
+ clear({env={
+ XDG_DATA_HOME=alter_slashes('/home/docwhat/.local'),
+ }})
+ eq(alter_slashes('/home/docwhat/.local' .. appended_dir), funcs.stdpath('data'))
+ end)
+
+ it('handles changes during runtime', function()
+ clear({env={
+ XDG_DATA_HOME=alter_slashes('/home/original'),
+ }})
+ eq(alter_slashes('/home/original' .. appended_dir), funcs.stdpath('data'))
+ command("let $XDG_DATA_HOME='"..alter_slashes('/home/new').."'")
+ eq(alter_slashes('/home/new' .. appended_dir), funcs.stdpath('data'))
+ end)
+
+ it("doesn't expand $VARIABLES", function()
+ clear({env={
+ XDG_DATA_HOME='$VARIABLES',
+ VARIABLES='this-should-not-happen',
+ }})
+ eq(alter_slashes('$VARIABLES' .. appended_dir), funcs.stdpath('data'))
+ end)
+
+ it("doesn't expand ~/", function()
+ clear({env={
+ XDG_DATA_HOME=alter_slashes('~/frobnitz'),
+ }})
+ eq(alter_slashes('~/frobnitz' .. appended_dir), funcs.stdpath('data'))
+ end)
+ end)
+
+ describe('with "cache"' , function ()
+ it('knows XDG_CACHE_HOME', function()
+ clear({env={
+ XDG_CACHE_HOME=alter_slashes('/home/docwhat/.cache'),
+ }})
+ eq(alter_slashes('/home/docwhat/.cache/nvim'), funcs.stdpath('cache'))
+ end)
+
+ it('handles changes during runtime', function()
+ clear({env={
+ XDG_CACHE_HOME=alter_slashes('/home/original'),
+ }})
+ eq(alter_slashes('/home/original/nvim'), funcs.stdpath('cache'))
+ command("let $XDG_CACHE_HOME='"..alter_slashes('/home/new').."'")
+ eq(alter_slashes('/home/new/nvim'), funcs.stdpath('cache'))
+ end)
+
+ it("doesn't expand $VARIABLES", function()
+ clear({env={
+ XDG_CACHE_HOME='$VARIABLES',
+ VARIABLES='this-should-not-happen',
+ }})
+ eq(alter_slashes('$VARIABLES/nvim'), funcs.stdpath('cache'))
+ end)
+
+ it("doesn't expand ~/", function()
+ clear({env={
+ XDG_CACHE_HOME=alter_slashes('~/frobnitz'),
+ }})
+ eq(alter_slashes('~/frobnitz/nvim'), funcs.stdpath('cache'))
+ end)
+ end)
+ end)
+
+ context('returns a List', function()
+ -- Some OS specific variables the system would have set.
+ local function base_env()
+ if helpers.iswin() then
+ return {
+ HOME='C:\\Users\\docwhat', -- technically, is not a usual PATH
+ HOMEDRIVE='C:',
+ HOMEPATH='\\Users\\docwhat',
+ LOCALAPPDATA='C:\\Users\\docwhat\\AppData\\Local',
+ TEMP='C:\\Users\\docwhat\\AppData\\Local\\Temp',
+ TMPDIR='C:\\Users\\docwhat\\AppData\\Local\\Temp',
+ TMP='C:\\Users\\docwhat\\AppData\\Local\\Temp',
+ }
+ else
+ return {
+ HOME='/home/docwhat',
+ HOMEDRIVE='HOMEDRIVE-should-be-ignored',
+ HOMEPATH='HOMEPATH-should-be-ignored',
+ LOCALAPPDATA='LOCALAPPDATA-should-be-ignored',
+ TEMP='TEMP-should-be-ignored',
+ TMPDIR='TMPDIR-should-be-ignored',
+ TMP='TMP-should-be-ignored',
+ }
+ end
+ end
+
+ local function set_paths_via_system(var_name, paths)
+ local env = base_env()
+ env[var_name] = table.concat(paths, ':')
+ clear({env=env})
+ end
+
+ local function set_paths_at_runtime(var_name, paths)
+ clear({env=base_env()})
+ meths.set_var('env_val', table.concat(paths, ':'))
+ command(('let $%s=g:env_val'):format(var_name))
+ end
+
+ local function behaves_like_dir_list_env(msg, stdpath_arg, env_var_name, paths, expected_paths)
+ describe(msg, function()
+ it('set via system', function()
+ set_paths_via_system(env_var_name, paths)
+ eq(expected_paths, funcs.stdpath(stdpath_arg))
+ end)
+
+ it('set at runtime', function()
+ set_paths_at_runtime(env_var_name, paths)
+ eq(expected_paths, funcs.stdpath(stdpath_arg))
+ end)
+ end)
+ end
+
+ describe('with "config_dirs"' , function ()
+ behaves_like_dir_list_env(
+ 'handles XDG_CONFIG_DIRS with one path',
+ 'config_dirs', 'XDG_CONFIG_DIRS',
+ {
+ alter_slashes('/home/docwhat/.config')
+ },
+ {
+ alter_slashes('/home/docwhat/.config/nvim')
+ })
+
+ behaves_like_dir_list_env(
+ 'handles XDG_CONFIG_DIRS with two paths',
+ 'config_dirs', 'XDG_CONFIG_DIRS',
+ {
+ alter_slashes('/home/docwhat/.config'),
+ alter_slashes('/etc/config')
+ },
+ {
+ alter_slashes('/home/docwhat/.config/nvim'),
+ alter_slashes('/etc/config/nvim')
+ })
+
+ behaves_like_dir_list_env(
+ "doesn't expand $VAR and $IBLES",
+ 'config_dirs', 'XDG_CONFIG_DIRS',
+ { '$HOME', '$TMP' },
+ {
+ alter_slashes('$HOME/nvim'),
+ alter_slashes('$TMP/nvim')
+ })
+
+
+ behaves_like_dir_list_env(
+ "doesn't expand ~/",
+ 'config_dirs', 'XDG_CONFIG_DIRS',
+ {
+ alter_slashes('~/.oldconfig'),
+ alter_slashes('~/.olderconfig')
+ },
+ {
+ alter_slashes('~/.oldconfig/nvim'),
+ alter_slashes('~/.olderconfig/nvim')
+ })
+ end)
+
+ describe('with "data_dirs"' , function ()
+ behaves_like_dir_list_env(
+ 'knows XDG_DATA_DIRS with one path',
+ 'data_dirs', 'XDG_DATA_DIRS',
+ {
+ alter_slashes('/home/docwhat/.data')
+ },
+ {
+ alter_slashes('/home/docwhat/.data/nvim')
+ })
+
+ behaves_like_dir_list_env(
+ 'knows XDG_DATA_DIRS with two paths',
+ 'data_dirs', 'XDG_DATA_DIRS',
+ {
+ alter_slashes('/home/docwhat/.data'),
+ alter_slashes('/etc/local')
+ },
+ {
+ alter_slashes('/home/docwhat/.data/nvim'),
+ alter_slashes('/etc/local/nvim'),
+ })
+
+ behaves_like_dir_list_env(
+ "doesn't expand $VAR and $IBLES",
+ 'data_dirs', 'XDG_DATA_DIRS',
+ { '$HOME', '$TMP' },
+ {
+ alter_slashes('$HOME/nvim'),
+ alter_slashes('$TMP/nvim')
+ })
+
+ behaves_like_dir_list_env(
+ "doesn't expand ~/",
+ 'data_dirs', 'XDG_DATA_DIRS',
+ {
+ alter_slashes('~/.oldconfig'),
+ alter_slashes('~/.olderconfig')
+ },
+ {
+ alter_slashes('~/.oldconfig/nvim'),
+ alter_slashes('~/.olderconfig/nvim'),
+ })
+ end)
+ end)
+
+ describe('errors', function()
+ it('on unknown strings', function()
+ eq('Vim(call):E6100: "capybara" is not a valid stdpath', exc_exec('call stdpath("capybara")'))
+ eq('Vim(call):E6100: "" is not a valid stdpath', exc_exec('call stdpath("")'))
+ eq('Vim(call):E6100: "23" is not a valid stdpath', exc_exec('call stdpath(23)'))
+ end)
+
+ it('on non-strings', function()
+ eq('Vim(call):E731: using Dictionary as a String', exc_exec('call stdpath({"eris": 23})'))
+ eq('Vim(call):E730: using List as a String', exc_exec('call stdpath([23])'))
+ end)
+ end)
+end)
diff --git a/test/functional/options/num_options_spec.lua b/test/functional/options/num_options_spec.lua
new file mode 100644
index 0000000000..ed17ffdd3c
--- /dev/null
+++ b/test/functional/options/num_options_spec.lua
@@ -0,0 +1,97 @@
+-- Tests for :setlocal and :setglobal
+
+local helpers = require('test.functional.helpers')(after_each)
+local clear, feed_command, eval, eq, meths =
+ helpers.clear, helpers.feed_command, helpers.eval, helpers.eq, helpers.meths
+
+local function should_fail(opt, value, errmsg)
+ feed_command('setglobal ' .. opt .. '=' .. value)
+ eq(errmsg, eval("v:errmsg"):match("E%d*"))
+ feed_command('let v:errmsg = ""')
+ feed_command('setlocal ' .. opt .. '=' .. value)
+ eq(errmsg, eval("v:errmsg"):match("E%d*"))
+ feed_command('let v:errmsg = ""')
+ local status, err = pcall(meths.set_option, opt, value)
+ eq(status, false)
+ eq(errmsg, err:match("E%d*"))
+ eq('', eval("v:errmsg"))
+end
+
+local function should_succeed(opt, value)
+ feed_command('setglobal ' .. opt .. '=' .. value)
+ feed_command('setlocal ' .. opt .. '=' .. value)
+ meths.set_option(opt, value)
+ eq(value, meths.get_option(opt))
+ eq('', eval("v:errmsg"))
+end
+
+describe(':setlocal', function()
+ before_each(clear)
+
+ it('setlocal sets only local value', function()
+ eq(0, meths.get_option('iminsert'))
+ feed_command('setlocal iminsert=1')
+ eq(0, meths.get_option('iminsert'))
+ eq(0, meths.get_option('imsearch'))
+ feed_command('setlocal imsearch=1')
+ eq(0, meths.get_option('imsearch'))
+ end)
+end)
+
+describe(':set validation', function()
+ before_each(clear)
+
+ it('setlocal and setglobal validate values', function()
+ should_fail('shiftwidth', -10, 'E487')
+ should_succeed('shiftwidth', 0)
+ should_fail('tabstop', -10, 'E487')
+ should_fail('winheight', -10, 'E487')
+ should_fail('winheight', 0, 'E487')
+ should_fail('winminheight', -1, 'E487')
+ should_succeed('winminheight', 0)
+ should_fail('winwidth', 0, 'E487')
+ should_fail('helpheight', -1, 'E487')
+ should_fail('maxcombine', 7, 'E474')
+ should_fail('iminsert', 3, 'E474')
+ should_fail('imsearch', 3, 'E474')
+ should_fail('titlelen', -1, 'E487')
+ should_fail('cmdheight', 0, 'E487')
+ should_fail('updatecount', -1, 'E487')
+ should_fail('textwidth', -1, 'E487')
+ should_fail('tabstop', 0, 'E487')
+ should_fail('timeoutlen', -1, 'E487')
+ should_fail('history', 1000000, 'E474')
+ should_fail('regexpengine', -1, 'E474')
+ should_fail('regexpengine', 3, 'E474')
+ should_succeed('regexpengine', 2)
+ should_fail('report', -1, 'E487')
+ should_succeed('report', 0)
+ should_fail('scrolloff', -1, 'E49')
+ should_fail('sidescrolloff', -1, 'E487')
+ should_fail('sidescroll', -1, 'E487')
+ should_fail('cmdwinheight', 0, 'E487')
+ should_fail('updatetime', -1, 'E487')
+
+ should_fail('foldlevel', -5, 'E487')
+ should_fail('foldcolumn', 13, 'E474')
+ should_fail('conceallevel', 4, 'E474')
+ should_fail('numberwidth', 11, 'E474')
+ should_fail('numberwidth', 0, 'E487')
+
+ -- If smaller than 1 this one is set to 'lines'-1
+ feed_command('setglobal window=-10')
+ meths.set_option('window', -10)
+ eq(23, meths.get_option('window'))
+ eq('', eval("v:errmsg"))
+ end)
+
+ it('set wmh/wh wmw/wiw checks', function()
+ feed_command('set winheight=2')
+ feed_command('set winminheight=3')
+ eq('E591', eval("v:errmsg"):match("E%d*"))
+
+ feed_command('set winwidth=2')
+ feed_command('set winminwidth=3')
+ eq('E592', eval("v:errmsg"):match("E%d*"))
+ end)
+end)
diff --git a/test/functional/shada/merging_spec.lua b/test/functional/shada/merging_spec.lua
index 7a15c8908b..a628baff53 100644
--- a/test/functional/shada/merging_spec.lua
+++ b/test/functional/shada/merging_spec.lua
@@ -525,6 +525,85 @@ describe('ShaDa marks support code', function()
eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t'))
end)
+ it('can merge with file with mark 9 as the only numeric mark', function()
+ wshada('\007\001\014\130\161f\196\006' .. mock_file_path .. '-\161n9')
+ eq(0, exc_exec(sdrcmd()))
+ nvim_command('normal! `9oabc')
+ eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t'))
+ eq(0, exc_exec('wshada ' .. shada_fname))
+ local found = {}
+ for _, v in ipairs(read_shada_file(shada_fname)) do
+ if v.type == 7 and v.value.f == mock_file_path .. '-' then
+ local name = ('%c'):format(v.value.n)
+ found[name] = (found[name] or 0) + 1
+ end
+ end
+ eq({['0']=1, ['1']=1}, found)
+ end)
+
+ it('removes duplicates while merging', function()
+ wshada('\007\001\014\130\161f\196\006' .. mock_file_path .. '-\161n9'
+ .. '\007\001\014\130\161f\196\006' .. mock_file_path .. '-\161n9')
+ eq(0, exc_exec(sdrcmd()))
+ eq(0, exc_exec('wshada ' .. shada_fname))
+ local found = 0
+ for _, v in ipairs(read_shada_file(shada_fname)) do
+ if v.type == 7 and v.value.f == mock_file_path .. '-' then
+ print(require('test.helpers').format_luav(v))
+ found = found + 1
+ end
+ end
+ eq(1, found)
+ end)
+
+ it('does not leak when no append is performed due to too many marks',
+ function()
+ wshada('\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'a\161n0'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'b\161n1'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161n2'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161n3'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'e\161n4'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'f\161n5'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'g\161n6'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'h\161n7'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'i\161n8'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'j\161n9'
+ .. '\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'k\161n9')
+ eq(0, exc_exec(sdrcmd()))
+ eq(0, exc_exec('wshada ' .. shada_fname))
+ local found = {}
+ for _, v in ipairs(read_shada_file(shada_fname)) do
+ if v.type == 7 and v.value.f:sub(1, #mock_file_path) == mock_file_path then
+ found[#found + 1] = v.value.f:sub(#v.value.f)
+ end
+ end
+ eq({'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'}, found)
+ end)
+
+ it('does not leak when last mark in file removes some of the earlier ones',
+ function()
+ wshada('\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'a\161n0'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'b\161n1'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'c\161n2'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'd\161n3'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'e\161n4'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'f\161n5'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'g\161n6'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'h\161n7'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'i\161n8'
+ .. '\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'j\161n9'
+ .. '\007\003\018\131\162mX\195\161f\196\006' .. mock_file_path .. 'k\161n9')
+ eq(0, exc_exec(sdrcmd()))
+ eq(0, exc_exec('wshada ' .. shada_fname))
+ local found = {}
+ for _, v in ipairs(read_shada_file(shada_fname)) do
+ if v.type == 7 and v.value.f:sub(1, #mock_file_path) == mock_file_path then
+ found[#found + 1] = v.value.f:sub(#v.value.f)
+ end
+ end
+ eq({'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'k'}, found)
+ end)
+
it('uses last A mark with gt timestamp from file when reading with !',
function()
wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
@@ -563,13 +642,14 @@ describe('ShaDa marks support code', function()
nvim_command('normal! `A')
eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t'))
eq(0, exc_exec('wshada ' .. shada_fname))
- local found = 0
+ local found = {}
for _, v in ipairs(read_shada_file(shada_fname)) do
- if v.type == 7 and v.value.f == '' .. mock_file_path .. '-' then
- found = found + 1
+ if v.type == 7 and v.value.f == mock_file_path .. '-' then
+ local name = ('%c'):format(v.value.n)
+ found[name] = (found[name] or 0) + 1
end
end
- eq(1, found)
+ eq({['0']=1, A=1}, found)
end)
it('uses last A mark with eq timestamp from instance when writing',
@@ -580,30 +660,33 @@ describe('ShaDa marks support code', function()
nvim_command('normal! `A')
eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t'))
eq(0, exc_exec('wshada ' .. shada_fname))
- local found = 0
+ local found = {}
for _, v in ipairs(read_shada_file(shada_fname)) do
if v.type == 7 and v.value.f == mock_file_path .. '-' then
- found = found + 1
+ local name = ('%c'):format(v.value.n)
+ found[name] = (found[name] or 0) + 1
end
end
- eq(1, found)
+ eq({['0']=1, A=1}, found)
end)
- it('uses last A mark with gt timestamp from file when writing',
- function()
+ it('uses last A mark with gt timestamp from file when writing', function()
wshada('\007\001\018\131\162mX\195\161f\196\006' .. mock_file_path .. '-\161nA')
eq(0, exc_exec(sdrcmd()))
wshada('\007\002\018\131\162mX\195\161f\196\006' .. mock_file_path .. '?\161nA')
nvim_command('normal! `A')
eq('-', funcs.fnamemodify(curbufmeths.get_name(), ':t'))
eq(0, exc_exec('wshada ' .. shada_fname))
- local found = 0
+ local found = {}
for _, v in ipairs(read_shada_file(shada_fname)) do
- if v.type == 7 and v.value.f == '' .. mock_file_path .. '?' then
- found = found + 1
+ if v.type == 7 then
+ local name = ('%c'):format(v.value.n)
+ local t = found[name] or {}
+ t[v.value.f] = (t[v.value.f] or 0) + 1
+ found[name] = t
end
end
- eq(1, found)
+ eq({['0']={[mock_file_path .. '-']=1}, A={[mock_file_path .. '?']=1}}, found)
end)
it('uses last a mark with gt timestamp from instance when reading',
diff --git a/test/functional/shada/shada_spec.lua b/test/functional/shada/shada_spec.lua
index ca44026852..720855860a 100644
--- a/test/functional/shada/shada_spec.lua
+++ b/test/functional/shada/shada_spec.lua
@@ -181,13 +181,13 @@ describe('ShaDa support code', function()
nvim_command('set shada+=%')
nvim_command('wshada! ' .. shada_fname)
local readme_fname = funcs.resolve(paths.test_source_path) .. '/README.md'
- eq({[7]=1, [8]=2, [9]=1, [10]=4, [11]=1}, find_file(readme_fname))
+ eq({[7]=2, [8]=2, [9]=1, [10]=4, [11]=1}, find_file(readme_fname))
nvim_command('set shada+=r~')
nvim_command('wshada! ' .. shada_fname)
eq({}, find_file(readme_fname))
nvim_command('set shada-=r~')
nvim_command('wshada! ' .. shada_fname)
- eq({[7]=1, [8]=2, [9]=1, [10]=4, [11]=1}, find_file(readme_fname))
+ eq({[7]=2, [8]=2, [9]=1, [10]=4, [11]=1}, find_file(readme_fname))
nvim_command('set shada+=r' .. funcs.escape(
funcs.escape(paths.test_source_path, '$~'), ' "\\,'))
nvim_command('wshada! ' .. shada_fname)
@@ -206,7 +206,7 @@ describe('ShaDa support code', function()
nvim_command('undo')
nvim_command('set shada+=%')
nvim_command('wshada! ' .. shada_fname)
- eq({[7]=1, [8]=2, [9]=1, [10]=4, [11]=2}, find_file(fname))
+ eq({[7]=2, [8]=2, [9]=1, [10]=4, [11]=2}, find_file(fname))
nvim_command('set shada+=r' .. pwd .. '/АБВ')
nvim_command('wshada! ' .. shada_fname)
eq({}, find_file(fname))
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index 171745eb57..2f9abfd3f6 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -115,16 +115,12 @@ describe('tui', function()
]])
end)
- it('does not mangle unmapped ALT-key chord', function()
- -- Vim represents ALT/META by setting the "high bit" of the modified key;
- -- we do _not_. #3982
- --
- -- Example: for input ALT+j:
- -- * Vim (Nvim prior to #3982) sets high-bit, inserts "ê".
- -- * Nvim (after #3982) inserts "j".
- feed_data('i\027j')
+ it('interprets ESC+key as ALT chord', function()
+ -- Vim represents ALT/META by setting the "high bit" of the modified key:
+ -- ALT+j inserts "ê". Nvim does not (#3982).
+ feed_data('i\022\027j')
screen:expect([[
- j{1: } |
+ <M-j>{1: } |
{4:~ }|
{4:~ }|
{4:~ }|
diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua
index ffb6a26aef..3c316d1cfa 100644
--- a/test/functional/ui/cmdline_highlight_spec.lua
+++ b/test/functional/ui/cmdline_highlight_spec.lua
@@ -24,6 +24,7 @@ before_each(function()
clear()
screen = Screen.new(40, 8)
screen:attach()
+ command("set display-=msgsep")
source([[
highlight RBP1 guibg=Red
highlight RBP2 guibg=Yellow
@@ -737,6 +738,22 @@ describe('Command-line coloring', function()
feed('<CR><CR>')
eq('', meths.get_var('out'))
end)
+ it('does not crash when callback has caught not-a-editor-command exception',
+ function()
+ source([[
+ function CaughtExc(cmdline) abort
+ try
+ gibberish
+ catch
+ " Do nothing
+ endtry
+ return []
+ endfunction
+ ]])
+ set_color_cb('CaughtExc')
+ start_prompt('1')
+ eq(1, meths.eval('1'))
+ end)
end)
describe('Ex commands coloring support', function()
it('works', function()
diff --git a/test/functional/ui/cursor_spec.lua b/test/functional/ui/cursor_spec.lua
index b47210a777..812c095add 100644
--- a/test/functional/ui/cursor_spec.lua
+++ b/test/functional/ui/cursor_spec.lua
@@ -194,8 +194,8 @@ describe('ui/cursor', function()
if m.blinkoff then m.blinkoff = 400 end
if m.blinkwait then m.blinkwait = 700 end
end
- if m.hl_id then m.hl_id = 48 end
- if m.id_lm then m.id_lm = 49 end
+ if m.hl_id then m.hl_id = 49 end
+ if m.id_lm then m.id_lm = 50 end
end
-- Assert the new expectation.
diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua
index 6f1b31964b..ab3b1c3cac 100644
--- a/test/functional/ui/highlight_spec.lua
+++ b/test/functional/ui/highlight_spec.lua
@@ -94,6 +94,7 @@ describe('highlight defaults', function()
clear()
screen = Screen.new()
screen:attach()
+ command("set display-=msgsep")
end)
after_each(function()
@@ -312,7 +313,7 @@ describe('highlight defaults', function()
end)
end)
-describe('guisp (special/undercurl)', function()
+describe('highlight', function()
local screen
before_each(function()
@@ -321,7 +322,31 @@ describe('guisp (special/undercurl)', function()
screen:attach()
end)
- it('can be set and is applied like foreground or background', function()
+ it('cterm=standout gui=standout', function()
+ screen:detach()
+ screen = Screen.new(20,5)
+ screen:attach()
+ screen:set_default_attr_ids({
+ [1] = {bold = true, foreground = Screen.colors.Blue1},
+ [2] = {standout = true, bold = true, underline = true,
+ background = Screen.colors.Gray90, foreground = Screen.colors.Blue1},
+ [3] = {standout = true, underline = true,
+ background = Screen.colors.Gray90}
+ })
+ feed_command('hi CursorLine cterm=standout,underline gui=standout,underline')
+ feed_command('set cursorline')
+ feed_command('set listchars=space:.,eol:¬,tab:>-,extends:>,precedes:<,trail:* list')
+ feed('i\t abcd <cr>\t abcd <cr><esc>k')
+ screen:expect([[
+ {1:>-------.}abcd{1:*¬} |
+ {2:^>-------.}{3:abcd}{2:*¬}{3: }|
+ {1:¬} |
+ {1:~ }|
+ |
+ ]])
+ end)
+
+ it('guisp (special/undercurl)', function()
feed_command('syntax on')
feed_command('syn keyword TmpKeyword neovim')
feed_command('syn keyword TmpKeyword1 special')
@@ -650,6 +675,76 @@ describe("'listchars' highlight", function()
end)
end)
+describe("MsgSeparator highlight and msgsep fillchar", function()
+ before_each(clear)
+ it("works", function()
+ local screen = Screen.new(50,5)
+ screen:set_default_attr_ids({
+ [1] = {bold=true, foreground=Screen.colors.Blue},
+ [2] = {bold=true, reverse=true},
+ [3] = {bold = true, foreground = Screen.colors.SeaGreen4},
+ [4] = {background = Screen.colors.Cyan, bold = true, reverse = true},
+ [5] = {bold = true, background = Screen.colors.Magenta}
+ })
+ screen:attach()
+
+ -- defaults
+ feed_command("ls")
+ screen:expect([[
+ |
+ {2: }|
+ :ls |
+ 1 %a "[No Name]" line 1 |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ feed('<cr>')
+
+ feed_command("set fillchars+=msgsep:-")
+ feed_command("ls")
+ screen:expect([[
+ |
+ {2:--------------------------------------------------}|
+ :ls |
+ 1 %a "[No Name]" line 1 |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+
+ -- linked to StatusLine per default
+ feed_command("hi StatusLine guibg=Cyan")
+ feed_command("ls")
+ screen:expect([[
+ |
+ {4:--------------------------------------------------}|
+ :ls |
+ 1 %a "[No Name]" line 1 |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+
+ -- but can be unlinked
+ feed_command("hi clear MsgSeparator")
+ feed_command("hi MsgSeparator guibg=Magenta gui=bold")
+ feed_command("ls")
+ screen:expect([[
+ |
+ {5:--------------------------------------------------}|
+ :ls |
+ 1 %a "[No Name]" line 1 |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+
+ -- when display doesn't contain msgsep, these options have no effect
+ feed_command("set display-=msgsep")
+ feed_command("ls")
+ screen:expect([[
+ {1:~ }|
+ {1:~ }|
+ :ls |
+ 1 %a "[No Name]" line 1 |
+ {3:Press ENTER or type command to continue}^ |
+ ]])
+ end)
+end)
+
describe("'winhighlight' highlight", function()
local screen
@@ -683,6 +778,9 @@ describe("'winhighlight' highlight", function()
[22] = {bold = true, foreground = Screen.colors.SeaGreen4},
[23] = {background = Screen.colors.LightMagenta},
[24] = {background = Screen.colors.WebGray},
+ [25] = {bold = true, foreground = Screen.colors.Green1},
+ [26] = {background = Screen.colors.Red},
+ [27] = {background = Screen.colors.DarkBlue, bold = true, foreground = Screen.colors.Green1},
})
command("hi Background1 guibg=DarkBlue")
command("hi Background2 guibg=DarkGreen")
@@ -952,6 +1050,39 @@ describe("'winhighlight' highlight", function()
]])
end)
+ it("background doesn't override syntax background", function()
+ command('syntax on')
+ command('syntax keyword Foobar foobar')
+ command('syntax keyword Article the')
+ command('hi Foobar guibg=#FF0000')
+ command('hi Article guifg=#00FF00 gui=bold')
+ insert('the foobar was foobar')
+ screen:expect([[
+ {25:the} {26:foobar} was {26:fooba}|
+ {26:^r} |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ |
+ ]])
+
+ -- winhl=Normal:Group with background doesn't override syntax background,
+ -- but does combine with syntax foreground.
+ command('set winhl=Normal:Background1')
+ screen:expect([[
+ {27:the}{1: }{26:foobar}{1: was }{26:fooba}|
+ {26:^r}{1: }|
+ {2:~ }|
+ {2:~ }|
+ {2:~ }|
+ {2:~ }|
+ {2:~ }|
+ |
+ ]])
+ end)
+
it('can override NonText, Conceal and EndOfBuffer', function()
curbufmeths.set_lines(0,-1,true, {"raa\000"})
command('call matchaddpos("Conceal", [[1,2]], 0, -1, {"conceal": "#"})')
diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua
index 8b0cb82365..27e4066d9f 100644
--- a/test/functional/ui/inccommand_spec.lua
+++ b/test/functional/ui/inccommand_spec.lua
@@ -63,6 +63,7 @@ local function common_setup(screen, inccommand, text)
command("syntax on")
command("set nohlsearch")
command("hi Substitute guifg=red guibg=yellow")
+ command("set display-=msgsep")
screen:attach()
screen:set_default_attr_ids({
[1] = {foreground = Screen.colors.Fuchsia},
diff --git a/test/functional/ui/input_spec.lua b/test/functional/ui/input_spec.lua
index 8e62a37ef1..3dd9a2506e 100644
--- a/test/functional/ui/input_spec.lua
+++ b/test/functional/ui/input_spec.lua
@@ -1,6 +1,7 @@
local helpers = require('test.functional.helpers')(after_each)
local clear, feed_command, nvim = helpers.clear, helpers.feed_command, helpers.nvim
local feed, next_msg, eq = helpers.feed, helpers.next_msg, helpers.eq
+local command = helpers.command
local expect = helpers.expect
local write_file = helpers.write_file
local Screen = require('test.functional.ui.screen')
@@ -127,6 +128,10 @@ describe('input utf sequences that contain CSI/K_SPECIAL', function()
end)
describe('input non-printable chars', function()
+ after_each(function()
+ os.remove('Xtest-overwrite')
+ end)
+
it("doesn't crash when echoing them back", function()
write_file("Xtest-overwrite", [[foobar]])
clear()
@@ -137,6 +142,7 @@ describe('input non-printable chars', function()
[3] = {bold = true, foreground = Screen.colors.SeaGreen4}
})
screen:attach()
+ command("set display-=msgsep")
feed_command("e Xtest-overwrite")
screen:expect([[
diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua
index 05d5a6409a..debd324977 100644
--- a/test/functional/ui/mouse_spec.lua
+++ b/test/functional/ui/mouse_spec.lua
@@ -26,6 +26,7 @@ describe('ui/mouse/input', function()
[4] = {reverse = true},
[5] = {bold = true, reverse = true},
})
+ command("set display-=msgsep")
feed('itesting<cr>mouse<cr>support and selection<esc>')
screen:expect([[
testing |
diff --git a/test/functional/ui/output_spec.lua b/test/functional/ui/output_spec.lua
index 4246020fab..02ca566bd8 100644
--- a/test/functional/ui/output_spec.lua
+++ b/test/functional/ui/output_spec.lua
@@ -40,10 +40,10 @@ describe("shell command :!", function()
-- to avoid triggering a UI flush.
child_session.feed_data(":!printf foo; sleep 200\n")
screen:expect([[
+ |
{4:~ }|
{4:~ }|
- {4:~ }|
- {4:~ }|
+ {5: }|
:!printf foo; sleep 200 |
foo |
{3:-- TERMINAL --} |
@@ -99,6 +99,7 @@ describe("shell command :!", function()
end
local screen = Screen.new(50, 4)
screen:attach()
+ command("set display-=msgsep")
-- Print TAB chars. #2958
feed([[:!printf '1\t2\t3'<CR>]])
screen:expect([[
@@ -153,6 +154,7 @@ describe("shell command :!", function()
[1] = {bold = true, foreground = Screen.colors.Blue1},
[2] = {foreground = Screen.colors.Blue1},
[3] = {bold = true, foreground = Screen.colors.SeaGreen4},
+ [4] = {bold = true, reverse = true},
})
screen:attach()
end)
@@ -170,10 +172,10 @@ describe("shell command :!", function()
or [[:!ls bang_filter_spec ]])
feed([[\l]])
screen:expect([[
+ |
{1:~ }|
{1:~ }|
- {1:~ }|
- {1:~ }|
+ {4: }|
]]..result..[[ |
f1 |
f2 |
@@ -187,9 +189,9 @@ describe("shell command :!", function()
feed_command('!cat test/functional/fixtures/shell_data.txt')
screen.bell = false
screen:expect([[
+ |
{1:~ }|
- {1:~ }|
- {1:~ }|
+ {4: }|
:!cat test/functional/fixtures/shell_data.txt |
{2:^@^A^B^C^D^E^F^H} |
{2:^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\^]^^^_} |
@@ -213,8 +215,8 @@ describe("shell command :!", function()
feed_command(cmd)
-- Note: only the first example of split composed char works
screen:expect([[
- {1:~ }|
- {1:~ }|
+ |
+ {4: }|
:]]..cmd..[[ |
å |
ref: å̲ |
diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua
index bbdf576641..7fafd6b352 100644
--- a/test/functional/ui/screen_basic_spec.lua
+++ b/test/functional/ui/screen_basic_spec.lua
@@ -76,11 +76,26 @@ describe('Screen', function()
local function check()
eq(true, screen.suspended)
end
+
+ command('let g:ev = []')
+ command('autocmd VimResume * :call add(g:ev, "r")')
+ command('autocmd VimSuspend * :call add(g:ev, "s")')
+
+ eq(false, screen.suspended)
command('suspend')
+ eq({ 's', 'r' }, eval('g:ev'))
+
screen:expect(check)
screen.suspended = false
+
feed('<c-z>')
+ eq({ 's', 'r', 's', 'r' }, eval('g:ev'))
+
screen:expect(check)
+ screen.suspended = false
+
+ command('suspend')
+ eq({ 's', 'r', 's', 'r', 's', 'r' }, eval('g:ev'))
end)
end)
@@ -355,7 +370,8 @@ describe('Screen', function()
]])
end)
- it('execute command with multi-line output', function()
+ it('execute command with multi-line output without msgsep', function()
+ command("set display-=msgsep")
feed(':ls<cr>')
screen:expect([[
{0:~ }|
@@ -375,6 +391,28 @@ describe('Screen', function()
]])
feed('<cr>') -- skip the "Press ENTER..." state or tests will hang
end)
+
+ it('execute command with multi-line output and with msgsep', function()
+ command("set display+=msgsep")
+ feed(':ls<cr>')
+ screen:expect([[
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ :ls |
+ 1 %a "[No Name]" line 1 |
+ {7:Press ENTER or type command to continue}^ |
+ ]])
+ feed('<cr>') -- skip the "Press ENTER..." state or tests will hang
+ end)
end)
describe('scrolling and clearing', function()
@@ -573,6 +611,7 @@ describe('Screen', function()
command('nnoremap <F1> :echo "TEST"<CR>')
feed(':ls<CR>')
screen:expect([[
+ |
{0:~ }|
{0:~ }|
{0:~ }|
@@ -582,8 +621,7 @@ describe('Screen', function()
{0:~ }|
{0:~ }|
{0:~ }|
- {0:~ }|
- {0:~ }|
+ {1: }|
:ls |
1 %a "[No Name]" line 1 |
{7:Press ENTER or type command to continue}^ |
@@ -608,21 +646,3 @@ describe('Screen', function()
end)
end)
end)
-
-describe('nvim_ui_attach()', function()
- before_each(function()
- clear()
- end)
- it('handles very large width/height #2180', function()
- local screen = Screen.new(999, 999)
- screen:attach()
- eq(999, eval('&lines'))
- eq(999, eval('&columns'))
- end)
- it('invalid option returns error', function()
- local screen = Screen.new()
- local status, rv = pcall(function() screen:attach({foo={'foo'}}) end)
- eq(false, status)
- eq('No such ui option', rv:match("No such .*"))
- end)
-end)
diff --git a/test/helpers.lua b/test/helpers.lua
index 91ceed4df1..e0645d083f 100644
--- a/test/helpers.lua
+++ b/test/helpers.lua
@@ -16,6 +16,19 @@ end
local function ok(res)
return assert.is_true(res)
end
+local function matches(pat, actual)
+ if nil ~= string.match(actual, pat) then
+ return true
+ end
+ error(string.format('Pattern does not match.\nPattern:\n%s\nActual:\n%s', pat, actual))
+end
+-- Expect an error matching pattern `pat`.
+local function expect_err(pat, ...)
+ local fn = select(1, ...)
+ local fn_args = {...}
+ table.remove(fn_args, 1)
+ assert.error_matches(function() return fn(unpack(fn_args)) end, pat)
+end
-- initial_path: directory to recurse into
-- re: include pattern (string)
@@ -469,6 +482,8 @@ format_luav = function(v, indent, opts)
end
elseif type(v) == 'nil' then
ret = 'nil'
+ elseif type(v) == 'boolean' then
+ ret = (v and 'true' or 'false')
else
print(type(v))
-- Not implemented yet
@@ -561,6 +576,7 @@ return {
deepcopy = deepcopy,
dictdiff = dictdiff,
eq = eq,
+ expect_err = expect_err,
filter = filter,
fixtbl = fixtbl,
fixtbl_rec = fixtbl_rec,
@@ -570,6 +586,7 @@ return {
hasenv = hasenv,
intchar2lua = intchar2lua,
map = map,
+ matches = matches,
mergedicts_copy = mergedicts_copy,
neq = neq,
ok = ok,