mirror of
https://github.com/neovim/neovim.git
synced 2026-02-21 01:40:19 +10:00
This is a better way to prevent parallel tests from interfering with each other, as there are many ways files can be created and deleted in tests, so enforcing different file names is hard. Using $TMPDIR can also work in most cases, but 'backipskip' etc. have special defaults for $TMPDIR. Symlink runtime/, src/, test/ and README.md to Xtest_xdg dir to make tests more convenient (and symlinking test/ is required for busted). Also, use README.md instead of test/README.md in the Ex mode inccommand test, as test/README.md no longer contains 'N' char.
269 lines
9.1 KiB
Lua
269 lines
9.1 KiB
Lua
local t = require('test.testutil')
|
|
local n = require('test.functional.testnvim')()
|
|
|
|
local eq, clear, call, write_file, command = t.eq, n.clear, n.call, t.write_file, n.command
|
|
local exc_exec = n.exc_exec
|
|
local eval = n.eval
|
|
local is_os = t.is_os
|
|
|
|
describe('executable()', function()
|
|
before_each(clear)
|
|
|
|
it('returns 1 for commands in $PATH', function()
|
|
local exe = is_os('win') and 'ping' or 'ls'
|
|
eq(1, call('executable', exe))
|
|
command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")')
|
|
eq(1, call('executable', 'null'))
|
|
eq(1, call('executable', 'true'))
|
|
eq(1, call('executable', 'false'))
|
|
end)
|
|
|
|
if is_os('win') then
|
|
it('exepath respects shellslash', function()
|
|
-- test/ cannot be a symlink in this test.
|
|
n.api.nvim_set_current_dir(t.paths.test_source_path)
|
|
|
|
command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")')
|
|
eq(
|
|
[[test\functional\fixtures\bin\null.CMD]],
|
|
call('fnamemodify', call('exepath', 'null'), ':.')
|
|
)
|
|
command('set shellslash')
|
|
eq(
|
|
'test/functional/fixtures/bin/null.CMD',
|
|
call('fnamemodify', call('exepath', 'null'), ':.')
|
|
)
|
|
end)
|
|
|
|
it('stdpath respects shellslash', function()
|
|
-- Needs to check paths relative to repo root dir.
|
|
n.api.nvim_set_current_dir(t.paths.test_source_path)
|
|
|
|
t.matches(
|
|
[[build\Xtest_xdg[%w_]*\share\nvim%-data]],
|
|
call('fnamemodify', call('stdpath', 'data'), ':.')
|
|
)
|
|
command('set shellslash')
|
|
t.matches(
|
|
'build/Xtest_xdg[%w_]*/share/nvim%-data',
|
|
call('fnamemodify', call('stdpath', 'data'), ':.')
|
|
)
|
|
end)
|
|
end
|
|
|
|
it('fails for invalid values', function()
|
|
for _, input in ipairs({ 'v:null', 'v:true', 'v:false', '{}', '[]' }) do
|
|
eq(
|
|
'Vim(call):E1174: String required for argument 1',
|
|
exc_exec('call executable(' .. input .. ')')
|
|
)
|
|
end
|
|
command('let $PATH = fnamemodify("./test/functional/fixtures/bin", ":p")')
|
|
for _, input in ipairs({ 'v:null', 'v:true', 'v:false' }) do
|
|
eq(
|
|
'Vim(call):E1174: String required for argument 1',
|
|
exc_exec('call executable(' .. input .. ')')
|
|
)
|
|
end
|
|
end)
|
|
|
|
it('returns 0 for empty strings', function()
|
|
eq(0, call('executable', '""'))
|
|
end)
|
|
|
|
it('returns 0 for non-existent files', function()
|
|
eq(0, call('executable', 'no_such_file_exists_209ufq23f'))
|
|
end)
|
|
|
|
it('sibling to nvim binary', function()
|
|
-- Some executable in build/bin/, *not* in $PATH nor CWD.
|
|
local sibling_exe = 'printargs-test'
|
|
-- Windows: siblings are in Nvim's "pseudo-$PATH".
|
|
local expected = is_os('win') and 1 or 0
|
|
if is_os('win') then
|
|
eq('arg1=lemon;arg2=sky;arg3=tree;', call('system', sibling_exe .. ' lemon sky tree'))
|
|
end
|
|
eq(expected, call('executable', sibling_exe))
|
|
end)
|
|
|
|
describe('exec-bit', function()
|
|
setup(function()
|
|
clear()
|
|
write_file('Xtest_not_executable', 'non-executable file')
|
|
write_file('Xtest_executable', 'executable file (exec-bit set)')
|
|
if not is_os('win') then -- N/A for Windows.
|
|
call('system', { 'chmod', '-x', 'Xtest_not_executable' })
|
|
call('system', { 'chmod', '+x', 'Xtest_executable' })
|
|
end
|
|
end)
|
|
|
|
teardown(function()
|
|
os.remove('Xtest_not_executable')
|
|
os.remove('Xtest_executable')
|
|
end)
|
|
|
|
it('not set', function()
|
|
eq(0, call('executable', 'Xtest_not_executable'))
|
|
eq(0, call('executable', './Xtest_not_executable'))
|
|
end)
|
|
|
|
it('set, unqualified and not in $PATH', function()
|
|
eq(0, call('executable', 'Xtest_executable'))
|
|
end)
|
|
|
|
it('set, qualified as a path', function()
|
|
local expected = is_os('win') and 0 or 1
|
|
eq(expected, call('executable', './Xtest_executable'))
|
|
end)
|
|
end)
|
|
end)
|
|
|
|
describe('executable() (Windows)', function()
|
|
if not is_os('win') then
|
|
pending('N/A for non-windows')
|
|
return
|
|
end
|
|
|
|
local exts = { 'bat', 'exe', 'com', 'cmd' }
|
|
setup(function()
|
|
for _, ext in ipairs(exts) do
|
|
write_file('test_executable_' .. ext .. '.' .. ext, '')
|
|
end
|
|
write_file('test_executable_zzz.zzz', '')
|
|
end)
|
|
|
|
teardown(function()
|
|
for _, ext in ipairs(exts) do
|
|
os.remove('test_executable_' .. ext .. '.' .. ext)
|
|
end
|
|
os.remove('test_executable_zzz.zzz')
|
|
end)
|
|
|
|
it('tries default extensions on a filename if $PATHEXT is empty', function()
|
|
-- Empty $PATHEXT defaults to ".com;.exe;.bat;.cmd".
|
|
clear({ env = { PATHEXT = '' } })
|
|
for _, ext in ipairs(exts) do
|
|
eq(1, call('executable', 'test_executable_' .. ext))
|
|
end
|
|
eq(0, call('executable', 'test_executable_zzz'))
|
|
end)
|
|
|
|
it('tries default extensions on a filepath if $PATHEXT is empty', function()
|
|
-- Empty $PATHEXT defaults to ".com;.exe;.bat;.cmd".
|
|
clear({ env = { PATHEXT = '' } })
|
|
for _, ext in ipairs(exts) do
|
|
eq(1, call('executable', '.\\test_executable_' .. ext))
|
|
end
|
|
eq(0, call('executable', '.\\test_executable_zzz'))
|
|
end)
|
|
|
|
it('system([…]), jobstart([…]) use $PATHEXT #9569', function()
|
|
-- Empty $PATHEXT defaults to ".com;.exe;.bat;.cmd".
|
|
clear({ env = { PATHEXT = '' } })
|
|
-- Invoking `cmdscript` should find/execute `cmdscript.cmd`.
|
|
eq('much success\n', call('system', { 'test/functional/fixtures/cmdscript' }))
|
|
assert(0 < call('jobstart', { 'test/functional/fixtures/cmdscript' }))
|
|
end)
|
|
|
|
it('full path with extension', function()
|
|
-- Empty $PATHEXT defaults to ".com;.exe;.bat;.cmd".
|
|
clear({ env = { PATHEXT = '' } })
|
|
-- Some executable we can expect in the test env.
|
|
local exe = 'printargs-test'
|
|
local exedir = eval("fnamemodify(v:progpath, ':h')")
|
|
local exepath = exedir .. '/' .. exe .. '.exe'
|
|
eq(1, call('executable', exepath))
|
|
eq('arg1=lemon;arg2=sky;arg3=tree;', call('system', exepath .. ' lemon sky tree'))
|
|
end)
|
|
|
|
it('full path without extension', function()
|
|
-- Empty $PATHEXT defaults to ".com;.exe;.bat;.cmd".
|
|
clear({ env = { PATHEXT = '' } })
|
|
-- Some executable we can expect in the test env.
|
|
local exe = 'printargs-test'
|
|
local exedir = eval("fnamemodify(v:progpath, ':h')")
|
|
local exepath = exedir .. '/' .. exe
|
|
eq('arg1=lemon;arg2=sky;arg3=tree;', call('system', exepath .. ' lemon sky tree'))
|
|
eq(1, call('executable', exepath))
|
|
end)
|
|
|
|
it('respects $PATHEXT when trying extensions on a filename', function()
|
|
clear({ env = { PATHEXT = '.zzz' } })
|
|
for _, ext in ipairs(exts) do
|
|
eq(0, call('executable', 'test_executable_' .. ext))
|
|
end
|
|
eq(1, call('executable', 'test_executable_zzz'))
|
|
end)
|
|
|
|
it('respects $PATHEXT when trying extensions on a filepath', function()
|
|
clear({ env = { PATHEXT = '.zzz' } })
|
|
for _, ext in ipairs(exts) do
|
|
eq(0, call('executable', '.\\test_executable_' .. ext))
|
|
end
|
|
eq(1, call('executable', '.\\test_executable_zzz'))
|
|
end)
|
|
|
|
it('with weird $PATHEXT', function()
|
|
clear({ env = { PATHEXT = ';' } })
|
|
eq(0, call('executable', '.\\test_executable_zzz'))
|
|
clear({ env = { PATHEXT = ';;;.zzz;;' } })
|
|
eq(1, call('executable', '.\\test_executable_zzz'))
|
|
end)
|
|
|
|
it("unqualified filename, Unix-style 'shell'", function()
|
|
clear({ env = { PATHEXT = '' } })
|
|
command('set shell=sh')
|
|
for _, ext in ipairs(exts) do
|
|
eq(0, call('executable', 'test_executable_' .. ext .. '.' .. ext))
|
|
end
|
|
eq(0, call('executable', 'test_executable_zzz.zzz'))
|
|
end)
|
|
|
|
it("relative path, Unix-style 'shell' (backslashes)", function()
|
|
clear({ env = { PATHEXT = '' } })
|
|
command('set shell=bash.exe')
|
|
for _, ext in ipairs(exts) do
|
|
eq(1, call('executable', '.\\test_executable_' .. ext .. '.' .. ext))
|
|
eq(1, call('executable', './test_executable_' .. ext .. '.' .. ext))
|
|
end
|
|
eq(1, call('executable', '.\\test_executable_zzz.zzz'))
|
|
eq(1, call('executable', './test_executable_zzz.zzz'))
|
|
end)
|
|
|
|
it('unqualified filename, $PATHEXT contains dot', function()
|
|
clear({ env = { PATHEXT = '.;.zzz' } })
|
|
for _, ext in ipairs(exts) do
|
|
eq(1, call('executable', 'test_executable_' .. ext .. '.' .. ext))
|
|
end
|
|
eq(1, call('executable', 'test_executable_zzz.zzz'))
|
|
clear({ env = { PATHEXT = '.zzz;.' } })
|
|
for _, ext in ipairs(exts) do
|
|
eq(1, call('executable', 'test_executable_' .. ext .. '.' .. ext))
|
|
end
|
|
eq(1, call('executable', 'test_executable_zzz.zzz'))
|
|
end)
|
|
|
|
it('relative path, $PATHEXT contains dot (backslashes)', function()
|
|
clear({ env = { PATHEXT = '.;.zzz' } })
|
|
for _, ext in ipairs(exts) do
|
|
eq(1, call('executable', '.\\test_executable_' .. ext .. '.' .. ext))
|
|
eq(1, call('executable', './test_executable_' .. ext .. '.' .. ext))
|
|
end
|
|
eq(1, call('executable', '.\\test_executable_zzz.zzz'))
|
|
eq(1, call('executable', './test_executable_zzz.zzz'))
|
|
end)
|
|
|
|
it('ignores case of extension', function()
|
|
clear({ env = { PATHEXT = '.ZZZ' } })
|
|
eq(1, call('executable', 'test_executable_zzz.zzz'))
|
|
end)
|
|
|
|
it('relative path does not search $PATH', function()
|
|
clear({ env = { PATHEXT = '' } })
|
|
eq(0, call('executable', './System32/notepad.exe'))
|
|
eq(0, call('executable', '.\\System32\\notepad.exe'))
|
|
eq(0, call('executable', '../notepad.exe'))
|
|
eq(0, call('executable', '..\\notepad.exe'))
|
|
end)
|
|
end)
|