neovim/test/functional/ui/output_spec.lua

292 lines
10 KiB
Lua

local Screen = require('test.functional.ui.screen')
local t = require('test.functional.testutil')()
local tt = require('test.functional.terminal.testutil')
local assert_alive = t.assert_alive
local mkdir, write_file, rmdir = t.mkdir, t.write_file, t.rmdir
local eq = t.eq
local feed = t.feed
local feed_command = t.feed_command
local clear = t.clear
local command = t.command
local testprg = t.testprg
local nvim_dir = t.nvim_dir
local has_powershell = t.has_powershell
local set_shell_powershell = t.set_shell_powershell
local skip = t.skip
local is_os = t.is_os
clear() -- for has_powershell()
describe('shell command :!', function()
local screen
before_each(function()
clear()
screen = tt.setup_child_nvim({
'-u',
'NONE',
'-i',
'NONE',
'--cmd',
'colorscheme vim',
'--cmd',
t.nvim_set .. ' notermguicolors',
})
screen:expect([[
{1: } |
{4:~ }|*4
|
{3:-- TERMINAL --} |
]])
end)
after_each(function()
tt.feed_data('\3') -- Ctrl-C
end)
it('displays output without LF/EOF. #4646 #4569 #3772', function()
skip(is_os('win'))
-- NOTE: We use a child nvim (within a :term buffer)
-- to avoid triggering a UI flush.
tt.feed_data(':!printf foo; sleep 200\n')
screen:expect([[
|
{4:~ }|*2
{5: }|
:!printf foo; sleep 200 |
foo |
{3:-- TERMINAL --} |
]])
end)
it('throttles shell-command output greater than ~10KB', function()
skip(is_os('openbsd'), 'FIXME #10804')
skip(is_os('win'))
tt.feed_data((':!%s REP 30001 foo\n'):format(testprg('shell-test')))
-- If we observe any line starting with a dot, then throttling occurred.
-- Avoid false failure on slow systems.
screen:expect { any = '\n%.', timeout = 20000 }
-- Final chunk of output should always be displayed, never skipped.
-- (Throttling is non-deterministic, this test is merely a sanity check.)
screen:expect(
[[
29997: foo |
29998: foo |
29999: foo |
30000: foo |
|
{10:Press ENTER or type command to continue}{1: } |
{3:-- TERMINAL --} |
]],
{
-- test/functional/testutil.lua defaults to background=light.
[1] = { reverse = true },
[3] = { bold = true },
[10] = { foreground = 2 },
}
)
end)
end)
describe('shell command :!', function()
before_each(function()
clear()
end)
it('cat a binary file #4142', function()
feed(":exe 'silent !cat '.shellescape(v:progpath)<CR>")
assert_alive()
end)
it([[display \x08 char #4142]], function()
feed(':silent !echo \08<CR>')
assert_alive()
end)
it('handles control codes', function()
skip(is_os('win'), 'missing printf')
local screen = Screen.new(50, 4)
screen:attach()
-- Print TAB chars. #2958
feed([[:!printf '1\t2\t3'<CR>]])
screen:expect {
grid = [[
{3: }|
:!printf '1\t2\t3' |
1 2 3 |
{6:Press ENTER or type command to continue}^ |
]],
}
feed([[<CR>]])
-- Print BELL control code. #4338
screen.bell = false
feed([[:!printf '\007\007\007\007text'<CR>]])
screen:expect {
grid = [[
{3: }|
:!printf '\007\007\007\007text' |
text |
{6:Press ENTER or type command to continue}^ |
]],
condition = function()
eq(true, screen.bell)
end,
}
feed([[<CR>]])
-- Print BS control code.
feed([[:echo system('printf ''\010\n''')<CR>]])
screen:expect([[
{3: }|
{18:^H} |
|
{6:Press ENTER or type command to continue}^ |
]])
feed([[<CR>]])
-- Print LF control code.
feed([[:!printf '\n'<CR>]])
screen:expect([[
:!printf '\n' |
|*2
{6:Press ENTER or type command to continue}^ |
]])
feed([[<CR>]])
end)
describe('', function()
local screen
before_each(function()
rmdir('bang_filter_spec')
mkdir('bang_filter_spec')
write_file('bang_filter_spec/f1', 'f1')
write_file('bang_filter_spec/f2', 'f2')
write_file('bang_filter_spec/f3', 'f3')
screen = Screen.new(53, 10)
screen:attach()
end)
after_each(function()
rmdir('bang_filter_spec')
end)
it("doesn't truncate Last line of shell output #3269", function()
command(
is_os('win') and [[nnoremap <silent>\l :!dir /b bang_filter_spec<cr>]]
or [[nnoremap <silent>\l :!ls bang_filter_spec<cr>]]
)
local result = (
is_os('win') and [[:!dir /b bang_filter_spec]] or [[:!ls bang_filter_spec ]]
)
feed([[\l]])
screen:expect([[
|
{1:~ }|*2
{3: }|
]] .. result .. [[ |
f1 |
f2 |
f3 |
|
{6:Press ENTER or type command to continue}^ |
]])
end)
it('handles binary and multibyte data', function()
feed_command('!cat test/functional/fixtures/shell_data.txt')
screen.bell = false
screen:expect {
grid = [[
|
{1:~ }|
{3: }|
:!cat test/functional/fixtures/shell_data.txt |
{18:^@^A^B^C^D^E^F^H} |
{18:^N^O^P^Q^R^S^T^U^V^W^X^Y^Z^[^\^]^^^_} |
ö 한글 {18:<a5><c3>} |
t {18:<ff>} |
|
{6:Press ENTER or type command to continue}^ |
]],
condition = function()
eq(true, screen.bell)
end,
}
end)
it('handles multibyte sequences split over buffer boundaries', function()
command('cd ' .. nvim_dir)
local cmd = is_os('win') and '!shell-test UTF-8 ' or '!./shell-test UTF-8'
feed_command(cmd)
-- Note: only the first example of split composed char works
screen:expect([[
|
{3: }|
:]] .. cmd .. [[ |
å |
ref: å̲ |
1: å̲ |
2: å ̲ |
3: å ̲ |
|
{6:Press ENTER or type command to continue}^ |
]])
end)
end)
if has_powershell() then
it('powershell supports literal strings', function()
set_shell_powershell()
local screen = Screen.new(45, 4)
screen:attach()
feed_command([[!'Write-Output $a']])
screen:expect([[
:!'Write-Output $a' |
Write-Output $a |
|
{6:Press ENTER or type command to continue}^ |
]])
feed_command([[!$a = 1; Write-Output '$a']])
screen:expect([[
:!$a = 1; Write-Output '$a' |
$a |
|
{6:Press ENTER or type command to continue}^ |
]])
feed_command([[!"Write-Output $a"]])
screen:expect([[
:!"Write-Output $a" |
Write-Output |
|
{6:Press ENTER or type command to continue}^ |
]])
feed_command([[!$a = 1; Write-Output "$a"]])
screen:expect([[
:!$a = 1; Write-Output "$a" |
1 |
|
{6:Press ENTER or type command to continue}^ |
]])
if is_os('win') then
feed_command([[!& 'cmd.exe' /c 'echo $a']])
screen:expect([[
:!& 'cmd.exe' /c 'echo $a' |
$a |
|
{6:Press ENTER or type command to continue}^ |
]])
else
feed_command([[!& '/bin/sh' -c 'echo ''$a''']])
screen:expect([[
:!& '/bin/sh' -c 'echo ''$a''' |
$a |
|
{6:Press ENTER or type command to continue}^ |
]])
end
end)
end
end)