diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 21:52:58 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 21:52:58 +0000 |
commit | 931bffbda3668ddc609fc1da8f9eb576b170aa52 (patch) | |
tree | d8c1843a95da5ea0bb4acc09f7e37843d9995c86 /test/functional/ex_cmds/swapfile_preserve_recover_spec.lua | |
parent | 142d9041391780ac15b89886a54015fdc5c73995 (diff) | |
parent | 4a8bf24ac690004aedf5540fa440e788459e5e34 (diff) | |
download | rneovim-userreg.tar.gz rneovim-userreg.tar.bz2 rneovim-userreg.zip |
Merge remote-tracking branch 'upstream/master' into userreguserreg
Diffstat (limited to 'test/functional/ex_cmds/swapfile_preserve_recover_spec.lua')
-rw-r--r-- | test/functional/ex_cmds/swapfile_preserve_recover_spec.lua | 235 |
1 files changed, 199 insertions, 36 deletions
diff --git a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua index 8eed00c973..436873b464 100644 --- a/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua +++ b/test/functional/ex_cmds/swapfile_preserve_recover_spec.lua @@ -1,6 +1,5 @@ local Screen = require('test.functional.ui.screen') local helpers = require('test.functional.helpers')(after_each) -local lfs = require('lfs') local luv = require('luv') local eq, eval, expect, exec = helpers.eq, helpers.eval, helpers.expect, helpers.exec @@ -13,13 +12,19 @@ local nvim_prog = helpers.nvim_prog local ok = helpers.ok local rmdir = helpers.rmdir local new_argv = helpers.new_argv +local new_pipename = helpers.new_pipename local pesc = helpers.pesc local os_kill = helpers.os_kill local set_session = helpers.set_session local spawn = helpers.spawn -local nvim_async = helpers.nvim_async +local async_meths = helpers.async_meths local expect_msg_seq = helpers.expect_msg_seq local pcall_err = helpers.pcall_err +local mkdir = helpers.mkdir +local poke_eventloop = helpers.poke_eventloop +local meths = helpers.meths +local retry = helpers.retry +local write_file = helpers.write_file describe(':recover', function() before_each(clear) @@ -37,40 +42,40 @@ describe(':recover', function() end) -describe(':preserve', function() - local swapdir = lfs.currentdir()..'/Xtest_recover_dir' +describe("preserve and (R)ecover with custom 'directory'", function() + local swapdir = luv.cwd()..'/Xtest_recover_dir' + local testfile = 'Xtest_recover_file1' + -- 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:gsub([[\]], [[\\]])..[[// + set swapfile fileformat=unix undolevels=-1 + ]] + + local nvim0 before_each(function() - clear() + nvim0 = spawn(new_argv()) + set_session(nvim0) rmdir(swapdir) - lfs.mkdir(swapdir) + mkdir(swapdir) end) after_each(function() command('%bwipeout!') rmdir(swapdir) end) - it("saves to custom 'directory' and (R)ecovers #1836", function() - local testfile = 'Xtest_recover_file1' - -- 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:gsub([[\]], [[\\]])..[[// - set swapfile fileformat=unix undolevels=-1 - ]] - + local function setup_swapname() exec(init) command('edit! '..testfile) feed('isometext<esc>') - command('preserve') exec('redir => g:swapname | silent swapname | redir END') + return eval('g:swapname') + end - local swappath1 = eval('g:swapname') - - os_kill(eval('getpid()')) + local function test_recover(swappath1) -- Start another Nvim instance. - local nvim2 = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed'}, - true) + local nvim2 = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--embed'}, true) set_session(nvim2) exec(init) @@ -90,12 +95,41 @@ describe(':preserve', function() -- Verify that :swapname was not truncated (:help 'shortmess'). ok(nil == string.find(swappath1, '%.%.%.')) ok(nil == string.find(swappath2, '%.%.%.')) + end + + it('with :preserve and SIGKILL', function() + local swappath1 = setup_swapname() + command('preserve') + os_kill(eval('getpid()')) + test_recover(swappath1) + end) + + it('closing stdio channel without :preserve #22096', function() + local swappath1 = setup_swapname() + nvim0:close() + test_recover(swappath1) + end) + + it('killing TUI process without :preserve #22096', function() + helpers.skip(helpers.is_os('win')) + local screen0 = Screen.new() + screen0:attach() + local child_server = new_pipename() + funcs.termopen({nvim_prog, '-u', 'NONE', '-i', 'NONE', '--listen', child_server}) + screen0:expect({any = pesc('[No Name]')}) -- Wait for the child process to start. + local child_session = helpers.connect(child_server) + set_session(child_session) + local swappath1 = setup_swapname() + set_session(nvim0) + command('call chanclose(&channel)') -- Kill the child process. + screen0:expect({any = pesc('[Process exited 1]')}) -- Wait for the child process to stop. + test_recover(swappath1) end) end) describe('swapfile detection', function() - local swapdir = lfs.currentdir()..'/Xtest_swapdialog_dir' + local swapdir = luv.cwd()..'/Xtest_swapdialog_dir' local nvim0 -- Put swapdir at the start of the 'directory' list. #1836 -- Note: `set swapfile` *must* go after `set directory`: otherwise it may @@ -108,7 +142,7 @@ describe('swapfile detection', function() nvim0 = spawn(new_argv()) set_session(nvim0) rmdir(swapdir) - lfs.mkdir(swapdir) + mkdir(swapdir) end) after_each(function() set_session(nvim0) @@ -137,6 +171,7 @@ describe('swapfile detection', function() local screen2 = Screen.new(256, 40) screen2:attach() exec(init) + command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). -- With shortmess+=F command('set shortmess+=F') @@ -160,7 +195,7 @@ describe('swapfile detection', function() feed('e') -- Chose "Edit" at the swap dialog. screen2:expect(expected_no_dialog) - -- With API (via eval/VimL) call and shortmess+=F + -- With API (via eval/Vimscript) call and shortmess+=F feed(':call nvim_command("edit %")<CR>') screen2:expect{any=[[Found a swap file by the name ".*]] ..[[Xtest_swapdialog_dir[/\].*]]..testfile..[[%.swp"]]} @@ -169,7 +204,7 @@ describe('swapfile detection', function() screen2:expect(expected_no_dialog) -- With API call and shortmess+=F - nvim_async('command', 'edit %') + async_meths.command('edit %') screen2:expect{any=[[Found a swap file by the name ".*]] ..[[Xtest_swapdialog_dir[/\].*]]..testfile..[[%.swp"]]} feed('e') -- Chose "Edit" at the swap dialog. @@ -185,11 +220,29 @@ describe('swapfile detection', function() nvim2:close() end) + it('default SwapExists handler selects "(E)dit" and skips prompt', function() + exec(init) + command('edit Xfile1') + command("put ='some text...'") + command('preserve') -- Make sure the swap file exists. + local nvimpid = funcs.getpid() + + local nvim1 = spawn(new_argv(), true, nil, true) + set_session(nvim1) + local screen = Screen.new(75, 18) + screen:attach() + exec(init) + feed(':edit Xfile1\n') + + screen:expect({ any = ('W325: Ignoring swapfile from Nvim process %d'):format(nvimpid) }) + nvim1:close() + end) + -- oldtest: Test_swap_prompt_splitwin() it('selecting "q" in the attention prompt', function() exec(init) command('edit Xfile1') - command('preserve') -- should help to make sure the swap file exists + command('preserve') -- Make sure the swap file exists. local screen = Screen.new(75, 18) screen:set_default_attr_ids({ @@ -201,7 +254,9 @@ describe('swapfile detection', function() set_session(nvim1) screen:attach() exec(init) + command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). feed(':split Xfile1\n') + -- The default SwapExists handler does _not_ skip this prompt. screen:expect({ any = pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: }^') }) @@ -233,6 +288,7 @@ describe('swapfile detection', function() set_session(nvim2) screen:attach() exec(init) + command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). command('set more') command('au bufadd * let foo_w = wincol()') feed(':e Xfile1<CR>') @@ -266,8 +322,9 @@ describe('swapfile detection', function() nvim2:close() end) - -- oldtest: Test_nocatch_process_still_running() - it('allows deleting swapfile created before boot vim-patch:8.2.2586', function() + --- @param swapexists boolean Enable the default SwapExists handler. + --- @param on_swapfile_running fun(screen: any) Called after swapfile ("STILL RUNNING") prompt. + local function test_swapfile_after_reboot(swapexists, on_swapfile_running) local screen = Screen.new(75, 30) screen:set_default_attr_ids({ [0] = {bold = true, foreground = Screen.colors.Blue}, -- NonText @@ -277,6 +334,9 @@ describe('swapfile detection', function() screen:attach() exec(init) + if not swapexists then + command('autocmd! nvim_swapfile') -- Delete the default handler (which skips the dialog). + end command('set nohidden') exec([=[ @@ -313,12 +373,7 @@ describe('swapfile detection', function() os.rename('Xswap', swname) feed(':edit Xswaptest<CR>') - screen:expect({any = table.concat({ - pesc('{2:E325: ATTENTION}'), - 'file name: .*Xswaptest', - 'process ID: %d* %(STILL RUNNING%)', - pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: }^'), - }, '.*')}) + on_swapfile_running(screen) feed('e') @@ -330,7 +385,8 @@ describe('swapfile detection', function() ]]) -- pretend that the swapfile was created before boot - lfs.touch(swname, os.time() - luv.uptime() - 10) + local atime = os.time() - luv.uptime() - 10 + luv.fs_utime(swname, atime, atime) feed(':edit Xswaptest<CR>') screen:expect({any = table.concat({ @@ -339,5 +395,112 @@ describe('swapfile detection', function() }, '.*')}) feed('e') + end + + -- oldtest: Test_nocatch_process_still_running() + it('swapfile created before boot vim-patch:8.2.2586', function() + test_swapfile_after_reboot(false, function(screen) + screen:expect({any = table.concat({ + pesc('{2:E325: ATTENTION}'), + 'file name: .*Xswaptest', + 'process ID: %d* %(STILL RUNNING%)', + pesc('{1:[O]pen Read-Only, (E)dit anyway, (R)ecover, (Q)uit, (A)bort: }^'), + }, '.*')}) + end) + end) + + it('swapfile created before boot + default SwapExists handler', function() + test_swapfile_after_reboot(true, function(screen) + screen:expect({ any = 'W325: Ignoring swapfile from Nvim process' }) + end) + end) + +end) + +describe('quitting swapfile dialog on startup stops TUI properly', function() + local swapdir = luv.cwd()..'/Xtest_swapquit_dir' + local testfile = 'Xtest_swapquit_file1' + local otherfile = 'Xtest_swapquit_file2' + -- 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_dir = [[set directory^=]]..swapdir:gsub([[\]], [[\\]])..[[//]] + local init_set = [[set swapfile fileformat=unix nomodified undolevels=-1 nohidden]] + + before_each(function() + clear({args = {'--cmd', init_dir, '--cmd', init_set}}) + rmdir(swapdir) + mkdir(swapdir) + write_file(testfile, [[ + first + second + third + + ]]) + command('edit! '..testfile) + feed('Gisometext<esc>') + poke_eventloop() + clear() -- Leaves a swap file behind + meths.ui_attach(80, 30, {}) + end) + after_each(function() + rmdir(swapdir) + os.remove(testfile) + os.remove(otherfile) + end) + + it('(Q)uit at first file argument', function() + local chan = funcs.termopen({nvim_prog, '-u', 'NONE', '-i', 'NONE', + '--cmd', init_dir, '--cmd', init_set, + testfile}) + retry(nil, nil, function() + eq('[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:', + eval("getline('$')->trim(' ', 2)")) + end) + meths.chan_send(chan, 'q') + retry(nil, nil, function() + eq({'', '[Process exited 1]', ''}, + eval("[1, 2, '$']->map({_, lnum -> getline(lnum)->trim(' ', 2)})")) + end) + end) + + it('(A)bort at second file argument with -p', function() + local chan = funcs.termopen({nvim_prog, '-u', 'NONE', '-i', 'NONE', + '--cmd', init_dir, '--cmd', init_set, + '-p', otherfile, testfile}) + retry(nil, nil, function() + eq('[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:', + eval("getline('$')->trim(' ', 2)")) + end) + meths.chan_send(chan, 'a') + retry(nil, nil, function() + eq({'', '[Process exited 1]', ''}, + eval("[1, 2, '$']->map({_, lnum -> getline(lnum)->trim(' ', 2)})")) + end) + end) + + it('(Q)uit at file opened by -t', function() + write_file(otherfile, ([[ + !_TAG_FILE_ENCODING utf-8 // + first %s /^ \zsfirst$/ + second %s /^ \zssecond$/ + third %s /^ \zsthird$/]]):format(testfile, testfile, testfile)) + local chan = funcs.termopen({nvim_prog, '-u', 'NONE', '-i', 'NONE', + '--cmd', init_dir, '--cmd', init_set, + '--cmd', 'set tags='..otherfile, '-tsecond'}) + retry(nil, nil, function() + eq('[O]pen Read-Only, (E)dit anyway, (R)ecover, (D)elete it, (Q)uit, (A)bort:', + eval("getline('$')->trim(' ', 2)")) + end) + meths.chan_send(chan, 'q') + retry(nil, nil, function() + eq('Press ENTER or type command to continue', + eval("getline('$')->trim(' ', 2)")) + end) + meths.chan_send(chan, '\r') + retry(nil, nil, function() + eq({'', '[Process exited 1]', ''}, + eval("[1, 2, '$']->map({_, lnum -> getline(lnum)->trim(' ', 2)})")) + end) end) end) |