aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/api/server_requests_spec.lua61
-rw-r--r--test/functional/clipboard/clipboard_provider_spec.lua6
-rw-r--r--test/functional/core/exit_spec.lua61
-rw-r--r--test/functional/ex_cmds/ctrl_c_spec.lua2
-rw-r--r--test/functional/ex_cmds/menu_spec.lua250
-rw-r--r--test/functional/lua/utility_functions_spec.lua108
-rw-r--r--test/functional/options/tabstop_spec.lua23
-rw-r--r--test/functional/plugin/health_spec.lua34
-rw-r--r--test/functional/provider/ruby_spec.lua2
-rw-r--r--test/functional/terminal/window_spec.lua55
-rw-r--r--test/functional/ui/bufhl_spec.lua31
-rw-r--r--test/functional/ui/cmdline_spec.lua525
-rw-r--r--test/functional/ui/highlight_spec.lua6
-rw-r--r--test/functional/ui/inccommand_spec.lua38
14 files changed, 1150 insertions, 52 deletions
diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua
index 9f245d913b..4380e52b8b 100644
--- a/test/functional/api/server_requests_spec.lua
+++ b/test/functional/api/server_requests_spec.lua
@@ -109,7 +109,28 @@ describe('server -> client', function()
end)
describe('requests and notifications interleaved', function()
- -- This tests that the following scenario won't happen:
+ it('does not delay notifications during pending request', function()
+ local received = false
+ local function on_setup()
+ eq("retval", funcs.rpcrequest(cid, "doit"))
+ stop()
+ end
+ local function on_request(method)
+ if method == "doit" then
+ funcs.rpcnotify(cid, "headsup")
+ eq(true,received)
+ return "retval"
+ end
+ end
+ local function on_notification(method)
+ if method == "headsup" then
+ received = true
+ end
+ end
+ run(on_request, on_notification, on_setup)
+ end)
+
+ -- This tests the following scenario:
--
-- server->client [request ] (1)
-- client->server [request ] (2) triggered by (1)
@@ -124,36 +145,38 @@ describe('server -> client', function()
-- only deals with one server->client request at a time. (In other words,
-- the client cannot send a response to a request that is not at the top
-- of nvim's request stack).
- --
- -- But above scenario shoudn't happen by the way notifications are dealt in
- -- Nvim: they are only sent after there are no pending server->client
- -- request(the request stack fully unwinds). So (3) is only sent after the
- -- client returns (6).
- it('works', function()
- local expected = 300
- local notified = 0
+ pending('will close connection if not properly synchronized', function()
local function on_setup()
eq('notified!', eval('rpcrequest('..cid..', "notify")'))
end
local function on_request(method)
- eq('notify', method)
- eq(1, eval('rpcnotify('..cid..', "notification")'))
- return 'notified!'
+ if method == "notify" then
+ eq(1, eval('rpcnotify('..cid..', "notification")'))
+ return 'notified!'
+ elseif method == "nested" then
+ -- do some busywork, so the first request will return
+ -- before this one
+ for _ = 1, 5 do
+ eq(2, eval("1+1"))
+ end
+ eq(1, eval('rpcnotify('..cid..', "nested_done")'))
+ return 'done!'
+ end
end
local function on_notification(method)
- eq('notification', method)
- if notified == expected then
- stop()
- return
+ if method == "notification" then
+ eq('done!', eval('rpcrequest('..cid..', "nested")'))
+ elseif method == "nested_done" then
+ -- this should never have been sent
+ ok(false)
end
- notified = notified + 1
- eq('notified!', eval('rpcrequest('..cid..', "notify")'))
end
run(on_request, on_notification, on_setup)
- eq(expected, notified)
+ -- ignore disconnect failure, otherwise detected by after_each
+ clear()
end)
end)
diff --git a/test/functional/clipboard/clipboard_provider_spec.lua b/test/functional/clipboard/clipboard_provider_spec.lua
index b90335e70a..a3ea3b568f 100644
--- a/test/functional/clipboard/clipboard_provider_spec.lua
+++ b/test/functional/clipboard/clipboard_provider_spec.lua
@@ -100,7 +100,7 @@ describe('clipboard', function()
^ |
~ |
~ |
- clipboard: No provider. Try ":CheckHealth" or ":h clipboard". |
+ clipboard: No provider. Try ":checkhealth" or ":h clipboard". |
]], nil, {{bold = true, foreground = Screen.colors.Blue}})
end)
@@ -112,7 +112,7 @@ describe('clipboard', function()
feed_command('redir @+> | bogus_cmd | redir END')
screen:expect([[
~ |
- clipboard: No provider. Try ":CheckHealth" or ":h clipboard". |
+ clipboard: No provider. Try ":checkhealth" or ":h clipboard". |
E492: Not an editor command: bogus_cmd | redir END |
Press ENTER or type command to continue^ |
]], nil, {{bold = true, foreground = Screen.colors.Blue}})
@@ -132,7 +132,7 @@ describe('clipboard', function()
^ |
~ |
~ |
- clipboard: No provider. Try ":CheckHealth" or ":h clipboard". |
+ clipboard: No provider. Try ":checkhealth" or ":h clipboard". |
]], nil, {{bold = true, foreground = Screen.colors.Blue}})
end)
diff --git a/test/functional/core/exit_spec.lua b/test/functional/core/exit_spec.lua
index 3fb39f3e78..188a6a2c11 100644
--- a/test/functional/core/exit_spec.lua
+++ b/test/functional/core/exit_spec.lua
@@ -2,8 +2,12 @@ local helpers = require('test.functional.helpers')(after_each)
local command = helpers.command
local eval = helpers.eval
-local eq, neq = helpers.eq, helpers.neq
+local eq = helpers.eq
local run = helpers.run
+local funcs = helpers.funcs
+local nvim_prog = helpers.nvim_prog
+local redir_exec = helpers.redir_exec
+local wait = helpers.wait
describe('v:exiting', function()
local cid
@@ -29,18 +33,53 @@ describe('v:exiting', function()
end
run(on_request, nil, on_setup)
end)
+end)
- it('is non-zero after :cquit', function()
- local function on_setup()
- command('autocmd VimLeavePre * call rpcrequest('..cid..', "")')
- command('autocmd VimLeave * call rpcrequest('..cid..', "")')
- command('cquit')
- end
- local function on_request()
- neq(0, eval('v:exiting'))
- return ''
+describe(':cquit', function()
+ local function test_cq(cmdline, exit_code, redir_msg)
+ if redir_msg then
+ eq('\n' .. redir_msg, redir_exec(cmdline))
+ wait()
+ eq(2, eval("1+1")) -- Still alive?
+ else
+ funcs.system({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless', '--cmd', cmdline})
+ eq(exit_code, eval('v:shell_error'))
end
- run(on_request, nil, on_setup)
+ end
+
+ before_each(function()
+ helpers.clear()
+ end)
+
+ it('exits with non-zero after :cquit', function()
+ test_cq('cquit', 1, nil)
end)
+ it('exits with non-zero after :cquit 123', function()
+ test_cq('cquit 123', 123, nil)
+ end)
+
+ it('exits with non-zero after :123 cquit', function()
+ test_cq('123 cquit', 123, nil)
+ end)
+
+ it('exits with 0 after :cquit 0', function()
+ test_cq('cquit 0', 0, nil)
+ end)
+
+ it('exits with 0 after :0 cquit', function()
+ test_cq('0 cquit', 0, nil)
+ end)
+
+ it('exits with redir msg for multiple exit codes after :cquit 1 2', function()
+ test_cq('cquit 1 2', nil, 'E488: Trailing characters: cquit 1 2')
+ end)
+
+ it('exits with redir msg for non-number exit code after :cquit X', function()
+ test_cq('cquit X', nil, 'E488: Trailing characters: cquit X')
+ end)
+
+ it('exits with redir msg for negative exit code after :cquit -1', function()
+ test_cq('cquit -1', nil, 'E488: Trailing characters: cquit -1')
+ end)
end)
diff --git a/test/functional/ex_cmds/ctrl_c_spec.lua b/test/functional/ex_cmds/ctrl_c_spec.lua
index 091a008814..8f76099f79 100644
--- a/test/functional/ex_cmds/ctrl_c_spec.lua
+++ b/test/functional/ex_cmds/ctrl_c_spec.lua
@@ -47,7 +47,7 @@ describe("CTRL-C (mapped)", function()
end
-- The test is time-sensitive. Try different sleep values.
- local ms_values = {1, 10, 100, 1000, 10000}
+ local ms_values = {100, 1000, 10000}
for i, ms in ipairs(ms_values) do
if i < #ms_values then
local status, _ = pcall(test_ctrl_c, ms)
diff --git a/test/functional/ex_cmds/menu_spec.lua b/test/functional/ex_cmds/menu_spec.lua
index 55da8da8dc..2c0535acda 100644
--- a/test/functional/ex_cmds/menu_spec.lua
+++ b/test/functional/ex_cmds/menu_spec.lua
@@ -107,7 +107,7 @@ describe('menu_get', function()
sid = 1,
noremap = 1,
enabled = 1,
- rhs = "inormal\27",
+ rhs = "inormal<Esc>",
silent = 0
},
v = {
@@ -242,7 +242,7 @@ describe('menu_get', function()
sid = 1,
noremap = 1,
enabled = 1,
- rhs = "\18\"",
+ rhs = "<C-R>\"",
silent = 0
},
n = {
@@ -379,5 +379,251 @@ describe('menu_get', function()
}
eq(expected, m)
end)
+end)
+
+describe('menu_get', function()
+
+ before_each(function()
+ clear()
+ end)
+
+ it('returns <keycode> representation of special keys', function()
+ command('nnoremenu &Test.Test inormal<ESC>')
+ command('inoremenu &Test.Test2 <Tab><Esc>')
+ command('vnoremenu &Test.Test3 yA<C-R>0<Tab>xyz<Esc>')
+ command('inoremenu &Test.Test4 <c-r>*')
+ command('inoremenu &Test.Test5 <c-R>+')
+ command('nnoremenu &Test.Test6 <Nop>')
+ command('nnoremenu &Test.Test7 <NOP>')
+ command('nnoremenu &Test.Test8 <NoP>')
+ command('nnoremenu &Test.Test9 ""')
+
+ local m = funcs.menu_get("");
+ local expected = {
+ {
+ shortcut = "T",
+ hidden = 0,
+ submenus = {
+ {
+ priority = 500,
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "inormal<Esc>",
+ silent = 0
+ }
+ },
+ name = "Test",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ i = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "<Tab><Esc>",
+ silent = 0
+ }
+ },
+ name = "Test2",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ s = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "yA<C-R>0<Tab>xyz<Esc>",
+ silent = 0
+ },
+ v = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "yA<C-R>0<Tab>xyz<Esc>",
+ silent = 0
+ }
+ },
+ name = "Test3",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ i = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "<C-R>*",
+ silent = 0
+ }
+ },
+ name = "Test4",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ i = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "<C-R>+",
+ silent = 0
+ }
+ },
+ name = "Test5",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "",
+ silent = 0
+ }
+ },
+ name = "Test6",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "",
+ silent = 0
+ }
+ },
+ name = "Test7",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "",
+ silent = 0
+ }
+ },
+ name = "Test8",
+ hidden = 0
+ },
+ {
+ priority = 500,
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "\"\"",
+ silent = 0
+ }
+ },
+ name = "Test9",
+ hidden = 0
+ }
+ },
+ priority = 500,
+ name = "Test"
+ }
+ }
+
+ eq(m, expected)
+ end)
+
+ it('works with right-aligned text and spaces', function()
+ command('nnoremenu &Test<Tab>Y.Test<Tab>X\\ x inormal<Alt-j>')
+ command('nnoremenu &Test\\ 1.Test\\ 2 Wargl')
+ command('nnoremenu &Test4.Test<Tab>3 i space<Esc>')
+
+ local m = funcs.menu_get("");
+ local expected = {
+ {
+ shortcut = "T",
+ hidden = 0,
+ actext = "Y",
+ submenus = {
+ {
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "inormal<Alt-j>",
+ silent = 0
+ }
+ },
+ hidden = 0,
+ actext = "X x",
+ priority = 500,
+ name = "Test"
+ }
+ },
+ priority = 500,
+ name = "Test"
+ },
+ {
+ shortcut = "T",
+ hidden = 0,
+ submenus = {
+ {
+ priority = 500,
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "Wargl",
+ silent = 0
+ }
+ },
+ name = "Test 2",
+ hidden = 0
+ }
+ },
+ priority = 500,
+ name = "Test 1"
+ },
+ {
+ shortcut = "T",
+ hidden = 0,
+ submenus = {
+ {
+ mappings = {
+ n = {
+ sid = 1,
+ noremap = 1,
+ enabled = 1,
+ rhs = "i space<Esc>",
+ silent = 0
+ }
+ },
+ hidden = 0,
+ actext = "3",
+ priority = 500,
+ name = "Test"
+ }
+ },
+ priority = 500,
+ name = "Test4"
+ }
+ }
+ eq(m, expected)
+ end)
end)
diff --git a/test/functional/lua/utility_functions_spec.lua b/test/functional/lua/utility_functions_spec.lua
new file mode 100644
index 0000000000..d5756e134d
--- /dev/null
+++ b/test/functional/lua/utility_functions_spec.lua
@@ -0,0 +1,108 @@
+-- Test suite for testing interactions with API bindings
+local helpers = require('test.functional.helpers')(after_each)
+
+local funcs = helpers.funcs
+local clear = helpers.clear
+local eq = helpers.eq
+
+before_each(clear)
+
+describe('vim.stricmp', function()
+ -- İ: `tolower("İ")` is `i` which has length 1 while `İ` itself has
+ -- length 2 (in bytes).
+ -- Ⱥ: `tolower("Ⱥ")` is `ⱥ` which has length 2 while `Ⱥ` itself has
+ -- length 3 (in bytes).
+ --
+ -- Note: 'i' !=? 'İ' and 'ⱥ' !=? 'Ⱥ' on some systems.
+ -- Note: Built-in Nvim comparison (on systems lacking `strcasecmp`) works
+ -- only on ASCII characters.
+ it('works', function()
+ eq(0, funcs.luaeval('vim.stricmp("a", "A")'))
+ eq(0, funcs.luaeval('vim.stricmp("A", "a")'))
+ eq(0, funcs.luaeval('vim.stricmp("a", "a")'))
+ eq(0, funcs.luaeval('vim.stricmp("A", "A")'))
+
+ eq(0, funcs.luaeval('vim.stricmp("", "")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0", "\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0\\0", "\\0\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0\\0\\0", "\\0\\0\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0\\0\\0A", "\\0\\0\\0a")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0A")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0a")'))
+
+ eq(0, funcs.luaeval('vim.stricmp("a\\0", "A\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("A\\0", "a\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("a\\0", "a\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("A\\0", "A\\0")'))
+
+ eq(0, funcs.luaeval('vim.stricmp("\\0a", "\\0A")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0A", "\\0a")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0a", "\\0a")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0A", "\\0A")'))
+
+ eq(0, funcs.luaeval('vim.stricmp("\\0a\\0", "\\0A\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0A\\0", "\\0a\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0a\\0", "\\0a\\0")'))
+ eq(0, funcs.luaeval('vim.stricmp("\\0A\\0", "\\0A\\0")'))
+
+ eq(-1, funcs.luaeval('vim.stricmp("a", "B")'))
+ eq(-1, funcs.luaeval('vim.stricmp("A", "b")'))
+ eq(-1, funcs.luaeval('vim.stricmp("a", "b")'))
+ eq(-1, funcs.luaeval('vim.stricmp("A", "B")'))
+
+ eq(-1, funcs.luaeval('vim.stricmp("", "\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0", "\\0\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0\\0", "\\0\\0\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0\\0\\0A", "\\0\\0\\0b")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0B")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0\\0\\0a", "\\0\\0\\0b")'))
+
+ eq(-1, funcs.luaeval('vim.stricmp("a\\0", "B\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("A\\0", "b\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("a\\0", "b\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("A\\0", "B\\0")'))
+
+ eq(-1, funcs.luaeval('vim.stricmp("\\0a", "\\0B")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0A", "\\0b")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0a", "\\0b")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0A", "\\0B")'))
+
+ eq(-1, funcs.luaeval('vim.stricmp("\\0a\\0", "\\0B\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0A\\0", "\\0b\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0a\\0", "\\0b\\0")'))
+ eq(-1, funcs.luaeval('vim.stricmp("\\0A\\0", "\\0B\\0")'))
+
+ eq(1, funcs.luaeval('vim.stricmp("c", "B")'))
+ eq(1, funcs.luaeval('vim.stricmp("C", "b")'))
+ eq(1, funcs.luaeval('vim.stricmp("c", "b")'))
+ eq(1, funcs.luaeval('vim.stricmp("C", "B")'))
+
+ eq(1, funcs.luaeval('vim.stricmp("\\0", "")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0\\0", "\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0\\0\\0", "\\0\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0\\0\\0\\0", "\\0\\0\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0\\0\\0C", "\\0\\0\\0b")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0\\0\\0c", "\\0\\0\\0B")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0\\0\\0c", "\\0\\0\\0b")'))
+
+ eq(1, funcs.luaeval('vim.stricmp("c\\0", "B\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("C\\0", "b\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("c\\0", "b\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("C\\0", "B\\0")'))
+
+ eq(1, funcs.luaeval('vim.stricmp("c\\0", "B")'))
+ eq(1, funcs.luaeval('vim.stricmp("C\\0", "b")'))
+ eq(1, funcs.luaeval('vim.stricmp("c\\0", "b")'))
+ eq(1, funcs.luaeval('vim.stricmp("C\\0", "B")'))
+
+ eq(1, funcs.luaeval('vim.stricmp("\\0c", "\\0B")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0C", "\\0b")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0c", "\\0b")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0C", "\\0B")'))
+
+ eq(1, funcs.luaeval('vim.stricmp("\\0c\\0", "\\0B\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0C\\0", "\\0b\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0c\\0", "\\0b\\0")'))
+ eq(1, funcs.luaeval('vim.stricmp("\\0C\\0", "\\0B\\0")'))
+ end)
+end)
diff --git a/test/functional/options/tabstop_spec.lua b/test/functional/options/tabstop_spec.lua
new file mode 100644
index 0000000000..dc3ba38438
--- /dev/null
+++ b/test/functional/options/tabstop_spec.lua
@@ -0,0 +1,23 @@
+local helpers = require('test.functional.helpers')(after_each)
+
+local clear = helpers.clear
+local feed = helpers.feed
+local eq = helpers.eq
+local eval = helpers.eval
+
+describe("'tabstop' option", function()
+ before_each(function()
+ clear()
+ end)
+
+ -- NOTE: Setting 'tabstop' to a big number reproduces crash #2838.
+ -- Disallowing big 'tabstop' would not fix #2838, only hide it.
+ it("tabstop=<big-number> does not crash #2838", function()
+ -- Insert a <Tab> character for 'tabstop' to work with.
+ feed('i<Tab><Esc>')
+ -- Set 'tabstop' to a very high value.
+ -- Use feed(), not command(), to provoke crash.
+ feed(':set tabstop=3000000000<CR>')
+ eq(2, eval("1+1")) -- Still alive?
+ end)
+end)
diff --git a/test/functional/plugin/health_spec.lua b/test/functional/plugin/health_spec.lua
index 8646ec98bf..b5374210e6 100644
--- a/test/functional/plugin/health_spec.lua
+++ b/test/functional/plugin/health_spec.lua
@@ -2,7 +2,29 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local plugin_helpers = require('test.functional.plugin.helpers')
+local clear = helpers.clear
+local curbuf_contents = helpers.curbuf_contents
local command = helpers.command
+local eq = helpers.eq
+
+describe(':checkhealth', function()
+ it("detects invalid $VIMRUNTIME", function()
+ clear({
+ env={ VIMRUNTIME='bogus', },
+ })
+ local status, err = pcall(command, 'checkhealth')
+ eq(false, status)
+ eq('Invalid $VIMRUNTIME: bogus', string.match(err, 'Invalid.*'))
+ end)
+ it("detects invalid $VIM", function()
+ clear()
+ -- Do this after startup, otherwise it just breaks $VIMRUNTIME.
+ command("let $VIM='zub'")
+ command("checkhealth nvim")
+ eq("ERROR: $VIM is invalid: zub",
+ string.match(curbuf_contents(), "ERROR: $VIM .* zub"))
+ end)
+end)
describe('health.vim', function()
before_each(function()
@@ -14,7 +36,7 @@ describe('health.vim', function()
command("set runtimepath+=test/functional/fixtures")
end)
- it("reports", function()
+ it("health#report_*()", function()
helpers.source([[
let g:health_report = execute([
\ "call health#report_start('Check Bar')",
@@ -44,9 +66,9 @@ describe('health.vim', function()
end)
- describe(":CheckHealth", function()
+ describe(":checkhealth", function()
it("concatenates multiple reports", function()
- command("CheckHealth success1 success2")
+ command("checkhealth success1 success2")
helpers.expect([[
health#success1#check
@@ -65,7 +87,7 @@ describe('health.vim', function()
end)
it("gracefully handles broken healthcheck", function()
- command("CheckHealth broken")
+ command("checkhealth broken")
helpers.expect([[
health#broken#check
@@ -89,7 +111,7 @@ describe('health.vim', function()
Bar = { foreground=Screen.colors.Purple },
Bullet = { bold=true, foreground=Screen.colors.Brown },
})
- command("CheckHealth foo success1")
+ command("checkhealth foo success1")
command("1tabclose")
command("set laststatus=0")
screen:expect([[
@@ -107,7 +129,7 @@ describe('health.vim', function()
end)
it("gracefully handles invalid healthcheck", function()
- command("CheckHealth non_existent_healthcheck")
+ command("checkhealth non_existent_healthcheck")
helpers.expect([[
health#non_existent_healthcheck#check
diff --git a/test/functional/provider/ruby_spec.lua b/test/functional/provider/ruby_spec.lua
index 9f5ef3b3fc..c70f90da1c 100644
--- a/test/functional/provider/ruby_spec.lua
+++ b/test/functional/provider/ruby_spec.lua
@@ -16,7 +16,7 @@ do
clear()
if missing_provider('ruby') then
pending(
- "Cannot find the neovim RubyGem. Try :CheckHealth",
+ "Cannot find the neovim RubyGem. Try :checkhealth",
function() end)
return
end
diff --git a/test/functional/terminal/window_spec.lua b/test/functional/terminal/window_spec.lua
index 0f705cfe40..231618c5da 100644
--- a/test/functional/terminal/window_spec.lua
+++ b/test/functional/terminal/window_spec.lua
@@ -2,6 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local thelpers = require('test.functional.terminal.helpers')
local feed, clear = helpers.feed, helpers.clear
local wait = helpers.wait
+local iswin = helpers.iswin
describe('terminal window', function()
local screen
@@ -11,9 +12,53 @@ describe('terminal window', function()
screen = thelpers.screen_setup()
end)
- describe('with colorcolumn set', function()
+ describe("with 'number'", function()
+ it('wraps text', function()
+ feed([[<C-\><C-N>]])
+ feed([[:set numberwidth=1 number<CR>i]])
+ screen:expect([[
+ {7:1 }tty ready |
+ {7:2 }rows: 6, cols: 48 |
+ {7:3 }{1: } |
+ {7:4 } |
+ {7:5 } |
+ {7:6 } |
+ {3:-- TERMINAL --} |
+ ]])
+ thelpers.feed_data({'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'})
+ screen:expect([[
+ {7:1 }tty ready |
+ {7:2 }rows: 6, cols: 48 |
+ {7:3 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUV|
+ {7:4 }WXYZ{1: } |
+ {7:5 } |
+ {7:6 } |
+ {3:-- TERMINAL --} |
+ ]])
+
+ if iswin() then
+ return -- win: :terminal resize is unreliable #7007
+ end
+
+ -- numberwidth=9
+ feed([[<C-\><C-N>]])
+ feed([[:set numberwidth=9 number<CR>i]])
+ thelpers.feed_data({' abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'})
+ screen:expect([[
+ {7: 1 }tty ready |
+ {7: 2 }rows: 6, cols: 48 |
+ {7: 3 }abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNO|
+ {7: 4 }WXYZ abcdefghijklmnopqrstuvwxyzABCDEFGHIJ|
+ {7: 5 }KLMNOPQRSTUVWXYZrows: 6, cols: 41 |
+ {7: 6 }{1: } |
+ {3:-- TERMINAL --} |
+ ]])
+ end)
+ end)
+
+ describe("with 'colorcolumn'", function()
before_each(function()
- feed('<c-\\><c-n>')
+ feed([[<C-\><C-N>]])
screen:expect([[
tty ready |
{2:^ } |
@@ -23,7 +68,7 @@ describe('terminal window', function()
|
|
]])
- feed(':set colorcolumn=20<cr>i')
+ feed(':set colorcolumn=20<CR>i')
end)
it('wont show the color column', function()
@@ -41,7 +86,7 @@ describe('terminal window', function()
describe('with fold set', function()
before_each(function()
- feed('<c-\\><c-n>:set foldenable foldmethod=manual<cr>i')
+ feed([[<C-\><C-N>:set foldenable foldmethod=manual<CR>i]])
thelpers.feed_data({'line1', 'line2', 'line3', 'line4', ''})
screen:expect([[
tty ready |
@@ -55,7 +100,7 @@ describe('terminal window', function()
end)
it('wont show any folds', function()
- feed('<c-\\><c-n>ggvGzf')
+ feed([[<C-\><C-N>ggvGzf]])
wait()
screen:expect([[
^tty ready |
diff --git a/test/functional/ui/bufhl_spec.lua b/test/functional/ui/bufhl_spec.lua
index e1e11203e0..2143c01139 100644
--- a/test/functional/ui/bufhl_spec.lua
+++ b/test/functional/ui/bufhl_spec.lua
@@ -24,7 +24,8 @@ describe('Buffer highlighting', function()
[6] = {foreground = Screen.colors.DarkCyan}, -- Identifier
[7] = {bold = true},
[8] = {underline = true, bold = true, foreground = Screen.colors.SlateBlue},
- [9] = {foreground = Screen.colors.SlateBlue, underline = true}
+ [9] = {foreground = Screen.colors.SlateBlue, underline = true},
+ [10] = {foreground = Screen.colors.Red}
})
curbuf = request('nvim_get_current_buf')
end)
@@ -255,4 +256,32 @@ describe('Buffer highlighting', function()
|
]])
end)
+
+ it('works with new syntax groups', function()
+ insert([[
+ fancy code in a new fancy language]])
+ add_hl(-1, "FancyLangItem", 0, 0, 5)
+ screen:expect([[
+ fancy code in a new fancy languag^e |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]])
+
+ command('hi FancyLangItem guifg=red')
+ screen:expect([[
+ {10:fancy} code in a new fancy languag^e |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]])
+ end)
end)
diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua
new file mode 100644
index 0000000000..0f8302b036
--- /dev/null
+++ b/test/functional/ui/cmdline_spec.lua
@@ -0,0 +1,525 @@
+local helpers = require('test.functional.helpers')(after_each)
+local Screen = require('test.functional.ui.screen')
+local clear, feed, eq = helpers.clear, helpers.feed, helpers.eq
+local source = helpers.source
+local ok = helpers.ok
+local command = helpers.command
+
+describe('external cmdline', function()
+ local screen
+ local last_level = 0
+ local cmdline = {}
+ local block = nil
+
+ before_each(function()
+ clear()
+ cmdline, block = {}, nil
+ screen = Screen.new(25, 5)
+ screen:attach({rgb=true, ext_cmdline=true})
+ screen:set_on_event_handler(function(name, data)
+ if name == "cmdline_show" then
+ local content, pos, firstc, prompt, indent, level = unpack(data)
+ ok(level > 0)
+ cmdline[level] = {content=content, pos=pos, firstc=firstc,
+ prompt=prompt, indent=indent}
+ last_level = level
+ elseif name == "cmdline_hide" then
+ local level = data[1]
+ cmdline[level] = nil
+ elseif name == "cmdline_special_char" then
+ local char, shift, level = unpack(data)
+ cmdline[level].special = {char, shift}
+ elseif name == "cmdline_pos" then
+ local pos, level = unpack(data)
+ cmdline[level].pos = pos
+ elseif name == "cmdline_block_show" then
+ block = data[1]
+ elseif name == "cmdline_block_append" then
+ block[#block+1] = data[1]
+ elseif name == "cmdline_block_hide" then
+ block = nil
+ end
+ end)
+ end)
+
+ after_each(function()
+ screen:detach()
+ end)
+
+ local function expect_cmdline(level, expected)
+ local attr_ids = screen._default_attr_ids
+ local attr_ignore = screen._default_attr_ignore
+ local actual = ''
+ for _, chunk in ipairs(cmdline[level] and cmdline[level].content or {}) do
+ local attrs, text = chunk[1], chunk[2]
+ if screen:_equal_attrs(attrs, {}) then
+ actual = actual..text
+ else
+ local attr_id = screen:_get_attr_id(attr_ids, attr_ignore, attrs)
+ actual = actual..'{' .. attr_id .. ':' .. text .. '}'
+ end
+ end
+ eq(expected, actual)
+ end
+
+ it('works', function()
+ feed(':')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq(1, last_level)
+ eq({{
+ content = { { {}, "" } },
+ firstc = ":",
+ indent = 0,
+ pos = 0,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ feed('sign')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "sign" } },
+ firstc = ":",
+ indent = 0,
+ pos = 4,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ feed('<Left>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "sign" } },
+ firstc = ":",
+ indent = 0,
+ pos = 3,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ feed('<bs>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "sin" } },
+ firstc = ":",
+ indent = 0,
+ pos = 2,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ feed('<Esc>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({}, cmdline)
+ end)
+ end)
+
+ it("works with input()", function()
+ feed(':call input("input", "default")<cr>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "default" } },
+ firstc = "",
+ indent = 0,
+ pos = 7,
+ prompt = "input"
+ }}, cmdline)
+ end)
+ feed('<cr>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({}, cmdline)
+ end)
+
+ end)
+
+ it("works with special chars and nested cmdline", function()
+ feed(':xx<c-r>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "xx" } },
+ firstc = ":",
+ indent = 0,
+ pos = 2,
+ prompt = "",
+ special = {'"', true},
+ }}, cmdline)
+ end)
+
+ feed('=')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "xx" } },
+ firstc = ":",
+ indent = 0,
+ pos = 2,
+ prompt = "",
+ special = {'"', true},
+ },{
+ content = { { {}, "" } },
+ firstc = "=",
+ indent = 0,
+ pos = 0,
+ prompt = "",
+ }}, cmdline)
+ end)
+
+ feed('1+2')
+ local expectation = {{
+ content = { { {}, "xx" } },
+ firstc = ":",
+ indent = 0,
+ pos = 2,
+ prompt = "",
+ special = {'"', true},
+ },{
+ content = { { {}, "1+2" } },
+ firstc = "=",
+ indent = 0,
+ pos = 3,
+ prompt = "",
+ }}
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq(expectation, cmdline)
+ end)
+
+ -- erase information, so we check if it is retransmitted
+ cmdline = {}
+ command("redraw!")
+ -- redraw! forgets cursor position. Be OK with that, as UI should indicate
+ -- focus is at external cmdline anyway.
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ ^ |
+ ]], nil, nil, function()
+ eq(expectation, cmdline)
+ end)
+
+
+ feed('<cr>')
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ ^ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "xx3" } },
+ firstc = ":",
+ indent = 0,
+ pos = 3,
+ prompt = "",
+ }}, cmdline)
+ end)
+
+ feed('<esc>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({}, cmdline)
+ end)
+ end)
+
+ it("works with function definitions", function()
+ feed(':function Foo()<cr>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "" } },
+ firstc = ":",
+ indent = 2,
+ pos = 0,
+ prompt = "",
+ }}, cmdline)
+ eq({{{{}, 'function Foo()'}}}, block)
+ end)
+
+ feed('line1<cr>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{{{}, 'function Foo()'}},
+ {{{}, ' line1'}}}, block)
+ end)
+
+ block = {}
+ command("redraw!")
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ ^ |
+ ]], nil, nil, function()
+ eq({{{{}, 'function Foo()'}},
+ {{{}, ' line1'}}}, block)
+ end)
+
+
+ feed('endfunction<cr>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq(nil, block)
+ end)
+ end)
+
+ it("works with cmdline window", function()
+ feed(':make')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "make" } },
+ firstc = ":",
+ indent = 0,
+ pos = 4,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ feed('<c-f>')
+ screen:expect([[
+ |
+ [No Name] |
+ :make^ |
+ [Command Line] |
+ |
+ ]], nil, nil, function()
+ eq({}, cmdline)
+ end)
+
+ -- nested cmdline
+ feed(':yank')
+ screen:expect([[
+ |
+ [No Name] |
+ :make^ |
+ [Command Line] |
+ |
+ ]], nil, nil, function()
+ eq({nil, {
+ content = { { {}, "yank" } },
+ firstc = ":",
+ indent = 0,
+ pos = 4,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ cmdline = {}
+ command("redraw!")
+ screen:expect([[
+ |
+ [No Name] |
+ :make |
+ [Command Line] |
+ ^ |
+ ]], nil, nil, function()
+ eq({nil, {
+ content = { { {}, "yank" } },
+ firstc = ":",
+ indent = 0,
+ pos = 4,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ feed("<c-c>")
+ screen:expect([[
+ |
+ [No Name] |
+ :make^ |
+ [Command Line] |
+ |
+ ]], nil, nil, function()
+ eq({}, cmdline)
+ end)
+
+ feed("<c-c>")
+ screen:expect([[
+ |
+ [No Name] |
+ :make^ |
+ [Command Line] |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "make" } },
+ firstc = ":",
+ indent = 0,
+ pos = 4,
+ prompt = ""
+ }}, cmdline)
+ end)
+
+ cmdline = {}
+ command("redraw!")
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ ^ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "make" } },
+ firstc = ":",
+ indent = 0,
+ pos = 4,
+ prompt = ""
+ }}, cmdline)
+ end)
+ end)
+
+ it('works with inputsecret()', function()
+ feed(":call inputsecret('secret:')<cr>abc123")
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{
+ content = { { {}, "******" } },
+ firstc = "",
+ indent = 0,
+ pos = 6,
+ prompt = "secret:"
+ }}, cmdline)
+ end)
+ end)
+
+ it('works with highlighted cmdline', function()
+ source([[
+ highlight RBP1 guibg=Red
+ highlight RBP2 guibg=Yellow
+ highlight RBP3 guibg=Green
+ highlight RBP4 guibg=Blue
+ let g:NUM_LVLS = 4
+ function RainBowParens(cmdline)
+ let ret = []
+ let i = 0
+ let lvl = 0
+ while i < len(a:cmdline)
+ if a:cmdline[i] is# '('
+ call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)])
+ let lvl += 1
+ elseif a:cmdline[i] is# ')'
+ let lvl -= 1
+ call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)])
+ endif
+ let i += 1
+ endwhile
+ return ret
+ endfunction
+ map <f5> :let x = input({'prompt':'>','highlight':'RainBowParens'})<cr>
+ "map <f5> :let x = input({'prompt':'>'})<cr>
+ ]])
+ screen:set_default_attr_ids({
+ RBP1={background = Screen.colors.Red},
+ RBP2={background = Screen.colors.Yellow},
+ RBP3={background = Screen.colors.Green},
+ RBP4={background = Screen.colors.Blue},
+ EOB={bold = true, foreground = Screen.colors.Blue1},
+ ERR={foreground = Screen.colors.Grey100, background = Screen.colors.Red},
+ SK={foreground = Screen.colors.Blue},
+ PE={bold = true, foreground = Screen.colors.SeaGreen4}
+ })
+ feed('<f5>(a(b)a)')
+ screen:expect([[
+ ^ |
+ {EOB:~ }|
+ {EOB:~ }|
+ {EOB:~ }|
+ |
+ ]], nil, nil, function()
+ expect_cmdline(1, '{RBP1:(}a{RBP2:(}b{RBP2:)}a{RBP1:)}')
+ end)
+ end)
+end)
diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua
index 077b0ec14c..d1357ea525 100644
--- a/test/functional/ui/highlight_spec.lua
+++ b/test/functional/ui/highlight_spec.lua
@@ -518,7 +518,7 @@ describe("'listchars' highlight", function()
]])
feed_command('set cursorline')
screen:expect([[
- {2:^>-------.}{1:abcd}{2:.}{1:Lorem}{3:>}|
+ {2:^>-------.}{1:abcd}{2:.}{1:Lorem}{4:>}|
{5:>-------.}abcd{5:*}{4:¬} |
{4:¬} |
{4:~ }|
@@ -526,7 +526,7 @@ describe("'listchars' highlight", function()
]])
feed('$')
screen:expect([[
- {3:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }|
+ {4:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }|
{4:<} |
{4:<} |
{4:~ }|
@@ -607,7 +607,7 @@ describe("'listchars' highlight", function()
feed('<esc>$')
screen:expect([[
{4:<} |
- {3:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }|
+ {4:<}{1:r}{2:.}{1:sit}{2:.}{1:ame^t}{3:¬}{1: }|
{4:<} |
{4:~ }|
|
diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua
index c8fa2888d1..cc023ef10d 100644
--- a/test/functional/ui/inccommand_spec.lua
+++ b/test/functional/ui/inccommand_spec.lua
@@ -701,6 +701,25 @@ describe(":substitute, inccommand=split", function()
eq(0, eval("&modified"))
end)
+ it("shows preview when cmd modifiers are present", function()
+ -- one modifier
+ feed(':keeppatterns %s/tw/to')
+ screen:expect([[too lines]], nil, nil, nil, true)
+ feed('<Esc>')
+ screen:expect([[two lines]], nil, nil, nil, true)
+
+ -- multiple modifiers
+ feed(':keeppatterns silent %s/tw/to')
+ screen:expect([[too lines]], nil, nil, nil, true)
+ feed('<Esc>')
+ screen:expect([[two lines]], nil, nil, nil, true)
+
+ -- non-modifier prefix
+ feed(':silent tabedit %s/tw/to')
+ screen:expect([[two lines]], nil, nil, nil, true)
+ feed('<Esc>')
+ end)
+
it('shows split window when typing the pattern', function()
feed(":%s/tw")
screen:expect([[
@@ -1140,6 +1159,25 @@ describe("inccommand=nosplit", function()
]])
end)
+ it("shows preview when cmd modifiers are present", function()
+ -- one modifier
+ feed(':keeppatterns %s/tw/to')
+ screen:expect([[too lines]], nil, nil, nil, true)
+ feed('<Esc>')
+ screen:expect([[two lines]], nil, nil, nil, true)
+
+ -- multiple modifiers
+ feed(':keeppatterns silent %s/tw/to')
+ screen:expect([[too lines]], nil, nil, nil, true)
+ feed('<Esc>')
+ screen:expect([[two lines]], nil, nil, nil, true)
+
+ -- non-modifier prefix
+ feed(':silent tabedit %s/tw/to')
+ screen:expect([[two lines]], nil, nil, nil, true)
+ feed('<Esc>')
+ end)
+
it('never shows preview buffer', function()
feed_command("set hlsearch")