aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/api/vim_spec.lua22
-rw-r--r--test/functional/autocmd/dirchanged_spec.lua2
-rw-r--r--test/functional/core/fileio_spec.lua15
-rw-r--r--test/functional/core/server_spec.lua (renamed from test/functional/vimscript/server_spec.lua)129
-rw-r--r--test/functional/core/startup_spec.lua20
-rw-r--r--test/functional/editor/defaults_spec.lua100
-rw-r--r--test/functional/editor/mode_insert_spec.lua93
-rw-r--r--test/functional/ex_cmds/mksession_spec.lua2
-rw-r--r--test/functional/lua/uri_spec.lua2
-rw-r--r--test/functional/lua/vim_spec.lua36
-rw-r--r--test/functional/options/autochdir_spec.lua2
-rw-r--r--test/functional/options/defaults_spec.lua562
-rw-r--r--test/functional/plugin/lsp_spec.lua117
-rw-r--r--test/functional/plugin/tohtml_spec.lua87
-rw-r--r--test/functional/terminal/buffer_spec.lua2
-rw-r--r--test/functional/terminal/tui_spec.lua2
-rw-r--r--test/functional/testnvim.lua23
-rw-r--r--test/functional/ui/decorations_spec.lua13
-rw-r--r--test/functional/ui/multigrid_spec.lua1
-rw-r--r--test/functional/ui/popupmenu_spec.lua9
-rw-r--r--test/functional/vimscript/fnamemodify_spec.lua3
-rw-r--r--test/old/testdir/setup.vim1
-rw-r--r--test/old/testdir/test_breakindent.vim65
-rw-r--r--test/old/testdir/test_utf8.vim15
-rw-r--r--test/testutil.lua27
-rw-r--r--test/unit/mbyte_spec.lua13
26 files changed, 878 insertions, 485 deletions
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 074d3ac0a3..71703c9b05 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -3201,7 +3201,7 @@ describe('API', function()
end)
describe('nvim_get_runtime_file', function()
- local p = n.alter_slashes
+ local p = t.fix_slashes
it('can find files', function()
eq({}, api.nvim_get_runtime_file('bork.borkbork', false))
eq({}, api.nvim_get_runtime_file('bork.borkbork', true))
@@ -3210,36 +3210,36 @@ describe('API', function()
local val = api.nvim_get_runtime_file('autoload/remote/*.vim', true)
eq(2, #val)
if endswith(val[1], 'define.vim') then
- ok(endswith(val[1], p 'autoload/remote/define.vim'))
- ok(endswith(val[2], p 'autoload/remote/host.vim'))
+ ok(endswith(p(val[1]), 'autoload/remote/define.vim'))
+ ok(endswith(p(val[2]), 'autoload/remote/host.vim'))
else
- ok(endswith(val[1], p 'autoload/remote/host.vim'))
- ok(endswith(val[2], p 'autoload/remote/define.vim'))
+ ok(endswith(p(val[1]), 'autoload/remote/host.vim'))
+ ok(endswith(p(val[2]), 'autoload/remote/define.vim'))
end
val = api.nvim_get_runtime_file('autoload/remote/*.vim', false)
eq(1, #val)
ok(
- endswith(val[1], p 'autoload/remote/define.vim')
- or endswith(val[1], p 'autoload/remote/host.vim')
+ endswith(p(val[1]), 'autoload/remote/define.vim')
+ or endswith(p(val[1]), 'autoload/remote/host.vim')
)
val = api.nvim_get_runtime_file('lua', true)
eq(1, #val)
- ok(endswith(val[1], p 'lua'))
+ ok(endswith(p(val[1]), 'lua'))
val = api.nvim_get_runtime_file('lua/vim', true)
eq(1, #val)
- ok(endswith(val[1], p 'lua/vim'))
+ ok(endswith(p(val[1]), 'lua/vim'))
end)
it('can find directories', function()
local val = api.nvim_get_runtime_file('lua/', true)
eq(1, #val)
- ok(endswith(val[1], p 'lua/'))
+ ok(endswith(p(val[1]), 'lua/'))
val = api.nvim_get_runtime_file('lua/vim/', true)
eq(1, #val)
- ok(endswith(val[1], p 'lua/vim/'))
+ ok(endswith(p(val[1]), 'lua/vim/'))
eq({}, api.nvim_get_runtime_file('foobarlang/', true))
end)
diff --git a/test/functional/autocmd/dirchanged_spec.lua b/test/functional/autocmd/dirchanged_spec.lua
index 24ac737b5b..1cde0e0552 100644
--- a/test/functional/autocmd/dirchanged_spec.lua
+++ b/test/functional/autocmd/dirchanged_spec.lua
@@ -9,7 +9,7 @@ local request = n.request
local is_os = t.is_os
describe('autocmd DirChanged and DirChangedPre', function()
- local curdir = vim.uv.cwd():gsub('\\', '/')
+ local curdir = t.fix_slashes(vim.uv.cwd())
local dirs = {
curdir .. '/Xtest-functional-autocmd-dirchanged.dir1',
curdir .. '/Xtest-functional-autocmd-dirchanged.dir2',
diff --git a/test/functional/core/fileio_spec.lua b/test/functional/core/fileio_spec.lua
index 073041fced..d33710a63d 100644
--- a/test/functional/core/fileio_spec.lua
+++ b/test/functional/core/fileio_spec.lua
@@ -321,11 +321,11 @@ end)
describe('tmpdir', function()
local tmproot_pat = [=[.*[/\\]nvim%.[^/\\]+]=]
local testlog = 'Xtest_tmpdir_log'
- local os_tmpdir
+ local os_tmpdir ---@type string
before_each(function()
-- Fake /tmp dir so that we can mess it up.
- os_tmpdir = vim.uv.fs_mkdtemp(vim.fs.dirname(t.tmpname(false)) .. '/nvim_XXXXXXXXXX')
+ os_tmpdir = assert(vim.uv.fs_mkdtemp(vim.fs.dirname(t.tmpname(false)) .. '/nvim_XXXXXXXXXX'))
end)
after_each(function()
@@ -414,15 +414,4 @@ describe('tmpdir', function()
rm_tmpdir()
eq('E5431: tempdir disappeared (3 times)', api.nvim_get_vvar('errmsg'))
end)
-
- it('$NVIM_APPNAME relative path', function()
- clear({
- env = {
- NVIM_APPNAME = 'a/b',
- NVIM_LOG_FILE = testlog,
- TMPDIR = os_tmpdir,
- },
- })
- matches([=[.*[/\\]a%%b%.[^/\\]+]=], fn.tempname())
- end)
end)
diff --git a/test/functional/vimscript/server_spec.lua b/test/functional/core/server_spec.lua
index 2dabe1afc1..0ec11169e9 100644
--- a/test/functional/vimscript/server_spec.lua
+++ b/test/functional/core/server_spec.lua
@@ -1,7 +1,6 @@
local t = require('test.testutil')
local n = require('test.functional.testnvim')()
-local assert_log = t.assert_log
local eq, neq, eval = t.eq, t.neq, n.eval
local clear, fn, api = n.clear, n.fn, n.api
local matches = t.matches
@@ -19,12 +18,16 @@ local function clear_serverlist()
end
end
-describe('server', function()
- after_each(function()
- check_close()
- os.remove(testlog)
- end)
+after_each(function()
+ check_close()
+ os.remove(testlog)
+end)
+
+before_each(function()
+ os.remove(testlog)
+end)
+describe('server', function()
it('serverstart() stores sockets in $XDG_RUNTIME_DIR', function()
local dir = 'Xtest_xdg_run'
mkdir(dir)
@@ -38,6 +41,21 @@ describe('server', function()
end
end)
+ it('broken $XDG_RUNTIME_DIR is not fatal #30282', function()
+ clear {
+ args_rm = { '--listen' },
+ env = { NVIM_LOG_FILE = testlog, XDG_RUNTIME_DIR = '/non-existent-dir/subdir//' },
+ }
+
+ if is_os('win') then
+ -- Windows pipes have a special namespace and thus aren't decided by $XDG_RUNTIME_DIR.
+ matches('nvim', api.nvim_get_vvar('servername'))
+ else
+ eq('', api.nvim_get_vvar('servername'))
+ t.assert_log('Failed to start server%: no such file or directory', testlog, 100)
+ end
+ end)
+
it('serverstart(), serverstop() does not set $NVIM', function()
clear()
local s = eval('serverstart()')
@@ -88,7 +106,7 @@ describe('server', function()
}
eq(0, eval("serverstop('')"))
eq(0, eval("serverstop('bogus-socket-name')"))
- assert_log('Not listening on bogus%-socket%-name', testlog, 10)
+ t.assert_log('Not listening on bogus%-socket%-name', testlog, 10)
end)
it('parses endpoints', function()
@@ -122,7 +140,7 @@ describe('server', function()
if status then
table.insert(expected, v4)
pcall(fn.serverstart, v4) -- exists already; ignore
- assert_log('Failed to start server: address already in use: 127%.0%.0%.1', testlog, 10)
+ t.assert_log('Failed to start server: address already in use: 127%.0%.0%.1', testlog, 10)
end
local v6 = '::1:12345'
@@ -130,13 +148,13 @@ describe('server', function()
if status then
table.insert(expected, v6)
pcall(fn.serverstart, v6) -- exists already; ignore
- assert_log('Failed to start server: address already in use: ::1', testlog, 10)
+ t.assert_log('Failed to start server: address already in use: ::1', testlog, 10)
end
eq(expected, fn.serverlist())
clear_serverlist()
-- Address without slashes is a "name" which is appended to a generated path. #8519
- matches([[.*[/\\]xtest1%.2%.3%.4[^/\\]*]], fn.serverstart('xtest1.2.3.4'))
+ matches([[[/\\]xtest1%.2%.3%.4[^/\\]*]], fn.serverstart('xtest1.2.3.4'))
clear_serverlist()
eq('Vim:Failed to start server: invalid argument', pcall_err(fn.serverstart, '127.0.0.1:65536')) -- invalid port
@@ -172,34 +190,77 @@ describe('server', function()
end)
describe('startup --listen', function()
- it('validates', function()
- clear()
+ -- Tests Nvim output when failing to start, with and without "--headless".
+ -- TODO(justinmk): clear() should have a way to get stdout if Nvim fails to start.
+ local function _test(args, env, expected)
+ local function run(cmd)
+ return n.exec_lua(function(cmd_, env_)
+ return vim
+ .system(cmd_, {
+ text = true,
+ env = vim.tbl_extend(
+ 'force',
+ -- Avoid noise in the logs; we expect failures for these tests.
+ { NVIM_LOG_FILE = testlog },
+ env_ or {}
+ ),
+ })
+ :wait()
+ end, cmd, env) --[[@as vim.SystemCompleted]]
+ end
+
+ local cmd = vim.list_extend({ n.nvim_prog, '+qall!', '--headless' }, args)
+ local r = run(cmd)
+ eq(1, r.code)
+ matches(expected, (r.stderr .. r.stdout):gsub('\\n', ' '))
- -- Tests args with and without "--headless".
- local function _test(args, expected)
- -- XXX: clear v:shell_error, sigh...
- fn.system({ n.nvim_prog, '-es', '+qall!' })
- assert(0 == eval('v:shell_error'))
- local cmd = vim.list_extend({ unpack(n.nvim_argv) }, vim.list_extend({ '--headless' }, args))
- local output = fn.system(cmd)
- assert(0 ~= eval('v:shell_error'))
- -- TODO(justinmk): output not properly captured on Windows?
- if is_os('win') then
- return
- end
- matches(expected, output)
- matches(expected, fn.system(vim.list_extend({ unpack(n.nvim_argv) }, args)))
+ if is_os('win') then
+ return -- On Windows, output without --headless is garbage.
end
+ table.remove(cmd, 3) -- Remove '--headless'.
+ assert(not vim.tbl_contains(cmd, '--headless'))
+ r = run(cmd)
+ eq(1, r.code)
+ matches(expected, (r.stderr .. r.stdout):gsub('\\n', ' '))
+ end
+
+ it('validates', function()
+ clear { env = { NVIM_LOG_FILE = testlog } }
+ local in_use = n.eval('v:servername') ---@type string Address already used by another server.
+
+ t.assert_nolog('Failed to start server', testlog, 100)
+ t.assert_nolog('Host lookup failed', testlog, 100)
- _test({ '--listen' }, 'nvim.*: Argument missing after: "%-%-listen"')
- _test({ '--listen2' }, 'nvim.*: Garbage after option argument: "%-%-listen2"')
- _test({ '--listen', n.eval('v:servername') }, 'nvim.*: Failed to %-%-listen: ".* already .*"')
- _test({ '--listen', '/' }, 'nvim.*: Failed to %-%-listen: ".*"')
+ _test({ '--listen' }, nil, 'nvim.*: Argument missing after: "%-%-listen"')
+ _test({ '--listen2' }, nil, 'nvim.*: Garbage after option argument: "%-%-listen2"')
+ _test(
+ { '--listen', in_use },
+ nil,
+ ('nvim.*: Failed to %%-%%-listen: [^:]+ already [^:]+: "%s"'):format(vim.pesc(in_use))
+ )
+ _test({ '--listen', '/' }, nil, 'nvim.*: Failed to %-%-listen: [^:]+: "/"')
_test(
{ '--listen', 'https://example.com' },
- ('nvim.*: Failed to %%-%%-listen: "%s"'):format(
- (is_os('mac') or is_os('win')) and 'unknown node or service'
- or 'service not available for socket type'
+ nil,
+ ('nvim.*: Failed to %%-%%-listen: %s: "https://example.com"'):format(
+ is_os('mac') and 'unknown node or service' or 'service not available for socket type'
+ )
+ )
+
+ t.assert_log('Failed to start server', testlog, 100)
+ t.assert_log('Host lookup failed', testlog, 100)
+
+ _test(
+ {},
+ { NVIM_LISTEN_ADDRESS = in_use },
+ ('nvim.*: Failed $NVIM_LISTEN_ADDRESS: [^:]+ already [^:]+: "%s"'):format(vim.pesc(in_use))
+ )
+ _test({}, { NVIM_LISTEN_ADDRESS = '/' }, 'nvim.*: Failed $NVIM_LISTEN_ADDRESS: [^:]+: "/"')
+ _test(
+ {},
+ { NVIM_LISTEN_ADDRESS = 'https://example.com' },
+ ('nvim.*: Failed $NVIM_LISTEN_ADDRESS: %s: "https://example.com"'):format(
+ is_os('mac') and 'unknown node or service' or 'service not available for socket type'
)
)
end)
@@ -212,6 +273,6 @@ describe('startup --listen', function()
-- Address without slashes is a "name" which is appended to a generated path. #8519
clear({ args = { '--listen', 'test-name' } })
- matches([[.*[/\\]test%-name[^/\\]*]], api.nvim_get_vvar('servername'))
+ matches([[[/\\]test%-name[^/\\]*]], api.nvim_get_vvar('servername'))
end)
end)
diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua
index 8d6ba9712a..f48bcb9360 100644
--- a/test/functional/core/startup_spec.lua
+++ b/test/functional/core/startup_spec.lua
@@ -27,7 +27,6 @@ local sleep = vim.uv.sleep
local startswith = vim.startswith
local write_file = t.write_file
local api = n.api
-local alter_slashes = n.alter_slashes
local is_os = t.is_os
local dedent = t.dedent
local tbl_map = vim.tbl_map
@@ -40,22 +39,15 @@ local testlog = 'Xtest-startupspec-log'
describe('startup', function()
it('--clean', function()
clear()
- ok(
- string.find(
- alter_slashes(api.nvim_get_option_value('runtimepath', {})),
- fn.stdpath('config'),
- 1,
- true
- ) ~= nil
+ matches(
+ vim.pesc(t.fix_slashes(fn.stdpath('config'))),
+ t.fix_slashes(api.nvim_get_option_value('runtimepath', {}))
)
+
clear('--clean')
ok(
- string.find(
- alter_slashes(api.nvim_get_option_value('runtimepath', {})),
- fn.stdpath('config'),
- 1,
- true
- ) == nil
+ not t.fix_slashes(api.nvim_get_option_value('runtimepath', {}))
+ :match(vim.pesc(t.fix_slashes(fn.stdpath('config'))))
)
end)
diff --git a/test/functional/editor/defaults_spec.lua b/test/functional/editor/defaults_spec.lua
new file mode 100644
index 0000000000..47fd177f7b
--- /dev/null
+++ b/test/functional/editor/defaults_spec.lua
@@ -0,0 +1,100 @@
+--
+-- Tests for default autocmds, mappings, commands, and menus.
+--
+-- See options/defaults_spec.lua for default options and environment decisions.
+--
+
+local t = require('test.testutil')
+local n = require('test.functional.testnvim')()
+local Screen = require('test.functional.ui.screen')
+
+describe('default', function()
+ describe('autocommands', function()
+ it('nvim_terminal.TermClose closes terminal with default shell on success', function()
+ n.clear()
+ n.api.nvim_set_option_value('shell', n.testprg('shell-test'), {})
+ n.command('set shellcmdflag=EXIT shellredir= shellpipe= shellquote= shellxquote=')
+
+ -- Should not block other events
+ n.command('let g:n=0')
+ n.command('au BufEnter * let g:n = g:n + 1')
+
+ n.command('terminal')
+ t.eq(1, n.eval('get(g:, "n", 0)'))
+
+ t.retry(nil, 1000, function()
+ t.neq('terminal', n.api.nvim_get_option_value('buftype', { buf = 0 }))
+ t.eq(2, n.eval('get(g:, "n", 0)'))
+ end)
+ end)
+ end)
+
+ describe('popupmenu', function()
+ it('can be disabled by user', function()
+ n.clear {
+ args = { '+autocmd! nvim_popupmenu', '+aunmenu PopUp' },
+ }
+ local screen = Screen.new(40, 8)
+ screen:attach()
+ n.insert([[
+ 1 line 1
+ 2 https://example.com
+ 3 line 3
+ 4 line 4]])
+
+ n.api.nvim_input_mouse('right', 'press', '', 0, 1, 4)
+ screen:expect({
+ grid = [[
+ 1 line 1 |
+ 2 ht^tps://example.com |
+ 3 line 3 |
+ 4 line 4 |
+ {1:~ }|*3
+ |
+ ]],
+ })
+ end)
+
+ it('right-click on URL shows "Open in web browser"', function()
+ n.clear()
+ local screen = Screen.new(40, 8)
+ screen:attach()
+ n.insert([[
+ 1 line 1
+ 2 https://example.com
+ 3 line 3
+ 4 line 4]])
+
+ n.api.nvim_input_mouse('right', 'press', '', 0, 3, 4)
+ screen:expect({
+ grid = [[
+ 1 line 1 |
+ 2 https://example.com |
+ 3 line 3 |
+ 4 li^ne 4 |
+ {1:~ }{4: Inspect }{1: }|
+ {1:~ }{4: }{1: }|
+ {1:~ }{4: Paste }{1: }|
+ {4: Select All } |
+ ]],
+ })
+
+ n.api.nvim_input_mouse('right', 'press', '', 0, 1, 4)
+ screen:expect({
+ grid = [[
+ 1 line 1 |
+ 2 ht^tps://example.com |
+ 3 l{4: Open in web browser } |
+ 4 l{4: Inspect } |
+ {1:~ }{4: }{1: }|
+ {1:~ }{4: Paste }{1: }|
+ {1:~ }{4: Select All }{1: }|
+ {4: } |
+ ]],
+ })
+ end)
+ end)
+
+ -- describe('key mappings', function()
+ -- end)
+end)
diff --git a/test/functional/editor/mode_insert_spec.lua b/test/functional/editor/mode_insert_spec.lua
index fc1e6c4ee4..87d5c46134 100644
--- a/test/functional/editor/mode_insert_spec.lua
+++ b/test/functional/editor/mode_insert_spec.lua
@@ -351,4 +351,97 @@ describe('insert-mode', function()
eq(2, api.nvim_win_get_cursor(0)[1])
end)
end)
+
+ it('backspace after replacing multibyte chars', function()
+ local screen = Screen.new(30, 3)
+ screen:attach()
+ api.nvim_buf_set_lines(0, 0, -1, true, { 'test ȧ̟̜̝̅̚m̆̉̐̐̇̈ å' })
+ feed('^Rabcdefghi')
+ screen:expect([[
+ abcdefghi^ |
+ {1:~ }|
+ {5:-- REPLACE --} |
+ ]])
+
+ feed('<bs>')
+ screen:expect([[
+ abcdefgh^å |
+ {1:~ }|
+ {5:-- REPLACE --} |
+ ]])
+
+ feed('<bs>')
+ screen:expect([[
+ abcdefg^ å |
+ {1:~ }|
+ {5:-- REPLACE --} |
+ ]])
+
+ feed('<bs>')
+ screen:expect([[
+ abcdef^m̆̉̐̐̇̈ å |
+ {1:~ }|
+ {5:-- REPLACE --} |
+ ]])
+
+ feed('<bs>')
+ screen:expect([[
+ abcde^ȧ̟̜̝̅̚m̆̉̐̐̇̈ å |
+ {1:~ }|
+ {5:-- REPLACE --} |
+ ]])
+
+ feed('<bs>')
+ screen:expect([[
+ abcd^ ȧ̟̜̝̅̚m̆̉̐̐̇̈ å |
+ {1:~ }|
+ {5:-- REPLACE --} |
+ ]])
+
+ feed('<esc>')
+
+ api.nvim_buf_set_lines(0, 0, -1, true, { 'wow 🧑‍🌾🏳️‍⚧️x' })
+ feed('^Rabcd')
+
+ screen:expect([[
+ abcd^🧑‍🌾🏳️‍⚧️x |
+ {1:~ }|
+ {5:-- REPLACE --} |
+ ]])
+
+ feed('e')
+ screen:expect([[
+ abcde^🏳️‍⚧️x |
+ {1:~ }|
+ {5:-- REPLACE --} |
+ ]])
+
+ feed('f')
+ screen:expect([[
+ abcdef^x |
+ {1:~ }|
+ {5:-- REPLACE --} |
+ ]])
+
+ feed('<bs>')
+ screen:expect([[
+ abcde^🏳️‍⚧️x |
+ {1:~ }|
+ {5:-- REPLACE --} |
+ ]])
+
+ feed('<bs>')
+ screen:expect([[
+ abcd^🧑‍🌾🏳️‍⚧️x |
+ {1:~ }|
+ {5:-- REPLACE --} |
+ ]])
+
+ feed('<bs>')
+ screen:expect([[
+ abc^ 🧑‍🌾🏳️‍⚧️x |
+ {1:~ }|
+ {5:-- REPLACE --} |
+ ]])
+ end)
end)
diff --git a/test/functional/ex_cmds/mksession_spec.lua b/test/functional/ex_cmds/mksession_spec.lua
index 9b24854362..8f09e802eb 100644
--- a/test/functional/ex_cmds/mksession_spec.lua
+++ b/test/functional/ex_cmds/mksession_spec.lua
@@ -170,7 +170,7 @@ describe(':mksession', function()
skip(is_os('win'), 'causes rmdir() to fail')
local cwd_dir = fn.fnamemodify('.', ':p:~'):gsub([[[\/]*$]], '')
- cwd_dir = cwd_dir:gsub([[\]], '/') -- :mksession always uses unix slashes.
+ cwd_dir = t.fix_slashes(cwd_dir) -- :mksession always uses unix slashes.
local session_path = cwd_dir .. '/' .. session_file
command('cd ' .. tab_dir)
diff --git a/test/functional/lua/uri_spec.lua b/test/functional/lua/uri_spec.lua
index 553afb35d3..258b96bc43 100644
--- a/test/functional/lua/uri_spec.lua
+++ b/test/functional/lua/uri_spec.lua
@@ -217,7 +217,7 @@ describe('URI methods', function()
]],
file
)
- local expected_uri = 'file:///' .. file:gsub('\\', '/')
+ local expected_uri = 'file:///' .. t.fix_slashes(file)
eq(expected_uri, exec_lua(test_case))
os.remove(file)
end)
diff --git a/test/functional/lua/vim_spec.lua b/test/functional/lua/vim_spec.lua
index 7bba24483e..599b688bf4 100644
--- a/test/functional/lua/vim_spec.lua
+++ b/test/functional/lua/vim_spec.lua
@@ -1071,42 +1071,28 @@ describe('lua stdlib', function()
]])
)
- -- Fix github issue #23654
ok(exec_lua([[
- local a = { sub = { [1] = 'a' } }
- local b = { sub = { b = 'a' } }
+ local a = { sub = { 'a', 'b' } }
+ local b = { sub = { 'b', 'c' } }
local c = vim.tbl_deep_extend('force', a, b)
- return vim.deep_equal(c, { sub = { [1] = 'a', b = 'a' } })
+ return vim.deep_equal(c, { sub = { 'b', 'c' } })
]]))
- matches(
- 'invalid "behavior": nil',
- pcall_err(
- exec_lua,
- [[
- return vim.tbl_deep_extend()
- ]]
- )
- )
+ matches('invalid "behavior": nil', pcall_err(exec_lua, [[return vim.tbl_deep_extend()]]))
matches(
'wrong number of arguments %(given 1, expected at least 3%)',
- pcall_err(
- exec_lua,
- [[
- return vim.tbl_deep_extend("keep")
- ]]
- )
+ pcall_err(exec_lua, [[return vim.tbl_deep_extend("keep")]])
)
matches(
'wrong number of arguments %(given 2, expected at least 3%)',
- pcall_err(
- exec_lua,
- [[
- return vim.tbl_deep_extend("keep", {})
- ]]
- )
+ pcall_err(exec_lua, [[return vim.tbl_deep_extend("keep", {})]])
+ )
+
+ matches(
+ 'after the second argument%: expected table, got number',
+ pcall_err(exec_lua, [[return vim.tbl_deep_extend("keep", {}, 42)]])
)
end)
diff --git a/test/functional/options/autochdir_spec.lua b/test/functional/options/autochdir_spec.lua
index c490ab67a9..a409262d84 100644
--- a/test/functional/options/autochdir_spec.lua
+++ b/test/functional/options/autochdir_spec.lua
@@ -22,7 +22,7 @@ describe("'autochdir'", function()
end)
it('is not overwritten by getwinvar() call #17609', function()
- local curdir = vim.uv.cwd():gsub('\\', '/')
+ local curdir = t.fix_slashes(vim.uv.cwd())
local dir_a = curdir .. '/Xtest-functional-options-autochdir.dir_a'
local dir_b = curdir .. '/Xtest-functional-options-autochdir.dir_b'
mkdir(dir_a)
diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua
index 0faced5149..e3d15fa30f 100644
--- a/test/functional/options/defaults_spec.lua
+++ b/test/functional/options/defaults_spec.lua
@@ -1,3 +1,9 @@
+--
+-- Tests for default options and environment decisions.
+--
+-- See editor/defaults_spec.lua for default autocmds, mappings, commands, and menus.
+--
+
local t = require('test.testutil')
local n = require('test.functional.testnvim')()
local Screen = require('test.functional.ui.screen')
@@ -17,7 +23,6 @@ local insert = n.insert
local neq = t.neq
local mkdir = t.mkdir
local rmdir = n.rmdir
-local alter_slashes = n.alter_slashes
local tbl_contains = vim.tbl_contains
local expect_exit = n.expect_exit
local check_close = n.check_close
@@ -256,7 +261,7 @@ describe('startup defaults', function()
NVIM_LOG_FILE = '', -- Empty is invalid.
},
})
- eq(xdgstatedir .. '/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/'))
+ eq(xdgstatedir .. '/log', t.fix_slashes(eval('$NVIM_LOG_FILE')))
end)
it('defaults to stdpath("log")/log if invalid', function()
@@ -267,7 +272,7 @@ describe('startup defaults', function()
NVIM_LOG_FILE = '.', -- Any directory is invalid.
},
})
- eq(xdgstatedir .. '/log', string.gsub(eval('$NVIM_LOG_FILE'), '\\', '/'))
+ eq(xdgstatedir .. '/log', t.fix_slashes(eval('$NVIM_LOG_FILE')))
-- Avoid "failed to open $NVIM_LOG_FILE" noise in test output.
expect_exit(command, 'qall!')
end)
@@ -377,69 +382,69 @@ describe('XDG defaults', function()
eq(
(
- (
+ t.fix_slashes(
root_path
- .. ('/x'):rep(4096)
- .. '/nvim'
- .. ','
- .. root_path
- .. ('/a'):rep(2048)
- .. '/nvim'
- .. ','
- .. root_path
- .. ('/b'):rep(2048)
- .. '/nvim'
- .. (',' .. root_path .. '/c/nvim')
- .. ','
- .. root_path
- .. ('/X'):rep(4096)
- .. '/'
- .. data_dir
- .. '/site'
- .. ','
- .. root_path
- .. ('/A'):rep(2048)
- .. '/nvim/site'
- .. ','
- .. root_path
- .. ('/B'):rep(2048)
- .. '/nvim/site'
- .. (',' .. root_path .. '/C/nvim/site')
- .. ','
- .. vimruntime
- .. ','
- .. libdir
- .. (',' .. root_path .. '/C/nvim/site/after')
- .. ','
- .. root_path
- .. ('/B'):rep(2048)
- .. '/nvim/site/after'
- .. ','
- .. root_path
- .. ('/A'):rep(2048)
- .. '/nvim/site/after'
- .. ','
- .. root_path
- .. ('/X'):rep(4096)
- .. '/'
- .. data_dir
- .. '/site/after'
- .. (',' .. root_path .. '/c/nvim/after')
- .. ','
- .. root_path
- .. ('/b'):rep(2048)
- .. '/nvim/after'
- .. ','
- .. root_path
- .. ('/a'):rep(2048)
- .. '/nvim/after'
- .. ','
- .. root_path
- .. ('/x'):rep(4096)
- .. '/nvim/after'
- ):gsub('\\', '/')
+ .. ('/x'):rep(4096)
+ .. '/nvim'
+ .. ','
+ .. root_path
+ .. ('/a'):rep(2048)
+ .. '/nvim'
+ .. ','
+ .. root_path
+ .. ('/b'):rep(2048)
+ .. '/nvim'
+ .. (',' .. root_path .. '/c/nvim')
+ .. ','
+ .. root_path
+ .. ('/X'):rep(4096)
+ .. '/'
+ .. data_dir
+ .. '/site'
+ .. ','
+ .. root_path
+ .. ('/A'):rep(2048)
+ .. '/nvim/site'
+ .. ','
+ .. root_path
+ .. ('/B'):rep(2048)
+ .. '/nvim/site'
+ .. (',' .. root_path .. '/C/nvim/site')
+ .. ','
+ .. vimruntime
+ .. ','
+ .. libdir
+ .. (',' .. root_path .. '/C/nvim/site/after')
+ .. ','
+ .. root_path
+ .. ('/B'):rep(2048)
+ .. '/nvim/site/after'
+ .. ','
+ .. root_path
+ .. ('/A'):rep(2048)
+ .. '/nvim/site/after'
+ .. ','
+ .. root_path
+ .. ('/X'):rep(4096)
+ .. '/'
+ .. data_dir
+ .. '/site/after'
+ .. (',' .. root_path .. '/c/nvim/after')
+ .. ','
+ .. root_path
+ .. ('/b'):rep(2048)
+ .. '/nvim/after'
+ .. ','
+ .. root_path
+ .. ('/a'):rep(2048)
+ .. '/nvim/after'
+ .. ','
+ .. root_path
+ .. ('/x'):rep(4096)
+ .. '/nvim/after'
+ )
),
- (api.nvim_get_option_value('runtimepath', {})):gsub('\\', '/')
+ t.fix_slashes(api.nvim_get_option_value('runtimepath', {}))
)
command('set runtimepath&')
command('set backupdir&')
@@ -448,85 +453,85 @@ describe('XDG defaults', function()
command('set viewdir&')
eq(
(
- (
+ t.fix_slashes(
root_path
- .. ('/x'):rep(4096)
- .. '/nvim'
- .. ','
- .. root_path
- .. ('/a'):rep(2048)
- .. '/nvim'
- .. ','
- .. root_path
- .. ('/b'):rep(2048)
- .. '/nvim'
- .. (',' .. root_path .. '/c/nvim')
- .. ','
- .. root_path
- .. ('/X'):rep(4096)
- .. '/'
- .. data_dir
- .. '/site'
- .. ','
- .. root_path
- .. ('/A'):rep(2048)
- .. '/nvim/site'
- .. ','
- .. root_path
- .. ('/B'):rep(2048)
- .. '/nvim/site'
- .. (',' .. root_path .. '/C/nvim/site')
- .. ','
- .. vimruntime
- .. ','
- .. libdir
- .. (',' .. root_path .. '/C/nvim/site/after')
- .. ','
- .. root_path
- .. ('/B'):rep(2048)
- .. '/nvim/site/after'
- .. ','
- .. root_path
- .. ('/A'):rep(2048)
- .. '/nvim/site/after'
- .. ','
- .. root_path
- .. ('/X'):rep(4096)
- .. '/'
- .. data_dir
- .. '/site/after'
- .. (',' .. root_path .. '/c/nvim/after')
- .. ','
- .. root_path
- .. ('/b'):rep(2048)
- .. '/nvim/after'
- .. ','
- .. root_path
- .. ('/a'):rep(2048)
- .. '/nvim/after'
- .. ','
- .. root_path
- .. ('/x'):rep(4096)
- .. '/nvim/after'
- ):gsub('\\', '/')
+ .. ('/x'):rep(4096)
+ .. '/nvim'
+ .. ','
+ .. root_path
+ .. ('/a'):rep(2048)
+ .. '/nvim'
+ .. ','
+ .. root_path
+ .. ('/b'):rep(2048)
+ .. '/nvim'
+ .. (',' .. root_path .. '/c/nvim')
+ .. ','
+ .. root_path
+ .. ('/X'):rep(4096)
+ .. '/'
+ .. data_dir
+ .. '/site'
+ .. ','
+ .. root_path
+ .. ('/A'):rep(2048)
+ .. '/nvim/site'
+ .. ','
+ .. root_path
+ .. ('/B'):rep(2048)
+ .. '/nvim/site'
+ .. (',' .. root_path .. '/C/nvim/site')
+ .. ','
+ .. vimruntime
+ .. ','
+ .. libdir
+ .. (',' .. root_path .. '/C/nvim/site/after')
+ .. ','
+ .. root_path
+ .. ('/B'):rep(2048)
+ .. '/nvim/site/after'
+ .. ','
+ .. root_path
+ .. ('/A'):rep(2048)
+ .. '/nvim/site/after'
+ .. ','
+ .. root_path
+ .. ('/X'):rep(4096)
+ .. '/'
+ .. data_dir
+ .. '/site/after'
+ .. (',' .. root_path .. '/c/nvim/after')
+ .. ','
+ .. root_path
+ .. ('/b'):rep(2048)
+ .. '/nvim/after'
+ .. ','
+ .. root_path
+ .. ('/a'):rep(2048)
+ .. '/nvim/after'
+ .. ','
+ .. root_path
+ .. ('/x'):rep(4096)
+ .. '/nvim/after'
+ )
),
- (api.nvim_get_option_value('runtimepath', {})):gsub('\\', '/')
+ t.fix_slashes(api.nvim_get_option_value('runtimepath', {}))
)
eq(
'.,' .. root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/backup//',
- (api.nvim_get_option_value('backupdir', {}):gsub('\\', '/'))
+ t.fix_slashes(api.nvim_get_option_value('backupdir', {}))
)
eq(
root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/swap//',
- (api.nvim_get_option_value('directory', {})):gsub('\\', '/')
+ t.fix_slashes(api.nvim_get_option_value('directory', {}))
)
eq(
root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/undo//',
- (api.nvim_get_option_value('undodir', {})):gsub('\\', '/')
+ t.fix_slashes(api.nvim_get_option_value('undodir', {}))
)
eq(
root_path .. ('/X'):rep(4096) .. '/' .. state_dir .. '/view//',
- (api.nvim_get_option_value('viewdir', {})):gsub('\\', '/')
+ t.fix_slashes(api.nvim_get_option_value('viewdir', {}))
)
end)
end)
@@ -568,26 +573,26 @@ describe('XDG defaults', function()
local vimruntime, libdir = vimruntime_and_libdir()
eq(
(
- (
+ t.fix_slashes(
'$XDG_DATA_HOME/nvim'
- .. ',$XDG_DATA_DIRS/nvim'
- .. ',$XDG_CONFIG_HOME/'
- .. data_dir
- .. '/site'
- .. ',$XDG_CONFIG_DIRS/nvim/site'
- .. ','
- .. vimruntime
- .. ','
- .. libdir
- .. ',$XDG_CONFIG_DIRS/nvim/site/after'
- .. ',$XDG_CONFIG_HOME/'
- .. data_dir
- .. '/site/after'
- .. ',$XDG_DATA_DIRS/nvim/after'
- .. ',$XDG_DATA_HOME/nvim/after'
- ):gsub('\\', '/')
+ .. ',$XDG_DATA_DIRS/nvim'
+ .. ',$XDG_CONFIG_HOME/'
+ .. data_dir
+ .. '/site'
+ .. ',$XDG_CONFIG_DIRS/nvim/site'
+ .. ','
+ .. vimruntime
+ .. ','
+ .. libdir
+ .. ',$XDG_CONFIG_DIRS/nvim/site/after'
+ .. ',$XDG_CONFIG_HOME/'
+ .. data_dir
+ .. '/site/after'
+ .. ',$XDG_DATA_DIRS/nvim/after'
+ .. ',$XDG_DATA_HOME/nvim/after'
+ )
),
- (api.nvim_get_option_value('runtimepath', {})):gsub('\\', '/')
+ t.fix_slashes(api.nvim_get_option_value('runtimepath', {}))
)
command('set runtimepath&')
command('set backupdir&')
@@ -596,80 +601,80 @@ describe('XDG defaults', function()
command('set viewdir&')
eq(
(
- (
+ t.fix_slashes(
'$XDG_DATA_HOME/nvim'
- .. ',$XDG_DATA_DIRS/nvim'
- .. ',$XDG_CONFIG_HOME/'
- .. data_dir
- .. '/site'
- .. ',$XDG_CONFIG_DIRS/nvim/site'
- .. ','
- .. vimruntime
- .. ','
- .. libdir
- .. ',$XDG_CONFIG_DIRS/nvim/site/after'
- .. ',$XDG_CONFIG_HOME/'
- .. data_dir
- .. '/site/after'
- .. ',$XDG_DATA_DIRS/nvim/after'
- .. ',$XDG_DATA_HOME/nvim/after'
- ):gsub('\\', '/')
+ .. ',$XDG_DATA_DIRS/nvim'
+ .. ',$XDG_CONFIG_HOME/'
+ .. data_dir
+ .. '/site'
+ .. ',$XDG_CONFIG_DIRS/nvim/site'
+ .. ','
+ .. vimruntime
+ .. ','
+ .. libdir
+ .. ',$XDG_CONFIG_DIRS/nvim/site/after'
+ .. ',$XDG_CONFIG_HOME/'
+ .. data_dir
+ .. '/site/after'
+ .. ',$XDG_DATA_DIRS/nvim/after'
+ .. ',$XDG_DATA_HOME/nvim/after'
+ )
),
- (api.nvim_get_option_value('runtimepath', {})):gsub('\\', '/')
+ t.fix_slashes(api.nvim_get_option_value('runtimepath', {}))
)
eq(
('.,$XDG_CONFIG_HOME/' .. state_dir .. '/backup//'),
- api.nvim_get_option_value('backupdir', {}):gsub('\\', '/')
+ t.fix_slashes(api.nvim_get_option_value('backupdir', {}))
)
eq(
('$XDG_CONFIG_HOME/' .. state_dir .. '/swap//'),
- api.nvim_get_option_value('directory', {}):gsub('\\', '/')
+ t.fix_slashes(api.nvim_get_option_value('directory', {}))
)
eq(
('$XDG_CONFIG_HOME/' .. state_dir .. '/undo//'),
- api.nvim_get_option_value('undodir', {}):gsub('\\', '/')
+ t.fix_slashes(api.nvim_get_option_value('undodir', {}))
)
eq(
('$XDG_CONFIG_HOME/' .. state_dir .. '/view//'),
- api.nvim_get_option_value('viewdir', {}):gsub('\\', '/')
+ t.fix_slashes(api.nvim_get_option_value('viewdir', {}))
)
command('set all&')
eq(
- (
+ t.fix_slashes(
'$XDG_DATA_HOME/nvim'
- .. ',$XDG_DATA_DIRS/nvim'
- .. ',$XDG_CONFIG_HOME/'
- .. data_dir
- .. '/site'
- .. ',$XDG_CONFIG_DIRS/nvim/site'
- .. ','
- .. vimruntime
- .. ','
- .. libdir
- .. ',$XDG_CONFIG_DIRS/nvim/site/after'
- .. ',$XDG_CONFIG_HOME/'
- .. data_dir
- .. '/site/after'
- .. ',$XDG_DATA_DIRS/nvim/after'
- .. ',$XDG_DATA_HOME/nvim/after'
- ):gsub('\\', '/'),
- (api.nvim_get_option_value('runtimepath', {})):gsub('\\', '/')
+ .. ',$XDG_DATA_DIRS/nvim'
+ .. ',$XDG_CONFIG_HOME/'
+ .. data_dir
+ .. '/site'
+ .. ',$XDG_CONFIG_DIRS/nvim/site'
+ .. ','
+ .. vimruntime
+ .. ','
+ .. libdir
+ .. ',$XDG_CONFIG_DIRS/nvim/site/after'
+ .. ',$XDG_CONFIG_HOME/'
+ .. data_dir
+ .. '/site/after'
+ .. ',$XDG_DATA_DIRS/nvim/after'
+ .. ',$XDG_DATA_HOME/nvim/after'
+ ),
+ t.fix_slashes(api.nvim_get_option_value('runtimepath', {}))
)
eq(
('.,$XDG_CONFIG_HOME/' .. state_dir .. '/backup//'),
- api.nvim_get_option_value('backupdir', {}):gsub('\\', '/')
+ t.fix_slashes(api.nvim_get_option_value('backupdir', {}))
)
eq(
('$XDG_CONFIG_HOME/' .. state_dir .. '/swap//'),
- api.nvim_get_option_value('directory', {}):gsub('\\', '/')
+ t.fix_slashes(api.nvim_get_option_value('directory', {}))
)
eq(
('$XDG_CONFIG_HOME/' .. state_dir .. '/undo//'),
- api.nvim_get_option_value('undodir', {}):gsub('\\', '/')
+ t.fix_slashes(api.nvim_get_option_value('undodir', {}))
)
eq(
('$XDG_CONFIG_HOME/' .. state_dir .. '/view//'),
- api.nvim_get_option_value('viewdir', {}):gsub('\\', '/')
+ t.fix_slashes(api.nvim_get_option_value('viewdir', {}))
)
eq(nil, (fn.tempname()):match('XDG_RUNTIME_DIR'))
end)
@@ -909,7 +914,7 @@ describe('stdpath()', function()
assert_alive() -- Check for crash. #8393
end)
- it('supports $NVIM_APPNAME', function()
+ it('$NVIM_APPNAME', function()
local appname = 'NVIM_APPNAME_TEST' .. ('_'):rep(106)
clear({ env = { NVIM_APPNAME = appname, NVIM_LOG_FILE = testlog } })
eq(appname, fn.fnamemodify(fn.stdpath('config'), ':t'))
@@ -933,7 +938,7 @@ describe('stdpath()', function()
local child = vim.fn.jobstart({ vim.v.progpath, '--clean', '--headless', '--listen', 'x', '+qall!' }, { env = { NVIM_APPNAME = %q } })
return vim.fn.jobwait({ child }, %d)[1]
]],
- alter_slashes(testAppname),
+ testAppname,
3000
)
eq(expected_exitcode, exec_lua(lua_code))
@@ -951,24 +956,43 @@ describe('stdpath()', function()
test_appname('a/b\\c', 0)
end)
+ it('$NVIM_APPNAME relative path', function()
+ local tmpdir = t.tmpname(false)
+ t.mkdir(tmpdir)
+
+ clear({
+ args_rm = { '--listen' },
+ env = {
+ NVIM_APPNAME = 'relative/appname',
+ NVIM_LOG_FILE = testlog,
+ TMPDIR = tmpdir,
+ },
+ })
+
+ t.matches(vim.pesc(tmpdir), t.fix_slashes(fn.tempname()))
+ t.assert_nolog('tempdir', testlog, 100)
+ t.assert_nolog('TMPDIR', testlog, 100)
+ t.matches([=[[/\\]relative%-appname.[^/\\]+]=], api.nvim_get_vvar('servername'))
+ end)
+
describe('returns a String', function()
describe('with "config"', function()
it('knows XDG_CONFIG_HOME', function()
clear({
env = {
- XDG_CONFIG_HOME = alter_slashes('/home/docwhat/.config'),
+ XDG_CONFIG_HOME = '/home/docwhat/.config',
},
})
- eq(alter_slashes('/home/docwhat/.config/nvim'), fn.stdpath('config'))
+ eq('/home/docwhat/.config/nvim', t.fix_slashes(fn.stdpath('config')))
end)
it('handles changes during runtime', function()
clear({ env = {
- XDG_CONFIG_HOME = alter_slashes('/home/original'),
+ XDG_CONFIG_HOME = '/home/original',
} })
- eq(alter_slashes('/home/original/nvim'), fn.stdpath('config'))
- command("let $XDG_CONFIG_HOME='" .. alter_slashes('/home/new') .. "'")
- eq(alter_slashes('/home/new/nvim'), fn.stdpath('config'))
+ eq('/home/original/nvim', t.fix_slashes(fn.stdpath('config')))
+ command("let $XDG_CONFIG_HOME='/home/new'")
+ eq('/home/new/nvim', t.fix_slashes(fn.stdpath('config')))
end)
it("doesn't expand $VARIABLES", function()
@@ -978,32 +1002,32 @@ describe('stdpath()', function()
VARIABLES = 'this-should-not-happen',
},
})
- eq(alter_slashes('$VARIABLES/nvim'), fn.stdpath('config'))
+ eq('$VARIABLES/nvim', t.fix_slashes(fn.stdpath('config')))
end)
it("doesn't expand ~/", function()
clear({ env = {
- XDG_CONFIG_HOME = alter_slashes('~/frobnitz'),
+ XDG_CONFIG_HOME = '~/frobnitz',
} })
- eq(alter_slashes('~/frobnitz/nvim'), fn.stdpath('config'))
+ eq('~/frobnitz/nvim', t.fix_slashes(fn.stdpath('config')))
end)
end)
describe('with "data"', function()
it('knows XDG_DATA_HOME', function()
clear({ env = {
- XDG_DATA_HOME = alter_slashes('/home/docwhat/.local'),
+ XDG_DATA_HOME = '/home/docwhat/.local',
} })
- eq(alter_slashes('/home/docwhat/.local/' .. datadir), fn.stdpath('data'))
+ eq('/home/docwhat/.local/' .. datadir, t.fix_slashes(fn.stdpath('data')))
end)
it('handles changes during runtime', function()
clear({ env = {
- XDG_DATA_HOME = alter_slashes('/home/original'),
+ XDG_DATA_HOME = '/home/original',
} })
- eq(alter_slashes('/home/original/' .. datadir), fn.stdpath('data'))
- command("let $XDG_DATA_HOME='" .. alter_slashes('/home/new') .. "'")
- eq(alter_slashes('/home/new/' .. datadir), fn.stdpath('data'))
+ eq('/home/original/' .. datadir, t.fix_slashes(fn.stdpath('data')))
+ command("let $XDG_DATA_HOME='/home/new'")
+ eq('/home/new/' .. datadir, t.fix_slashes(fn.stdpath('data')))
end)
it("doesn't expand $VARIABLES", function()
@@ -1013,14 +1037,14 @@ describe('stdpath()', function()
VARIABLES = 'this-should-not-happen',
},
})
- eq(alter_slashes('$VARIABLES/' .. datadir), fn.stdpath('data'))
+ eq('$VARIABLES/' .. datadir, t.fix_slashes(fn.stdpath('data')))
end)
it("doesn't expand ~/", function()
clear({ env = {
- XDG_DATA_HOME = alter_slashes('~/frobnitz'),
+ XDG_DATA_HOME = '~/frobnitz',
} })
- eq(alter_slashes('~/frobnitz/' .. datadir), fn.stdpath('data'))
+ eq('~/frobnitz/' .. datadir, t.fix_slashes(fn.stdpath('data')))
end)
end)
@@ -1028,19 +1052,19 @@ describe('stdpath()', function()
it('knows XDG_STATE_HOME', function()
clear({
env = {
- XDG_STATE_HOME = alter_slashes('/home/docwhat/.local'),
+ XDG_STATE_HOME = '/home/docwhat/.local',
},
})
- eq(alter_slashes('/home/docwhat/.local/' .. statedir), fn.stdpath('state'))
+ eq('/home/docwhat/.local/' .. statedir, t.fix_slashes(fn.stdpath('state')))
end)
it('handles changes during runtime', function()
clear({ env = {
- XDG_STATE_HOME = alter_slashes('/home/original'),
+ XDG_STATE_HOME = '/home/original',
} })
- eq(alter_slashes('/home/original/' .. statedir), fn.stdpath('state'))
- command("let $XDG_STATE_HOME='" .. alter_slashes('/home/new') .. "'")
- eq(alter_slashes('/home/new/' .. statedir), fn.stdpath('state'))
+ eq('/home/original/' .. statedir, t.fix_slashes(fn.stdpath('state')))
+ command("let $XDG_STATE_HOME='" .. '/home/new' .. "'")
+ eq('/home/new/' .. statedir, t.fix_slashes(fn.stdpath('state')))
end)
it("doesn't expand $VARIABLES", function()
@@ -1050,14 +1074,14 @@ describe('stdpath()', function()
VARIABLES = 'this-should-not-happen',
},
})
- eq(alter_slashes('$VARIABLES/' .. statedir), fn.stdpath('state'))
+ eq('$VARIABLES/' .. statedir, t.fix_slashes(fn.stdpath('state')))
end)
it("doesn't expand ~/", function()
clear({ env = {
- XDG_STATE_HOME = alter_slashes('~/frobnitz'),
+ XDG_STATE_HOME = '~/frobnitz',
} })
- eq(alter_slashes('~/frobnitz/' .. statedir), fn.stdpath('state'))
+ eq('~/frobnitz/' .. statedir, t.fix_slashes(fn.stdpath('state')))
end)
end)
@@ -1065,19 +1089,19 @@ describe('stdpath()', function()
it('knows XDG_CACHE_HOME', function()
clear({
env = {
- XDG_CACHE_HOME = alter_slashes('/home/docwhat/.cache'),
+ XDG_CACHE_HOME = '/home/docwhat/.cache',
},
})
- eq(alter_slashes('/home/docwhat/.cache/nvim'), fn.stdpath('cache'))
+ eq('/home/docwhat/.cache/nvim', t.fix_slashes(fn.stdpath('cache')))
end)
it('handles changes during runtime', function()
clear({ env = {
- XDG_CACHE_HOME = alter_slashes('/home/original'),
+ XDG_CACHE_HOME = '/home/original',
} })
- eq(alter_slashes('/home/original/nvim'), fn.stdpath('cache'))
- command("let $XDG_CACHE_HOME='" .. alter_slashes('/home/new') .. "'")
- eq(alter_slashes('/home/new/nvim'), fn.stdpath('cache'))
+ eq('/home/original/nvim', t.fix_slashes(fn.stdpath('cache')))
+ command("let $XDG_CACHE_HOME='" .. '/home/new' .. "'")
+ eq('/home/new/nvim', t.fix_slashes(fn.stdpath('cache')))
end)
it("doesn't expand $VARIABLES", function()
@@ -1087,14 +1111,14 @@ describe('stdpath()', function()
VARIABLES = 'this-should-not-happen',
},
})
- eq(alter_slashes('$VARIABLES/nvim'), fn.stdpath('cache'))
+ eq('$VARIABLES/nvim', t.fix_slashes(fn.stdpath('cache')))
end)
it("doesn't expand ~/", function()
clear({ env = {
- XDG_CACHE_HOME = alter_slashes('~/frobnitz'),
+ XDG_CACHE_HOME = '~/frobnitz',
} })
- eq(alter_slashes('~/frobnitz/nvim'), fn.stdpath('cache'))
+ eq('~/frobnitz/nvim', t.fix_slashes(fn.stdpath('cache')))
end)
end)
end)
@@ -1108,6 +1132,7 @@ describe('stdpath()', function()
HOMEDRIVE = 'C:',
HOMEPATH = '\\Users\\docwhat',
LOCALAPPDATA = 'C:\\Users\\docwhat\\AppData\\Local',
+ NVIM_LOG_FILE = testlog,
TEMP = 'C:\\Users\\docwhat\\AppData\\Local\\Temp',
TMPDIR = 'C:\\Users\\docwhat\\AppData\\Local\\Temp',
TMP = 'C:\\Users\\docwhat\\AppData\\Local\\Temp',
@@ -1118,6 +1143,7 @@ describe('stdpath()', function()
HOMEDRIVE = 'HOMEDRIVE-should-be-ignored',
HOMEPATH = 'HOMEPATH-should-be-ignored',
LOCALAPPDATA = 'LOCALAPPDATA-should-be-ignored',
+ NVIM_LOG_FILE = testlog,
TEMP = 'TEMP-should-be-ignored',
TMPDIR = 'TMPDIR-should-be-ignored',
TMP = 'TMP-should-be-ignored',
@@ -1141,12 +1167,18 @@ describe('stdpath()', function()
describe(msg, function()
it('set via system', function()
set_paths_via_system(env_var_name, paths)
- eq(expected_paths, fn.stdpath(stdpath_arg))
+ eq(expected_paths, t.fix_slashes(fn.stdpath(stdpath_arg)))
+ if not is_os('win') then
+ assert_log('$TMPDIR tempdir not a directory.*TMPDIR%-should%-be%-ignored', testlog, 100)
+ end
end)
it('set at runtime', function()
set_paths_at_runtime(env_var_name, paths)
- eq(expected_paths, fn.stdpath(stdpath_arg))
+ eq(expected_paths, t.fix_slashes(fn.stdpath(stdpath_arg)))
+ if not is_os('win') then
+ assert_log('$TMPDIR tempdir not a directory.*TMPDIR%-should%-be%-ignored', testlog, 100)
+ end
end)
end)
end
@@ -1157,10 +1189,10 @@ describe('stdpath()', function()
'config_dirs',
'XDG_CONFIG_DIRS',
{
- alter_slashes('/home/docwhat/.config'),
+ t.fix_slashes('/home/docwhat/.config'),
},
{
- alter_slashes('/home/docwhat/.config/nvim'),
+ t.fix_slashes('/home/docwhat/.config/nvim'),
}
)
@@ -1169,12 +1201,12 @@ describe('stdpath()', function()
'config_dirs',
'XDG_CONFIG_DIRS',
{
- alter_slashes('/home/docwhat/.config'),
- alter_slashes('/etc/config'),
+ t.fix_slashes('/home/docwhat/.config'),
+ t.fix_slashes('/etc/config'),
},
{
- alter_slashes('/home/docwhat/.config/nvim'),
- alter_slashes('/etc/config/nvim'),
+ t.fix_slashes('/home/docwhat/.config/nvim'),
+ t.fix_slashes('/etc/config/nvim'),
}
)
@@ -1184,25 +1216,25 @@ describe('stdpath()', function()
'XDG_CONFIG_DIRS',
{ '$HOME', '$TMP' },
{
- alter_slashes('$HOME/nvim'),
- alter_slashes('$TMP/nvim'),
+ t.fix_slashes('$HOME/nvim'),
+ t.fix_slashes('$TMP/nvim'),
}
)
behaves_like_dir_list_env("doesn't expand ~/", 'config_dirs', 'XDG_CONFIG_DIRS', {
- alter_slashes('~/.oldconfig'),
- alter_slashes('~/.olderconfig'),
+ t.fix_slashes('~/.oldconfig'),
+ t.fix_slashes('~/.olderconfig'),
}, {
- alter_slashes('~/.oldconfig/nvim'),
- alter_slashes('~/.olderconfig/nvim'),
+ t.fix_slashes('~/.oldconfig/nvim'),
+ t.fix_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'),
+ t.fix_slashes('/home/docwhat/.data'),
}, {
- alter_slashes('/home/docwhat/.data/nvim'),
+ t.fix_slashes('/home/docwhat/.data/nvim'),
})
behaves_like_dir_list_env(
@@ -1210,12 +1242,12 @@ describe('stdpath()', function()
'data_dirs',
'XDG_DATA_DIRS',
{
- alter_slashes('/home/docwhat/.data'),
- alter_slashes('/etc/local'),
+ t.fix_slashes('/home/docwhat/.data'),
+ t.fix_slashes('/etc/local'),
},
{
- alter_slashes('/home/docwhat/.data/nvim'),
- alter_slashes('/etc/local/nvim'),
+ t.fix_slashes('/home/docwhat/.data/nvim'),
+ t.fix_slashes('/etc/local/nvim'),
}
)
@@ -1225,17 +1257,17 @@ describe('stdpath()', function()
'XDG_DATA_DIRS',
{ '$HOME', '$TMP' },
{
- alter_slashes('$HOME/nvim'),
- alter_slashes('$TMP/nvim'),
+ t.fix_slashes('$HOME/nvim'),
+ t.fix_slashes('$TMP/nvim'),
}
)
behaves_like_dir_list_env("doesn't expand ~/", 'data_dirs', 'XDG_DATA_DIRS', {
- alter_slashes('~/.oldconfig'),
- alter_slashes('~/.olderconfig'),
+ t.fix_slashes('~/.oldconfig'),
+ t.fix_slashes('~/.olderconfig'),
}, {
- alter_slashes('~/.oldconfig/nvim'),
- alter_slashes('~/.olderconfig/nvim'),
+ t.fix_slashes('~/.oldconfig/nvim'),
+ t.fix_slashes('~/.olderconfig/nvim'),
})
end)
end)
@@ -1255,23 +1287,3 @@ describe('stdpath()', function()
end)
end)
end)
-
-describe('autocommands', function()
- it('closes terminal with default shell on success', function()
- clear()
- api.nvim_set_option_value('shell', n.testprg('shell-test'), {})
- command('set shellcmdflag=EXIT shellredir= shellpipe= shellquote= shellxquote=')
-
- -- Should not block other events
- command('let g:n=0')
- command('au BufEnter * let g:n = g:n + 1')
-
- command('terminal')
- eq(1, eval('get(g:, "n", 0)'))
-
- t.retry(nil, 1000, function()
- neq('terminal', api.nvim_get_option_value('buftype', { buf = 0 }))
- eq(2, eval('get(g:, "n", 0)'))
- end)
- end)
-end)
diff --git a/test/functional/plugin/lsp_spec.lua b/test/functional/plugin/lsp_spec.lua
index 1347ea9745..88b0e0c991 100644
--- a/test/functional/plugin/lsp_spec.lua
+++ b/test/functional/plugin/lsp_spec.lua
@@ -2673,7 +2673,7 @@ describe('LSP', function()
describe('lsp.util.locations_to_items', function()
it('Convert Location[] to items', function()
- local expected = {
+ local expected_template = {
{
filename = '/fake/uri',
lnum = 1,
@@ -2681,7 +2681,12 @@ describe('LSP', function()
col = 3,
end_col = 4,
text = 'testing',
- user_data = {
+ user_data = {},
+ },
+ }
+ local test_params = {
+ {
+ {
uri = 'file:///fake/uri',
range = {
start = { line = 0, character = 2 },
@@ -2689,23 +2694,28 @@ describe('LSP', function()
},
},
},
- }
- local actual = exec_lua(function()
- local bufnr = vim.uri_to_bufnr('file:///fake/uri')
- local lines = { 'testing', '123' }
- vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines)
- local locations = {
+ {
{
uri = 'file:///fake/uri',
range = {
start = { line = 0, character = 2 },
- ['end'] = { line = 1, character = 3 },
+ -- LSP spec: if character > line length, default to the line length.
+ ['end'] = { line = 1, character = 10000 },
},
},
- }
- return vim.lsp.util.locations_to_items(locations, 'utf-16')
- end)
- eq(expected, actual)
+ },
+ }
+ for _, params in ipairs(test_params) do
+ local actual = exec_lua(function(params0)
+ local bufnr = vim.uri_to_bufnr('file:///fake/uri')
+ local lines = { 'testing', '123' }
+ vim.api.nvim_buf_set_lines(bufnr, 0, 1, false, lines)
+ return vim.lsp.util.locations_to_items(params0, 'utf-16')
+ end, params)
+ local expected = vim.deepcopy(expected_template)
+ expected[1].user_data = params[1]
+ eq(expected, actual)
+ end
end)
it('Convert LocationLink[] to items', function()
@@ -3597,21 +3607,21 @@ describe('LSP', function()
range = {
['end'] = {
character = 8,
- line = 9,
+ line = 3,
},
start = {
character = 6,
- line = 9,
+ line = 3,
},
},
selectionRange = {
['end'] = {
character = 8,
- line = 9,
+ line = 3,
},
start = {
character = 6,
- line = 9,
+ line = 3,
},
},
uri = 'file:///home/jiangyinzuo/hello.cpp',
@@ -3641,21 +3651,21 @@ describe('LSP', function()
range = {
['end'] = {
character = 8,
- line = 8,
+ line = 2,
},
start = {
character = 6,
- line = 8,
+ line = 2,
},
},
selectionRange = {
['end'] = {
character = 8,
- line = 8,
+ line = 2,
},
start = {
character = 6,
- line = 8,
+ line = 2,
},
},
uri = 'file:///home/jiangyinzuo/hello.cpp',
@@ -3669,7 +3679,15 @@ describe('LSP', function()
})
local client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
local handler = require 'vim.lsp.handlers'['typeHierarchy/subtypes']
- handler(nil, clangd_response, { client_id = client_id, bufnr = 1 })
+ local bufnr = vim.api.nvim_get_current_buf()
+ vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
+ 'class B : public A{};',
+ 'class C : public B{};',
+ 'class D1 : public C{};',
+ 'class D2 : public C{};',
+ 'class E : public D1, D2 {};',
+ })
+ handler(nil, clangd_response, { client_id = client_id, bufnr = bufnr })
return vim.fn.getqflist()
end)
@@ -3679,7 +3697,7 @@ describe('LSP', function()
col = 7,
end_col = 0,
end_lnum = 0,
- lnum = 10,
+ lnum = 4,
module = '',
nr = 0,
pattern = '',
@@ -3693,7 +3711,7 @@ describe('LSP', function()
col = 7,
end_col = 0,
end_lnum = 0,
- lnum = 9,
+ lnum = 3,
module = '',
nr = 0,
pattern = '',
@@ -3753,7 +3771,15 @@ describe('LSP', function()
})
local client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
local handler = require 'vim.lsp.handlers'['typeHierarchy/subtypes']
- handler(nil, jdtls_response, { client_id = client_id, bufnr = 1 })
+ local bufnr = vim.api.nvim_get_current_buf()
+ vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
+ 'package mylist;',
+ '',
+ 'public class MyList {',
+ ' static class Inner extends MyList{}',
+ '~}',
+ })
+ handler(nil, jdtls_response, { client_id = client_id, bufnr = bufnr })
return vim.fn.getqflist()
end)
@@ -3830,21 +3856,21 @@ describe('LSP', function()
range = {
['end'] = {
character = 8,
- line = 9,
+ line = 3,
},
start = {
character = 6,
- line = 9,
+ line = 3,
},
},
selectionRange = {
['end'] = {
character = 8,
- line = 9,
+ line = 3,
},
start = {
character = 6,
- line = 9,
+ line = 3,
},
},
uri = 'file:///home/jiangyinzuo/hello.cpp',
@@ -3874,21 +3900,21 @@ describe('LSP', function()
range = {
['end'] = {
character = 8,
- line = 8,
+ line = 2,
},
start = {
character = 6,
- line = 8,
+ line = 2,
},
},
selectionRange = {
['end'] = {
character = 8,
- line = 8,
+ line = 2,
},
start = {
character = 6,
- line = 8,
+ line = 2,
},
},
uri = 'file:///home/jiangyinzuo/hello.cpp',
@@ -3902,7 +3928,16 @@ describe('LSP', function()
})
local client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
local handler = require 'vim.lsp.handlers'['typeHierarchy/supertypes']
- handler(nil, clangd_response, { client_id = client_id, bufnr = 1 })
+ local bufnr = vim.api.nvim_get_current_buf()
+ vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
+ 'class B : public A{};',
+ 'class C : public B{};',
+ 'class D1 : public C{};',
+ 'class D2 : public C{};',
+ 'class E : public D1, D2 {};',
+ })
+
+ handler(nil, clangd_response, { client_id = client_id, bufnr = bufnr })
return vim.fn.getqflist()
end)
@@ -3912,7 +3947,7 @@ describe('LSP', function()
col = 7,
end_col = 0,
end_lnum = 0,
- lnum = 10,
+ lnum = 4,
module = '',
nr = 0,
pattern = '',
@@ -3926,7 +3961,7 @@ describe('LSP', function()
col = 7,
end_col = 0,
end_lnum = 0,
- lnum = 9,
+ lnum = 3,
module = '',
nr = 0,
pattern = '',
@@ -3986,7 +4021,15 @@ describe('LSP', function()
})
local client_id = vim.lsp.start({ name = 'dummy', cmd = server.cmd })
local handler = require 'vim.lsp.handlers'['typeHierarchy/supertypes']
- handler(nil, jdtls_response, { client_id = client_id, bufnr = 1 })
+ local bufnr = vim.api.nvim_get_current_buf()
+ vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, {
+ 'package mylist;',
+ '',
+ 'public class MyList {',
+ ' static class Inner extends MyList{}',
+ '~}',
+ })
+ handler(nil, jdtls_response, { client_id = client_id, bufnr = bufnr })
return vim.fn.getqflist()
end)
diff --git a/test/functional/plugin/tohtml_spec.lua b/test/functional/plugin/tohtml_spec.lua
index dbf385c0c3..98a422935c 100644
--- a/test/functional/plugin/tohtml_spec.lua
+++ b/test/functional/plugin/tohtml_spec.lua
@@ -136,6 +136,50 @@ local function run_tohtml_and_assert(screen, func)
screen:expect({ grid = expected.grid, attr_ids = expected.attr_ids })
end
+---@param guifont boolean
+local function test_generates_html(guifont, expect_font)
+ insert([[line]])
+ exec('set termguicolors')
+ local bg = fn.synIDattr(fn.hlID('Normal'), 'bg#', 'gui')
+ local fg = fn.synIDattr(fn.hlID('Normal'), 'fg#', 'gui')
+ local tmpfile = t.tmpname()
+
+ exec_lua(
+ [[
+ local guifont, outfile = ...
+ local html = (guifont
+ and require('tohtml').tohtml(0,{title="title"})
+ or require('tohtml').tohtml(0,{title="title",font={ "dumyfont","anotherfont" }}))
+ vim.fn.writefile(html, outfile)
+ vim.cmd.split(outfile)
+ ]],
+ guifont,
+ tmpfile
+ )
+
+ local out_file = api.nvim_buf_get_name(api.nvim_get_current_buf())
+ eq({
+ '<!DOCTYPE html>',
+ '<html>',
+ '<head>',
+ '<meta charset="UTF-8">',
+ '<title>title</title>',
+ ('<meta name="colorscheme" content="%s"></meta>'):format(api.nvim_get_var('colors_name')),
+ '<style>',
+ ('* {font-family: %s,monospace}'):format(expect_font),
+ ('body {background-color: %s; color: %s}'):format(bg, fg),
+ '</style>',
+ '</head>',
+ '<body style="display: flex">',
+ '<pre>',
+ 'line',
+ '',
+ '</pre>',
+ '</body>',
+ '</html>',
+ }, fn.readfile(out_file))
+end
+
describe(':TOhtml', function()
--- @type test.functional.ui.screen
local screen
@@ -146,41 +190,16 @@ describe(':TOhtml', function()
exec('colorscheme default')
end)
- it('expected internal html generated', function()
- insert([[line]])
- exec('set termguicolors')
- local bg = fn.synIDattr(fn.hlID('Normal'), 'bg#', 'gui')
- local fg = fn.synIDattr(fn.hlID('Normal'), 'fg#', 'gui')
- exec_lua [[
- local outfile = vim.fn.tempname() .. '.html'
- local html = require('tohtml').tohtml(0,{title="title",font="dumyfont"})
- vim.fn.writefile(html, outfile)
- vim.cmd.split(outfile)
- ]]
- local out_file = api.nvim_buf_get_name(api.nvim_get_current_buf())
- eq({
- '<!DOCTYPE html>',
- '<html>',
- '<head>',
- '<meta charset="UTF-8">',
- '<title>title</title>',
- ('<meta name="colorscheme" content="%s"></meta>'):format(api.nvim_get_var('colors_name')),
- '<style>',
- '* {font-family: dumyfont,monospace}',
- ('body {background-color: %s; color: %s}'):format(bg, fg),
- '</style>',
- '</head>',
- '<body style="display: flex">',
- '<pre>',
- 'line',
- '',
- '</pre>',
- '</body>',
- '</html>',
- }, fn.readfile(out_file))
+ it('generates html with given font', function()
+ test_generates_html(false, '"dumyfont","anotherfont"')
+ end)
+
+ it("generates html, respects 'guifont'", function()
+ exec_lua [[vim.o.guifont='Font,Escape\\,comma, Ignore space after comma']]
+ test_generates_html(true, '"Font","Escape,comma","Ignore space after comma"')
end)
- it('expected internal html generated from range', function()
+ it('generates html from range', function()
insert([[
line1
line2
@@ -218,7 +237,7 @@ describe(':TOhtml', function()
}, fn.readfile(out_file))
end)
- it('highlight attributes generated', function()
+ it('generates highlight attributes', function()
--Make sure to uncomment the attribute in `html_syntax_match()`
exec('hi LINE guisp=#00ff00 gui=' .. table.concat({
'bold',
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
index 767a3dc205..888c4538af 100644
--- a/test/functional/terminal/buffer_spec.lua
+++ b/test/functional/terminal/buffer_spec.lua
@@ -342,7 +342,7 @@ describe(':terminal buffer', function()
command('wincmd p')
-- cwd will be inserted in a file URI, which cannot contain backs
- local cwd = fn.getcwd():gsub('\\', '/')
+ local cwd = t.fix_slashes(fn.getcwd())
local parent = cwd:match('^(.+/)')
local expected = '\027]7;file://host' .. parent
api.nvim_chan_send(term, string.format('%s\027\\', expected))
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index 50199bd83d..bba1436bdc 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -630,6 +630,8 @@ describe('TUI', function()
set mouse=a mousemodel=popup
aunmenu PopUp
+ " Delete the default MenuPopup event handler.
+ autocmd! nvim_popupmenu
menu PopUp.foo :let g:menustr = 'foo'<CR>
menu PopUp.bar :let g:menustr = 'bar'<CR>
menu PopUp.baz :let g:menustr = 'baz'<CR>
diff --git a/test/functional/testnvim.lua b/test/functional/testnvim.lua
index 66ce6daacb..8c8b239cd8 100644
--- a/test/functional/testnvim.lua
+++ b/test/functional/testnvim.lua
@@ -14,8 +14,7 @@ local is_os = t.is_os
local ok = t.ok
local sleep = uv.sleep
---- This module uses functions from the context of the test session, i.e. in the context of the
---- nvim being tests.
+--- Functions executing in the current nvim session/process being tested.
local M = {}
local runtime_set = 'set runtimepath^=./build/lib/nvim/'
@@ -903,26 +902,6 @@ function M.missing_provider(provider)
assert(false, 'Unknown provider: ' .. provider)
end
---- @param obj string|table
---- @return any
-function M.alter_slashes(obj)
- if not is_os('win') then
- return obj
- end
- if type(obj) == 'string' then
- local ret = obj:gsub('/', '\\')
- return ret
- elseif type(obj) == 'table' then
- --- @cast obj table<any,any>
- local ret = {} --- @type table<any,any>
- for k, v in pairs(obj) do
- ret[k] = M.alter_slashes(v)
- end
- return ret
- end
- assert(false, 'expected string or table of strings, got ' .. type(obj))
-end
-
local load_factor = 1
if t.is_ci() then
-- Compute load factor only once (but outside of any tests).
diff --git a/test/functional/ui/decorations_spec.lua b/test/functional/ui/decorations_spec.lua
index 61a5e1d6f7..042975f898 100644
--- a/test/functional/ui/decorations_spec.lua
+++ b/test/functional/ui/decorations_spec.lua
@@ -5641,6 +5641,19 @@ l5
]])
eq("Invalid 'sign_text'", pcall_err(api.nvim_buf_set_extmark, 0, ns, 5, 0, {sign_text='❤️x'}))
end)
+
+ it('auto signcolumn hides with invalidated sign', function()
+ api.nvim_set_option_value('signcolumn', 'auto', {})
+ api.nvim_buf_set_extmark(0, ns, 0, 0, {sign_text='S1', invalidate=true})
+ feed('ia<cr>b<esc>dd')
+ screen:expect({
+ grid = [[
+ ^a |
+ {1:~ }|*8
+ |
+ ]]
+ })
+ end)
end)
describe('decorations: virt_text', function()
diff --git a/test/functional/ui/multigrid_spec.lua b/test/functional/ui/multigrid_spec.lua
index dc48061a6c..63ae38d3c3 100644
--- a/test/functional/ui/multigrid_spec.lua
+++ b/test/functional/ui/multigrid_spec.lua
@@ -1095,6 +1095,7 @@ describe('ext_multigrid', function()
end)
it('supports mouse', function()
+ command('autocmd! nvim_popupmenu') -- Delete the default MenuPopup event handler.
insert('some text\nto be clicked')
screen:expect{grid=[[
## grid 1
diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua
index 370a18b908..3acbd5d987 100644
--- a/test/functional/ui/popupmenu_spec.lua
+++ b/test/functional/ui/popupmenu_spec.lua
@@ -851,6 +851,8 @@ describe('ui/ext_popupmenu', function()
set mouse=a mousemodel=popup
aunmenu PopUp
+ " Delete the default MenuPopup event handler.
+ autocmd! nvim_popupmenu
menu PopUp.foo :let g:menustr = 'foo'<CR>
menu PopUp.bar :let g:menustr = 'bar'<CR>
menu PopUp.baz :let g:menustr = 'baz'<CR>
@@ -3805,6 +3807,8 @@ describe('builtin popupmenu', function()
call setline(1, 'popup menu test')
set mouse=a mousemodel=popup
+ " Delete the default MenuPopup event handler.
+ autocmd! nvim_popupmenu
aunmenu PopUp
menu PopUp.foo :let g:menustr = 'foo'<CR>
menu PopUp.bar :let g:menustr = 'bar'<CR>
@@ -4489,6 +4493,9 @@ describe('builtin popupmenu', function()
-- oldtest: Test_popup_command_dump()
it(':popup command', function()
exec([[
+ " Delete the default MenuPopup event handler.
+ autocmd! nvim_popupmenu
+
func ChangeMenu()
aunmenu PopUp.&Paste
nnoremenu 1.40 PopUp.&Paste :echomsg "pasted"<CR>
@@ -4646,6 +4653,8 @@ describe('builtin popupmenu', function()
screen:try_resize(50, 20)
exec([[
set mousemodel=popup_setpos
+ " Delete the default MenuPopup event handler.
+ autocmd! nvim_popupmenu
aunmenu *
source $VIMRUNTIME/menu.vim
call setline(1, join(range(20)))
diff --git a/test/functional/vimscript/fnamemodify_spec.lua b/test/functional/vimscript/fnamemodify_spec.lua
index 51b1e8489a..f2cee9b83e 100644
--- a/test/functional/vimscript/fnamemodify_spec.lua
+++ b/test/functional/vimscript/fnamemodify_spec.lua
@@ -7,11 +7,10 @@ local fnamemodify = n.fn.fnamemodify
local getcwd = n.fn.getcwd
local command = n.command
local write_file = t.write_file
-local alter_slashes = n.alter_slashes
local is_os = t.is_os
local function eq_slashconvert(expected, got)
- eq(alter_slashes(expected), alter_slashes(got))
+ eq(t.fix_slashes(expected), t.fix_slashes(got))
end
describe('fnamemodify()', function()
diff --git a/test/old/testdir/setup.vim b/test/old/testdir/setup.vim
index 6f400c5e32..e7b4bb1a88 100644
--- a/test/old/testdir/setup.vim
+++ b/test/old/testdir/setup.vim
@@ -66,6 +66,7 @@ mapclear
mapclear!
aunmenu *
tlunmenu *
+autocmd! nvim_popupmenu
" Undo the 'grepprg' and 'grepformat' setting in _defaults.lua.
set grepprg& grepformat&
diff --git a/test/old/testdir/test_breakindent.vim b/test/old/testdir/test_breakindent.vim
index f09ab8684f..3787747104 100644
--- a/test/old/testdir/test_breakindent.vim
+++ b/test/old/testdir/test_breakindent.vim
@@ -837,18 +837,73 @@ func Test_breakindent20_list()
\ ]
let lines = s:screen_lines2(1, 9, 20)
call s:compare_lines(expect, lines)
+
+ " check with TABs
+ call setline(1, ["\t1.\tCongress shall make no law",
+ \ "\t2.) Congress shall make no law",
+ \ "\t3.] Congress shall make no law"])
+ setl tabstop=4 list listchars=tab:<->
+ norm! 1gg
+ redraw!
+ let expect = [
+ \ "<-->1.<>Congress ",
+ \ " shall make ",
+ \ " no law ",
+ \ "<-->2.) Congress ",
+ \ " shall make ",
+ \ " no law ",
+ \ "<-->3.] Congress ",
+ \ " shall make ",
+ \ " no law ",
+ \ ]
+ let lines = s:screen_lines2(1, 9, 20)
+ call s:compare_lines(expect, lines)
+
+ setl tabstop=2 nolist
+ redraw!
+ let expect = [
+ \ " 1. Congress ",
+ \ " shall make no ",
+ \ " law ",
+ \ " 2.) Congress ",
+ \ " shall make no ",
+ \ " law ",
+ \ " 3.] Congress ",
+ \ " shall make no ",
+ \ " law ",
+ \ ]
+ let lines = s:screen_lines2(1, 9, 20)
+ call s:compare_lines(expect, lines)
+
+ setl tabstop& list listchars=space:_
+ redraw!
+ let expect = [
+ \ "^I1.^ICongress_ ",
+ \ " shall_make_no_",
+ \ " law ",
+ \ "^I2.)_Congress_ ",
+ \ " shall_make_no_",
+ \ " law ",
+ \ "^I3.]_Congress_ ",
+ \ " shall_make_no_",
+ \ " law ",
+ \ ]
+ let lines = s:screen_lines2(1, 9, 20)
+ call s:compare_lines(expect, lines)
+
" check formatlistpat indent with different list levels
- let &l:flp = '^\s*\*\+\s\+'
+ let &l:flp = '^\s*\(\*\|•\)\+\s\+'
+ setl list&vim listchars&vim
%delete _
call setline(1, ['* Congress shall make no law',
- \ '*** Congress shall make no law',
+ \ '••• Congress shall make no law',
\ '**** Congress shall make no law'])
norm! 1gg
redraw!
let expect = [
\ "* Congress shall ",
\ " make no law ",
- \ "*** Congress shall ",
+ \ "••• Congress shall ",
\ " make no law ",
\ "**** Congress shall ",
\ " make no law ",
@@ -864,7 +919,7 @@ func Test_breakindent20_list()
let expect = [
\ "* Congress shall ",
\ "> make no law ",
- \ "*** Congress shall ",
+ \ "••• Congress shall ",
\ "> make no law ",
\ "**** Congress shall ",
\ "> make no law ",
@@ -880,7 +935,7 @@ func Test_breakindent20_list()
let expect = [
\ "* Congress shall ",
\ "> make no law ",
- \ "*** Congress shall ",
+ \ "••• Congress shall ",
\ "> make no law ",
\ "**** Congress shall ",
\ "> make no law ",
diff --git a/test/old/testdir/test_utf8.vim b/test/old/testdir/test_utf8.vim
index 3248dc9d98..5cac4066ea 100644
--- a/test/old/testdir/test_utf8.vim
+++ b/test/old/testdir/test_utf8.vim
@@ -228,6 +228,9 @@ func Test_setcellwidths()
call setcellwidths([[0x2103, 0x2103, 2]])
redraw
call assert_equal(19, wincol())
+ call setcellwidths([])
+ redraw
+ call assert_equal((aw == 'single') ? 10 : 19, wincol())
endfor
set ambiwidth& isprint&
@@ -252,15 +255,21 @@ func Test_setcellwidths()
call assert_fails('call setcellwidths([[0x33, 0x44, 2]])', 'E1114:')
- set listchars=tab:--\\u2192
+ set listchars=tab:--\\u2192 fillchars=stl:\\u2501
call assert_fails('call setcellwidths([[0x2192, 0x2192, 2]])', 'E834:')
-
- set fillchars=stl:\\u2501
call assert_fails('call setcellwidths([[0x2501, 0x2501, 2]])', 'E835:')
+ call setcellwidths([[0x201c, 0x201d, 1]])
+ set listchars& fillchars& ambiwidth=double
+
+ set listchars=nbsp:\\u201c fillchars=vert:\\u201d
+ call assert_fails('call setcellwidths([])', 'E834:')
set listchars&
+ call assert_fails('call setcellwidths([])', 'E835:')
set fillchars&
+
call setcellwidths([])
+ set ambiwidth&
bwipe!
endfunc
diff --git a/test/testutil.lua b/test/testutil.lua
index 01eaf25406..02f343891d 100644
--- a/test/testutil.lua
+++ b/test/testutil.lua
@@ -16,7 +16,7 @@ local function shell_quote(str)
return str
end
---- This module uses functions from the context of the test runner.
+--- Functions executing in the context of the test runner (not the current nvim test session).
--- @class test.testutil
local M = {
paths = Paths,
@@ -42,6 +42,29 @@ function M.isdir(path)
return stat.type == 'directory'
end
+--- (Only on Windows) Replaces yucky "\\" slashes with delicious "/" slashes in a string, or all
+--- string values in a table (recursively).
+---
+--- @param obj string|table
+--- @return any
+function M.fix_slashes(obj)
+ if not M.is_os('win') then
+ return obj
+ end
+ if type(obj) == 'string' then
+ local ret = obj:gsub('\\', '/')
+ return ret
+ elseif type(obj) == 'table' then
+ --- @cast obj table<any,any>
+ local ret = {} --- @type table<any,any>
+ for k, v in pairs(obj) do
+ ret[k] = M.fix_slashes(v)
+ end
+ return ret
+ end
+ assert(false, 'expected string or table of strings, got ' .. type(obj))
+end
+
--- @param ... string|string[]
--- @return string
function M.argss_to_cmd(...)
@@ -143,7 +166,7 @@ end
---
---@param pat (string) Lua pattern to match lines in the log file
---@param logfile? (string) Full path to log file (default=$NVIM_LOG_FILE)
----@param nrlines? (number) Search up to this many log lines
+---@param nrlines? (number) Search up to this many log lines (default 10)
---@param inverse? (boolean) Assert that the pattern does NOT match.
function M.assert_log(pat, logfile, nrlines, inverse)
logfile = logfile or os.getenv('NVIM_LOG_FILE') or '.nvimlog'
diff --git a/test/unit/mbyte_spec.lua b/test/unit/mbyte_spec.lua
index 787a8862ae..62390c8794 100644
--- a/test/unit/mbyte_spec.lua
+++ b/test/unit/mbyte_spec.lua
@@ -4,7 +4,6 @@ local itp = t.gen_itp(it)
local ffi = t.ffi
local eq = t.eq
local to_cstr = t.to_cstr
-local ok = t.ok
local lib = t.cimport(
'./src/nvim/mbyte.h',
@@ -302,7 +301,10 @@ describe('mbyte', function()
local mb_glyphs = {}
while pos < len do
local clen = lib.utfc_ptr2len(cstr + pos)
- ok(clen > 0) -- otherwise we get stuck
+ if clen == 0 then
+ eq(0, string.byte(str, pos + 1)) -- only NUL bytes can has length zery
+ clen = 1 -- but skip it, otherwise we get stuck
+ end
if clen > 1 then
table.insert(mb_glyphs, string.sub(str, pos + 1, pos + clen))
end
@@ -325,13 +327,18 @@ describe('mbyte', function()
-- stylua doesn't like ZWJ chars..
-- stylua: ignore start
check('hej och hå 🧑‍🌾!', { 'å', '🧑‍🌾' })
- -- emoji only (various kinds of combinations, use g8 to see them)
+
+ -- emoji (various kinds of combinations, use g8 to see them)
check("🏳️‍⚧️🧑‍🌾❤️😂🏴‍☠️", {"🏳️‍⚧️", "🧑‍🌾", "❤️", "😂", "🏴‍☠️"})
check('🏳️‍⚧️xy🧑‍🌾\r❤️😂å🏴‍☠️€', { '🏳️‍⚧️', '🧑‍🌾', '❤️', '😂', 'å', '🏴‍☠️', '€' })
+ check('🏳️‍⚧️\000🧑‍🌾\000❤️\000😂\000å\000🏴‍☠️\000€', { '🏳️‍⚧️', '🧑‍🌾', '❤️', '😂', 'å', '🏴‍☠️', '€' })
+ check('\195🏳️‍⚧️\198🧑‍🌾\165❤️\168\195😂\255🏴‍☠️\129€\165', { '🏳️‍⚧️', '🧑‍🌾', '❤️', '😂', '🏴‍☠️', '€' })
check('🇦🅱️ 🇦🇽 🇦🇨🇦 🇲🇽🇹🇱',{'🇦', '🅱️', '🇦🇽', '🇦🇨', '🇦', '🇲🇽', '🇹🇱'})
check('🏴󠁧󠁢󠁳󠁣󠁴󠁿🏴󠁧󠁢󠁷󠁬󠁳󠁿', {'🏴󠁧󠁢󠁳󠁣󠁴󠁿', '🏴󠁧󠁢󠁷󠁬󠁳󠁿'})
+ check('å\165ü\195aëq\168β\000\169本\255', {'å', 'ü', 'ë', 'β', '本'})
+
lib.p_arshape = true -- default
check('سلام', { 'س', 'لا', 'م' })
lib.p_arshape = false