diff options
Diffstat (limited to 'test/functional')
-rw-r--r-- | test/functional/eval/system_spec.lua | 108 | ||||
-rw-r--r-- | test/functional/ex_cmds/file_spec.lua | 35 | ||||
-rw-r--r-- | test/functional/ex_cmds/recover_spec.lua | 41 | ||||
-rw-r--r-- | test/functional/ex_cmds/syntax_spec.lua | 17 | ||||
-rw-r--r-- | test/functional/helpers.lua | 36 | ||||
-rw-r--r-- | test/functional/insert/ctrl_r_spec.lua | 19 | ||||
-rw-r--r-- | test/functional/normal/lang_spec.lua | 63 | ||||
-rw-r--r-- | test/functional/spell/spellfile_spec.lua | 110 | ||||
-rw-r--r-- | test/functional/terminal/edit_spec.lua | 5 | ||||
-rw-r--r-- | test/functional/ui/inccommand_spec.lua | 24 | ||||
-rw-r--r-- | test/functional/ui/screen.lua | 19 |
11 files changed, 385 insertions, 92 deletions
diff --git a/test/functional/eval/system_spec.lua b/test/functional/eval/system_spec.lua index bf95752e3b..7e213e2156 100644 --- a/test/functional/eval/system_spec.lua +++ b/test/functional/eval/system_spec.lua @@ -4,6 +4,8 @@ local nvim_dir = helpers.nvim_dir local eq, call, clear, eval, feed_command, feed, nvim = helpers.eq, helpers.call, helpers.clear, helpers.eval, helpers.feed_command, helpers.feed, helpers.nvim +local command = helpers.command +local iswin = helpers.iswin local Screen = require('test.functional.ui.screen') @@ -33,8 +35,7 @@ describe('system()', function() describe('command passed as a List', function() local function printargs_path() - return nvim_dir..'/printargs-test' - .. (helpers.os_name() == 'windows' and '.exe' or '') + return nvim_dir..'/printargs-test' .. (iswin() and '.exe' or '') end it('sets v:shell_error if cmd[0] is not executable', function() @@ -88,23 +89,32 @@ describe('system()', function() end) it('does NOT run in shell', function() - if helpers.os_name() ~= 'windows' then + if not iswin() then eq("* $PATH %PATH%\n", eval("system(['echo', '*', '$PATH', '%PATH%'])")) end end) end) - if helpers.pending_win32(pending) then return end - it('sets v:shell_error', function() - eval([[system("sh -c 'exit'")]]) - eq(0, eval('v:shell_error')) - eval([[system("sh -c 'exit 1'")]]) - eq(1, eval('v:shell_error')) - eval([[system("sh -c 'exit 5'")]]) - eq(5, eval('v:shell_error')) - eval([[system('this-should-not-exist')]]) - eq(127, eval('v:shell_error')) + if iswin() then + eval([[system("cmd.exe /c exit")]]) + eq(0, eval('v:shell_error')) + eval([[system("cmd.exe /c exit 1")]]) + eq(1, eval('v:shell_error')) + eval([[system("cmd.exe /c exit 5")]]) + eq(5, eval('v:shell_error')) + eval([[system('this-should-not-exist')]]) + eq(1, eval('v:shell_error')) + else + eval([[system("sh -c 'exit'")]]) + eq(0, eval('v:shell_error')) + eval([[system("sh -c 'exit 1'")]]) + eq(1, eval('v:shell_error')) + eval([[system("sh -c 'exit 5'")]]) + eq(5, eval('v:shell_error')) + eval([[system('this-should-not-exist')]]) + eq(127, eval('v:shell_error')) + end end) describe('executes shell function if passed a string', function() @@ -120,6 +130,40 @@ describe('system()', function() screen:detach() end) + if iswin() then + it('with shell=cmd.exe', function() + command('set shell=cmd.exe') + eq('""\n', eval([[system('echo ""')]])) + eq('"a b"\n', eval([[system('echo "a b"')]])) + eq('a \nb\n', eval([[system('echo a & echo b')]])) + eq('a \n', eval([[system('echo a 2>&1')]])) + eval([[system('cd "C:\Program Files"')]]) + eq(0, eval('v:shell_error')) + end) + + it('with shell=cmd', function() + command('set shell=cmd') + eq('"a b"\n', eval([[system('echo "a b"')]])) + end) + + it('with shell=$COMSPEC', function() + local comspecshell = eval("fnamemodify($COMSPEC, ':t')") + if comspecshell == 'cmd.exe' then + command('set shell=$COMSPEC') + eq('"a b"\n', eval([[system('echo "a b"')]])) + else + pending('$COMSPEC is not cmd.exe: ' .. comspecshell) + end + end) + + it('works with powershell', function() + helpers.set_shell_powershell() + eq('a\nb\n', eval([[system('echo a b')]])) + eq('C:\\\n', eval([[system('cd c:\; (Get-Location).Path')]])) + eq('a b\n', eval([[system('echo "a b"')]])) + end) + end + it('`echo` and waits for its return', function() feed(':call system("echo")<cr>') screen:expect([[ @@ -180,7 +224,11 @@ describe('system()', function() describe('passing no input', function() it('returns the program output', function() - eq("echoed", eval('system("echo -n echoed")')) + if iswin() then + eq("echoed\n", eval('system("echo echoed")')) + else + eq("echoed", eval('system("echo -n echoed")')) + end end) it('to backgrounded command does not crash', function() -- This is indeterminate, just exercise the codepath. May get E5677. @@ -277,21 +325,30 @@ describe('system()', function() end) end) -if helpers.pending_win32(pending) then return end - describe('systemlist()', function() -- Similar to `system()`, but returns List instead of String. before_each(clear) - it('sets the v:shell_error variable', function() - eval([[systemlist("sh -c 'exit'")]]) - eq(0, eval('v:shell_error')) - eval([[systemlist("sh -c 'exit 1'")]]) - eq(1, eval('v:shell_error')) - eval([[systemlist("sh -c 'exit 5'")]]) - eq(5, eval('v:shell_error')) - eval([[systemlist('this-should-not-exist')]]) - eq(127, eval('v:shell_error')) + it('sets v:shell_error', function() + if iswin() then + eval([[systemlist("cmd.exe /c exit")]]) + eq(0, eval('v:shell_error')) + eval([[systemlist("cmd.exe /c exit 1")]]) + eq(1, eval('v:shell_error')) + eval([[systemlist("cmd.exe /c exit 5")]]) + eq(5, eval('v:shell_error')) + eval([[systemlist('this-should-not-exist')]]) + eq(1, eval('v:shell_error')) + else + eval([[systemlist("sh -c 'exit'")]]) + eq(0, eval('v:shell_error')) + eval([[systemlist("sh -c 'exit 1'")]]) + eq(1, eval('v:shell_error')) + eval([[systemlist("sh -c 'exit 5'")]]) + eq(5, eval('v:shell_error')) + eval([[systemlist('this-should-not-exist')]]) + eq(127, eval('v:shell_error')) + end end) describe('exectues shell function', function() @@ -389,6 +446,7 @@ describe('systemlist()', function() after_each(delete_file(fname)) it('replaces NULs by newline characters', function() + if helpers.pending_win32(pending) then return end eq({'part1\npart2\npart3'}, eval('systemlist("cat '..fname..'")')) end) end) diff --git a/test/functional/ex_cmds/file_spec.lua b/test/functional/ex_cmds/file_spec.lua new file mode 100644 index 0000000000..771c283134 --- /dev/null +++ b/test/functional/ex_cmds/file_spec.lua @@ -0,0 +1,35 @@ +local helpers = require('test.functional.helpers')(after_each) +local lfs = require('lfs') +local clear = helpers.clear +local command = helpers.command +local eq = helpers.eq +local funcs = helpers.funcs +local rmdir = helpers.rmdir + +describe(':file', function() + local swapdir = lfs.currentdir()..'/Xtest-file_spec' + before_each(function() + clear() + rmdir(swapdir) + lfs.mkdir(swapdir) + end) + after_each(function() + command('%bwipeout!') + rmdir(swapdir) + end) + + it("rename does not lose swapfile #6487", function() + local testfile = 'test-file_spec' + local testfile_renamed = testfile..'-renamed' + -- Note: `set swapfile` *must* go after `set directory`: otherwise it may + -- attempt to create a swapfile in different directory. + command('set directory^='..swapdir..'//') + command('set swapfile fileformat=unix undolevels=-1') + + command('edit! '..testfile) + -- Before #6487 this gave "E301: Oops, lost the swap file !!!" on Windows. + command('file '..testfile_renamed) + eq(testfile_renamed..'.swp', + string.match(funcs.execute('swapname'), '[^%%]+$')) + end) +end) diff --git a/test/functional/ex_cmds/recover_spec.lua b/test/functional/ex_cmds/recover_spec.lua index 36bf85015a..cb68c29b9a 100644 --- a/test/functional/ex_cmds/recover_spec.lua +++ b/test/functional/ex_cmds/recover_spec.lua @@ -1,12 +1,11 @@ --- Tests for :recover - local helpers = require('test.functional.helpers')(after_each) local lfs = require('lfs') local feed_command, eq, clear, eval, feed, expect, source = helpers.feed_command, helpers.eq, helpers.clear, helpers.eval, helpers.feed, helpers.expect, helpers.source - -if helpers.pending_win32(pending) then return end +local command = helpers.command +local ok = helpers.ok +local rmdir = helpers.rmdir describe(':recover', function() before_each(clear) @@ -23,30 +22,29 @@ describe(':preserve', function() local swapdir = lfs.currentdir()..'/testdir_recover_spec' before_each(function() clear() - helpers.rmdir(swapdir) + rmdir(swapdir) lfs.mkdir(swapdir) end) after_each(function() - helpers.rmdir(swapdir) + command('%bwipeout!') + rmdir(swapdir) end) it("saves to custom 'directory' and (R)ecovers (issue #1836)", function() local testfile = 'testfile_recover_spec' + -- Put swapdir at the start of the 'directory' list. #1836 -- Note: `set swapfile` *must* go after `set directory`: otherwise it may -- attempt to create a swapfile in different directory. local init = [[ - set directory^=]]..swapdir..[[// + set directory^=]]..swapdir:gsub([[\]], [[\\]])..[[// set swapfile fileformat=unix undolevels=-1 ]] source(init) - feed_command('set swapfile fileformat=unix undolevels=-1') - -- Put swapdir at the start of the 'directory' list. #1836 - feed_command('set directory^='..swapdir..'//') - feed_command('edit '..testfile) + command('edit! '..testfile) feed('isometext<esc>') - feed_command('preserve') - source('redir => g:swapname | swapname | redir END') + command('preserve') + source('redir => g:swapname | silent swapname | redir END') local swappath1 = eval('g:swapname') @@ -59,19 +57,20 @@ describe(':preserve', function() source(init) -- Use the "SwapExists" event to choose the (R)ecover choice at the dialog. - feed_command('autocmd SwapExists * let v:swapchoice = "r"') - feed_command('silent edit '..testfile) - source('redir => g:swapname | swapname | redir END') + command('autocmd SwapExists * let v:swapchoice = "r"') + command('silent edit! '..testfile) + source('redir => g:swapname | silent swapname | redir END') local swappath2 = eval('g:swapname') + expect('sometext') -- swapfile from session 1 should end in .swp - assert(testfile..'.swp' == string.match(swappath1, '[^%%]+$')) - + eq(testfile..'.swp', string.match(swappath1, '[^%%]+$')) -- swapfile from session 2 should end in .swo - assert(testfile..'.swo' == string.match(swappath2, '[^%%]+$')) - - expect('sometext') + eq(testfile..'.swo', string.match(swappath2, '[^%%]+$')) + -- Verify that :swapname was not truncated (:help 'shortmess'). + ok(nil == string.find(swappath1, '%.%.%.')) + ok(nil == string.find(swappath2, '%.%.%.')) end) end) diff --git a/test/functional/ex_cmds/syntax_spec.lua b/test/functional/ex_cmds/syntax_spec.lua new file mode 100644 index 0000000000..c9e96703de --- /dev/null +++ b/test/functional/ex_cmds/syntax_spec.lua @@ -0,0 +1,17 @@ +local helpers = require('test.functional.helpers')(after_each) + +local eq = helpers.eq +local clear = helpers.clear +local exc_exec = helpers.exc_exec + +describe(':syntax', function() + before_each(clear) + + describe('keyword', function() + it('does not crash when group name contains unprintable characters', + function() + eq('Vim(syntax):E669: Unprintable character in group name', + exc_exec('syntax keyword \024 foo bar')) + end) + end) +end) diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 13b06e7f1b..5882758b5a 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -32,20 +32,15 @@ local nvim_set = 'set shortmess+=I background=light noswapfile noautoindent' ..' belloff= noshowcmd noruler nomore' local nvim_argv = {nvim_prog, '-u', 'NONE', '-i', 'NONE', '-N', '--cmd', nvim_set, '--embed'} - -local mpack = require('mpack') - -local tmpname = global_helpers.tmpname -local uname = global_helpers.uname - --- Formulate a path to the directory containing nvim. We use this to --- help run test executables. It helps to keep the tests working, even --- when the build is not in the default location. +-- Directory containing nvim. local nvim_dir = nvim_prog:gsub("[/\\][^/\\]+$", "") if nvim_dir == nvim_prog then nvim_dir = "." end +local mpack = require('mpack') +local tmpname = global_helpers.tmpname +local uname = global_helpers.uname local prepend_argv if os.getenv('VALGRIND') then @@ -353,7 +348,7 @@ end local function set_shell_powershell() source([[ set shell=powershell shellquote=\" shellpipe=\| shellredir=> - set shellcmdflag=\ -ExecutionPolicy\ RemoteSigned\ -Command + set shellcmdflag=\ -NoProfile\ -ExecutionPolicy\ RemoteSigned\ -Command let &shellxquote=' ' ]]) end @@ -430,21 +425,27 @@ end local function do_rmdir(path) if lfs.attributes(path, 'mode') ~= 'directory' then - return nil + return -- Don't complain. end for file in lfs.dir(path) do if file ~= '.' and file ~= '..' then local abspath = path..'/'..file if lfs.attributes(abspath, 'mode') == 'directory' then - local ret = do_rmdir(abspath) -- recurse - if not ret then - return nil - end + do_rmdir(abspath) -- recurse else local ret, err = os.remove(abspath) if not ret then - error('os.remove: '..err) - return nil + if not session then + error('os.remove: '..err) + else + -- Try Nvim delete(): it handles `readonly` attribute on Windows, + -- and avoids Lua cross-version/platform incompatibilities. + if -1 == nvim_call('delete', abspath) then + local hint = (os_name() == 'windows' + and ' (hint: try :%bwipeout! before rmdir())' or '') + error('delete() failed'..hint..': '..abspath) + end + end end end end @@ -453,7 +454,6 @@ local function do_rmdir(path) if not ret then error('lfs.rmdir('..path..'): '..err) end - return ret end local function rmdir(path) diff --git a/test/functional/insert/ctrl_r_spec.lua b/test/functional/insert/ctrl_r_spec.lua new file mode 100644 index 0000000000..adc3c4b406 --- /dev/null +++ b/test/functional/insert/ctrl_r_spec.lua @@ -0,0 +1,19 @@ +local helpers = require('test.functional.helpers')(after_each) +local clear, feed = helpers.clear, helpers.feed +local expect, command = helpers.expect, helpers.command + +describe('insert-mode Ctrl-R', function() + before_each(clear) + + it('works', function() + command("let @@ = 'test'") + feed('i<C-r>"') + expect('test') + end) + + it('works with multi-byte text', function() + command("let @@ = 'påskägg'") + feed('i<C-r>"') + expect('påskägg') + end) +end) diff --git a/test/functional/normal/lang_spec.lua b/test/functional/normal/lang_spec.lua new file mode 100644 index 0000000000..24d1262f5f --- /dev/null +++ b/test/functional/normal/lang_spec.lua @@ -0,0 +1,63 @@ +local helpers = require('test.functional.helpers')(after_each) +local clear, insert, eq = helpers.clear, helpers.insert, helpers.eq +local command, expect = helpers.command, helpers.expect +local feed, eval = helpers.feed, helpers.eval +local exc_exec = helpers.exc_exec + +describe('gu and gU', function() + before_each(clear) + + it('works in any locale with default casemap', function() + eq('internal,keepascii', eval('&casemap')) + insert("iI") + feed("VgU") + expect("II") + feed("Vgu") + expect("ii") + end) + + describe('works in Turkish locale', function() + clear() + + local err = exc_exec('lang ctype tr_TR.UTF-8') + if err ~= 0 then + pending("Locale tr_TR.UTF-8 not supported", function() end) + return + end + + before_each(function() + command('lang ctype tr_TR.UTF-8') + end) + + it('with default casemap', function() + eq('internal,keepascii', eval('&casemap')) + -- expect ASCII behavior + insert("iI") + feed("VgU") + expect("II") + feed("Vgu") + expect("ii") + end) + + it('with casemap=""', function() + command('set casemap=') + -- expect either Turkish locale behavior or ASCII behavior + local iupper = eval("toupper('i')") + if iupper == "İ" then + insert("iI") + feed("VgU") + expect("İI") + feed("Vgu") + expect("iı") + elseif iupper == "I" then + insert("iI") + feed("VgU") + expect("II") + feed("Vgu") + expect("ii") + else + error("expected toupper('i') to be either 'I' or 'İ'") + end + end) + end) +end) diff --git a/test/functional/spell/spellfile_spec.lua b/test/functional/spell/spellfile_spec.lua new file mode 100644 index 0000000000..afd2c1bce4 --- /dev/null +++ b/test/functional/spell/spellfile_spec.lua @@ -0,0 +1,110 @@ +local helpers = require('test.functional.helpers')(after_each) +local lfs = require('lfs') + +local eq = helpers.eq +local clear = helpers.clear +local meths = helpers.meths +local exc_exec = helpers.exc_exec +local rmdir = helpers.rmdir +local write_file = helpers.write_file + +local testdir = 'Xtest-functional-spell-spellfile.d' + +describe('spellfile', function() + before_each(function() + clear() + rmdir(testdir) + lfs.mkdir(testdir) + lfs.mkdir(testdir .. '/spell') + end) + after_each(function() + rmdir(testdir) + end) + -- ┌ Magic string (#VIMSPELLMAGIC) + -- │ ┌ Spell file version (#VIMSPELLVERSION) + local spellheader = 'VIMspell\050' + it('errors out when prefcond section is truncated', function() + meths.set_option('runtimepath', testdir) + write_file(testdir .. '/spell/en.ascii.spl', + -- ┌ Section identifier (#SN_PREFCOND) + -- │ ┌ Section flags (#SNF_REQUIRED or zero) + -- │ │ ┌ Section length (4 bytes, MSB first) + spellheader .. '\003\001\000\000\000\003' + -- ┌ Number of regexes in section (2 bytes, MSB first) + -- │ ┌ Condition length (1 byte) + -- │ │ ┌ Condition regex (missing!) + .. '\000\001\001') + meths.set_option('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) + write_file(testdir .. '/spell/en.ascii.spl', + -- ┌ Section identifier (#SN_PREFCOND) + -- │ ┌ Section flags (#SNF_REQUIRED or zero) + -- │ │ ┌ Section length (4 bytes, MSB first) + spellheader .. '\003\001\000\000\000\008' + -- ┌ Number of regexes in section (2 bytes, MSB first) + -- │ ┌ Condition length (1 byte) + -- │ │ ┌ Condition regex + -- │ │ │ ┌ End of sections marker + .. '\000\001\005ab\000cd\255' + -- ┌ LWORDTREE tree length (4 bytes) + -- │ ┌ 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') + 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) + write_file(testdir .. '/spell/en.ascii.spl', + -- ┌ Section identifier (#SN_REGION) + -- │ ┌ Section flags (#SNF_REQUIRED or zero) + -- │ │ ┌ Section length (4 bytes, MSB first) + spellheader .. '\000\001\000\000\000\008' + -- ┌ Regions ┌ End of sections marker + .. '01234\00067\255' + -- ┌ LWORDTREE tree length (4 bytes) + -- │ ┌ 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') + 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) + write_file(testdir .. '/spell/en.ascii.spl', + -- ┌ Section identifier (#SN_SAL) + -- │ ┌ Section flags (#SNF_REQUIRED or zero) + -- │ │ ┌ Section length (4 bytes, MSB first) + spellheader .. '\005\001\000\000\000\008' + -- ┌ salflags + -- │ ┌ salcount (2 bytes, MSB first) + -- │ │ ┌ salfromlen (1 byte) + -- │ │ │ ┌ Special character + -- │ │ │ │┌ salfrom (should not contain NUL) + -- │ │ │ ││ ┌ saltolen + -- │ │ │ ││ │ ┌ salto + -- │ │ │ ││ │ │┌ End of sections marker + .. '\000\000\001\0024\000\0017\255' + -- ┌ LWORDTREE tree length (4 bytes) + -- │ ┌ 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') + 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) + write_file(testdir .. '/spell/en.ascii.spl', + spellheader:sub(1, -3) .. '\000\000') + meths.set_option('spelllang', 'en') + eq('Vim(set):E757: This does not look like a spell file', + exc_exec('set spell')) + end) +end) diff --git a/test/functional/terminal/edit_spec.lua b/test/functional/terminal/edit_spec.lua index 42a5c768bb..d2b2d8a60c 100644 --- a/test/functional/terminal/edit_spec.lua +++ b/test/functional/terminal/edit_spec.lua @@ -45,11 +45,8 @@ describe(':edit term://*', function() local bufcontents = {} local winheight = curwinmeths.get_height() local buf_cont_start = rep_size - sb - winheight + 2 - local function bufline (i) - return ('%d: foobar'):format(i) - end for i = buf_cont_start,(rep_size - 1) do - bufcontents[#bufcontents + 1] = bufline(i) + bufcontents[#bufcontents + 1] = ('%d: foobar'):format(i) end bufcontents[#bufcontents + 1] = '' bufcontents[#bufcontents + 1] = '[Process exited 0]' diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua index b7a33cb64d..a7be1a9dc8 100644 --- a/test/functional/ui/inccommand_spec.lua +++ b/test/functional/ui/inccommand_spec.lua @@ -1,6 +1,7 @@ local helpers = require('test.functional.helpers')(after_each) local Screen = require('test.functional.ui.screen') local clear = helpers.clear +local command = helpers.command local curbufmeths = helpers.curbufmeths local eq = helpers.eq local eval = helpers.eval @@ -21,9 +22,9 @@ local default_text = [[ local function common_setup(screen, inccommand, text) if screen then - feed_command("syntax on") - feed_command("set nohlsearch") - feed_command("hi Substitute guifg=red guibg=yellow") + command("syntax on") + command("set nohlsearch") + command("hi Substitute guifg=red guibg=yellow") screen:attach() screen:set_default_attr_ids({ [1] = {foreground = Screen.colors.Fuchsia}, @@ -46,7 +47,7 @@ local function common_setup(screen, inccommand, text) }) end - feed_command("set inccommand=" .. (inccommand and inccommand or "")) + command("set inccommand=" .. (inccommand and inccommand or "")) if text then insert(text) @@ -456,7 +457,7 @@ describe(":substitute, 'inccommand' preserves undo", function() insert("X") feed("IY<esc>") feed(":%s/tw/MO/<esc>") - -- execute("undo") here would cause "Press ENTER". + -- feed_command("undo") here would cause "Press ENTER". feed("u") expect(default_text:gsub("Inc", "XInc")) feed("u") @@ -514,7 +515,7 @@ describe(":substitute, 'inccommand' preserves undo", function() feed("Ay<esc>") feed("Az<esc>") feed(":%s/tw/AR<esc>") - -- using execute("undo") here will result in a "Press ENTER" prompt + -- feed_command("undo") here would cause "Press ENTER". feed("u") expect(default_text:gsub("lines", "linesxy")) feed("u") @@ -603,7 +604,7 @@ describe(":substitute, 'inccommand' preserves undo", function() feed_command("set undolevels=-1") feed(":%s/tw/MO/g<enter>") - -- using execute("undo") here will result in a "Press ENTER" prompt + -- feed_command("undo") here will result in a "Press ENTER" prompt feed("u") if case == "split" then screen:expect([[ @@ -804,7 +805,6 @@ describe(":substitute, inccommand=split", function() it('does not show split window for :s/', function() feed("2gg") feed(":s/tw") - wait() screen:expect([[ Inc substitution on | two lines | @@ -1291,14 +1291,14 @@ describe("'inccommand' and :cnoremap", function() it('work with remapped characters', function() for _, case in pairs(cases) do refresh(case) - local command = "%s/lines/LINES/g" + local cmd = "%s/lines/LINES/g" - for i = 1, string.len(command) do - local c = string.sub(command, i, i) + for i = 1, string.len(cmd) do + local c = string.sub(cmd, i, i) feed_command("cnoremap ".. c .. " " .. c) end - feed_command(command) + feed_command(cmd) expect([[ Inc substitution on two LINES diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua index 2f2cc85dab..afbcd222c7 100644 --- a/test/functional/ui/screen.lua +++ b/test/functional/ui/screen.lua @@ -284,18 +284,13 @@ function Screen:wait(check, timeout) if failure_after_success then print([[ -Warning: Screen changes have been received after the expected state was seen. -This is probably due to an indeterminism in the test. Try adding -`wait()` (or even a separate `screen:expect(...)`) at a point of possible -indeterminism, typically in between a `feed()` or `execute()` which is non- -synchronous, and a synchronous api call. - -Note that sometimes a `wait` can trigger redraws and consequently generate more -indeterminism. If adding `wait` calls seems to increase the frequency of these -messages, try removing every `wait` call in the test. - -If everything else fails, use Screen:redraw_debug to help investigate what is - causing the problem. + +Warning: Screen changes were received after the expected state. This indicates +indeterminism in the test. Try adding wait() (or screen:expect(...)) between +asynchronous (feed(), nvim_input()) and synchronous API calls. + - Use Screen:redraw_debug() to investigate the problem. + - wait() can trigger redraws and consequently generate more indeterminism. + In that case try removing every wait(). ]]) local tb = debug.traceback() local index = string.find(tb, '\n%s*%[C]') |