aboutsummaryrefslogtreecommitdiff
path: root/test/functional/core
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2023-11-30 20:35:25 +0000
committerJosh Rahm <joshuarahm@gmail.com>2023-11-30 20:35:25 +0000
commit1b7b916b7631ddf73c38e3a0070d64e4636cb2f3 (patch)
treecd08258054db80bb9a11b1061bb091c70b76926a /test/functional/core
parenteaa89c11d0f8aefbb512de769c6c82f61a8baca3 (diff)
parent4a8bf24ac690004aedf5540fa440e788459e5e34 (diff)
downloadrneovim-aucmd_textputpost.tar.gz
rneovim-aucmd_textputpost.tar.bz2
rneovim-aucmd_textputpost.zip
Merge remote-tracking branch 'upstream/master' into aucmd_textputpostaucmd_textputpost
Diffstat (limited to 'test/functional/core')
-rw-r--r--test/functional/core/channels_spec.lua2
-rw-r--r--test/functional/core/exit_spec.lua38
-rw-r--r--test/functional/core/fileio_spec.lua108
-rw-r--r--test/functional/core/job_spec.lua41
-rw-r--r--test/functional/core/main_spec.lua29
-rw-r--r--test/functional/core/path_spec.lua114
-rw-r--r--test/functional/core/remote_spec.lua41
-rw-r--r--test/functional/core/spellfile_spec.lua26
-rw-r--r--test/functional/core/startup_spec.lua401
9 files changed, 587 insertions, 213 deletions
diff --git a/test/functional/core/channels_spec.lua b/test/functional/core/channels_spec.lua
index 8275575c24..5771ddcb94 100644
--- a/test/functional/core/channels_spec.lua
+++ b/test/functional/core/channels_spec.lua
@@ -230,6 +230,7 @@ describe('channels', function()
end)
it('can use buffered output mode', function()
+ skip(funcs.executable('grep') == 0, 'missing "grep" command')
source([[
let g:job_opts = {
\ 'on_stdout': function('OnEvent'),
@@ -262,6 +263,7 @@ describe('channels', function()
end)
it('can use buffered output mode with no stream callback', function()
+ skip(funcs.executable('grep') == 0, 'missing "grep" command')
source([[
function! OnEvent(id, data, event) dict
call rpcnotify(1, a:event, a:id, a:data, self.stdout)
diff --git a/test/functional/core/exit_spec.lua b/test/functional/core/exit_spec.lua
index 05a69e1992..d474b77806 100644
--- a/test/functional/core/exit_spec.lua
+++ b/test/functional/core/exit_spec.lua
@@ -25,30 +25,34 @@ describe('v:exiting', function()
eq(1, eval('v:exiting is v:null'))
end)
- it('is 0 on normal exit', function()
+ local function test_exiting(setup_fn)
local function on_setup()
- command('autocmd VimLeavePre * call rpcrequest('..cid..', "")')
- command('autocmd VimLeave * call rpcrequest('..cid..', "")')
- command('quit')
+ command('autocmd VimLeavePre * call rpcrequest('..cid..', "exit", "VimLeavePre")')
+ command('autocmd VimLeave * call rpcrequest('..cid..', "exit", "VimLeave")')
+ setup_fn()
end
- local function on_request()
+ local requests_args = {}
+ local function on_request(name, args)
+ eq('exit', name)
+ table.insert(requests_args, args)
eq(0, eval('v:exiting'))
return ''
end
run(on_request, nil, on_setup)
+ eq({{'VimLeavePre'}, {'VimLeave'}}, requests_args)
+ end
+
+ it('is 0 on normal exit', function()
+ test_exiting(function()
+ command('quit')
+ end)
end)
+
it('is 0 on exit from Ex mode involving try-catch vim-patch:8.0.0184', function()
- local function on_setup()
- command('autocmd VimLeavePre * call rpcrequest('..cid..', "")')
- command('autocmd VimLeave * call rpcrequest('..cid..', "")')
+ test_exiting(function()
feed('gQ')
feed_command('try', 'call NoFunction()', 'catch', 'echo "bye"', 'endtry', 'quit')
- end
- local function on_request()
- eq(0, eval('v:exiting'))
- return ''
- end
- run(on_request, nil, on_setup)
+ end)
end)
end)
@@ -89,14 +93,14 @@ describe(':cquit', function()
end)
it('exits with redir msg for multiple exit codes after :cquit 1 2', function()
- test_cq('cquit 1 2', nil, 'nvim_exec(): Vim(cquit):E488: Trailing characters: 2: cquit 1 2')
+ test_cq('cquit 1 2', nil, 'nvim_exec2(): Vim(cquit):E488: Trailing characters: 2: cquit 1 2')
end)
it('exits with redir msg for non-number exit code after :cquit X', function()
- test_cq('cquit X', nil, 'nvim_exec(): Vim(cquit):E488: Trailing characters: X: cquit X')
+ test_cq('cquit X', nil, 'nvim_exec2(): Vim(cquit):E488: Trailing characters: X: cquit X')
end)
it('exits with redir msg for negative exit code after :cquit -1', function()
- test_cq('cquit -1', nil, 'nvim_exec(): Vim(cquit):E488: Trailing characters: -1: cquit -1')
+ test_cq('cquit -1', nil, 'nvim_exec2(): Vim(cquit):E488: Trailing characters: -1: cquit -1')
end)
end)
diff --git a/test/functional/core/fileio_spec.lua b/test/functional/core/fileio_spec.lua
index 4e9891a4de..65f947132e 100644
--- a/test/functional/core/fileio_spec.lua
+++ b/test/functional/core/fileio_spec.lua
@@ -1,4 +1,4 @@
-local lfs = require('lfs')
+local luv = require('luv')
local helpers = require('test.functional.helpers')(after_each)
local assert_log = helpers.assert_log
@@ -15,10 +15,10 @@ local request = helpers.request
local retry = helpers.retry
local rmdir = helpers.rmdir
local matches = helpers.matches
+local meths = helpers.meths
local mkdir = helpers.mkdir
local sleep = helpers.sleep
local read_file = helpers.read_file
-local tmpname = helpers.tmpname
local trim = helpers.trim
local currentdir = helpers.funcs.getcwd
local assert_alive = helpers.assert_alive
@@ -40,15 +40,18 @@ describe('fileio', function()
os.remove('Xtest_startup_file1')
os.remove('Xtest_startup_file1~')
os.remove('Xtest_startup_file2')
+ os.remove('Xtest_startup_file2~')
os.remove('Xtest_тест.md')
os.remove('Xtest-u8-int-max')
os.remove('Xtest-overwrite-forced')
rmdir('Xtest_startup_swapdir')
rmdir('Xtest_backupdir')
+ rmdir('Xtest_backupdir with spaces')
end)
it('fsync() codepaths #8304', function()
clear({ args={ '-i', 'Xtest_startup_shada',
+ '--cmd', 'set nofsync',
'--cmd', 'set directory=Xtest_startup_swapdir' } })
-- These cases ALWAYS force fsync (regardless of 'fsync' option):
@@ -132,6 +135,28 @@ describe('fileio', function()
eq('foo', foo_contents);
end)
+ it('backup with full path with spaces', function()
+ skip(is_ci('cirrus'))
+ clear()
+ mkdir('Xtest_backupdir with spaces')
+ command('set backup')
+ command('set backupdir=Xtest_backupdir\\ with\\ spaces//')
+ command('write Xtest_startup_file1')
+ feed('ifoo<esc>')
+ command('write')
+ feed('Abar<esc>')
+ command('write')
+
+ -- Backup filename = fullpath, separators replaced with "%".
+ local backup_file_name = string.gsub(currentdir()..'/Xtest_startup_file1',
+ is_os('win') and '[:/\\]' or '/', '%%') .. '~'
+ local foo_contents = trim(read_file('Xtest_backupdir with spaces/'..backup_file_name))
+ local foobar_contents = trim(read_file('Xtest_startup_file1'))
+
+ eq('foobar', foobar_contents);
+ eq('foo', foo_contents);
+ end)
+
it('backup symlinked files #11349', function()
skip(is_ci('cirrus'))
clear()
@@ -141,7 +166,7 @@ describe('fileio', function()
local backup_file_name = link_file_name .. '~'
write_file('Xtest_startup_file1', initial_content, false)
- lfs.link('Xtest_startup_file1', link_file_name, true)
+ luv.fs_symlink('Xtest_startup_file1', link_file_name)
command('set backup')
command('set backupcopy=yes')
command('edit ' .. link_file_name)
@@ -165,7 +190,7 @@ describe('fileio', function()
local backup_file_name = backup_dir .. sep .. link_file_name .. '~'
write_file('Xtest_startup_file1', initial_content, false)
- lfs.link('Xtest_startup_file1', link_file_name, true)
+ luv.fs_symlink('Xtest_startup_file1', link_file_name)
mkdir(backup_dir)
command('set backup')
command('set backupcopy=yes')
@@ -235,8 +260,8 @@ describe('fileio', function()
screen:expect([[
{2:WARNING: The file has been changed since}|
{2: reading it!!!} |
- {3:Do you really want to write to it (y/n)^?}|
- |
+ {3:Do you really want to write to it (y/n)?}|
+ ^ |
]])
feed("n")
@@ -261,13 +286,11 @@ end)
describe('tmpdir', function()
local tmproot_pat = [=[.*[/\\]nvim%.[^/\\]+]=]
local testlog = 'Xtest_tmpdir_log'
- local faketmp
+ local os_tmpdir
before_each(function()
-- Fake /tmp dir so that we can mess it up.
- faketmp = tmpname()
- os.remove(faketmp)
- mkdir(faketmp)
+ os_tmpdir = vim.uv.fs_mkdtemp(vim.fs.dirname(helpers.tmpname()) .. '/nvim_XXXXXXXXXX')
end)
after_each(function()
@@ -275,16 +298,21 @@ describe('tmpdir', function()
os.remove(testlog)
end)
- it('failure modes', function()
- clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=faketmp, } })
- assert_nolog('tempdir is not a directory', testlog)
- assert_nolog('tempdir has invalid permissions', testlog)
-
+ local function get_tmproot()
-- Tempfiles typically look like: "…/nvim.<user>/xxx/0".
-- - "…/nvim.<user>/xxx/" is the per-process tmpdir, not shared with other Nvims.
-- - "…/nvim.<user>/" is the tmpdir root, shared by all Nvims (normally).
local tmproot = (funcs.tempname()):match(tmproot_pat)
ok(tmproot:len() > 4, 'tmproot like "nvim.foo"', tmproot)
+ return tmproot
+ end
+
+ it('failure modes', function()
+ clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=os_tmpdir, } })
+ assert_nolog('tempdir is not a directory', testlog)
+ assert_nolog('tempdir has invalid permissions', testlog)
+
+ local tmproot = get_tmproot()
-- Test how Nvim handles invalid tmpdir root (by hostile users or accidents).
--
@@ -292,7 +320,7 @@ describe('tmpdir', function()
expect_exit(command, ':qall!')
rmdir(tmproot)
write_file(tmproot, '') -- Not a directory, vim_mktempdir() should skip it.
- clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=faketmp, } })
+ clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=os_tmpdir, } })
matches(tmproot_pat, funcs.stdpath('run')) -- Tickle vim_mktempdir().
-- Assert that broken tmpdir root was handled.
assert_log('tempdir root not a directory', testlog, 100)
@@ -303,18 +331,62 @@ describe('tmpdir', function()
os.remove(tmproot)
mkdir(tmproot)
funcs.setfperm(tmproot, 'rwxr--r--') -- Invalid permissions, vim_mktempdir() should skip it.
- clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=faketmp, } })
+ clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=os_tmpdir, } })
matches(tmproot_pat, funcs.stdpath('run')) -- Tickle vim_mktempdir().
-- Assert that broken tmpdir root was handled.
assert_log('tempdir root has invalid permissions', testlog, 100)
end)
it('too long', function()
- local bigname = ('%s/%s'):format(faketmp, ('x'):rep(666))
+ local bigname = ('%s/%s'):format(os_tmpdir, ('x'):rep(666))
mkdir(bigname)
clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=bigname, } })
matches(tmproot_pat, funcs.stdpath('run')) -- Tickle vim_mktempdir().
local len = (funcs.tempname()):len()
ok(len > 4 and len < 256, '4 < len < 256', tostring(len))
end)
+
+ it('disappeared #1432', function()
+ clear({ env={ NVIM_LOG_FILE=testlog, TMPDIR=os_tmpdir, } })
+ assert_nolog('tempdir disappeared', testlog)
+
+ local function rm_tmpdir()
+ local tmpname1 = funcs.tempname()
+ local tmpdir1 = funcs.fnamemodify(tmpname1, ':h')
+ eq(funcs.stdpath('run'), tmpdir1)
+
+ rmdir(tmpdir1)
+ retry(nil, 1000, function()
+ eq(0, funcs.isdirectory(tmpdir1))
+ end)
+ local tmpname2 = funcs.tempname()
+ local tmpdir2 = funcs.fnamemodify(tmpname2, ':h')
+ neq(tmpdir1, tmpdir2)
+ end
+
+ -- Your antivirus hates you...
+ rm_tmpdir()
+ assert_log('tempdir disappeared', testlog, 100)
+ funcs.tempname()
+ funcs.tempname()
+ funcs.tempname()
+ eq('', meths.get_vvar('errmsg'))
+ rm_tmpdir()
+ funcs.tempname()
+ funcs.tempname()
+ funcs.tempname()
+ eq('E5431: tempdir disappeared (2 times)', meths.get_vvar('errmsg'))
+ rm_tmpdir()
+ eq('E5431: tempdir disappeared (3 times)', meths.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%.[^/\\]+]=], funcs.tempname())
+ end)
+
end)
diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua
index 1bae626b98..038368c387 100644
--- a/test/functional/core/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -88,7 +88,6 @@ describe('jobs', function()
end)
it('append environment with pty #env', function()
- skip(is_os('win'))
nvim('command', "let $VAR = 'abc'")
nvim('command', "let $TOTO = 'goodbye world'")
nvim('command', "let g:job_opts.pty = v:true")
@@ -701,7 +700,7 @@ describe('jobs', function()
os.remove('Xtest_jobstart_env')
end)
- describe('jobwait', function()
+ describe('jobwait()', function()
before_each(function()
if is_os('win') then
helpers.set_shell_powershell()
@@ -806,7 +805,6 @@ describe('jobs', function()
end)
it('can be called recursively', function()
- skip(is_os('win'), "TODO: Need `cat`")
source([[
let g:opts = {}
let g:counter = 0
@@ -876,6 +874,43 @@ describe('jobs', function()
eq({'notification', 'wait', {{-1, -1}}}, next_msg())
end)
end)
+
+ it('hides cursor and flushes messages before blocking', function()
+ local screen = Screen.new(50, 6)
+ screen:set_default_attr_ids({
+ [0] = {foreground = Screen.colors.Blue, bold = true}; -- NonText
+ [1] = {bold = true, reverse = true}; -- MsgSeparator
+ [2] = {bold = true, foreground = Screen.colors.SeaGreen}; -- MoreMsg
+ })
+ screen:attach()
+ command([[let g:id = jobstart([v:progpath, '--clean', '--headless'])]])
+ source([[
+ func PrintAndWait()
+ echon "aaa\nbbb"
+ call jobwait([g:id], 300)
+ echon "\nccc"
+ endfunc
+ ]])
+ feed_command('call PrintAndWait()')
+ screen:expect{grid=[[
+ |
+ {0:~ }|
+ {0:~ }|
+ {1: }|
+ aaa |
+ bbb |
+ ]], timeout=100}
+ screen:expect{grid=[[
+ |
+ {1: }|
+ aaa |
+ bbb |
+ ccc |
+ {2:Press ENTER or type command to continue}^ |
+ ]]}
+ feed('<CR>')
+ funcs.jobstop(meths.get_var('id'))
+ end)
end)
pending('exit event follows stdout, stderr', function()
diff --git a/test/functional/core/main_spec.lua b/test/functional/core/main_spec.lua
index ab11e14a67..19c7a93730 100644
--- a/test/functional/core/main_spec.lua
+++ b/test/functional/core/main_spec.lua
@@ -1,8 +1,9 @@
-local lfs = require('lfs')
+local luv = require('luv')
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local eq = helpers.eq
+local matches = helpers.matches
local feed = helpers.feed
local eval = helpers.eval
local clear = helpers.clear
@@ -12,34 +13,38 @@ local write_file = helpers.write_file
local is_os = helpers.is_os
local skip = helpers.skip
-describe('Command-line option', function()
+describe('command-line option', function()
describe('-s', function()
local fname = 'Xtest-functional-core-main-s'
local fname_2 = fname .. '.2'
local nonexistent_fname = fname .. '.nonexistent'
local dollar_fname = '$' .. fname
+
before_each(function()
clear()
os.remove(fname)
os.remove(dollar_fname)
end)
+
after_each(function()
os.remove(fname)
os.remove(dollar_fname)
end)
+
it('treats - as stdin', function()
- eq(nil, lfs.attributes(fname))
+ eq(nil, luv.fs_stat(fname))
funcs.system(
{nvim_prog_abs(), '-u', 'NONE', '-i', 'NONE', '--headless',
'--cmd', 'set noswapfile shortmess+=IFW fileformats=unix',
'-s', '-', fname},
{':call setline(1, "42")', ':wqall!', ''})
eq(0, eval('v:shell_error'))
- local attrs = lfs.attributes(fname)
+ local attrs = luv.fs_stat(fname)
eq(#('42\n'), attrs.size)
end)
+
it('does not expand $VAR', function()
- eq(nil, lfs.attributes(fname))
+ eq(nil, luv.fs_stat(fname))
eq(true, not not dollar_fname:find('%$%w+'))
write_file(dollar_fname, ':call setline(1, "100500")\n:wqall!\n')
funcs.system(
@@ -47,9 +52,10 @@ describe('Command-line option', function()
'--cmd', 'set noswapfile shortmess+=IFW fileformats=unix',
'-s', dollar_fname, fname})
eq(0, eval('v:shell_error'))
- local attrs = lfs.attributes(fname)
+ local attrs = luv.fs_stat(fname)
eq(#('100500\n'), attrs.size)
end)
+
it('does not crash after reading from stdin in non-headless mode', function()
skip(is_os('win'))
local screen = Screen.new(40, 8)
@@ -100,6 +106,7 @@ describe('Command-line option', function()
]])
]=]
end)
+
it('errors out when trying to use nonexistent file with -s', function()
eq(
'Cannot open for reading: "'..nonexistent_fname..'": no such file or directory\n',
@@ -110,6 +117,7 @@ describe('Command-line option', function()
'-s', nonexistent_fname}))
eq(2, eval('v:shell_error'))
end)
+
it('errors out when trying to use -s twice', function()
write_file(fname, ':call setline(1, "1")\n:wqall!\n')
write_file(dollar_fname, ':call setline(1, "2")\n:wqall!\n')
@@ -121,7 +129,14 @@ describe('Command-line option', function()
'--cmd', 'language C',
'-s', fname, '-s', dollar_fname, fname_2}))
eq(2, eval('v:shell_error'))
- eq(nil, lfs.attributes(fname_2))
+ eq(nil, luv.fs_stat(fname_2))
end)
end)
+
+ it('nvim -v, :version', function()
+ matches('Run ":verbose version"', funcs.execute(':version'))
+ matches('Compilation: .*Run :checkhealth', funcs.execute(':verbose version'))
+ matches('Run "nvim %-V1 %-v"', funcs.system({nvim_prog_abs(), '-v'}))
+ matches('Compilation: .*Run :checkhealth', funcs.system({nvim_prog_abs(), '-V1', '-v'}))
+ end)
end)
diff --git a/test/functional/core/path_spec.lua b/test/functional/core/path_spec.lua
index a786887bbd..97c32f7de6 100644
--- a/test/functional/core/path_spec.lua
+++ b/test/functional/core/path_spec.lua
@@ -1,21 +1,25 @@
local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
+local command = helpers.command
local eq = helpers.eq
local eval = helpers.eval
-local command = helpers.command
-local insert = helpers.insert
local feed = helpers.feed
+local funcs = helpers.funcs
+local insert = helpers.insert
local is_os = helpers.is_os
+local mkdir = helpers.mkdir
+local rmdir = helpers.rmdir
+local write_file = helpers.write_file
+
+local function join_path(...)
+ local pathsep = (is_os('win') and '\\' or '/')
+ return table.concat({...}, pathsep)
+end
describe('path collapse', function()
local targetdir
local expected_path
- local function join_path(...)
- local pathsep = (is_os('win') and '\\' or '/')
- return table.concat({...}, pathsep)
- end
-
before_each(function()
targetdir = join_path('test', 'functional', 'fixtures')
clear()
@@ -57,14 +61,108 @@ describe('path collapse', function()
end)
end)
+describe('expand wildcard', function()
+ before_each(clear)
+
+ it('with special characters #24421', function()
+ local folders = is_os('win') and {
+ '{folder}',
+ 'folder$name'
+ } or {
+ 'folder-name',
+ 'folder#name'
+ }
+ for _, folder in ipairs(folders) do
+ mkdir(folder)
+ local file = join_path(folder, 'file.txt')
+ write_file(file, '')
+ eq(file, eval('expand("'..folder..'/*")'))
+ rmdir(folder)
+ end
+ end)
+end)
+
describe('file search', function()
+ local testdir = 'Xtest_path_spec'
+
before_each(clear)
- it('find multibyte file name in line #20517', function()
+ setup(function()
+ mkdir(testdir)
+ end)
+
+ teardown(function()
+ rmdir(testdir)
+ end)
+
+ it('gf finds multibyte filename in line #20517', function()
command('cd test/functional/fixtures')
insert('filename_with_unicode_ααα')
eq('', eval('expand("%")'))
feed('gf')
eq('filename_with_unicode_ααα', eval('expand("%:t")'))
end)
+
+ it('gf/<cfile> matches Windows drive-letter filepaths (without ":" in &isfname)', function()
+ local iswin = is_os('win')
+ local function test_cfile(input, expected, expected_win)
+ expected = (iswin and expected_win or expected) or input
+ command('%delete')
+ insert(input)
+ command('norm! 0')
+ eq(expected, eval('expand("<cfile>")'))
+ end
+
+ test_cfile([[c:/d:/foo/bar.txt]]) -- TODO(justinmk): should return "d:/foo/bar.txt" ?
+ test_cfile([[//share/c:/foo/bar/]])
+ test_cfile([[file://c:/foo/bar]])
+ test_cfile([[file://c:/foo/bar:42]])
+ test_cfile([[file://c:/foo/bar:42:666]])
+ test_cfile([[https://c:/foo/bar]])
+ test_cfile([[\foo\bar]], [[foo]], [[\foo\bar]])
+ test_cfile([[/foo/bar]], [[/foo/bar]])
+ test_cfile([[c:\foo\bar]], [[c:]], [[c:\foo\bar]])
+ test_cfile([[c:\foo\bar:42:666]], [[c:]], [[c:\foo\bar]])
+ test_cfile([[c:/foo/bar]])
+ test_cfile([[c:/foo/bar:42]], [[c:/foo/bar]])
+ test_cfile([[c:/foo/bar:42:666]], [[c:/foo/bar]])
+ test_cfile([[c:foo\bar]], [[c]])
+ test_cfile([[c:foo/bar]], [[c]])
+ test_cfile([[c:foo]], [[c]])
+ -- Examples from: https://learn.microsoft.com/en-us/dotnet/standard/io/file-path-formats#example-ways-to-refer-to-the-same-file
+ test_cfile([[c:\temp\test-file.txt]], [[c:]], [[c:\temp\test-file.txt]])
+ test_cfile([[\\127.0.0.1\c$\temp\test-file.txt]], [[127.0.0.1]], [[\\127.0.0.1\c$\temp\test-file.txt]])
+ test_cfile([[\\LOCALHOST\c$\temp\test-file.txt]], [[LOCALHOST]], [[\\LOCALHOST\c$\temp\test-file.txt]])
+ -- not supported yet
+ test_cfile([[\\.\c:\temp\test-file.txt]], [[.]], [[\\.\c]])
+ -- not supported yet
+ test_cfile([[\\?\c:\temp\test-file.txt]], [[c:]], [[\\]])
+ test_cfile([[\\.\UNC\LOCALHOST\c$\temp\test-file.txt]], [[.]], [[\\.\UNC\LOCALHOST\c$\temp\test-file.txt]])
+ test_cfile([[\\127.0.0.1\c$\temp\test-file.txt]], [[127.0.0.1]], [[\\127.0.0.1\c$\temp\test-file.txt]])
+ end)
+
+ ---@param funcname 'finddir' | 'findfile'
+ local function test_find_func(funcname, folder, item)
+ local d = join_path(testdir, folder)
+ mkdir(d)
+ local expected = join_path(d, item)
+ if funcname == 'finddir' then
+ mkdir(expected)
+ else
+ write_file(expected, '')
+ end
+ eq(expected, funcs[funcname](item, d:gsub(' ', [[\ ]])))
+ end
+
+ it('finddir()', function()
+ test_find_func('finddir', 'directory', 'folder')
+ test_find_func('finddir', 'directory', 'folder name')
+ test_find_func('finddir', 'fold#er name', 'directory')
+ end)
+
+ it('findfile()', function()
+ test_find_func('findfile', 'directory', 'file.txt')
+ test_find_func('findfile', 'directory', 'file name.txt')
+ test_find_func('findfile', 'fold#er name', 'file.txt')
+ end)
end)
diff --git a/test/functional/core/remote_spec.lua b/test/functional/core/remote_spec.lua
index 846d79abf3..a0ec748446 100644
--- a/test/functional/core/remote_spec.lua
+++ b/test/functional/core/remote_spec.lua
@@ -3,11 +3,12 @@ local helpers = require('test.functional.helpers')(after_each)
local clear = helpers.clear
local command = helpers.command
local eq = helpers.eq
+local exec_capture = helpers.exec_capture
local exec_lua = helpers.exec_lua
local expect = helpers.expect
local funcs = helpers.funcs
local insert = helpers.insert
-local meths = helpers.meths
+local nvim_prog = helpers.nvim_prog
local new_argv = helpers.new_argv
local neq = helpers.neq
local set_session = helpers.set_session
@@ -38,10 +39,10 @@ describe('Remote', function()
server:close()
end)
+ -- Run a `nvim --remote*` command and return { stdout, stderr } of the process
local function run_remote(...)
set_session(server)
local addr = funcs.serverlist()[1]
- local client_argv = new_argv({args={'--server', addr, ...}})
-- Create an nvim instance just to run the remote-invoking nvim. We want
-- to wait for the remote instance to exit and calling jobwait blocks
@@ -50,32 +51,43 @@ describe('Remote', function()
local client_starter = spawn(new_argv(), false, nil, true)
set_session(client_starter)
-- Call jobstart() and jobwait() in the same RPC request to reduce flakiness.
- eq({ 0 }, exec_lua([[return vim.fn.jobwait({ vim.fn.jobstart(...) })]], client_argv))
+ eq({ 0 }, exec_lua([[return vim.fn.jobwait({ vim.fn.jobstart({...}, {
+ stdout_buffered = true,
+ stderr_buffered = true,
+ on_stdout = function(_, data, _)
+ _G.Remote_stdout = table.concat(data, '\n')
+ end,
+ on_stderr = function(_, data, _)
+ _G.Remote_stderr = table.concat(data, '\n')
+ end,
+ }) })]], nvim_prog, '--clean', '--headless', '--server', addr, ...))
+ local res = exec_lua([[return { _G.Remote_stdout, _G.Remote_stderr }]])
client_starter:close()
set_session(server)
+ return res
end
it('edit a single file', function()
- run_remote('--remote', fname)
+ eq({ '', '' }, run_remote('--remote', fname))
expect(contents)
eq(2, #funcs.getbufinfo())
end)
it('tab edit a single file with a non-changed buffer', function()
- run_remote('--remote-tab', fname)
+ eq({ '', '' }, run_remote('--remote-tab', fname))
expect(contents)
eq(1, #funcs.gettabinfo())
end)
it('tab edit a single file with a changed buffer', function()
insert('hello')
- run_remote('--remote-tab', fname)
+ eq({ '', '' }, run_remote('--remote-tab', fname))
expect(contents)
eq(2, #funcs.gettabinfo())
end)
it('edit multiple files', function()
- run_remote('--remote', fname, other_fname)
+ eq({ '', '' }, run_remote('--remote', fname, other_fname))
expect(contents)
command('next')
expect(other_contents)
@@ -83,7 +95,7 @@ describe('Remote', function()
end)
it('send keys', function()
- run_remote('--remote-send', ':edit '..fname..'<CR><C-W>v')
+ eq({ '', '' }, run_remote('--remote-send', ':edit '..fname..'<CR><C-W>v'))
expect(contents)
eq(2, #funcs.getwininfo())
-- Only a single buffer as we're using edit and not drop like --remote does
@@ -91,8 +103,13 @@ describe('Remote', function()
end)
it('evaluate expressions', function()
- run_remote('--remote-expr', 'setline(1, "Yo")')
+ eq({ '0', '' }, run_remote('--remote-expr', 'setline(1, "Yo")'))
+ eq({ 'Yo', '' }, run_remote('--remote-expr', 'getline(1)'))
expect('Yo')
+ eq({ ('k'):rep(1234), '' }, run_remote('--remote-expr', 'repeat("k", 1234)'))
+ eq({ '1.25', '' }, run_remote('--remote-expr', '1.25'))
+ eq({ 'no', '' }, run_remote('--remote-expr', '0z6E6F'))
+ eq({ '\t', '' }, run_remote('--remote-expr', '"\t"'))
end)
end)
@@ -101,7 +118,7 @@ describe('Remote', function()
expect(contents)
eq(1, #funcs.getbufinfo())
-- Since we didn't pass silent, we should get a complaint
- neq(nil, string.find(meths.exec('messages', true), 'E247'))
+ neq(nil, string.find(exec_capture('messages'), 'E247:'))
end)
it('creates server if not found with tabs', function()
@@ -110,10 +127,10 @@ describe('Remote', function()
eq(2, #funcs.gettabinfo())
eq(2, #funcs.getbufinfo())
-- We passed silent, so no message should be issued about the server not being found
- eq(nil, string.find(meths.exec('messages', true), 'E247'))
+ eq(nil, string.find(exec_capture('messages'), 'E247:'))
end)
- pending('exits with error on', function()
+ describe('exits with error on', function()
local function run_and_check_exit_code(...)
local bogus_argv = new_argv(...)
diff --git a/test/functional/core/spellfile_spec.lua b/test/functional/core/spellfile_spec.lua
index afd2c1bce4..e3a59085cf 100644
--- a/test/functional/core/spellfile_spec.lua
+++ b/test/functional/core/spellfile_spec.lua
@@ -1,5 +1,4 @@
local helpers = require('test.functional.helpers')(after_each)
-local lfs = require('lfs')
local eq = helpers.eq
local clear = helpers.clear
@@ -7,6 +6,7 @@ local meths = helpers.meths
local exc_exec = helpers.exc_exec
local rmdir = helpers.rmdir
local write_file = helpers.write_file
+local mkdir = helpers.mkdir
local testdir = 'Xtest-functional-spell-spellfile.d'
@@ -14,8 +14,8 @@ describe('spellfile', function()
before_each(function()
clear()
rmdir(testdir)
- lfs.mkdir(testdir)
- lfs.mkdir(testdir .. '/spell')
+ mkdir(testdir)
+ mkdir(testdir .. '/spell')
end)
after_each(function()
rmdir(testdir)
@@ -24,7 +24,7 @@ describe('spellfile', function()
-- │ ┌ Spell file version (#VIMSPELLVERSION)
local spellheader = 'VIMspell\050'
it('errors out when prefcond section is truncated', function()
- meths.set_option('runtimepath', testdir)
+ meths.set_option_value('runtimepath', testdir, {})
write_file(testdir .. '/spell/en.ascii.spl',
-- ┌ Section identifier (#SN_PREFCOND)
-- │ ┌ Section flags (#SNF_REQUIRED or zero)
@@ -34,12 +34,12 @@ describe('spellfile', function()
-- │ ┌ Condition length (1 byte)
-- │ │ ┌ Condition regex (missing!)
.. '\000\001\001')
- meths.set_option('spelllang', 'en')
+ meths.set_option_value('spelllang', 'en', {})
eq('Vim(set):E758: Truncated spell file',
exc_exec('set spell'))
end)
it('errors out when prefcond regexp contains NUL byte', function()
- meths.set_option('runtimepath', testdir)
+ meths.set_option_value('runtimepath', testdir, {})
write_file(testdir .. '/spell/en.ascii.spl',
-- ┌ Section identifier (#SN_PREFCOND)
-- │ ┌ Section flags (#SNF_REQUIRED or zero)
@@ -54,12 +54,12 @@ describe('spellfile', function()
-- │ ┌ KWORDTREE tree length (4 bytes)
-- │ │ ┌ PREFIXTREE tree length
.. '\000\000\000\000\000\000\000\000\000\000\000\000')
- meths.set_option('spelllang', 'en')
+ meths.set_option_value('spelllang', 'en', {})
eq('Vim(set):E759: Format error in spell file',
exc_exec('set spell'))
end)
it('errors out when region contains NUL byte', function()
- meths.set_option('runtimepath', testdir)
+ meths.set_option_value('runtimepath', testdir, {})
write_file(testdir .. '/spell/en.ascii.spl',
-- ┌ Section identifier (#SN_REGION)
-- │ ┌ Section flags (#SNF_REQUIRED or zero)
@@ -71,12 +71,12 @@ describe('spellfile', function()
-- │ ┌ KWORDTREE tree length (4 bytes)
-- │ │ ┌ PREFIXTREE tree length
.. '\000\000\000\000\000\000\000\000\000\000\000\000')
- meths.set_option('spelllang', 'en')
+ meths.set_option_value('spelllang', 'en', {})
eq('Vim(set):E759: Format error in spell file',
exc_exec('set spell'))
end)
it('errors out when SAL section contains NUL byte', function()
- meths.set_option('runtimepath', testdir)
+ meths.set_option_value('runtimepath', testdir, {})
write_file(testdir .. '/spell/en.ascii.spl',
-- ┌ Section identifier (#SN_SAL)
-- │ ┌ Section flags (#SNF_REQUIRED or zero)
@@ -95,15 +95,15 @@ describe('spellfile', function()
-- │ ┌ KWORDTREE tree length (4 bytes)
-- │ │ ┌ PREFIXTREE tree length
.. '\000\000\000\000\000\000\000\000\000\000\000\000')
- meths.set_option('spelllang', 'en')
+ meths.set_option_value('spelllang', 'en', {})
eq('Vim(set):E759: Format error in spell file',
exc_exec('set spell'))
end)
it('errors out when spell header contains NUL bytes', function()
- meths.set_option('runtimepath', testdir)
+ meths.set_option_value('runtimepath', testdir, {})
write_file(testdir .. '/spell/en.ascii.spl',
spellheader:sub(1, -3) .. '\000\000')
- meths.set_option('spelllang', 'en')
+ meths.set_option_value('spelllang', 'en', {})
eq('Vim(set):E757: This does not look like a spell file',
exc_exec('set spell'))
end)
diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua
index e9b47a0251..94ec3d4907 100644
--- a/test/functional/core/startup_spec.lua
+++ b/test/functional/core/startup_spec.lua
@@ -9,6 +9,8 @@ local ok = helpers.ok
local eq = helpers.eq
local matches = helpers.matches
local eval = helpers.eval
+local exec = helpers.exec
+local exec_capture = helpers.exec_capture
local exec_lua = helpers.exec_lua
local feed = helpers.feed
local funcs = helpers.funcs
@@ -27,21 +29,36 @@ local meths = helpers.meths
local alter_slashes = helpers.alter_slashes
local is_os = helpers.is_os
local dedent = helpers.dedent
-
-local testfile = 'Xtest_startuptime'
-after_each(function()
- os.remove(testfile)
-end)
+local tbl_map = helpers.tbl_map
+local tbl_filter = helpers.tbl_filter
+local endswith = helpers.endswith
describe('startup', function()
it('--clean', function()
clear()
- ok(string.find(alter_slashes(meths.get_option('runtimepath')), funcs.stdpath('config'), 1, true) ~= nil)
+ ok(string.find(alter_slashes(meths.get_option_value('runtimepath', {})), funcs.stdpath('config'), 1, true) ~= nil)
clear('--clean')
- ok(string.find(alter_slashes(meths.get_option('runtimepath')), funcs.stdpath('config'), 1, true) == nil)
+ ok(string.find(alter_slashes(meths.get_option_value('runtimepath', {})), funcs.stdpath('config'), 1, true) == nil)
+ end)
+
+ it('prevents remote UI infinite loop', function()
+ clear()
+ local screen
+ screen = Screen.new(84, 3)
+ screen:attach()
+ funcs.termopen({ nvim_prog, '-u', 'NONE', '--server', eval('v:servername'), '--remote-ui' })
+ screen:expect([[
+ ^Cannot attach UI of :terminal child to its parent. (Unset $NVIM to skip this check) |
+ |
+ |
+ ]])
end)
it('--startuptime', function()
+ local testfile = 'Xtest_startuptime'
+ finally(function()
+ os.remove(testfile)
+ end)
clear({ args = {'--startuptime', testfile}})
assert_log('sourcing', testfile, 100)
assert_log("require%('vim%._editor'%)", testfile, 100)
@@ -58,7 +75,7 @@ describe('startup', function()
^ |
|
Entering Debug mode. Type "cont" to continue. |
- nvim_exec() |
+ nvim_exec2() |
cmd: aunmenu * |
> |
|
@@ -77,13 +94,7 @@ describe('startup', function()
end)
describe('startup', function()
- before_each(function()
- clear()
- os.remove('Xtest_startup_ttyout')
- end)
- after_each(function()
- os.remove('Xtest_startup_ttyout')
- end)
+ before_each(clear)
describe('-l Lua', function()
local function assert_l_out(expected, nvim_args, lua_args, script, input)
@@ -104,10 +115,11 @@ describe('startup', function()
it('os.exit() sets Nvim exitcode', function()
-- tricky: LeakSanitizer triggers on os.exit() and disrupts the return value, disable it
exec_lua [[
- local asan_options = os.getenv 'ASAN_OPTIONS'
- if asan_options ~= nil and asan_options ~= '' then
- vim.loop.os_setenv('ASAN_OPTIONS', asan_options..':detect_leaks=0')
+ local asan_options = os.getenv('ASAN_OPTIONS') or ''
+ if asan_options ~= '' then
+ asan_options = asan_options .. ':'
end
+ vim.uv.os_setenv('ASAN_OPTIONS', asan_options .. ':detect_leaks=0')
]]
-- nvim -l foo.lua -arg1 -- a b c
assert_l_out([[
@@ -133,12 +145,12 @@ describe('startup', function()
end)
it('executes stdin "-"', function()
- assert_l_out('arg0=- args=2 whoa',
+ assert_l_out('arg0=- args=2 whoa\n',
nil,
{ 'arg1', 'arg 2' },
'-',
"print(('arg0=%s args=%d %s'):format(_G.arg[0], #_G.arg, 'whoa'))")
- assert_l_out('biiig input: 1000042',
+ assert_l_out('biiig input: 1000042\n',
nil,
nil,
'-',
@@ -146,14 +158,37 @@ describe('startup', function()
eq(0, eval('v:shell_error'))
end)
+ it('does not truncate long print() message', function()
+ assert_l_out(('k'):rep(1234) .. '\n', nil, nil, '-', "print(('k'):rep(1234))")
+ end)
+
+ it('does not add newline when unnecessary', function()
+ assert_l_out('', nil, nil, '-', '')
+ assert_l_out('foobar\n', nil, nil, '-', [[print('foobar\n')]])
+ end)
+
it('sets _G.arg', function()
+ -- nvim -l foo.lua
+ assert_l_out([[
+ bufs:
+ nvim args: 3
+ lua args: {
+ [0] = "test/functional/fixtures/startup.lua"
+ }
+ ]],
+ {},
+ {}
+ )
+ eq(0, eval('v:shell_error'))
+
-- nvim -l foo.lua [args]
assert_l_out([[
bufs:
nvim args: 7
lua args: { "-arg1", "--arg2", "--", "arg3",
[0] = "test/functional/fixtures/startup.lua"
- }]],
+ }
+ ]],
{},
{ '-arg1', '--arg2', '--', 'arg3' }
)
@@ -165,7 +200,8 @@ describe('startup', function()
nvim args: 10
lua args: { "-arg1", "arg 2", "--", "file3", "file4",
[0] = "test/functional/fixtures/startup.lua"
- }]],
+ }
+ ]],
{ 'file1', 'file2', },
{ '-arg1', 'arg 2', '--', 'file3', 'file4' }
)
@@ -177,7 +213,8 @@ describe('startup', function()
nvim args: 5
lua args: { "-c", "set wrap?",
[0] = "test/functional/fixtures/startup.lua"
- }]],
+ }
+ ]],
{},
{ '-c', 'set wrap?' }
)
@@ -193,7 +230,8 @@ describe('startup', function()
nvim args: 7
lua args: { "-c", "set wrap?",
[0] = "test/functional/fixtures/startup.lua"
- }]],
+ }
+ ]],
{ '-c', 'set wrap?' },
{ '-c', 'set wrap?' }
)
@@ -201,15 +239,24 @@ describe('startup', function()
end)
it('disables swapfile/shada/config/plugins', function()
- assert_l_out('updatecount=0 shadafile=NONE loadplugins=false scriptnames=1',
+ assert_l_out('updatecount=0 shadafile=NONE loadplugins=false scripts=1\n',
nil,
nil,
'-',
- [[print(('updatecount=%d shadafile=%s loadplugins=%s scriptnames=%d'):format(
- vim.o.updatecount, vim.o.shadafile, tostring(vim.o.loadplugins), math.max(1, #vim.fn.split(vim.fn.execute('scriptnames'),'\n'))))]])
+ [[print(('updatecount=%d shadafile=%s loadplugins=%s scripts=%d'):format(
+ vim.o.updatecount, vim.o.shadafile, tostring(vim.o.loadplugins), math.max(1, #vim.fn.getscriptinfo())))]])
end)
end)
+ it('--cmd/-c/+ do not truncate long Lua print() message with --headless', function()
+ local out = funcs.system({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless',
+ '--cmd', 'lua print(("A"):rep(1234))',
+ '-c', 'lua print(("B"):rep(1234))',
+ '+lua print(("C"):rep(1234))',
+ '+q' })
+ eq(('A'):rep(1234) .. '\r\n' .. ('B'):rep(1234) .. '\r\n' .. ('C'):rep(1234), out)
+ end)
+
it('pipe at both ends: has("ttyin")==0 has("ttyout")==0', function()
-- system() puts a pipe at both ends.
local out = funcs.system({ nvim_prog, '-u', 'NONE', '-i', 'NONE', '--headless',
@@ -254,6 +301,10 @@ describe('startup', function()
if is_os('win') then
command([[set shellcmdflag=/s\ /c shellxquote=\"]])
end
+ os.remove('Xtest_startup_ttyout')
+ finally(function()
+ os.remove('Xtest_startup_ttyout')
+ end)
-- Running in :terminal
command([[exe printf("terminal %s -u NONE -i NONE --cmd \"]]
..nvim_set..[[\"]]
@@ -271,6 +322,10 @@ describe('startup', function()
if is_os('win') then
command([[set shellcmdflag=/s\ /c shellxquote=\"]])
end
+ os.remove('Xtest_startup_ttyout')
+ finally(function()
+ os.remove('Xtest_startup_ttyout')
+ end)
-- Running in :terminal
command([[exe printf("terminal echo foo | ]] -- Input from a pipe.
..[[%s -u NONE -i NONE --cmd \"]]
@@ -330,28 +385,6 @@ describe('startup', function()
{ '' }))
end)
- it('-e/-E interactive #7679', function()
- clear('-e')
- local screen = Screen.new(25, 3)
- screen:attach()
- feed("put ='from -e'<CR>")
- screen:expect([[
- :put ='from -e' |
- from -e |
- :^ |
- ]])
-
- clear('-E')
- screen = Screen.new(25, 3)
- screen:attach()
- feed("put ='from -E'<CR>")
- screen:expect([[
- :put ='from -E' |
- from -E |
- :^ |
- ]])
- end)
-
it('stdin with -es/-Es #7679', function()
local input = { 'append', 'line1', 'line2', '.', '%print', '' }
local inputstr = table.concat(input, '\n')
@@ -397,33 +430,16 @@ describe('startup', function()
for _,arg in ipairs({'-es', '-Es'}) do
local out = funcs.system({nvim_prog, arg,
'+set swapfile? updatecount? shadafile?',
- "+put =execute('scriptnames')", '+%print'})
+ "+put =map(getscriptinfo(), {-> v:val.name})", '+%print'})
local line1 = string.match(out, '^.-\n')
-- updatecount=0 means swapfile was disabled.
eq(" swapfile updatecount=0 shadafile=\n", line1)
-- Standard plugins were loaded, but not user config.
- eq('health.vim', string.match(out, 'health.vim'))
- eq(nil, string.match(out, 'init.vim'))
+ ok(string.find(out, 'man.lua') ~= nil)
+ ok(string.find(out, 'init.vim') == nil)
end
end)
- it('-e sets ex mode', function()
- local screen = Screen.new(25, 3)
- clear('-e')
- screen:attach()
- -- Verify we set the proper mode both before and after :vi.
- feed("put =mode(1)<CR>vi<CR>:put =mode(1)<CR>")
- screen:expect([[
- cv |
- ^n |
- :put =mode(1) |
- ]])
-
- eq('cv\n',
- funcs.system({nvim_prog, '-n', '-es' },
- { 'put =mode(1)', 'print', '' }))
- end)
-
it('fails on --embed with -es/-Es/-l', function()
matches('nvim[.exe]*: %-%-embed conflicts with %-es/%-Es/%-l',
funcs.system({nvim_prog, '--embed', '-es' }))
@@ -433,17 +449,6 @@ describe('startup', function()
funcs.system({nvim_prog, '--embed', '-l', 'foo.lua' }))
end)
- it('does not crash if --embed is given twice', function()
- clear{args={'--embed'}}
- assert_alive()
- end)
-
- it('does not crash when expanding cdpath during early_init', function()
- clear{env={CDPATH='~doesnotexist'}}
- assert_alive()
- eq(',~doesnotexist', eval('&cdpath'))
- end)
-
it('ENTER dismisses early message #7967', function()
local screen
screen = Screen.new(60, 6)
@@ -469,22 +474,24 @@ describe('startup', function()
]])
end)
- it("sets 'shortmess' when loading other tabs", function()
- clear({args={'-p', 'a', 'b', 'c'}})
- local screen = Screen.new(25, 4)
- screen:attach()
- screen:expect({grid=[[
- {1: a }{2: b c }{3: }{2:X}|
- ^ |
- {4:~ }|
- |
- ]],
- attr_ids={
- [1] = {bold = true},
- [2] = {background = Screen.colors.LightGrey, underline = true},
- [3] = {reverse = true},
- [4] = {bold = true, foreground = Screen.colors.Blue1},
- }})
+ it('-r works without --headless in PTY #23294', function()
+ exec([[
+ func Normalize(data) abort
+ " Windows: remove ^M and term escape sequences
+ return map(a:data, 'substitute(substitute(v:val, "\r", "", "g"), "\x1b\\%(\\]\\d\\+;.\\{-}\x07\\|\\[.\\{-}[\x40-\x7E]\\)", "", "g")')
+ endfunc
+ func OnOutput(id, data, event) dict
+ let g:stdout = Normalize(a:data)
+ endfunc
+ call jobstart([v:progpath, '-u', 'NONE', '-i', 'NONE', '-r'], {
+ \ 'pty': v:true,
+ \ 'stdout_buffered': v:true,
+ \ 'on_stdout': function('OnOutput'),
+ \ })
+ ]])
+ retry(nil, nil, function()
+ eq('Swap files found:', eval('g:stdout[0]'))
+ end)
end)
it('fixed hang issue with --headless (#11386)', function()
@@ -512,7 +519,102 @@ describe('startup', function()
'+q' })
eq('[\'+q\'] 1', out)
end)
+end)
+describe('startup', function()
+ it('-e/-E interactive #7679', function()
+ clear('-e')
+ local screen = Screen.new(25, 3)
+ screen:attach()
+ feed("put ='from -e'<CR>")
+ screen:expect([[
+ :put ='from -e' |
+ from -e |
+ :^ |
+ ]])
+
+ clear('-E')
+ screen = Screen.new(25, 3)
+ screen:attach()
+ feed("put ='from -E'<CR>")
+ screen:expect([[
+ :put ='from -E' |
+ from -E |
+ :^ |
+ ]])
+ end)
+
+ it('-e sets ex mode', function()
+ local screen = Screen.new(25, 3)
+ clear('-e')
+ screen:attach()
+ -- Verify we set the proper mode both before and after :vi.
+ feed("put =mode(1)<CR>vi<CR>:put =mode(1)<CR>")
+ screen:expect([[
+ cv |
+ ^n |
+ :put =mode(1) |
+ ]])
+
+ eq('cv\n',
+ funcs.system({nvim_prog, '-n', '-es' },
+ { 'put =mode(1)', 'print', '' }))
+ end)
+
+ it('-d does not diff non-arglist windows #13720 #21289', function()
+ write_file('Xdiff.vim', [[
+ let bufnr = nvim_create_buf(0, 1)
+ let config = {
+ \ 'relative': 'editor',
+ \ 'focusable': v:false,
+ \ 'width': 1,
+ \ 'height': 1,
+ \ 'row': 3,
+ \ 'col': 3
+ \ }
+ autocmd WinEnter * call nvim_open_win(bufnr, v:false, config)]])
+ finally(function()
+ os.remove('Xdiff.vim')
+ end)
+ clear{args={'-u', 'Xdiff.vim', '-d', 'Xdiff.vim', 'Xdiff.vim'}}
+ eq(true, meths.get_option_value('diff', {win = funcs.win_getid(1)}))
+ eq(true, meths.get_option_value('diff', {win = funcs.win_getid(2)}))
+ local float_win = funcs.win_getid(3)
+ eq('editor', meths.win_get_config(float_win).relative)
+ eq(false, meths.get_option_value('diff', {win = float_win}))
+ end)
+
+ it('does not crash if --embed is given twice', function()
+ clear{args={'--embed'}}
+ assert_alive()
+ end)
+
+ it('does not crash when expanding cdpath during early_init', function()
+ clear{env={CDPATH='~doesnotexist'}}
+ assert_alive()
+ eq(',~doesnotexist', eval('&cdpath'))
+ end)
+
+ it("sets 'shortmess' when loading other tabs", function()
+ clear({args={'-p', 'a', 'b', 'c'}})
+ local screen = Screen.new(25, 4)
+ screen:attach()
+ screen:expect({grid=[[
+ {1: a }{2: b c }{3: }{2:X}|
+ ^ |
+ {4:~ }|
+ |
+ ]],
+ attr_ids={
+ [1] = {bold = true},
+ [2] = {background = Screen.colors.LightGrey, underline = true},
+ [3] = {reverse = true},
+ [4] = {bold = true, foreground = Screen.colors.Blue1},
+ }})
+ end)
+end)
+
+describe('startup', function()
local function pack_clear(cmd)
-- add packages after config dir in rtp but before config/after
clear{args={'--cmd', 'set packpath=test/functional/fixtures', '--cmd', 'let paths=split(&rtp, ",")', '--cmd', 'let &rtp = paths[0]..",test/functional/fixtures,test/functional/fixtures/middle,"..join(paths[1:],",")', '--cmd', cmd}, env={XDG_CONFIG_HOME='test/functional/fixtures/'},
@@ -520,7 +622,6 @@ describe('startup', function()
}
end
-
it("handles &packpath during startup", function()
pack_clear [[
let g:x = bar#test()
@@ -585,7 +686,7 @@ describe('startup', function()
]]
eq({'ordinary', 'FANCY', 'mittel', 'FANCY after', 'ordinary after'}, exec_lua [[ return _G.test_loadorder ]])
- local rtp = meths.get_option'rtp'
+ local rtp = meths.get_option_value('rtp', {})
ok(startswith(rtp, 'test/functional/fixtures/nvim,test/functional/fixtures/pack/*/start/*,test/functional/fixtures/start/*,test/functional/fixtures,test/functional/fixtures/middle,'),
'startswith(…)', 'rtp='..rtp)
end)
@@ -627,13 +728,13 @@ describe('startup', function()
end)
it('window widths are correct when modelines set &columns with tabpages', function()
- write_file('tab1.noft', 'vim: columns=81')
- write_file('tab2.noft', 'vim: columns=81')
+ write_file('Xtab1.noft', 'vim: columns=81')
+ write_file('Xtab2.noft', 'vim: columns=81')
finally(function()
- os.remove('tab1.noft')
- os.remove('tab2.noft')
+ os.remove('Xtab1.noft')
+ os.remove('Xtab2.noft')
end)
- clear({args = {'-p', 'tab1.noft', 'tab2.noft'}})
+ clear({args = {'-p', 'Xtab1.noft', 'Xtab2.noft'}})
eq(81, meths.win_get_width(0))
command('tabnext')
eq(81, meths.win_get_width(0))
@@ -691,7 +792,6 @@ describe('sysinit', function()
eq('loaded 1 xdg 0 vim 1',
eval('printf("loaded %d xdg %d vim %d", g:loaded, get(g:, "xdg", 0), get(g:, "vim", 0))'))
end)
-
end)
describe('user config init', function()
@@ -718,15 +818,16 @@ describe('user config init', function()
end)
it('loads init.lua from XDG config home by default', function()
- clear{ args_rm={'-u' }, env=xenv }
+ clear{ args_rm={'-u'}, env=xenv }
eq(1, eval('g:lua_rc'))
eq(funcs.fnamemodify(init_lua_path, ':p'), eval('$MYVIMRC'))
end)
- describe('with existing .exrc in cwd', function()
+ describe('loads existing', function()
local exrc_path = '.exrc'
local xstate = 'Xstate'
+ local xstateenv = { XDG_CONFIG_HOME=xconfig, XDG_DATA_HOME=xdata, XDG_STATE_HOME=xstate }
local function setup_exrc_file(filename)
exrc_path = filename
@@ -756,10 +857,10 @@ describe('user config init', function()
end)
for _, filename in ipairs({ '.exrc', '.nvimrc', '.nvim.lua' }) do
- it('loads ' .. filename, function ()
+ it(filename .. ' in cwd', function()
setup_exrc_file(filename)
- clear{ args_rm = {'-u'}, env={ XDG_CONFIG_HOME=xconfig, XDG_STATE_HOME=xstate } }
+ clear{ args_rm={'-u'}, env=xstateenv }
-- The 'exrc' file is not trusted, and the prompt is skipped because there is no UI.
eq('---', eval('g:exrc_file'))
@@ -791,7 +892,7 @@ describe('user config init', function()
-- TERMINAL -- |
]], filename, string.rep(' ', 50 - #filename)))
- clear{ args_rm = {'-u'}, env={ XDG_CONFIG_HOME=xconfig, XDG_STATE_HOME=xstate } }
+ clear{ args_rm={'-u'}, env=xstateenv }
-- The 'exrc' file is now trusted.
eq(filename, eval('g:exrc_file'))
end)
@@ -824,7 +925,7 @@ describe('user config init', function()
clear{ args_rm={'-u'}, env=xenv }
feed('<cr><c-c>') -- Dismiss "Conflicting config …" message.
eq(1, eval('g:lua_rc'))
- matches('^E5422: Conflicting configs', meths.exec('messages', true))
+ matches('^E5422: Conflicting configs', exec_capture('messages'))
end)
end)
end)
@@ -850,40 +951,41 @@ describe('runtime:', function()
local plugin_folder_path = table.concat({xconfig, 'nvim', 'plugin'}, pathsep)
local plugin_file_path = table.concat({plugin_folder_path, 'plugin.lua'}, pathsep)
mkdir_p(plugin_folder_path)
+ finally(function()
+ rmdir(plugin_folder_path)
+ end)
write_file(plugin_file_path, [[ vim.g.lua_plugin = 1 ]])
clear{ args_rm={'-u'}, env=xenv }
eq(1, eval('g:lua_plugin'))
- rmdir(plugin_folder_path)
end)
it('loads plugin/*.lua from start packages', function()
- local plugin_path = table.concat({xconfig, 'nvim', 'pack', 'category',
- 'start', 'test_plugin'}, pathsep)
+ local plugin_path = table.concat({xconfig, 'nvim', 'pack', 'category', 'start', 'test_plugin'}, pathsep)
local plugin_folder_path = table.concat({plugin_path, 'plugin'}, pathsep)
- local plugin_file_path = table.concat({plugin_folder_path, 'plugin.lua'},
- pathsep)
+ local plugin_file_path = table.concat({plugin_folder_path, 'plugin.lua'}, pathsep)
local profiler_file = 'test_startuptime.log'
-
mkdir_p(plugin_folder_path)
+ finally(function()
+ os.remove(profiler_file)
+ rmdir(plugin_path)
+ end)
+
write_file(plugin_file_path, [[vim.g.lua_plugin = 2]])
clear{ args_rm={'-u'}, args={'--startuptime', profiler_file}, env=xenv }
eq(2, eval('g:lua_plugin'))
- -- Check if plugin_file_path is listed in :scriptname
- local scripts = meths.exec(':scriptnames', true)
- assert(scripts:find(plugin_file_path))
+ -- Check if plugin_file_path is listed in getscriptinfo()
+ local scripts = tbl_map(function(s) return s.name end, funcs.getscriptinfo())
+ ok(#tbl_filter(function(s) return endswith(s, plugin_file_path) end, scripts) > 0)
-- Check if plugin_file_path is listed in startup profile
local profile_reader = io.open(profiler_file, 'r')
local profile_log = profile_reader:read('*a')
profile_reader:close()
- assert(profile_log:find(plugin_file_path))
-
- os.remove(profiler_file)
- rmdir(plugin_path)
+ ok(profile_log:find(plugin_file_path) ~= nil)
end)
it('loads plugin/*.lua from site packages', function()
@@ -893,30 +995,59 @@ describe('runtime:', function()
local plugin_after_path = table.concat({plugin_path, 'after', 'plugin'}, pathsep)
local plugin_file_path = table.concat({plugin_folder_path, 'plugin.lua'}, pathsep)
local plugin_after_file_path = table.concat({plugin_after_path, 'helloo.lua'}, pathsep)
-
mkdir_p(plugin_folder_path)
- write_file(plugin_file_path, [[table.insert(_G.lista, "unos")]])
mkdir_p(plugin_after_path)
+ finally(function()
+ rmdir(plugin_path)
+ end)
+
+ write_file(plugin_file_path, [[table.insert(_G.lista, "unos")]])
write_file(plugin_after_file_path, [[table.insert(_G.lista, "dos")]])
clear{ args_rm={'-u'}, args={'--cmd', 'lua _G.lista = {}'}, env=xenv }
eq({'unos', 'dos'}, exec_lua "return _G.lista")
-
- rmdir(plugin_path)
end)
+ it('no crash setting &rtp in plugins with :packloadall called before #18315', function()
+ local plugin_folder_path = table.concat({xconfig, 'nvim', 'plugin'}, pathsep)
+ mkdir_p(plugin_folder_path)
+ finally(function()
+ rmdir(plugin_folder_path)
+ end)
+
+ write_file(table.concat({plugin_folder_path, 'plugin.vim'}, pathsep), [[
+ let &runtimepath = &runtimepath
+ let g:vim_plugin = 1
+ ]])
+ write_file(table.concat({plugin_folder_path, 'plugin.lua'}, pathsep), [[
+ vim.o.runtimepath = vim.o.runtimepath
+ vim.g.lua_plugin = 1
+ ]])
- it('loads ftdetect/*.lua', function()
- local ftdetect_folder = table.concat({xconfig, 'nvim', 'ftdetect'}, pathsep)
- local ftdetect_file = table.concat({ftdetect_folder , 'new-ft.lua'}, pathsep)
- mkdir_p(ftdetect_folder)
- write_file(ftdetect_file , [[vim.g.lua_ftdetect = 1]])
+ clear{ args_rm={'-u'}, args = {'--cmd', 'packloadall'}, env=xenv }
- clear{ args_rm={'-u'}, env=xenv }
+ eq(1, eval('g:vim_plugin'))
+ eq(1, eval('g:lua_plugin'))
+ end)
- eq(1, eval('g:lua_ftdetect'))
- rmdir(ftdetect_folder)
+ it("loads ftdetect/*.{vim,lua} respecting 'rtp' order", function()
+ local ftdetect_folder = table.concat({xconfig, 'nvim', 'ftdetect'}, pathsep)
+ local after_ftdetect_folder = table.concat({xconfig, 'nvim', 'after', 'ftdetect'}, pathsep)
+ mkdir_p(ftdetect_folder)
+ mkdir_p(after_ftdetect_folder)
+ finally(function()
+ rmdir(ftdetect_folder)
+ rmdir(after_ftdetect_folder)
+ end)
+ -- A .lua file is loaded after a .vim file if they only differ in extension.
+ -- All files in after/ftdetect/ are loaded after all files in ftdetect/.
+ write_file(table.concat({ftdetect_folder, 'new-ft.vim'}, pathsep), [[let g:seq ..= 'A']])
+ write_file(table.concat({ftdetect_folder, 'new-ft.lua'}, pathsep), [[vim.g.seq = vim.g.seq .. 'B']])
+ write_file(table.concat({after_ftdetect_folder, 'new-ft.vim'}, pathsep), [[let g:seq ..= 'a']])
+ write_file(table.concat({after_ftdetect_folder, 'new-ft.lua'}, pathsep), [[vim.g.seq = vim.g.seq .. 'b']])
+ clear{ args_rm={'-u'}, args = {'--cmd', 'let g:seq = ""'}, env=xenv }
+ eq('ABab', eval('g:seq'))
end)
end)