aboutsummaryrefslogtreecommitdiff
path: root/test/functional
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional')
-rw-r--r--test/functional/api/proc_spec.lua7
-rw-r--r--test/functional/api/server_requests_spec.lua3
-rw-r--r--test/functional/api/vim_spec.lua14
-rw-r--r--test/functional/core/job_spec.lua76
-rw-r--r--test/functional/core/startup_spec.lua25
-rw-r--r--test/functional/eval/timer_spec.lua116
-rw-r--r--test/functional/fixtures/tty-test.c3
-rw-r--r--test/functional/helpers.lua2
-rw-r--r--test/functional/legacy/055_list_and_dict_types_spec.lua2
-rw-r--r--test/functional/provider/python3_spec.lua6
-rw-r--r--test/functional/terminal/buffer_spec.lua7
-rw-r--r--test/functional/terminal/window_split_tab_spec.lua1
-rw-r--r--test/functional/ui/float_spec.lua91
-rw-r--r--test/functional/ui/inccommand_spec.lua16
-rw-r--r--test/functional/ui/input_spec.lua5
-rw-r--r--test/functional/ui/messages_spec.lua50
-rw-r--r--test/functional/ui/mode_spec.lua6
-rw-r--r--test/functional/ui/multigrid_spec.lua50
-rw-r--r--test/functional/ui/output_spec.lua3
-rw-r--r--test/functional/ui/popupmenu_spec.lua3
-rw-r--r--test/functional/ui/screen.lua14
21 files changed, 351 insertions, 149 deletions
diff --git a/test/functional/api/proc_spec.lua b/test/functional/api/proc_spec.lua
index e11e03203f..063d382790 100644
--- a/test/functional/api/proc_spec.lua
+++ b/test/functional/api/proc_spec.lua
@@ -4,8 +4,8 @@ local clear = helpers.clear
local eq = helpers.eq
local funcs = helpers.funcs
local iswin = helpers.iswin
+local neq = helpers.neq
local nvim_argv = helpers.nvim_argv
-local ok = helpers.ok
local request = helpers.request
local retry = helpers.retry
local NIL = helpers.NIL
@@ -63,8 +63,9 @@ describe('api', function()
local pid = funcs.getpid()
local pinfo = request('nvim_get_proc', pid)
eq((iswin() and 'nvim.exe' or 'nvim'), pinfo.name)
- ok(pinfo.pid == pid)
- ok(type(pinfo.ppid) == 'number' and pinfo.ppid ~= pid)
+ eq(pinfo.pid, pid)
+ eq(type(pinfo.ppid), 'number')
+ neq(pinfo.ppid, pid)
end)
it('validates input', function()
diff --git a/test/functional/api/server_requests_spec.lua b/test/functional/api/server_requests_spec.lua
index dbe9f20412..ddd044a10f 100644
--- a/test/functional/api/server_requests_spec.lua
+++ b/test/functional/api/server_requests_spec.lua
@@ -169,8 +169,7 @@ describe('server -> client', function()
if method == "notification" then
eq('done!', eval('rpcrequest('..cid..', "nested")'))
elseif method == "nested_done" then
- -- this should never have been sent
- ok(false)
+ ok(false, 'this should never have been sent')
end
end
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index 110b3a4b16..cd45914552 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -178,6 +178,11 @@ describe('API', function()
-- Verify NO hit-enter prompt.
eq({mode='n', blocking=false}, nvim("get_mode"))
end)
+
+ it('Does not cause heap buffer overflow with large output', function()
+ eq(eval('string(range(1000000))'),
+ nvim('command_output', 'echo range(1000000)'))
+ end)
end)
describe('nvim_eval', function()
@@ -1148,6 +1153,13 @@ describe('API', function()
before_each(function()
meths.set_option('isident', '')
end)
+
+ local it_maybe_pending = it
+ if (helpers.isCI('appveyor') and os.getenv('CONFIGURATION') == 'MSVC_32') then
+ -- For "works with &opt" (flaky on MSVC_32), but not easy to skip alone. #10241
+ it_maybe_pending = pending
+ end
+
local function simplify_east_api_node(line, east_api_node)
if east_api_node == NIL then
return nil
@@ -1345,7 +1357,7 @@ describe('API', function()
end
assert:set_parameter('TableFormatLevel', 1000000)
require('test.unit.viml.expressions.parser_tests')(
- it, _check_parsing, hl, fmtn)
+ it_maybe_pending, _check_parsing, hl, fmtn)
end)
describe('nvim_list_uis', function()
diff --git a/test/functional/core/job_spec.lua b/test/functional/core/job_spec.lua
index 180ed9aa02..2531b45521 100644
--- a/test/functional/core/job_spec.lua
+++ b/test/functional/core/job_spec.lua
@@ -707,11 +707,10 @@ describe('jobs', function()
it('will return -1 if the wait timed out', function()
source([[
call rpcnotify(g:channel, 'wait', jobwait([
- \ jobstart('exit 4'),
\ jobstart((has('win32') ? 'Start-Sleep 10' : 'sleep 10').'; exit 5'),
- \ ], has('win32') ? 6000 : 100))
+ \ ], 100))
]])
- eq({'notification', 'wait', {{4, -1}}}, next_msg())
+ eq({'notification', 'wait', {{-1}}}, next_msg())
end)
it('can pass 0 to check if a job exists', function()
@@ -769,16 +768,79 @@ describe('jobs', function()
-- ..c.."', '-c', '"..c.."'])")
-- Create child with several descendants.
+ if iswin() then
+ source([[
+ function! s:formatprocs(pid, prefix)
+ let result = ''
+ let result .= a:prefix . printf("%-24.24s%6s %12.12s %s\n",
+ \ s:procs[a:pid]['name'],
+ \ a:pid,
+ \ s:procs[a:pid]['Session Name'],
+ \ s:procs[a:pid]['Session'])
+ if has_key(s:procs[a:pid], 'children')
+ for pid in s:procs[a:pid]['children']
+ let result .= s:formatprocs(pid, a:prefix . ' ')
+ endfor
+ endif
+ return result
+ endfunction
+
+ function! PsTree() abort
+ let s:procs = {}
+ for proc in map(
+ \ map(
+ \ systemlist('tasklist /NH'),
+ \ 'substitute(v:val, "\r", "", "")'),
+ \ 'split(v:val, "\\s\\+")')
+ if len(proc) == 6
+ let s:procs[proc[1]] ..']]'..[[= {'name': proc[0],
+ \ 'Session Name': proc[2],
+ \ 'Session': proc[3]}
+ endif
+ endfor
+ for pid in keys(s:procs)
+ let children = nvim_get_proc_children(str2nr(pid))
+ if !empty(children)
+ let s:procs[pid]['children'] = children
+ for cpid in children
+ let s:procs[printf('%d', cpid)]['parent'] = str2nr(pid)
+ endfor
+ endif
+ endfor
+ let result = ''
+ for pid in sort(keys(s:procs), {i1, i2 -> i1 - i2})
+ if !has_key(s:procs[pid], 'parent')
+ let result .= s:formatprocs(pid, '')
+ endif
+ endfor
+ return result
+ endfunction
+ ]])
+ end
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()
- children = meths.get_proc_children(ppid)
- eq((iswin() and 4 or 3), #children)
- end)
+ if iswin() then
+ local status, result = pcall(retry, nil, nil, function()
+ children = meths.get_proc_children(ppid)
+ -- On Windows conhost.exe may exist, and
+ -- e.g. vctip.exe might appear. #10783
+ ok(#children >= 3 and #children <= 5)
+ end)
+ if not status then
+ print('')
+ print(eval('PsTree()'))
+ error(result)
+ end
+ else
+ retry(nil, nil, function()
+ children = meths.get_proc_children(ppid)
+ eq(3, #children)
+ end)
+ end
-- Assert that nvim_get_proc() sees the children.
for _, child_pid in ipairs(children) do
local info = meths.get_proc(child_pid)
diff --git a/test/functional/core/startup_spec.lua b/test/functional/core/startup_spec.lua
index 62a45fdf88..3b32c42ec0 100644
--- a/test/functional/core/startup_spec.lua
+++ b/test/functional/core/startup_spec.lua
@@ -226,6 +226,31 @@ describe('startup', function()
clear{env={CDPATH='~doesnotexist'}}
eq(',~doesnotexist', eval('&cdpath'))
end)
+
+ it('ENTER dismisses early message #7967', function()
+ local screen
+ screen = Screen.new(60, 6)
+ screen:attach()
+ command([[let g:id = termopen('"]]..nvim_prog..
+ [[" -u NONE -i NONE --cmd "set noruler" --cmd "let g:foo = g:bar"')]])
+ screen:expect([[
+ ^ |
+ Error detected while processing pre-vimrc command line: |
+ E121: Undefined variable: g:bar |
+ E15: Invalid expression: g:bar |
+ Press ENTER or type command to continue |
+ |
+ ]])
+ command([[call chansend(g:id, "\n")]])
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ [No Name] |
+ |
+ |
+ ]])
+ end)
end)
describe('sysinit', function()
diff --git a/test/functional/eval/timer_spec.lua b/test/functional/eval/timer_spec.lua
index cd099e30ed..5c5b1b42cb 100644
--- a/test/functional/eval/timer_spec.lua
+++ b/test/functional/eval/timer_spec.lua
@@ -1,6 +1,6 @@
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
-local feed, eq, eval = helpers.feed, helpers.eq, helpers.eval
+local feed, eq, eval, ok = helpers.feed, helpers.eq, helpers.eval, helpers.ok
local source, nvim_async, run = helpers.source, helpers.nvim_async, helpers.run
local clear, command, funcs = helpers.clear, helpers.command, helpers.funcs
local curbufmeths = helpers.curbufmeths
@@ -19,59 +19,71 @@ describe('timers', function()
end)
it('works one-shot', function()
- command("call timer_start(50, 'MyHandler')")
- eq(0,eval("g:val"))
- run(nil, nil, nil, load_adjust(200))
+ eq(0, eval("[timer_start(10, 'MyHandler'), g:val][1]"))
+ run(nil, nil, nil, load_adjust(100))
eq(1,eval("g:val"))
end)
it('works one-shot when repeat=0', function()
- command("call timer_start(50, 'MyHandler', {'repeat': 0})")
- eq(0,eval("g:val"))
- run(nil, nil, nil, load_adjust(200))
- eq(1,eval("g:val"))
+ eq(0, eval("[timer_start(10, 'MyHandler', {'repeat': 0}), g:val][1]"))
+ run(nil, nil, nil, load_adjust(100))
+ eq(1, eval("g:val"))
end)
-
it('works with repeat two', function()
- command("call timer_start(50, 'MyHandler', {'repeat': 2})")
- eq(0,eval("g:val"))
- run(nil, nil, nil, load_adjust(300))
- eq(2,eval("g:val"))
+ eq(0, eval("[timer_start(10, 'MyHandler', {'repeat': 2}), g:val][1]"))
+ run(nil, nil, nil, load_adjust(20))
+ retry(nil, load_adjust(300), function()
+ eq(2, eval("g:val"))
+ end)
end)
it('are triggered during sleep', function()
- command("call timer_start(50, 'MyHandler', {'repeat': 2})")
+ source([[
+ let g:val = -1
+ func! MyHandler(timer)
+ if g:val >= 0
+ let g:val += 1
+ if g:val == 2
+ call timer_stop(a:timer)
+ endif
+ endif
+ endfunc
+ ]])
+ eval("timer_start(10, 'MyHandler', {'repeat': -1})")
nvim_async("command", "sleep 10")
- eq(0,eval("g:val"))
- run(nil, nil, nil, load_adjust(300))
- eq(2,eval("g:val"))
+ eq(-1, eval("g:val")) -- timer did nothing yet.
+ nvim_async("command", "let g:val = 0")
+ run(nil, nil, nil, load_adjust(20))
+ retry(nil, nil, function()
+ eq(2, eval("g:val"))
+ end)
end)
it('works with zero timeout', function()
-- timer_start does still not invoke the callback immediately
- eq(0,eval("[timer_start(0, 'MyHandler', {'repeat': 1000}), g:val][1]"))
- run(nil, nil, nil, load_adjust(400))
- eq(1000,eval("g:val"))
+ eq(0, eval("[timer_start(0, 'MyHandler', {'repeat': 1000}), g:val][1]"))
+ retry(nil, nil, function()
+ eq(1000, eval("g:val"))
+ end)
end)
it('can be started during sleep', function()
nvim_async("command", "sleep 10")
-- this also tests that remote requests works during sleep
- eval("timer_start(50, 'MyHandler', {'repeat': 2})")
- eq(0,eval("g:val"))
- run(nil, nil, nil, load_adjust(300))
- eq(2,eval("g:val"))
+ eq(0, eval("[timer_start(10, 'MyHandler', {'repeat': 2}), g:val][1]"))
+ run(nil, nil, nil, load_adjust(20))
+ retry(nil, load_adjust(300), function() eq(2,eval("g:val")) end)
end)
it('are paused when event processing is disabled', function()
- command("call timer_start(50, 'MyHandler', {'repeat': -1})")
- run(nil, nil, nil, load_adjust(100))
+ command("call timer_start(5, 'MyHandler', {'repeat': -1})")
+ run(nil, nil, nil, load_adjust(10))
local count = eval("g:val")
-- shows two line error message and thus invokes the return prompt.
-- if we start to allow event processing here, we need to change this test.
feed(':throw "fatal error"<CR>')
- run(nil, nil, nil, load_adjust(300))
+ run(nil, nil, nil, load_adjust(30))
feed("<cr>")
local diff = eval("g:val") - count
assert(0 <= diff and diff <= 4,
@@ -79,12 +91,14 @@ describe('timers', function()
end)
it('are triggered in blocking getchar() call', function()
- command("call timer_start(50, 'MyHandler', {'repeat': -1})")
- nvim_async("command", "let g:c = getchar()")
- run(nil, nil, nil, load_adjust(300))
+ command("call timer_start(5, 'MyHandler', {'repeat': -1})")
+ nvim_async("command", "let g:val = 0 | let g:c = getchar()")
+ retry(nil, nil, function()
+ local val = eval("g:val")
+ ok(val >= 2, "expected >= 2, got: "..tostring(val))
+ eq(0, eval("getchar(1)"))
+ end)
feed("c")
- local count = eval("g:val")
- assert(count >= 3, 'expected count >= 3, got: '..tostring(count))
eq(99, eval("g:c"))
end)
@@ -99,12 +113,15 @@ describe('timers', function()
source([[
func! AddItem(timer)
call nvim_buf_set_lines(0, 2, 2, v:true, ['ITEM 3'])
+
+ " Meant to test for what Vim tests in Test_peek_and_get_char.
call getchar(1)
+
redraw
endfunc
- call timer_start(200, 'AddItem')
]])
nvim_async("command", "let g:c2 = getchar()")
+ nvim_async("command", "call timer_start("..load_adjust(100)..", 'AddItem')")
screen:expect([[
ITEM 1 |
@@ -137,18 +154,15 @@ describe('timers', function()
end)
it('can be stopped', function()
- local t = eval("timer_start(50, 'MyHandler', {'repeat': -1})")
- eq(0,eval("g:val"))
- run(nil, nil, nil, load_adjust(300))
- funcs.timer_stop(t)
+ local t_init_val = eval("[timer_start(5, 'MyHandler', {'repeat': -1}), g:val]")
+ eq(0, t_init_val[2])
+ run(nil, nil, nil, load_adjust(30))
+ funcs.timer_stop(t_init_val[1])
local count = eval("g:val")
- run(nil, nil, nil, load_adjust(300))
+ run(nil, load_adjust(300), nil, load_adjust(30))
local count2 = eval("g:val")
-- when count is eval:ed after timer_stop this should be non-racy
eq(count, count2)
- assert((3 <= count and count <= load_adjust(7)),
- string.format('expected (3 <= count <= %s), got: %s',
- load_adjust(7), tostring(count)))
end)
it('can be stopped from the handler', function()
@@ -162,10 +176,9 @@ describe('timers', function()
endif
endfunc
]])
+ eq(0, eval("g:val"))
command("call timer_start(10, 'MyHandler', {'repeat': -1})")
- eq(0,eval("g:val"))
- run(nil, nil, nil, load_adjust(50))
- retry(nil, 5000, function()
+ retry(nil, nil, function()
eq(3, eval("g:val"))
end)
end)
@@ -177,9 +190,9 @@ describe('timers', function()
let g:val2 += 1
endfunc
]])
- command("call timer_start(20, 'MyHandler', {'repeat': 3})")
- command("call timer_start(40, 'MyHandler2', {'repeat': 2})")
- run(nil, nil, nil, load_adjust(300))
+ command("call timer_start(2, 'MyHandler', {'repeat': 3})")
+ command("call timer_start(4, 'MyHandler2', {'repeat': 2})")
+ run(nil, nil, nil, load_adjust(30))
eq(3,eval("g:val"))
eq(2,eval("g:val2"))
end)
@@ -189,13 +202,15 @@ describe('timers', function()
let g:val = 0
func! MyHandler(timer)
call timer_stop(a:timer)
- sleep 100m
+ sleep 10m
let g:val += 1
endfunc
]])
command("call timer_start(5, 'MyHandler', {'repeat': 1})")
- run(nil, nil, nil, load_adjust(300))
- eq(1,eval("g:val"))
+ run(nil, nil, nil, load_adjust(10))
+ retry(nil, load_adjust(100), function()
+ eq(1, eval("g:val"))
+ end)
end)
@@ -232,5 +247,4 @@ describe('timers', function()
eq(1, eval('g:val'))
end)
-
end)
diff --git a/test/functional/fixtures/tty-test.c b/test/functional/fixtures/tty-test.c
index e2a78a594b..4438b73a22 100644
--- a/test/functional/fixtures/tty-test.c
+++ b/test/functional/fixtures/tty-test.c
@@ -38,6 +38,9 @@ bool owns_tty(void)
static void walk_cb(uv_handle_t *handle, void *arg)
{
if (!uv_is_closing(handle)) {
+#ifdef WIN32
+ uv_tty_set_mode(&tty, UV_TTY_MODE_NORMAL);
+#endif
uv_close(handle, NULL);
}
}
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index d4ace3030c..d040ff5f8c 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -445,6 +445,8 @@ function module.new_argv(...)
for _, k in ipairs({
'HOME',
'ASAN_OPTIONS',
+ 'TSAN_OPTIONS',
+ 'MSAN_OPTIONS',
'LD_LIBRARY_PATH',
'PATH',
'NVIM_LOG_FILE',
diff --git a/test/functional/legacy/055_list_and_dict_types_spec.lua b/test/functional/legacy/055_list_and_dict_types_spec.lua
index dcbd8b7dff..91ba8bb106 100644
--- a/test/functional/legacy/055_list_and_dict_types_spec.lua
+++ b/test/functional/legacy/055_list_and_dict_types_spec.lua
@@ -666,7 +666,7 @@ describe('list and dictionary types', function()
Vim(put):E741:
{'a': 99, 'b': 100}
No remove() of write-protected scope-level variable:
- Vim(put):E795:
+ Vim(put):E742:
No extend() of write-protected scope-level variable:
Vim(put):E742:
No :unlet of variable in locked scope:
diff --git a/test/functional/provider/python3_spec.lua b/test/functional/provider/python3_spec.lua
index 68d4d1e2a1..a3c6c57a73 100644
--- a/test/functional/provider/python3_spec.lua
+++ b/test/functional/provider/python3_spec.lua
@@ -90,6 +90,12 @@ describe('python3 provider', function()
eq({1, 2, {['key'] = 'val'}}, eval([[py3eval('[1, 2, {"key": "val"}]')]]))
end)
+ it('pyxeval #10758', function()
+ eq(0, eval([[&pyxversion]]))
+ eq(3, eval([[pyxeval('sys.version_info[:3][0]')]]))
+ eq(3, eval([[&pyxversion]]))
+ end)
+
it('RPC call to expand("<afile>") during BufDelete #5245 #5617', function()
source([=[
python3 << EOF
diff --git a/test/functional/terminal/buffer_spec.lua b/test/functional/terminal/buffer_spec.lua
index e598c325a8..1763574bf9 100644
--- a/test/functional/terminal/buffer_spec.lua
+++ b/test/functional/terminal/buffer_spec.lua
@@ -158,14 +158,15 @@ describe(':terminal buffer', function()
end)
it('handles loss of focus gracefully', function()
- if helpers.pending_win32(pending) then return end
-- Change the statusline to avoid printing the file name, which varies.
nvim('set_option', 'statusline', '==========')
feed_command('set laststatus=0')
-- Save the buffer number of the terminal for later testing.
local tbuf = eval('bufnr("%")')
-
+ local exitcmd = helpers.iswin()
+ and "['cmd', '/c', 'exit']"
+ or "['sh', '-c', 'exit']"
source([[
function! SplitWindow(id, data, event)
new
@@ -173,7 +174,7 @@ describe(':terminal buffer', function()
endfunction
startinsert
- call jobstart(['sh', '-c', 'exit'], {'on_exit': function("SplitWindow")})
+ call jobstart(]]..exitcmd..[[, {'on_exit': function("SplitWindow")})
call feedkeys("\<C-\>", 't') " vim will expect <C-n>, but be exited out of
" the terminal before it can be entered.
]])
diff --git a/test/functional/terminal/window_split_tab_spec.lua b/test/functional/terminal/window_split_tab_spec.lua
index ad70b3d14f..7b49a38e77 100644
--- a/test/functional/terminal/window_split_tab_spec.lua
+++ b/test/functional/terminal/window_split_tab_spec.lua
@@ -37,7 +37,6 @@ describe(':terminal', function()
end)
it('does not change size on WinEnter', function()
- if helpers.pending_win32(pending) then return end
feed('<c-\\><c-n>')
feed('k')
feed_command('2split')
diff --git a/test/functional/ui/float_spec.lua b/test/functional/ui/float_spec.lua
index 8a1758c4a0..8dfe36c799 100644
--- a/test/functional/ui/float_spec.lua
+++ b/test/functional/ui/float_spec.lua
@@ -383,6 +383,7 @@ describe('floating windows', function()
command('set number')
command('set signcolumn=yes')
command('set cursorline')
+ command('set foldcolumn=1')
command('hi NormalFloat guibg=#333333')
feed('ix<cr>y<cr><esc>gg')
local win = meths.open_win(0, false, {relative='editor', width=20, height=4, row=4, col=10, style='minimal'})
@@ -397,9 +398,9 @@ describe('floating windows', function()
[2:----------------------------------------]|
|
## grid 2
- {19: }{20: 1 }{21:^x }|
- {19: }{14: 2 }y |
- {19: }{14: 3 } |
+ {19: }{20: 1 }{21:^x }|
+ {19: }{14: 2 }y |
+ {19: }{14: 3 } |
{0:~ }|
{0:~ }|
{0:~ }|
@@ -410,15 +411,15 @@ describe('floating windows', function()
{15: }|
]], float_pos={[3] = {{id = 1001}, "NW", 1, 4, 10, true}}}
else
- screen:expect([[
- {19: }{20: 1 }{21:^x }|
- {19: }{14: 2 }y |
- {19: }{14: 3 } {15:x } |
+ screen:expect{grid=[[
+ {19: }{20: 1 }{21:^x }|
+ {19: }{14: 2 }y |
+ {19: }{14: 3 } {15:x } |
{0:~ }{15:y }{0: }|
{0:~ }{15: }{0: }|
{0:~ }{15: }{0: }|
|
- ]])
+ ]]}
end
-- signcolumn=yes still works if there actually are signs
@@ -435,9 +436,9 @@ describe('floating windows', function()
[2:----------------------------------------]|
|
## grid 2
- {17:πŒ’Μ€ΜΜ‚ΜƒΜ…Μ„πŒ’Μ€ΜΜ‚ΜƒΜ…Μ„}{20: 1 }{21:^x }|
- {19: }{14: 2 }y |
- {19: }{14: 3 } |
+ {19: }{17:πŒ’Μ€ΜΜ‚ΜƒΜ…Μ„πŒ’Μ€ΜΜ‚ΜƒΜ…Μ„}{20: 1 }{21:^x }|
+ {19: }{14: 2 }y |
+ {19: }{14: 3 } |
{0:~ }|
{0:~ }|
{0:~ }|
@@ -450,9 +451,9 @@ describe('floating windows', function()
else
screen:expect([[
- {17:πŒ’Μ€ΜΜ‚ΜƒΜ…Μ„πŒ’Μ€ΜΜ‚ΜƒΜ…Μ„}{20: 1 }{21:^x }|
- {19: }{14: 2 }y |
- {19: }{14: 3 } {17:πŒ’Μ€ΜΜ‚ΜƒΜ…Μ„πŒ’Μ€ΜΜ‚ΜƒΜ…Μ„}{15:x } |
+ {19: }{17:πŒ’Μ€ΜΜ‚ΜƒΜ…Μ„πŒ’Μ€ΜΜ‚ΜƒΜ…Μ„}{20: 1 }{21:^x }|
+ {19: }{14: 2 }y |
+ {19: }{14: 3 } {17:πŒ’Μ€ΜΜ‚ΜƒΜ…Μ„πŒ’Μ€ΜΜ‚ΜƒΜ…Μ„}{15:x } |
{0:~ }{19: }{15:y }{0: }|
{0:~ }{19: }{15: }{0: }|
{0:~ }{15: }{0: }|
@@ -474,9 +475,9 @@ describe('floating windows', function()
[2:----------------------------------------]|
|
## grid 2
- {19: }{20: 1 }{21:^x }|
- {19: }{14: 2 }y |
- {19: }{14: 3 } |
+ {19: }{20: 1 }{21:^x }|
+ {19: }{14: 2 }y |
+ {19: }{14: 3 } |
{0:~ }|
{0:~ }|
{0:~ }|
@@ -488,9 +489,9 @@ describe('floating windows', function()
]], float_pos={[3] = {{id = 1001}, "NW", 1, 4, 10, true}}}
else
screen:expect([[
- {19: }{20: 1 }{21:^x }|
- {19: }{14: 2 }y |
- {19: }{14: 3 } {15: } |
+ {19: }{20: 1 }{21:^x }|
+ {19: }{14: 2 }y |
+ {19: }{14: 3 } {15: } |
{0:~ }{15: }{0: }|
{0:~ }{15: }{0: }|
{0:~ }{15: }{0: }|
@@ -4143,14 +4144,14 @@ describe('floating windows', function()
[4:----------------------------------------]|
[4:----------------------------------------]|
:tabnew |
- ## grid 2
+ ## grid 2 (hidden)
x |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
- ## grid 3
+ ## grid 3 (hidden)
{1:y }|
{2:~ }|
## grid 4
@@ -4192,7 +4193,7 @@ describe('floating windows', function()
## grid 3
{1:y }|
{2:~ }|
- ## grid 4
+ ## grid 4 (hidden)
|
{0:~ }|
{0:~ }|
@@ -4222,13 +4223,13 @@ describe('floating windows', function()
[4:----------------------------------------]|
[4:----------------------------------------]|
:tabnext |
- ## grid 2
+ ## grid 2 (hidden)
x |
{0:~ }|
{0:~ }|
{0:~ }|
{0:~ }|
- ## grid 3
+ ## grid 3 (hidden)
{1:y }|
{2:~ }|
## grid 4
@@ -4266,7 +4267,7 @@ describe('floating windows', function()
[4:----------------------------------------]|
[4:----------------------------------------]|
:tabnew |
- ## grid 2
+ ## grid 2 (hidden)
x |
{0:~ }|
{0:~ }|
@@ -4312,7 +4313,7 @@ describe('floating windows', function()
{0:~ }|
{0:~ }|
{0:~ }|
- ## grid 4
+ ## grid 4 (hidden)
|
{0:~ }|
{0:~ }|
@@ -4332,7 +4333,7 @@ describe('floating windows', function()
[4:----------------------------------------]|
[4:----------------------------------------]|
:tabnext |
- ## grid 2
+ ## grid 2 (hidden)
x |
{0:~ }|
{0:~ }|
@@ -4364,7 +4365,11 @@ describe('floating windows', function()
[5] = {foreground = tonumber('0x990000'), background = tonumber('0xfff1ff')},
[6] = {foreground = tonumber('0x332533'), background = tonumber('0xfff1ff')},
[7] = {background = tonumber('0xffcfff'), bold = true, foreground = tonumber('0x0000d8')},
- [8] = {background = Screen.colors.LightMagenta, bold = true, foreground = Screen.colors.Blue1}
+ [8] = {background = Screen.colors.LightMagenta, bold = true, foreground = Screen.colors.Blue1},
+ [9] = {background = Screen.colors.LightMagenta, blend=30},
+ [10] = {foreground = Screen.colors.Red, background = Screen.colors.LightMagenta, blend=0},
+ [11] = {foreground = Screen.colors.Red, background = Screen.colors.LightMagenta, blend=80},
+ [12] = {background = Screen.colors.LightMagenta, bold = true, foreground = Screen.colors.Blue1, blend=30},
})
insert([[
Lorem ipsum dolor sit amet, consectetur
@@ -4444,9 +4449,9 @@ describe('floating windows', function()
qui officia deserunt mollit anim id est |
laborum^. |
## grid 4
- {1:test }|
- {1: }|
- {1:popup text }|
+ {9:test }|
+ {9: }|
+ {9:popup text }|
]], float_pos={[4] = {{id = 1002}, "NW", 1, 2, 5, true}}, unchanged=true}
else
screen:expect([[
@@ -4486,9 +4491,9 @@ describe('floating windows', function()
qui officia deserunt mollit anim id est |
laborum^. |
## grid 4
- {1:test }|
- {1: }|
- {4:popup text}{1: }|
+ {9:test }|
+ {9: }|
+ {10:popup text}{9: }|
]], float_pos={[4] = {{id = 1002}, "NW", 1, 2, 5, true}}}
else
screen:expect([[
@@ -4496,7 +4501,7 @@ describe('floating windows', function()
exercitation ullamco laboris nisi ut aliquip ex |
ea co{2:test}{3:o consequat}. Duis aute irure dolor in |
repre{3:henderit in vol}uptate velit esse cillum |
- dolor{4:popup text}{3:ul}la pariatur. Excepteur sint |
+ dolor{10:popup text}{3:ul}la pariatur. Excepteur sint |
occaecat cupidatat non proident, sunt in culpa |
qui officia deserunt mollit anim id est |
laborum^. |
@@ -4527,9 +4532,9 @@ describe('floating windows', function()
qui officia deserunt mollit anim id est |
laborum^. |
## grid 4
- {1:test }|
- {1: }|
- {4:popup text}{1: }|
+ {9:test }|
+ {9: }|
+ {11:popup text}{9: }|
]], float_pos={[4] = {{id = 1002}, "NW", 1, 2, 5, true}}, unchanged=true}
else
screen:expect([[
@@ -4569,9 +4574,9 @@ describe('floating windows', function()
qui officia deserunt mollit anim id est |
laborum^. |
## grid 4
- {4:popup text}{1: }|
- {8:~ }|
- {8:~ }|
+ {11:popup text}{9: }|
+ {12:~ }|
+ {12:~ }|
]], float_pos={[4] = {{id = 1002}, "NW", 1, 2, 5, true}}}
else
meths.input_mouse('wheel', 'down', '', 0, 4, 7)
@@ -4671,7 +4676,7 @@ describe('floating windows', function()
[2] = {foreground = Screen.colors.Grey0, background = tonumber('0xffcfff')},
[3] = {bold = true, foreground = Screen.colors.Blue1},
[4] = {background = tonumber('0xffcfff'), bold = true, foreground = tonumber('0xb282ff')},
- [5] = {background = Screen.colors.LightMagenta},
+ [5] = {background = Screen.colors.LightMagenta, blend=30},
})
if multigrid then
screen:expect{grid=[[
diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua
index 4f243e6413..238cc368da 100644
--- a/test/functional/ui/inccommand_spec.lua
+++ b/test/functional/ui/inccommand_spec.lua
@@ -2634,3 +2634,19 @@ it(':substitute with inccommand, timer-induced :redraw #9777', function()
:%s/foo/ZZZ^ |
]])
end)
+
+it('long :%s/ with inccommand does not collapse cmdline', function()
+ local screen = Screen.new(10,5)
+ clear()
+ common_setup(screen)
+ command('set inccommand=nosplit')
+ feed(':%s/AAAAAAA', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A',
+ 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A', 'A')
+ screen:expect([[
+ {15:~ }|
+ {15:~ }|
+ :%s/AAAAAAAA|
+ AAAAAAAAAAAA|
+ AAAAAAA^ |
+ ]])
+end)
diff --git a/test/functional/ui/input_spec.lua b/test/functional/ui/input_spec.lua
index 121cbe47d6..0009f2c31b 100644
--- a/test/functional/ui/input_spec.lua
+++ b/test/functional/ui/input_spec.lua
@@ -103,6 +103,11 @@ describe('mappings', function()
check_mapping('<kequal>','<kequal>')
check_mapping('<KPEquals>','<kequal>')
end)
+
+ it('support meta + multibyte char mapping', function()
+ add_mapping('<m-Γ€>', '<m-Γ€>')
+ check_mapping('<m-Γ€>', '<m-Γ€>')
+ end)
end)
describe('feeding large chunks of input with <Paste>', function()
diff --git a/test/functional/ui/messages_spec.lua b/test/functional/ui/messages_spec.lua
index 9a1a0f66a2..ed65c4526f 100644
--- a/test/functional/ui/messages_spec.lua
+++ b/test/functional/ui/messages_spec.lua
@@ -6,7 +6,10 @@ local eq = helpers.eq
local command = helpers.command
local set_method_error = helpers.set_method_error
local meths = helpers.meths
-
+local test_build_dir = helpers.test_build_dir
+local nvim_prog = helpers.nvim_prog
+local iswin = helpers.iswin
+local exc_exec = helpers.exc_exec
describe('ui/ext_messages', function()
local screen
@@ -1004,3 +1007,48 @@ describe('ui/ext_messages', function()
}}
end)
end)
+
+describe('ui/msg_puts_printf', function()
+ it('output multibyte characters correctly', function()
+ local screen
+ local cmd = ''
+ local locale_dir = test_build_dir..'/share/locale/ja/LC_MESSAGES'
+
+ clear({env={LANG='ja_JP.UTF-8'}})
+ screen = Screen.new(25, 5)
+ screen:attach()
+
+ if iswin() then
+ if os.execute('chcp 932 > NUL 2>&1') ~= 0 then
+ pending('missing japanese language features', function() end)
+ return
+ else
+ cmd = 'chcp 932 > NULL & '
+ end
+ else
+ if (exc_exec('lang ja_JP.UTF-8') ~= 0) then
+ pending('Locale ja_JP.UTF-8 not supported', function() end)
+ return
+ elseif helpers.isCI() then
+ -- Fails non--Windows CI. Message catalog direcotry issue?
+ pending('fails on unix CI', function() end)
+ return
+ end
+ end
+
+ os.execute('cmake -E make_directory '..locale_dir)
+ os.execute('cmake -E copy '..test_build_dir..'/src/nvim/po/ja.mo '..locale_dir..'/nvim.mo')
+
+ cmd = cmd..'"'..nvim_prog..'" -u NONE -i NONE -Es -V1'
+ command([[call termopen(']]..cmd..[[')]])
+ screen:expect([[
+ ^Exヒードにε…₯γ‚ŠγΎγ™. γƒŽγƒΌ |
+ γƒžγƒ«γƒ’γƒΌγƒ‰γ«ζˆ»γ‚‹γ«γ―"visu|
+ al"とε…₯εŠ›γ—γ¦γγ γ•γ„. |
+ : |
+ |
+ ]])
+
+ os.execute('cmake -E remove_directory '..test_build_dir..'/share')
+ end)
+end)
diff --git a/test/functional/ui/mode_spec.lua b/test/functional/ui/mode_spec.lua
index f6b3c1c3c9..a09df075aa 100644
--- a/test/functional/ui/mode_spec.lua
+++ b/test/functional/ui/mode_spec.lua
@@ -2,8 +2,7 @@ local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, feed, insert = helpers.clear, helpers.feed, helpers.insert
-local command, eval = helpers.command, helpers.eval
-local eq = helpers.eq
+local command = helpers.command
describe('ui mode_change event', function()
local screen
@@ -63,7 +62,7 @@ describe('ui mode_change event', function()
]], mode="normal"}
command("set showmatch")
- eq(eval('&matchtime'), 5) -- tenths of seconds
+ command("set matchtime=1") -- tenths of seconds
feed('a(stuff')
screen:expect{grid=[[
word(stuff^ |
@@ -80,7 +79,6 @@ describe('ui mode_change event', function()
{2:-- INSERT --} |
]], mode="showmatch"}
- screen:sleep(400)
screen:expect{grid=[[
word(stuff)^ |
{0:~ }|
diff --git a/test/functional/ui/multigrid_spec.lua b/test/functional/ui/multigrid_spec.lua
index c5a23e4661..a910f5e2ea 100644
--- a/test/functional/ui/multigrid_spec.lua
+++ b/test/functional/ui/multigrid_spec.lua
@@ -76,7 +76,7 @@ describe('ext_multigrid', function()
it('positions windows correctly', function()
command('vsplit')
- screen:expect([[
+ screen:expect{grid=[[
## grid 1
[3:--------------------------]{12:β”‚}[2:--------------------------]|
[3:--------------------------]{12:β”‚}[2:--------------------------]|
@@ -118,15 +118,15 @@ describe('ext_multigrid', function()
{1:~ }|
{1:~ }|
{1:~ }|
- ]], nil, nil, function()
+ ]], condition=function()
eq({
- [2] = { win = 1000, startrow = 0, startcol = 27, width = 26, height = 12 },
- [3] = { win = 1001, startrow = 0, startcol = 0, width = 26, height = 12 }
+ [2] = { win = {id=1000}, startrow = 0, startcol = 27, width = 26, height = 12 },
+ [3] = { win = {id=1001}, startrow = 0, startcol = 0, width = 26, height = 12 }
}, screen.win_position)
- end)
+ end}
command('wincmd l')
command('split')
- screen:expect([[
+ screen:expect{grid=[[
## grid 1
[3:--------------------------]{12:β”‚}[4:--------------------------]|
[3:--------------------------]{12:β”‚}[4:--------------------------]|
@@ -168,16 +168,16 @@ describe('ext_multigrid', function()
{1:~ }|
{1:~ }|
{1:~ }|
- ]], nil, nil, function()
+ ]], condition=function()
eq({
- [2] = { win = 1000, startrow = 7, startcol = 27, width = 26, height = 5 },
- [3] = { win = 1001, startrow = 0, startcol = 0, width = 26, height = 12 },
- [4] = { win = 1002, startrow = 0, startcol = 27, width = 26, height = 6 }
+ [2] = { win = {id=1000}, startrow = 7, startcol = 27, width = 26, height = 5 },
+ [3] = { win = {id=1001}, startrow = 0, startcol = 0, width = 26, height = 12 },
+ [4] = { win = {id=1002}, startrow = 0, startcol = 27, width = 26, height = 6 }
}, screen.win_position)
- end)
+ end}
command('wincmd h')
command('q')
- screen:expect([[
+ screen:expect{grid=[[
## grid 1
[4:-----------------------------------------------------]|
[4:-----------------------------------------------------]|
@@ -206,12 +206,12 @@ describe('ext_multigrid', function()
{1:~ }|
{1:~ }|
{1:~ }|
- ]], nil, nil, function()
+ ]], condition=function()
eq({
- [2] = { win = 1000, startrow = 7, startcol = 0, width = 53, height = 5 },
- [4] = { win = 1002, startrow = 0, startcol = 0, width = 53, height = 6 }
+ [2] = { win = {id=1000}, startrow = 7, startcol = 0, width = 53, height = 5 },
+ [4] = { win = {id=1002}, startrow = 0, startcol = 0, width = 53, height = 6 }
}, screen.win_position)
- end)
+ end}
end)
describe('split', function ()
@@ -1206,7 +1206,7 @@ describe('ext_multigrid', function()
]])
end)
- it('handles switich tabs', function()
+ it('handles switch tabs', function()
command('vsp')
screen:expect([[
## grid 1
@@ -1271,7 +1271,7 @@ describe('ext_multigrid', function()
[4:-----------------------------------------------------]|
{11:[No Name] }|
|
- ## grid 2
+ ## grid 2 (hidden)
|
{1:~ }|
{1:~ }|
@@ -1284,7 +1284,7 @@ describe('ext_multigrid', function()
{1:~ }|
{1:~ }|
{1:~ }|
- ## grid 3
+ ## grid 3 (hidden)
|
{1:~ }|
{1:~ }|
@@ -1328,7 +1328,7 @@ describe('ext_multigrid', function()
[4:-----------------------------------------------------]|
{12:[No Name] }|
|
- ## grid 2
+ ## grid 2 (hidden)
|
{1:~ }|
{1:~ }|
@@ -1341,7 +1341,7 @@ describe('ext_multigrid', function()
{1:~ }|
{1:~ }|
{1:~ }|
- ## grid 3
+ ## grid 3 (hidden)
|
{1:~ }|
{1:~ }|
@@ -1409,13 +1409,13 @@ describe('ext_multigrid', function()
{1:~ }|
{1:~ }|
{1:~ }|
- ## grid 4
+ ## grid 4 (hidden)
|
{1:~ }|
{1:~ }|
{1:~ }|
{1:~ }|
- ## grid 5
+ ## grid 5 (hidden)
|
{1:~ }|
{1:~ }|
@@ -1440,7 +1440,7 @@ describe('ext_multigrid', function()
[4:-----------------------------------------------------]|
{12:[No Name] }|
|
- ## grid 2
+ ## grid 2 (hidden)
|
{1:~ }|
{1:~ }|
@@ -1452,7 +1452,7 @@ describe('ext_multigrid', function()
{1:~ }|
{1:~ }|
{1:~ }|
- ## grid 3
+ ## grid 3 (hidden)
|
{1:~ }|
{1:~ }|
diff --git a/test/functional/ui/output_spec.lua b/test/functional/ui/output_spec.lua
index 24bf66e2d8..4a0e7ccad0 100644
--- a/test/functional/ui/output_spec.lua
+++ b/test/functional/ui/output_spec.lua
@@ -12,8 +12,6 @@ local command = helpers.command
local nvim_dir = helpers.nvim_dir
describe("shell command :!", function()
- if helpers.pending_win32(pending) then return end
-
local screen
before_each(function()
clear()
@@ -36,6 +34,7 @@ describe("shell command :!", function()
end)
it("displays output without LF/EOF. #4646 #4569 #3772", function()
+ if helpers.pending_win32(pending) then return end
-- NOTE: We use a child nvim (within a :term buffer)
-- to avoid triggering a UI flush.
child_session.feed_data(":!printf foo; sleep 200\n")
diff --git a/test/functional/ui/popupmenu_spec.lua b/test/functional/ui/popupmenu_spec.lua
index 9bfea28ed7..c4cfc9d8d3 100644
--- a/test/functional/ui/popupmenu_spec.lua
+++ b/test/functional/ui/popupmenu_spec.lua
@@ -1644,6 +1644,7 @@ describe('builtin popupmenu', function()
[42] = {foreground = tonumber('0x0c0c0c'), background = tonumber('0xe5a8e5')},
[43] = {background = tonumber('0x7f5d7f'), bold = true, foreground = tonumber('0x3f3f3f')},
[44] = {foreground = tonumber('0x3f3f3f'), background = tonumber('0x7f5d7f')},
+ [45] = {background = Screen.colors.WebGray, blend=0},
})
command('syntax on')
command('set mouse=a')
@@ -1761,7 +1762,7 @@ describe('builtin popupmenu', function()
Lorem ipsum d{1:ol}or sit amet, consectetur |
adipisicing elit, sed do eiusmod tempor |
bla bla incididunt^ |
- incidid{22: incididunt }{27: }d{1:ol}ore magna aliqua. |
+ incidid{45: incididunt }{27: }d{1:ol}ore magna aliqua. |
Ut enim{28: }{29:ut}{28: minim veniam}{25:,} quis nostrud |
exercit{28:a}{29:labore}{28:llamco la}{25:b}oris nisi ut aliquip ex |
{2:[No Nam}{30:e}{43:et}{30:[+] }{32: }{2: }|
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index 81a15cada2..3b39794465 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -316,9 +316,10 @@ local ext_keys = {
-- cmdline_block: Expected ext_cmdline block (for function definitions)
-- wildmenu_items: Expected items for ext_wildmenu
-- wildmenu_pos: Expected position for ext_wildmenu
-function Screen:expect(expected, attr_ids, attr_ignore)
+function Screen:expect(expected, attr_ids, attr_ignore, ...)
local grid, condition = nil, nil
local expected_rows = {}
+ assert(next({...}) == nil, "invalid args to expect()")
if type(expected) == "table" then
assert(not (attr_ids ~= nil or attr_ignore ~= nil))
local is_key = {grid=true, attr_ids=true, attr_ignore=true, condition=true,
@@ -499,7 +500,8 @@ function Screen:_wait(check, flags)
local did_miminal_timeout = false
local function notification_cb(method, args)
- assert(method == 'redraw')
+ assert(method == 'redraw', string.format(
+ 'notification_cb: unexpected method (%s, args=%s)', method, inspect(args)))
did_flush = self:_redraw(args)
if not did_flush then
return
@@ -1211,7 +1213,11 @@ function Screen:render(headers, attr_state, preview)
local rv = {}
for igrid,grid in pairs(self._grids) do
if headers then
- table.insert(rv, "## grid "..igrid)
+ local suffix = ""
+ if igrid > 1 and self.win_position[igrid] == nil and self.float_pos[igrid] == nil then
+ suffix = " (hidden)"
+ end
+ table.insert(rv, "## grid "..igrid..suffix)
end
for i = 1, grid.height do
local cursor = self._cursor.grid == igrid and self._cursor.row == i
@@ -1491,7 +1497,7 @@ function Screen:_equal_attrs(a, b)
a.underline == b.underline and a.undercurl == b.undercurl and
a.italic == b.italic and a.reverse == b.reverse and
a.foreground == b.foreground and a.background == b.background and
- a.special == b.special
+ a.special == b.special and a.blend == b.blend
end
function Screen:_equal_info(a, b)