diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/functional/autocmd/termclose_spec.lua | 6 | ||||
-rw-r--r-- | test/functional/core/job_spec.lua | 168 | ||||
-rw-r--r-- | test/functional/eval/system_spec.lua | 8 | ||||
-rw-r--r-- | test/functional/helpers.lua | 2 | ||||
-rw-r--r-- | test/functional/options/defaults_spec.lua | 276 | ||||
-rw-r--r-- | test/functional/terminal/mouse_spec.lua | 16 | ||||
-rw-r--r-- | test/functional/terminal/tui_spec.lua | 10 | ||||
-rw-r--r-- | test/functional/ui/screen_basic_spec.lua | 16 |
8 files changed, 412 insertions, 90 deletions
diff --git a/test/functional/autocmd/termclose_spec.lua b/test/functional/autocmd/termclose_spec.lua index 0804579a4f..db4e5379d0 100644 --- a/test/functional/autocmd/termclose_spec.lua +++ b/test/functional/autocmd/termclose_spec.lua @@ -32,7 +32,7 @@ describe('TermClose event', function() end) it('kills job trapping SIGTERM', function() - if helpers.pending_win32(pending) then return end + if iswin() then return end nvim('set_option', 'shell', 'sh') nvim('set_option', 'shellcmdflag', '-c') command([[ let g:test_job = jobstart('trap "" TERM && echo 1 && sleep 60', { ]] @@ -51,8 +51,8 @@ describe('TermClose event', function() ok(duration <= 4000) -- Epsilon for slow CI end) - it('kills pty job trapping SIGHUP and SIGTERM', function() - if helpers.pending_win32(pending) then return end + it('kills PTY job trapping SIGHUP and SIGTERM', function() + if iswin() then return end nvim('set_option', 'shell', 'sh') nvim('set_option', 'shellcmdflag', '-c') command([[ let g:test_job = jobstart('trap "" HUP TERM && echo 1 && sleep 60', { ]] diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua index 24bff423df..e90339b0cd 100644 --- a/test/functional/core/job_spec.lua +++ b/test/functional/core/job_spec.lua @@ -19,14 +19,18 @@ local expect_twostreams = helpers.expect_twostreams local expect_msg_seq = helpers.expect_msg_seq local Screen = require('test.functional.ui.screen') +-- Kill process with given pid +local function os_kill(pid) + return os.execute((iswin() + and 'taskkill /f /t /pid '..pid..' > nul' + or 'kill -9 '..pid..' > /dev/null')) +end + describe('jobs', function() local channel before_each(function() clear() - if iswin() then - helpers.set_shell_powershell() - end channel = nvim('get_api_info')[1] nvim('set_var', 'channel', channel) source([[ @@ -52,7 +56,7 @@ describe('jobs', function() it('uses &shell and &shellcmdflag if passed a string', function() nvim('command', "let $VAR = 'abc'") if iswin() then - nvim('command', "let j = jobstart('echo $env:VAR', g:job_opts)") + nvim('command', "let j = jobstart('echo %VAR%', g:job_opts)") else nvim('command', "let j = jobstart('echo $VAR', g:job_opts)") end @@ -64,7 +68,7 @@ describe('jobs', function() it('changes to given / directory', function() nvim('command', "let g:job_opts.cwd = '/'") if iswin() then - nvim('command', "let j = jobstart('(Get-Location).Path', g:job_opts)") + nvim('command', "let j = jobstart('cd', g:job_opts)") else nvim('command', "let j = jobstart('pwd', g:job_opts)") end @@ -79,7 +83,7 @@ describe('jobs', function() mkdir(dir) nvim('command', "let g:job_opts.cwd = '" .. dir .. "'") if iswin() then - nvim('command', "let j = jobstart('(Get-Location).Path', g:job_opts)") + nvim('command', "let j = jobstart('cd', g:job_opts)") else nvim('command', "let j = jobstart('pwd', g:job_opts)") end @@ -103,7 +107,7 @@ describe('jobs', function() local _, err = pcall(function() nvim('command', "let g:job_opts.cwd = '" .. dir .. "'") if iswin() then - nvim('command', "let j = jobstart('pwd|%{$_.Path}', g:job_opts)") + nvim('command', "let j = jobstart('cd', g:job_opts)") else nvim('command', "let j = jobstart('pwd', g:job_opts)") end @@ -134,10 +138,8 @@ describe('jobs', function() end) it('invokes callbacks when the job writes and exits', function() - -- TODO: hangs on Windows - if helpers.pending_win32(pending) then return end nvim('command', "let g:job_opts.on_stderr = function('OnEvent')") - nvim('command', [[call jobstart('echo ""', g:job_opts)]]) + nvim('command', [[call jobstart(has('win32') ? 'echo:' : 'echo', g:job_opts)]]) expect_twostreams({{'notification', 'stdout', {0, {'', ''}}}, {'notification', 'stdout', {0, {''}}}}, {{'notification', 'stderr', {0, {''}}}}) @@ -145,15 +147,28 @@ describe('jobs', function() end) it('allows interactive commands', function() - if helpers.pending_win32(pending) then return end -- TODO: Need `cat`. - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") + nvim('command', "let j = jobstart(has('win32') ? ['find', '/v', ''] : ['cat', '-'], g:job_opts)") neq(0, eval('j')) nvim('command', 'call jobsend(j, "abc\\n")') eq({'notification', 'stdout', {0, {'abc', ''}}}, next_msg()) nvim('command', 'call jobsend(j, "123\\nxyz\\n")') - eq({'notification', 'stdout', {0, {'123', 'xyz', ''}}}, next_msg()) + expect_msg_seq( + { {'notification', 'stdout', {0, {'123', 'xyz', ''}}} + }, + -- Alternative sequence: + { {'notification', 'stdout', {0, {'123', ''}}}, + {'notification', 'stdout', {0, {'xyz', ''}}} + } + ) nvim('command', 'call jobsend(j, [123, "xyz", ""])') - eq({'notification', 'stdout', {0, {'123', 'xyz', ''}}}, next_msg()) + expect_msg_seq( + { {'notification', 'stdout', {0, {'123', 'xyz', ''}}} + }, + -- Alternative sequence: + { {'notification', 'stdout', {0, {'123', ''}}}, + {'notification', 'stdout', {0, {'xyz', ''}}} + } + ) nvim('command', "call jobstop(j)") eq({'notification', 'stdout', {0, {''}}}, next_msg()) eq({'notification', 'exit', {0, 0}}, next_msg()) @@ -226,16 +241,14 @@ describe('jobs', function() end) it('closes the job streams with jobclose', function() - if helpers.pending_win32(pending) then return end -- TODO: Need `cat`. - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") + nvim('command', "let j = jobstart(has('win32') ? ['find', '/v', ''] : ['cat', '-'], g:job_opts)") nvim('command', 'call jobclose(j, "stdin")') eq({'notification', 'stdout', {0, {''}}}, next_msg()) - eq({'notification', 'exit', {0, 0}}, next_msg()) + eq({'notification', 'exit', {0, iswin() and 1 or 0}}, next_msg()) end) it("disallows jobsend on a job that closed stdin", function() - if helpers.pending_win32(pending) then return end -- TODO: Need `cat`. - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") + nvim('command', "let j = jobstart(has('win32') ? ['find', '/v', ''] : ['cat', '-'], g:job_opts)") nvim('command', 'call jobclose(j, "stdin")') eq(false, pcall(function() nvim('command', 'call jobsend(j, ["some data"])') @@ -248,8 +261,7 @@ describe('jobs', function() end) it('disallows jobstop twice on the same job', function() - if helpers.pending_win32(pending) then return end -- TODO: Need `cat`. - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") + nvim('command', "let j = jobstart(has('win32') ? ['find', '/v', ''] : ['cat', '-'], g:job_opts)") neq(0, eval('j')) eq(true, pcall(eval, "jobstop(j)")) eq(false, pcall(eval, "jobstop(j)")) @@ -260,41 +272,49 @@ describe('jobs', function() end) it('can get the pid value using getpid', function() - if helpers.pending_win32(pending) then return end -- TODO: Need `cat`. - nvim('command', "let j = jobstart(['cat', '-'], g:job_opts)") + nvim('command', "let j = jobstart(has('win32') ? ['find', '/v', ''] : ['cat', '-'], g:job_opts)") local pid = eval('jobpid(j)') - eq(0,os.execute('ps -p '..pid..' > /dev/null')) + neq(NIL, meths.get_proc(pid)) nvim('command', 'call jobstop(j)') eq({'notification', 'stdout', {0, {''}}}, next_msg()) - eq({'notification', 'exit', {0, 0}}, next_msg()) - neq(0,os.execute('ps -p '..pid..' > /dev/null')) + if iswin() then + expect_msg_seq( + -- win64 + { {'notification', 'exit', {0, 1}} + }, + -- win32 + { {'notification', 'exit', {0, 15}} + } + ) + else + eq({'notification', 'exit', {0, 0}}, next_msg()) + end + eq(NIL, meths.get_proc(pid)) end) it("do not survive the exit of nvim", function() - if helpers.pending_win32(pending) then return end -- use sleep, which doesn't die on stdin close - nvim('command', "let g:j = jobstart(['sleep', '1000'], g:job_opts)") + nvim('command', "let g:j = jobstart(has('win32') ? ['ping', '-n', '1001', '127.0.0.1'] : ['sleep', '1000'], g:job_opts)") local pid = eval('jobpid(g:j)') - eq(0,os.execute('ps -p '..pid..' > /dev/null')) + neq(NIL, meths.get_proc(pid)) clear() - neq(0,os.execute('ps -p '..pid..' > /dev/null')) + eq(NIL, meths.get_proc(pid)) end) it('can survive the exit of nvim with "detach"', function() - if helpers.pending_win32(pending) then return end nvim('command', 'let g:job_opts.detach = 1') - nvim('command', "let g:j = jobstart(['sleep', '1000'], g:job_opts)") + nvim('command', "let g:j = jobstart(has('win32') ? ['ping', '-n', '1001', '127.0.0.1'] : ['sleep', '1000'], g:job_opts)") local pid = eval('jobpid(g:j)') - eq(0,os.execute('ps -p '..pid..' > /dev/null')) + neq(NIL, meths.get_proc(pid)) clear() - eq(0,os.execute('ps -p '..pid..' > /dev/null')) + neq(NIL, meths.get_proc(pid)) -- clean up after ourselves - os.execute('kill -9 '..pid..' > /dev/null') + eq(0, os_kill(pid)) end) it('can pass user data to the callback', function() nvim('command', 'let g:job_opts.user = {"n": 5, "s": "str", "l": [1]}') - nvim('command', [[call jobstart('echo "foo"', g:job_opts)]]) + nvim('command', [[call jobstart('echo foo', g:job_opts)]]) local data = {n = 5, s = 'str', l = {1}} expect_msg_seq( { {'notification', 'stdout', {data, {'foo', ''}}}, @@ -312,14 +332,14 @@ describe('jobs', function() it('can omit data callbacks', function() nvim('command', 'unlet g:job_opts.on_stdout') nvim('command', 'let g:job_opts.user = 5') - nvim('command', [[call jobstart('echo "foo"', g:job_opts)]]) + nvim('command', [[call jobstart('echo foo', g:job_opts)]]) eq({'notification', 'exit', {5, 0}}, next_msg()) end) it('can omit exit callback', function() nvim('command', 'unlet g:job_opts.on_exit') nvim('command', 'let g:job_opts.user = 5') - nvim('command', [[call jobstart('echo "foo"', g:job_opts)]]) + nvim('command', [[call jobstart('echo foo', g:job_opts)]]) expect_msg_seq( { {'notification', 'stdout', {5, {'foo', ''} } }, {'notification', 'stdout', {5, {''} } }, @@ -401,15 +421,14 @@ describe('jobs', function() end) it('does not repeat output with slow output handlers', function() - if helpers.pending_win32(pending) then return end source([[ let d = {'data': []} function! d.on_stdout(job, data, event) dict - call add(self.data, a:data) + call add(self.data, Normalize(a:data)) sleep 200m endfunction if has('win32') - let cmd = '1,2,3,4,5 | foreach-object -process {echo $_; sleep 0.1}' + let cmd = 'for /L %I in (1,1,5) do @(echo %I& ping -n 2 127.0.0.1 > nul)' else let cmd = ['sh', '-c', 'for i in $(seq 1 5); do echo $i; sleep 0.1; done'] endif @@ -428,7 +447,7 @@ describe('jobs', function() endfunction let Callback = function('PrintArgs', ["foo", "bar"]) let g:job_opts = {'on_stdout': Callback} - call jobstart('echo "some text"', g:job_opts) + call jobstart('echo some text', g:job_opts) ]]) expect_msg_seq( { {'notification', '1', {'foo', 'bar', {'some text', ''}, 'stdout'}}, @@ -448,7 +467,7 @@ describe('jobs', function() return {id, data, event -> rpcnotify(g:channel, '1', a1, a2, Normalize(data), event)} endfun let g:job_opts = {'on_stdout': MkFun()} - call jobstart('echo "some text"', g:job_opts) + call jobstart('echo some text', g:job_opts) ]]) expect_msg_seq( { {'notification', '1', {'foo', 'bar', {'some text', ''}, 'stdout'}}, @@ -463,7 +482,7 @@ describe('jobs', function() it('jobstart() works when closure passed directly to `jobstart`', function() source([[ let g:job_opts = {'on_stdout': {id, data, event -> rpcnotify(g:channel, '1', 'foo', 'bar', Normalize(data), event)}} - call jobstart('echo "some text"', g:job_opts) + call jobstart('echo some text', g:job_opts) ]]) expect_msg_seq( { {'notification', '1', {'foo', 'bar', {'some text', ''}, 'stdout'}}, @@ -476,9 +495,20 @@ describe('jobs', function() end) describe('jobwait', function() + before_each(function() + if iswin() then + helpers.set_shell_powershell() + end + end) + it('returns a list of status codes', function() source([[ - call rpcnotify(g:channel, 'wait', jobwait([ + call rpcnotify(g:channel, 'wait', jobwait(has('win32') ? [ + \ jobstart('Start-Sleep -Milliseconds 100; exit 4'), + \ jobstart('Start-Sleep -Milliseconds 300; exit 5'), + \ jobstart('Start-Sleep -Milliseconds 500; exit 6'), + \ jobstart('Start-Sleep -Milliseconds 700; exit 7') + \ ] : [ \ jobstart('sleep 0.10; exit 4'), \ jobstart('sleep 0.110; exit 5'), \ jobstart('sleep 0.210; exit 6'), @@ -498,7 +528,12 @@ describe('jobs', function() endif let g:exits += 1 endfunction - call jobwait([ + call jobwait(has('win32') ? [ + \ jobstart('Start-Sleep -Milliseconds 100; exit 5', g:dict), + \ jobstart('Start-Sleep -Milliseconds 300; exit 5', g:dict), + \ jobstart('Start-Sleep -Milliseconds 500; exit 5', g:dict), + \ jobstart('Start-Sleep -Milliseconds 700; exit 5', g:dict) + \ ] : [ \ jobstart('sleep 0.010; exit 5', g:dict), \ jobstart('sleep 0.030; exit 5', g:dict), \ jobstart('sleep 0.050; exit 5', g:dict), @@ -511,7 +546,12 @@ describe('jobs', function() it('will return status codes in the order of passed ids', function() source([[ - call rpcnotify(g:channel, 'wait', jobwait([ + call rpcnotify(g:channel, 'wait', jobwait(has('win32') ? [ + \ jobstart('Start-Sleep -Milliseconds 700; exit 4'), + \ jobstart('Start-Sleep -Milliseconds 500; exit 5'), + \ jobstart('Start-Sleep -Milliseconds 300; exit 6'), + \ jobstart('Start-Sleep -Milliseconds 100; exit 7') + \ ] : [ \ jobstart('sleep 0.070; exit 4'), \ jobstart('sleep 0.050; exit 5'), \ jobstart('sleep 0.030; exit 6'), @@ -525,7 +565,7 @@ describe('jobs', function() source([[ call rpcnotify(g:channel, 'wait', jobwait([ \ -10, - \ jobstart('sleep 0.01; exit 5'), + \ jobstart((has('win32') ? 'Start-Sleep -Milliseconds 100' : 'sleep 0.01').'; exit 5'), \ ])) ]]) eq({'notification', 'wait', {{-3, 5}}}, next_msg()) @@ -534,7 +574,9 @@ describe('jobs', function() it('will return -2 when interrupted without timeout', function() feed_command('call rpcnotify(g:channel, "ready") | '.. 'call rpcnotify(g:channel, "wait", '.. - 'jobwait([jobstart("sleep 10; exit 55")]))') + 'jobwait([jobstart("'.. + (iswin() and 'Start-Sleep 10' or 'sleep 10').. + '; exit 55")]))') eq({'notification', 'ready', {}}, next_msg()) feed('<c-c>') eq({'notification', 'wait', {{-2}}}, next_msg()) @@ -543,7 +585,9 @@ describe('jobs', function() it('will return -2 when interrupted with timeout', function() feed_command('call rpcnotify(g:channel, "ready") | '.. 'call rpcnotify(g:channel, "wait", '.. - 'jobwait([jobstart("sleep 10; exit 55")], 10000))') + 'jobwait([jobstart("'.. + (iswin() and 'Start-Sleep 10' or 'sleep 10').. + '; exit 55")], 10000))') eq({'notification', 'ready', {}}, next_msg()) feed('<c-c>') eq({'notification', 'wait', {{-2}}}, next_msg()) @@ -598,20 +642,22 @@ describe('jobs', function() end) describe('with timeout argument', function() - if helpers.pending_win32(pending) then return end it('will return -1 if the wait timed out', function() source([[ call rpcnotify(g:channel, 'wait', jobwait([ \ jobstart('exit 4'), - \ jobstart('sleep 10; exit 5'), - \ ], 100)) + \ jobstart((has('win32') ? 'Start-Sleep 10' : 'sleep 10').'; exit 5'), + \ ], has('win32') ? 3000 : 100)) ]]) eq({'notification', 'wait', {{4, -1}}}, next_msg()) end) it('can pass 0 to check if a job exists', function() source([[ - call rpcnotify(g:channel, 'wait', jobwait([ + call rpcnotify(g:channel, 'wait', jobwait(has('win32') ? [ + \ jobstart('Start-Sleep -Milliseconds 50; exit 4'), + \ jobstart('Start-Sleep -Milliseconds 300; exit 5'), + \ ] : [ \ jobstart('sleep 0.05; exit 4'), \ jobstart('sleep 0.3; exit 5'), \ ], 0)) @@ -633,10 +679,9 @@ describe('jobs', function() end) it('cannot have both rpc and pty options', function() - if helpers.pending_win32(pending) then return end -- TODO: Need `cat`. command("let g:job_opts.pty = v:true") command("let g:job_opts.rpc = v:true") - local _, err = pcall(command, "let j = jobstart(['cat', '-'], g:job_opts)") + local _, err = pcall(command, "let j = jobstart(has('win32') ? ['find', '/v', ''] : ['cat', '-'], g:job_opts)") ok(string.find(err, "E475: Invalid argument: job cannot have both 'pty' and 'rpc' options set") ~= nil) end) @@ -656,19 +701,16 @@ describe('jobs', function() end) it('jobstop() kills entire process tree #6530', function() - command('set shell& shellcmdflag& shellquote& shellpipe& shellredir& shellxquote&') - -- XXX: Using `nvim` isn't a good test, it reaps its children on exit. -- local c = 'call jobstart([v:progpath, "-u", "NONE", "-i", "NONE", "--headless"])' -- local j = eval("jobstart([v:progpath, '-u', 'NONE', '-i', 'NONE', '--headless', '-c', '" -- ..c.."', '-c', '"..c.."'])") -- Create child with several descendants. - local j = (iswin() - and eval([=[jobstart('start /b cmd /c "ping 127.0.0.1 -n 1 -w 30000 > NUL"]=] - ..[=[ & start /b cmd /c "ping 127.0.0.1 -n 1 -w 40000 > NUL"]=] - ..[=[ & start /b cmd /c "ping 127.0.0.1 -n 1 -w 50000 > NUL"')]=]) - or eval("jobstart('sleep 30 | sleep 30 | sleep 30')")) + local sleep_cmd = (iswin() + and 'ping -n 31 127.0.0.1' + or 'sleep 30') + local j = eval("jobstart('"..sleep_cmd..' | '..sleep_cmd..' | '..sleep_cmd.."')") local ppid = funcs.jobpid(j) local children retry(nil, nil, function() diff --git a/test/functional/eval/system_spec.lua b/test/functional/eval/system_spec.lua index 201426c40b..23cea4c038 100644 --- a/test/functional/eval/system_spec.lua +++ b/test/functional/eval/system_spec.lua @@ -255,10 +255,8 @@ describe('system()', function() end end) it('to backgrounded command does not crash', function() - -- cmd.exe doesn't background a command with & - if iswin() then return end -- This is indeterminate, just exercise the codepath. May get E5677. - feed_command('call system("echo -n echoed &")') + feed_command('call system(has("win32") ? "start /b /wait cmd /c echo echoed" : "echo -n echoed &")') local v_errnum = string.match(eval("v:errmsg"), "^E%d*:") if v_errnum then eq("E5677:", v_errnum) @@ -272,10 +270,8 @@ describe('system()', function() eq("input", eval('system("cat -", "input")')) end) it('to backgrounded command does not crash', function() - -- cmd.exe doesn't background a command with & - if iswin() then return end -- This is indeterminate, just exercise the codepath. May get E5677. - feed_command('call system("cat - &", "input")') + feed_command('call system(has("win32") ? "start /b /wait more" : "cat - &", "input")') local v_errnum = string.match(eval("v:errmsg"), "^E%d*:") if v_errnum then eq("E5677:", v_errnum) diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index bf11042dd6..03c6f3bbaa 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -427,7 +427,7 @@ end local function set_shell_powershell() source([[ set shell=powershell shellquote=( shellpipe=\| shellredir=> shellxquote= - set shellcmdflag=-NoLogo\ -NoProfile\ -ExecutionPolicy\ RemoteSigned\ -Command + let &shellcmdflag = '-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command Remove-Item -Force alias:sleep;' ]]) end diff --git a/test/functional/options/defaults_spec.lua b/test/functional/options/defaults_spec.lua index 9e29baba2d..f452cafd22 100644 --- a/test/functional/options/defaults_spec.lua +++ b/test/functional/options/defaults_spec.lua @@ -5,12 +5,15 @@ local Screen = require('test.functional.ui.screen') local meths = helpers.meths local command = helpers.command local clear = helpers.clear +local exc_exec = helpers.exc_exec local eval = helpers.eval local eq = helpers.eq +local funcs = helpers.funcs local insert = helpers.insert local neq = helpers.neq local mkdir = helpers.mkdir local rmdir = helpers.rmdir +local alter_slashes = helpers.alter_slashes describe('startup defaults', function() describe(':filetype', function() @@ -422,3 +425,276 @@ describe('XDG-based defaults', function() end) end) end) + + +describe('stdpath()', function() + context('returns a String', function() + describe('with "config"' , function () + it('knows XDG_CONFIG_HOME', function() + clear({env={ + XDG_CONFIG_HOME=alter_slashes('/home/docwhat/.config'), + }}) + eq(alter_slashes('/home/docwhat/.config/nvim'), funcs.stdpath('config')) + end) + + it('handles changes during runtime', function() + clear({env={ + XDG_CONFIG_HOME=alter_slashes('/home/original'), + }}) + eq(alter_slashes('/home/original/nvim'), funcs.stdpath('config')) + command("let $XDG_CONFIG_HOME='"..alter_slashes('/home/new').."'") + eq(alter_slashes('/home/new/nvim'), funcs.stdpath('config')) + end) + + it("doesn't expand $VARIABLES", function() + clear({env={ + XDG_CONFIG_HOME='$VARIABLES', + VARIABLES='this-should-not-happen', + }}) + eq(alter_slashes('$VARIABLES/nvim'), funcs.stdpath('config')) + end) + + it("doesn't expand ~/", function() + clear({env={ + XDG_CONFIG_HOME=alter_slashes('~/frobnitz'), + }}) + eq(alter_slashes('~/frobnitz/nvim'), funcs.stdpath('config')) + end) + end) + + describe('with "data"' , function () + local appended_dir + setup(function() + -- Windows appends 'nvim-data' instead of just 'nvim' to + -- prevent collisions due to XDG_CONFIG_HOME and XDG_DATA_HOME + -- being the same. + if helpers.iswin() then + appended_dir = '/nvim-data' + else + appended_dir = '/nvim' + end + end) + + it('knows XDG_DATA_HOME', function() + clear({env={ + XDG_DATA_HOME=alter_slashes('/home/docwhat/.local'), + }}) + eq(alter_slashes('/home/docwhat/.local' .. appended_dir), funcs.stdpath('data')) + end) + + it('handles changes during runtime', function() + clear({env={ + XDG_DATA_HOME=alter_slashes('/home/original'), + }}) + eq(alter_slashes('/home/original' .. appended_dir), funcs.stdpath('data')) + command("let $XDG_DATA_HOME='"..alter_slashes('/home/new').."'") + eq(alter_slashes('/home/new' .. appended_dir), funcs.stdpath('data')) + end) + + it("doesn't expand $VARIABLES", function() + clear({env={ + XDG_DATA_HOME='$VARIABLES', + VARIABLES='this-should-not-happen', + }}) + eq(alter_slashes('$VARIABLES' .. appended_dir), funcs.stdpath('data')) + end) + + it("doesn't expand ~/", function() + clear({env={ + XDG_DATA_HOME=alter_slashes('~/frobnitz'), + }}) + eq(alter_slashes('~/frobnitz' .. appended_dir), funcs.stdpath('data')) + end) + end) + + describe('with "cache"' , function () + it('knows XDG_CACHE_HOME', function() + clear({env={ + XDG_CACHE_HOME=alter_slashes('/home/docwhat/.cache'), + }}) + eq(alter_slashes('/home/docwhat/.cache/nvim'), funcs.stdpath('cache')) + end) + + it('handles changes during runtime', function() + clear({env={ + XDG_CACHE_HOME=alter_slashes('/home/original'), + }}) + eq(alter_slashes('/home/original/nvim'), funcs.stdpath('cache')) + command("let $XDG_CACHE_HOME='"..alter_slashes('/home/new').."'") + eq(alter_slashes('/home/new/nvim'), funcs.stdpath('cache')) + end) + + it("doesn't expand $VARIABLES", function() + clear({env={ + XDG_CACHE_HOME='$VARIABLES', + VARIABLES='this-should-not-happen', + }}) + eq(alter_slashes('$VARIABLES/nvim'), funcs.stdpath('cache')) + end) + + it("doesn't expand ~/", function() + clear({env={ + XDG_CACHE_HOME=alter_slashes('~/frobnitz'), + }}) + eq(alter_slashes('~/frobnitz/nvim'), funcs.stdpath('cache')) + end) + end) + end) + + context('returns a List', function() + -- Some OS specific variables the system would have set. + local function base_env() + if helpers.iswin() then + return { + HOME='C:\\Users\\docwhat', -- technically, is not a usual PATH + HOMEDRIVE='C:', + HOMEPATH='\\Users\\docwhat', + LOCALAPPDATA='C:\\Users\\docwhat\\AppData\\Local', + TEMP='C:\\Users\\docwhat\\AppData\\Local\\Temp', + TMPDIR='C:\\Users\\docwhat\\AppData\\Local\\Temp', + TMP='C:\\Users\\docwhat\\AppData\\Local\\Temp', + } + else + return { + HOME='/home/docwhat', + HOMEDRIVE='HOMEDRIVE-should-be-ignored', + HOMEPATH='HOMEPATH-should-be-ignored', + LOCALAPPDATA='LOCALAPPDATA-should-be-ignored', + TEMP='TEMP-should-be-ignored', + TMPDIR='TMPDIR-should-be-ignored', + TMP='TMP-should-be-ignored', + } + end + end + + local function set_paths_via_system(var_name, paths) + local env = base_env() + env[var_name] = table.concat(paths, ':') + clear({env=env}) + end + + local function set_paths_at_runtime(var_name, paths) + clear({env=base_env()}) + meths.set_var('env_val', table.concat(paths, ':')) + command(('let $%s=g:env_val'):format(var_name)) + end + + local function behaves_like_dir_list_env(msg, stdpath_arg, env_var_name, paths, expected_paths) + describe(msg, function() + it('set via system', function() + set_paths_via_system(env_var_name, paths) + eq(expected_paths, funcs.stdpath(stdpath_arg)) + end) + + it('set at runtime', function() + set_paths_at_runtime(env_var_name, paths) + eq(expected_paths, funcs.stdpath(stdpath_arg)) + end) + end) + end + + describe('with "config_dirs"' , function () + behaves_like_dir_list_env( + 'handles XDG_CONFIG_DIRS with one path', + 'config_dirs', 'XDG_CONFIG_DIRS', + { + alter_slashes('/home/docwhat/.config') + }, + { + alter_slashes('/home/docwhat/.config/nvim') + }) + + behaves_like_dir_list_env( + 'handles XDG_CONFIG_DIRS with two paths', + 'config_dirs', 'XDG_CONFIG_DIRS', + { + alter_slashes('/home/docwhat/.config'), + alter_slashes('/etc/config') + }, + { + alter_slashes('/home/docwhat/.config/nvim'), + alter_slashes('/etc/config/nvim') + }) + + behaves_like_dir_list_env( + "doesn't expand $VAR and $IBLES", + 'config_dirs', 'XDG_CONFIG_DIRS', + { '$HOME', '$TMP' }, + { + alter_slashes('$HOME/nvim'), + alter_slashes('$TMP/nvim') + }) + + + behaves_like_dir_list_env( + "doesn't expand ~/", + 'config_dirs', 'XDG_CONFIG_DIRS', + { + alter_slashes('~/.oldconfig'), + alter_slashes('~/.olderconfig') + }, + { + alter_slashes('~/.oldconfig/nvim'), + alter_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') + }, + { + alter_slashes('/home/docwhat/.data/nvim') + }) + + behaves_like_dir_list_env( + 'knows XDG_DATA_DIRS with two paths', + 'data_dirs', 'XDG_DATA_DIRS', + { + alter_slashes('/home/docwhat/.data'), + alter_slashes('/etc/local') + }, + { + alter_slashes('/home/docwhat/.data/nvim'), + alter_slashes('/etc/local/nvim'), + }) + + behaves_like_dir_list_env( + "doesn't expand $VAR and $IBLES", + 'data_dirs', 'XDG_DATA_DIRS', + { '$HOME', '$TMP' }, + { + alter_slashes('$HOME/nvim'), + alter_slashes('$TMP/nvim') + }) + + behaves_like_dir_list_env( + "doesn't expand ~/", + 'data_dirs', 'XDG_DATA_DIRS', + { + alter_slashes('~/.oldconfig'), + alter_slashes('~/.olderconfig') + }, + { + alter_slashes('~/.oldconfig/nvim'), + alter_slashes('~/.olderconfig/nvim'), + }) + end) + end) + + describe('errors', function() + it('on unknown strings', function() + eq('Vim(call):E6100: "capybara" is not a valid stdpath', exc_exec('call stdpath("capybara")')) + eq('Vim(call):E6100: "" is not a valid stdpath', exc_exec('call stdpath("")')) + eq('Vim(call):E6100: "23" is not a valid stdpath', exc_exec('call stdpath(23)')) + end) + + it('on non-strings', function() + eq('Vim(call):E731: using Dictionary as a String', exc_exec('call stdpath({"eris": 23})')) + eq('Vim(call):E730: using List as a String', exc_exec('call stdpath([23])')) + end) + end) +end) diff --git a/test/functional/terminal/mouse_spec.lua b/test/functional/terminal/mouse_spec.lua index a21d9f0a56..263a5ce79d 100644 --- a/test/functional/terminal/mouse_spec.lua +++ b/test/functional/terminal/mouse_spec.lua @@ -101,7 +101,7 @@ describe('terminal mouse', function() line28 │line28 | line29 │line29 | line30 │line30 | - rows: 5, cols: 24 │rows: 5, cols: 24 | + rows: 5, cols: 25 │rows: 5, cols: 25 | {2:^ } │{2: } | ========== ========== | :vsp | @@ -111,7 +111,7 @@ describe('terminal mouse', function() {7: 1 }^ │line28 | {4:~ }│line29 | {4:~ }│line30 | - {4:~ }│rows: 5, cols: 24 | + {4:~ }│rows: 5, cols: 25 | {4:~ }│{2: } | ========== ========== | :enew | set number | @@ -121,7 +121,7 @@ describe('terminal mouse', function() {7: 27 }line │line28 | {7: 28 }line │line29 | {7: 29 }line │line30 | - {7: 30 }line │rows: 5, cols: 24 | + {7: 30 }line │rows: 5, cols: 25 | {7: 31 }^ │{2: } | ========== ========== | | @@ -131,7 +131,7 @@ describe('terminal mouse', function() {7: 27 }line │line28 | {7: 28 }line │line29 | {7: 29 }line │line30 | - {7: 30 }line │rows: 5, cols: 24 | + {7: 30 }line │rows: 5, cols: 25 | {7: 31 } │{1: } | ========== ========== | {3:-- TERMINAL --} | @@ -142,7 +142,7 @@ describe('terminal mouse', function() screen:expect([[ {7: 27 }line │line29 | {7: 28 }line │line30 | - {7: 29 }line │rows: 5, cols: 24 | + {7: 29 }line │rows: 5, cols: 25 | {7: 30 }line │mouse enabled | {7: 31 } │{1: } | ========== ========== | @@ -155,7 +155,7 @@ describe('terminal mouse', function() screen:expect([[ {7: 21 }line │line29 | {7: 22 }line │line30 | - {7: 23 }line │rows: 5, cols: 24 | + {7: 23 }line │rows: 5, cols: 25 | {7: 24 }line │mouse enabled | {7: 25 }line │{1: } | ========== ========== | @@ -165,7 +165,7 @@ describe('terminal mouse', function() screen:expect([[ {7: 26 }line │line29 | {7: 27 }line │line30 | - {7: 28 }line │rows: 5, cols: 24 | + {7: 28 }line │rows: 5, cols: 25 | {7: 29 }line │mouse enabled | {7: 30 }line │{1: } | ========== ========== | @@ -178,7 +178,7 @@ describe('terminal mouse', function() screen:expect([[ {7: 27 }line │line29 | {7: 28 }l^ine │line30 | - {7: 29 }line │rows: 5, cols: 24 | + {7: 29 }line │rows: 5, cols: 25 | {7: 30 }line │mouse enabled | {7: 31 } │{2: } | ========== ========== | diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua index 2f9abfd3f6..0ae5802a01 100644 --- a/test/functional/terminal/tui_spec.lua +++ b/test/functional/terminal/tui_spec.lua @@ -387,15 +387,7 @@ describe('tui FocusGained/FocusLost', function() -- Exit cmdline-mode. Redraws from timers/events are blocked during -- cmdline-mode, so the buffer won't be updated until we exit cmdline-mode. feed_data('\n') - screen:expect([[ - {1: } | - lost | - gained | - {4:~ }| - {5:[No Name] [+] }| - : | - {3:-- TERMINAL --} | - ]]) + screen:expect('lost'..(' '):rep(46)..'\ngained', nil, nil, nil, true) end) end) diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua index 8a1f9b0d19..7fafd6b352 100644 --- a/test/functional/ui/screen_basic_spec.lua +++ b/test/functional/ui/screen_basic_spec.lua @@ -4,6 +4,7 @@ local spawn, set_session, clear = helpers.spawn, helpers.set_session, helpers.cl local feed, command = helpers.feed, helpers.command local insert = helpers.insert local eq = helpers.eq +local eval = helpers.eval local iswin = helpers.iswin describe('screen', function() @@ -75,11 +76,26 @@ describe('Screen', function() local function check() eq(true, screen.suspended) end + + command('let g:ev = []') + command('autocmd VimResume * :call add(g:ev, "r")') + command('autocmd VimSuspend * :call add(g:ev, "s")') + + eq(false, screen.suspended) command('suspend') + eq({ 's', 'r' }, eval('g:ev')) + screen:expect(check) screen.suspended = false + feed('<c-z>') + eq({ 's', 'r', 's', 'r' }, eval('g:ev')) + screen:expect(check) + screen.suspended = false + + command('suspend') + eq({ 's', 'r', 's', 'r', 's', 'r' }, eval('g:ev')) end) end) |