aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2024-02-06 14:05:49 +0800
committerGitHub <noreply@github.com>2024-02-06 14:05:49 +0800
commitd6fac187f1dee41bb0d6161c160f5fb5842b59b7 (patch)
tree158474346e6cea0b04ebfbae1debb13e95b90589
parentf6042d5c300c008fb4b3e3ec4e81537feffbaa0b (diff)
downloadrneovim-d6fac187f1dee41bb0d6161c160f5fb5842b59b7.tar.gz
rneovim-d6fac187f1dee41bb0d6161c160f5fb5842b59b7.tar.bz2
rneovim-d6fac187f1dee41bb0d6161c160f5fb5842b59b7.zip
test(tui_spec): prevent race between nvim_input and nvim_paste (#27356)
-rw-r--r--test/functional/terminal/helpers.lua13
-rw-r--r--test/functional/terminal/tui_spec.lua207
2 files changed, 78 insertions, 142 deletions
diff --git a/test/functional/terminal/helpers.lua b/test/functional/terminal/helpers.lua
index b878b9eb43..05db1b3c8c 100644
--- a/test/functional/terminal/helpers.lua
+++ b/test/functional/terminal/helpers.lua
@@ -97,18 +97,19 @@ local function screen_setup(extra_rows, command, cols, env, screen_opts)
[1] = { reverse = true }, -- focused cursor
[2] = { background = 11 }, -- unfocused cursor
[3] = { bold = true },
- [4] = { foreground = 12 },
+ [4] = { foreground = 12 }, -- NonText in :terminal session
[5] = { bold = true, reverse = true },
- -- 6 was a duplicate item
- [7] = { foreground = 130 },
- [8] = { foreground = 15, background = 1 }, -- error message
+ [6] = { foreground = 81 }, -- SpecialKey in :terminal session
+ [7] = { foreground = 130 }, -- LineNr in host session
+ [8] = { foreground = 15, background = 1 }, -- ErrorMsg in :terminal session
[9] = { foreground = 4 },
- [10] = { foreground = 121 }, -- "Press ENTER" in embedded :terminal session.
- [11] = { foreground = tonumber('0x00000b') },
+ [10] = { foreground = 121 }, -- MoreMsg in :terminal session
+ [11] = { foreground = 11 }, -- LineNr in :terminal session
[12] = { underline = true },
[13] = { underline = true, reverse = true },
[14] = { underline = true, reverse = true, bold = true },
[15] = { underline = true, foreground = 12 },
+ [16] = { background = 248, foreground = 0 }, -- Visual in :terminal session
})
screen:attach(screen_opts or { rgb = false })
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index a78994f998..9dd5b00b83 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -338,18 +338,13 @@ describe('TUI', function()
feed_data('\022\007') -- ctrl+g
feed_data('\022\022') -- ctrl+v
feed_data('\022\013') -- ctrl+m
- local attrs = screen:get_default_attr_ids()
- attrs[11] = { foreground = 81 }
- screen:expect(
- [[
- {11:^G^V^M}{1: } |
+ screen:expect([[
+ {6:^G^V^M}{1: } |
{4:~ }|*3
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
- ]],
- attrs
- )
+ ]])
end)
local function test_mouse_wheel(esc)
@@ -978,8 +973,7 @@ describe('TUI', function()
it('paste: select-mode', function()
feed_data('ithis is line 1\nthis is line 2\nline 3 is here\n\027')
wait_for_mode('n')
- screen:expect {
- grid = [[
+ screen:expect([[
this is line 1 |
this is line 2 |
line 3 is here |
@@ -987,24 +981,29 @@ describe('TUI', function()
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]],
- }
+ ]])
-- Select-mode. Use <C-n> to move down.
feed_data('gg04lgh\14\14')
- wait_for_mode('s')
+ screen:expect([[
+ this{16: is line 1} |
+ {16:this is line 2} |
+ {16:line}{1: }3 is here |
+ |
+ {5:[No Name] [+] }|
+ {3:-- SELECT --} |
+ {3:-- TERMINAL --} |
+ ]])
feed_data('\027[200~')
feed_data('just paste it™')
feed_data('\027[201~')
- screen:expect {
- grid = [[
+ screen:expect([[
thisjust paste it{1:™}3 is here |
|
{4:~ }|*2
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]],
- }
+ ]])
-- Undo.
feed_data('u')
expect_child_buf_lines {
@@ -1028,27 +1027,23 @@ describe('TUI', function()
child_exec_lua('vim.o.statusline="^^^^^^^"')
child_exec_lua('vim.cmd.terminal(...)', testprg('tty-test'))
feed_data('i')
- screen:expect {
- grid = [[
+ screen:expect([[
tty ready |
{1: } |
|*2
{5:^^^^^^^ }|
{3:-- TERMINAL --} |*2
- ]],
- }
+ ]])
feed_data('\027[200~')
feed_data('hallo')
feed_data('\027[201~')
- screen:expect {
- grid = [[
+ screen:expect([[
tty ready |
hallo{1: } |
|*2
{5:^^^^^^^ }|
{3:-- TERMINAL --} |*2
- ]],
- }
+ ]])
end)
it('paste: normal-mode (+CRLF #10872)', function()
@@ -1060,38 +1055,27 @@ describe('TUI', function()
local expected_crlf = { 'line 1', 'ESC:\027 / CR: ', 'x' }
local expected_grid1 = [[
line 1 |
- ESC:{11:^[} / CR: |
+ ESC:{6:^[} / CR: |
{1:x} |
{4:~ }|
{5:[No Name] [+] 3,1 All}|
|
{3:-- TERMINAL --} |
]]
- local expected_attr = {
- [1] = { reverse = true },
- [3] = { bold = true },
- [4] = { foreground = tonumber('0x00000c') },
- [5] = { bold = true, reverse = true },
- [11] = { foreground = tonumber('0x000051') },
- [12] = { reverse = true, foreground = tonumber('0x000051') },
- }
-- "bracketed paste"
feed_data('\027[200~' .. table.concat(expected_lf, '\n') .. '\027[201~')
- screen:expect { grid = expected_grid1, attr_ids = expected_attr }
+ screen:expect(expected_grid1)
-- Dot-repeat/redo.
feed_data('.')
- screen:expect {
- grid = [[
- ESC:{11:^[} / CR: |
+ screen:expect([[
+ ESC:{6:^[} / CR: |
xline 1 |
- ESC:{11:^[} / CR: |
+ ESC:{6:^[} / CR: |
{1:x} |
{5:[No Name] [+] 5,1 Bot}|
|
{3:-- TERMINAL --} |
- ]],
- attr_ids = expected_attr,
- }
+ ]])
-- Undo.
feed_data('u')
expect_child_buf_lines(expected_crlf)
@@ -1103,7 +1087,7 @@ describe('TUI', function()
wait_for_mode('n')
-- CRLF input
feed_data('\027[200~' .. table.concat(expected_lf, '\r\n') .. '\027[201~')
- screen:expect { grid = expected_grid1, attr_ids = expected_attr }
+ screen:expect(expected_grid1)
expect_child_buf_lines(expected_crlf)
end)
@@ -1112,35 +1096,39 @@ describe('TUI', function()
feed_data('\027:""') -- Enter Cmdline-mode.
feed_data('\027[D') -- <Left> to place cursor between quotes.
wait_for_mode('c')
+ screen:expect([[
+ foo |
+ |
+ {4:~ }|*2
+ {5:[No Name] [+] }|
+ :"{1:"} |
+ {3:-- TERMINAL --} |
+ ]])
-- "bracketed paste"
feed_data('\027[200~line 1\nline 2\n')
wait_for_mode('c')
feed_data('line 3\nline 4\n\027[201~')
wait_for_mode('c')
- screen:expect {
- grid = [[
+ screen:expect([[
foo |
|
{4:~ }|*2
{5:[No Name] [+] }|
:"line 1{1:"} |
{3:-- TERMINAL --} |
- ]],
- }
+ ]])
-- Dot-repeat/redo.
feed_data('\027[27u')
wait_for_mode('n')
feed_data('.')
- screen:expect {
- grid = [[
+ screen:expect([[
foo |*2
{1: } |
{4:~ }|
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]],
- }
+ ]])
end)
it('paste: cmdline-mode collects chunks of unfinished line', function()
@@ -1148,11 +1136,13 @@ describe('TUI', function()
retry(nil, nil, function()
local _, cmdline = child_session:request('nvim_call_function', 'getcmdline', {})
eq(expected, cmdline)
+ local _, pos = child_session:request('nvim_call_function', 'getcmdpos', {})
+ eq(#expected, pos) -- Cursor is just before the last char.
end)
end
feed_data('\027:""') -- Enter Cmdline-mode.
feed_data('\027[D') -- <Left> to place cursor between quotes.
- wait_for_mode('c')
+ expect_cmdline('""')
feed_data('\027[200~stuff 1 ')
expect_cmdline('"stuff 1 "')
-- Discards everything after the first line.
@@ -1180,20 +1170,17 @@ describe('TUI', function()
-- Prepare something for dot-repeat/redo.
feed_data('ifoo\n\027[27u')
wait_for_mode('n')
- screen:expect {
- grid = [[
+ screen:expect([[
foo |
{1: } |
{4:~ }|*2
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]],
- }
+ ]])
-- Start pasting...
feed_data('\027[200~line 1\nline 2\n')
- screen:expect {
- grid = [[
+ screen:expect([[
foo |
|
{5: }|
@@ -1201,52 +1188,39 @@ describe('TUI', function()
{8:ake fail} |
{10:Press ENTER or type command to continue}{1: } |
{3:-- TERMINAL --} |
- ]],
- }
+ ]])
-- Remaining chunks are discarded after vim.paste() failure.
feed_data('line 3\nline 4\n')
feed_data('line 5\nline 6\n')
feed_data('line 7\nline 8\n')
-- Stop paste.
feed_data('\027[201~')
- feed_data('\n') -- <CR>
+ feed_data('\n') -- <CR> to dismiss hit-enter prompt
expect_child_buf_lines({ 'foo', '' })
- --Dot-repeat/redo is not modified by failed paste.
+ -- Dot-repeat/redo is not modified by failed paste.
feed_data('.')
- screen:expect {
- grid = [[
+ screen:expect([[
foo |*2
{1: } |
{4:~ }|
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]],
- }
+ ]])
-- Editor should still work after failed/drained paste.
feed_data('ityped input...\027[27u')
- screen:expect {
- grid = [[
+ screen:expect([[
foo |*2
typed input..{1:.} |
{4:~ }|
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]],
- }
+ ]])
-- Paste works if vim.paste() succeeds.
- child_session:request(
- 'nvim_exec_lua',
- [[
- vim.paste = _G.save_paste_fn
- ]],
- {}
- )
+ child_session:request('nvim_exec_lua', [[vim.paste = _G.save_paste_fn]], {})
feed_data('\027[200~line A\nline B\n\027[201~')
- feed_data('\n') -- <CR>
- screen:expect {
- grid = [[
+ screen:expect([[
foo |
typed input...line A |
line B |
@@ -1254,8 +1228,7 @@ describe('TUI', function()
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]],
- }
+ ]])
end)
it('paste: vim.paste() cancel (retval=false) #10865', function()
@@ -1284,8 +1257,7 @@ describe('TUI', function()
{}
)
feed_data('\027[200~fail 1\nfail 2\n\027[201~')
- screen:expect {
- grid = [[
+ screen:expect([[
|
{4:~ }|
{5: }|
@@ -1293,13 +1265,11 @@ describe('TUI', function()
{8:hanges, 'modifiable' is off} |
{10:Press ENTER or type command to continue}{1: } |
{3:-- TERMINAL --} |
- ]],
- }
- feed_data('\n') -- <Enter>
+ ]])
+ feed_data('\n') -- <Enter> to dismiss hit-enter prompt
child_session:request('nvim_command', 'set modifiable')
feed_data('\027[200~success 1\nsuccess 2\n\027[201~')
- screen:expect {
- grid = [[
+ screen:expect([[
success 1 |
success 2 |
{1: } |
@@ -1307,8 +1277,7 @@ describe('TUI', function()
{5:[No Name] [+] }|
|
{3:-- TERMINAL --} |
- ]],
- }
+ ]])
end)
it('paste: exactly 64 bytes #10311', function()
@@ -1337,15 +1306,13 @@ describe('TUI', function()
wait_for_mode('c')
-- "bracketed paste"
feed_data('\027[200~' .. expected .. '\027[201~')
- screen:expect {
- grid = [[
+ screen:expect([[
|
{4:~ }|*3
{5:[No Name] }|
:<{1: } |
{3:-- TERMINAL --} |
- ]],
- }
+ ]])
end)
it('paste: big burst of input', function()
@@ -1387,9 +1354,10 @@ describe('TUI', function()
it('paste: forwards spurious "start paste" code', function()
-- If multiple "start paste" sequences are sent without a corresponding
-- "stop paste" sequence, only the first occurrence should be consumed.
-
+ feed_data('i')
+ wait_for_mode('i')
-- Send the "start paste" sequence.
- feed_data('i\027[200~')
+ feed_data('\027[200~')
feed_data('\npasted from terminal (1)\n')
-- Send spurious "start paste" sequence.
feed_data('\027[200~')
@@ -1397,8 +1365,7 @@ describe('TUI', function()
-- Send the "stop paste" sequence.
feed_data('\027[201~')
- screen:expect {
- grid = [[
+ screen:expect([[
|
pasted from terminal (1) |
{6:^[}[200~ |
@@ -1406,22 +1373,14 @@ describe('TUI', function()
{5:[No Name] [+] }|
{3:-- INSERT --} |
{3:-- TERMINAL --} |
- ]],
- attr_ids = {
- [1] = { reverse = true },
- [2] = { background = tonumber('0x00000b') },
- [3] = { bold = true },
- [4] = { foreground = tonumber('0x00000c') },
- [5] = { bold = true, reverse = true },
- [6] = { foreground = tonumber('0x000051') },
- },
- }
+ ]])
end)
it('paste: ignores spurious "stop paste" code', function()
-- If "stop paste" sequence is received without a preceding "start paste"
-- sequence, it should be ignored.
feed_data('i')
+ wait_for_mode('i')
-- Send "stop paste" sequence.
feed_data('\027[201~')
screen:expect([[
@@ -1435,15 +1394,7 @@ describe('TUI', function()
it('paste: split "start paste" code', function()
feed_data('i')
- screen:expect {
- grid = [[
- {1: } |
- {4:~ }|*3
- {5:[No Name] }|
- {3:-- INSERT --} |
- {3:-- TERMINAL --} |
- ]],
- }
+ wait_for_mode('i')
-- Send split "start paste" sequence.
feed_data('\027[2')
feed_data('00~pasted from terminal\027[201~')
@@ -1458,15 +1409,7 @@ describe('TUI', function()
it('paste: split "stop paste" code', function()
feed_data('i')
- screen:expect {
- grid = [[
- {1: } |
- {4:~ }|*3
- {5:[No Name] }|
- {3:-- INSERT --} |
- {3:-- TERMINAL --} |
- ]],
- }
+ wait_for_mode('i')
-- Send split "stop paste" sequence.
feed_data('\027[200~pasted from terminal\027[20')
feed_data('1~')
@@ -1494,15 +1437,7 @@ describe('TUI', function()
{}
)
feed_data('i')
- screen:expect {
- grid = [[
- {1: } |
- {4:~ }|*3
- {5:[No Name] }|
- {3:-- INSERT --} |
- {3:-- TERMINAL --} |
- ]],
- }
+ wait_for_mode('i')
feed_data('\027[200~pasted') -- phase 1
screen:expect([[
pasted{1: } |