aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2017-06-26 14:49:15 +0200
committerBjörn Linse <bjorn.linse@gmail.com>2018-10-15 20:13:11 +0200
commitc8810a51a3a7ef1185b45c07d93f7e6769c5ab55 (patch)
tree55e62aa6c09a729c9c34bd5d4d4d40321f982376
parent8fd092f3ff15bf70f84ec0d716c5aaa2c7379fa1 (diff)
downloadrneovim-c8810a51a3a7ef1185b45c07d93f7e6769c5ab55.tar.gz
rneovim-c8810a51a3a7ef1185b45c07d93f7e6769c5ab55.tar.bz2
rneovim-c8810a51a3a7ef1185b45c07d93f7e6769c5ab55.zip
tests: improve robustness of immediate successes in screen tests
-rw-r--r--test/functional/api/menu_spec.lua8
-rw-r--r--test/functional/eval/execute_spec.lua4
-rw-r--r--test/functional/eval/input_spec.lua16
-rw-r--r--test/functional/eval/timer_spec.lua15
-rw-r--r--test/functional/legacy/search_spec.lua21
-rw-r--r--test/functional/normal/put_spec.lua13
-rw-r--r--test/functional/options/fillchars_spec.lua7
-rw-r--r--test/functional/terminal/scrollback_spec.lua3
-rw-r--r--test/functional/terminal/tui_spec.lua4
-rw-r--r--test/functional/ui/cmdline_highlight_spec.lua15
-rw-r--r--test/functional/ui/cmdline_spec.lua11
-rw-r--r--test/functional/ui/highlight_spec.lua4
-rw-r--r--test/functional/ui/inccommand_spec.lua46
-rw-r--r--test/functional/ui/mouse_spec.lua27
-rw-r--r--test/functional/ui/output_spec.lua19
-rw-r--r--test/functional/ui/screen.lua161
-rw-r--r--test/functional/ui/screen_basic_spec.lua35
-rw-r--r--test/functional/ui/searchhl_spec.lua12
-rw-r--r--test/functional/ui/wildmode_spec.lua36
-rw-r--r--test/functional/viml/completion_spec.lua4
20 files changed, 314 insertions, 147 deletions
diff --git a/test/functional/api/menu_spec.lua b/test/functional/api/menu_spec.lua
index d55b7b118a..2cfa0e3e47 100644
--- a/test/functional/api/menu_spec.lua
+++ b/test/functional/api/menu_spec.lua
@@ -20,15 +20,15 @@ describe("update_menu notification", function()
end)
local function expect_sent(expected)
- screen:wait(function()
+ screen:expect{condition=function()
if screen.update_menu ~= expected then
if expected then
- return 'update_menu was expected but not sent'
+ error('update_menu was expected but not sent')
else
- return 'update_menu was sent unexpectedly'
+ error('update_menu was sent unexpectedly')
end
end
- end)
+ end, unchanged=(not expected)}
end
it("should be sent when adding a menu", function()
diff --git a/test/functional/eval/execute_spec.lua b/test/functional/eval/execute_spec.lua
index 925e311c7d..af37ab8d55 100644
--- a/test/functional/eval/execute_spec.lua
+++ b/test/functional/eval/execute_spec.lua
@@ -161,13 +161,13 @@ describe('execute()', function()
eq('42', eval('g:mes'))
command('let g:mes = execute("echon 13", "silent")')
- screen:expect([[
+ screen:expect{grid=[[
^ |
~ |
~ |
~ |
|
- ]])
+ ]], unchanged=true}
eq('13', eval('g:mes'))
end)
diff --git a/test/functional/eval/input_spec.lua b/test/functional/eval/input_spec.lua
index 777f49462d..82e75d7a8e 100644
--- a/test/functional/eval/input_spec.lua
+++ b/test/functional/eval/input_spec.lua
@@ -150,13 +150,13 @@ describe('input()', function()
{T:Foo>}Bar^ |
]])
command('redraw!')
- screen:expect([[
+ screen:expect{grid=[[
|
{EOB:~ }|
{EOB:~ }|
{EOB:~ }|
{T:Foo>}Bar^ |
- ]])
+ ]], reset=true}
feed('<BS>')
screen:expect([[
|
@@ -166,13 +166,13 @@ describe('input()', function()
{T:Foo>}Ba^ |
]])
command('redraw!')
- screen:expect([[
+ screen:expect{grid=[[
|
{EOB:~ }|
{EOB:~ }|
{EOB:~ }|
{T:Foo>}Ba^ |
- ]])
+ ]], reset=true}
end)
it('allows omitting everything with dictionary argument', function()
command('echohl Test')
@@ -348,13 +348,13 @@ describe('inputdialog()', function()
{T:Foo>}Bar^ |
]])
command('redraw!')
- screen:expect([[
+ screen:expect{grid=[[
|
{EOB:~ }|
{EOB:~ }|
{EOB:~ }|
{T:Foo>}Bar^ |
- ]])
+ ]], reset=true}
feed('<BS>')
screen:expect([[
|
@@ -364,13 +364,13 @@ describe('inputdialog()', function()
{T:Foo>}Ba^ |
]])
command('redraw!')
- screen:expect([[
+ screen:expect{grid=[[
|
{EOB:~ }|
{EOB:~ }|
{EOB:~ }|
{T:Foo>}Ba^ |
- ]])
+ ]], reset=true}
end)
it('allows omitting everything with dictionary argument', function()
command('echohl Test')
diff --git a/test/functional/eval/timer_spec.lua b/test/functional/eval/timer_spec.lua
index 040ab30522..c945f12e0e 100644
--- a/test/functional/eval/timer_spec.lua
+++ b/test/functional/eval/timer_spec.lua
@@ -113,7 +113,6 @@ describe('timers', function()
^ |
]])
- screen:sleep(200)
screen:expect([[
ITEM 1 |
ITEM 2 |
@@ -200,13 +199,14 @@ describe('timers', function()
screen:attach()
screen:set_default_attr_ids( {[0] = {bold=true, foreground=255}} )
source([[
+ let g:val = 0
func! MyHandler(timer)
echo "evil"
+ let g:val = 1
endfunc
]])
command("call timer_start(100, 'MyHandler', {'repeat': 1})")
feed(":good")
- screen:sleep(200)
screen:expect([[
|
{0:~ }|
@@ -215,6 +215,17 @@ describe('timers', function()
{0:~ }|
:good^ |
]])
+
+ screen:expect{grid=[[
+ |
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ {0:~ }|
+ :good^ |
+ ]], intermediate=true, timeout=200}
+
+ eq(1, eval('g:val'))
end)
end)
diff --git a/test/functional/legacy/search_spec.lua b/test/functional/legacy/search_spec.lua
index 277d8d6c7f..3ed06a22e7 100644
--- a/test/functional/legacy/search_spec.lua
+++ b/test/functional/legacy/search_spec.lua
@@ -92,6 +92,7 @@ describe('search cmdline', function()
9 {inc:the}se |
/the^ |
]])
+ screen.bell = false
feed('<C-G>')
if wrapscan == 'wrapscan' then
screen:expect([[
@@ -100,11 +101,13 @@ describe('search cmdline', function()
/the^ |
]])
else
- screen:expect([[
+ screen:expect{grid=[[
8 them |
9 {inc:the}se |
/the^ |
- ]])
+ ]], condition=function()
+ eq(true, screen.bell)
+ end}
feed('<CR>')
eq({0, 0, 0, 0}, funcs.getpos('"'))
end
@@ -120,6 +123,7 @@ describe('search cmdline', function()
10 foobar |
?the^ |
]])
+ screen.bell = false
if wrapscan == 'wrapscan' then
feed('<C-G>')
screen:expect([[
@@ -135,11 +139,13 @@ describe('search cmdline', function()
]])
else
feed('<C-G>')
- screen:expect([[
+ screen:expect{grid=[[
9 {inc:the}se |
10 foobar |
?the^ |
- ]])
+ ]], condition=function()
+ eq(true, screen.bell)
+ end}
feed('<CR>')
screen:expect([[
9 ^these |
@@ -173,6 +179,7 @@ describe('search cmdline', function()
3 the |
?the^ |
]])
+ screen.bell = false
feed('<C-T>')
if wrapscan == 'wrapscan' then
screen:expect([[
@@ -181,11 +188,13 @@ describe('search cmdline', function()
?the^ |
]])
else
- screen:expect([[
+ screen:expect{grid=[[
2 {inc:the}se |
3 the |
?the^ |
- ]])
+ ]], condition=function()
+ eq(true, screen.bell)
+ end}
end
end
diff --git a/test/functional/normal/put_spec.lua b/test/functional/normal/put_spec.lua
index 148a35ec6b..29cef13e39 100644
--- a/test/functional/normal/put_spec.lua
+++ b/test/functional/normal/put_spec.lua
@@ -874,20 +874,23 @@ describe('put command', function()
local function bell_test(actions, should_ring)
local screen = Screen.new()
screen:attach()
+ if should_ring then
+ -- check bell is not set by nvim before the action
+ screen:sleep(50)
+ end
helpers.ok(not screen.bell and not screen.visualbell)
actions()
- helpers.wait()
- screen:wait(function()
+ screen:expect{condition=function()
if should_ring then
if not screen.bell and not screen.visualbell then
- return 'Bell was not rung after action'
+ error('Bell was not rung after action')
end
else
if screen.bell or screen.visualbell then
- return 'Bell was rung after action'
+ error('Bell was rung after action')
end
end
- end)
+ end, unchanged=(not should_ring)}
screen:detach()
end
diff --git a/test/functional/options/fillchars_spec.lua b/test/functional/options/fillchars_spec.lua
index ab61935d4c..99177a11b4 100644
--- a/test/functional/options/fillchars_spec.lua
+++ b/test/functional/options/fillchars_spec.lua
@@ -36,6 +36,13 @@ describe("'fillchars'", function()
]])
end)
it('supports whitespace', function()
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]])
command('set fillchars=eob:\\ ')
screen:expect([[
^ |
diff --git a/test/functional/terminal/scrollback_spec.lua b/test/functional/terminal/scrollback_spec.lua
index 5e36fea474..2e236327c8 100644
--- a/test/functional/terminal/scrollback_spec.lua
+++ b/test/functional/terminal/scrollback_spec.lua
@@ -426,9 +426,8 @@ describe("'scrollback' option", function()
curbufmeths.set_option('scrollback', 200)
-- Wait for prompt.
- screen:expect{any='$'}
+ screen:expect{any='%$'}
- wait()
if iswin() then
feed_data('for($i=1;$i -le 30;$i++){Write-Host \"line$i\"}\r')
else
diff --git a/test/functional/terminal/tui_spec.lua b/test/functional/terminal/tui_spec.lua
index 834720edc6..365bd2a0be 100644
--- a/test/functional/terminal/tui_spec.lua
+++ b/test/functional/terminal/tui_spec.lua
@@ -370,7 +370,7 @@ describe('tui FocusGained/FocusLost', function()
{3:-- TERMINAL --} |
]])
feed_data('\027[O')
- screen:expect([[
+ screen:expect{grid=[[
|
{4:~ }|
{4:~ }|
@@ -378,7 +378,7 @@ describe('tui FocusGained/FocusLost', function()
{5:[No Name] }|
:{1: } |
{3:-- TERMINAL --} |
- ]])
+ ]], unchanged=true}
end)
it('in cmdline-mode', function()
diff --git a/test/functional/ui/cmdline_highlight_spec.lua b/test/functional/ui/cmdline_highlight_spec.lua
index 5d9fffdf23..768b24dd81 100644
--- a/test/functional/ui/cmdline_highlight_spec.lua
+++ b/test/functional/ui/cmdline_highlight_spec.lua
@@ -267,7 +267,7 @@ describe('Command-line coloring', function()
:echo {RBP1:(}{RBP2:(}42{RBP2:)}^ |
]])
redraw_input()
- screen:expect([[
+ screen:expect{grid=[[
|
{EOB:~ }|
{EOB:~ }|
@@ -276,7 +276,7 @@ describe('Command-line coloring', function()
{EOB:~ }|
{EOB:~ }|
:echo {RBP1:(}{RBP2:(}42{RBP2:)}^ |
- ]])
+ ]], reset=true}
end)
for _, func_part in ipairs({'', 'n', 'msg'}) do
it('disables :echo' .. func_part .. ' messages', function()
@@ -855,17 +855,6 @@ describe('Ex commands coloring support', function()
{EOB:~ }|
|
]])
- feed('<CR>')
- screen:expect([[
- ^ |
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- {EOB:~ }|
- |
- ]])
eq('Error detected while processing :\nE605: Exception not caught: 42',
meths.command_output('messages'))
end)
diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua
index af26a6d88f..e86414fe5f 100644
--- a/test/functional/ui/cmdline_spec.lua
+++ b/test/functional/ui/cmdline_spec.lua
@@ -253,9 +253,6 @@ local function test_cmdline(linegrid)
]], cmdline=expectation}
-- erase information, so we check if it is retransmitted
- -- TODO(bfredl): when we add a flag to screen:expect{}
- -- to explicitly check redraw!, it should also do this
- screen.cmdline = {}
command("redraw!")
screen:expect{grid=[[
^ |
@@ -263,7 +260,7 @@ local function test_cmdline(linegrid)
{1:~ }|
{1:~ }|
|
- ]], cmdline=expectation}
+ ]], cmdline=expectation, reset=true}
feed('<cr>')
@@ -323,7 +320,6 @@ local function test_cmdline(linegrid)
{{' line1'}},
}}
- screen.cmdline_block = {}
command("redraw!")
screen:expect{grid=[[
^ |
@@ -339,7 +335,7 @@ local function test_cmdline(linegrid)
}}, cmdline_block = {
{{'function Foo()'}},
{{' line1'}},
- }}
+ }, reset=true}
feed('endfunction<cr>')
screen:expect{grid=[[
@@ -415,7 +411,6 @@ local function test_cmdline(linegrid)
pos = 4,
}}}
- screen.cmdline = {}
command("redraw!")
screen:expect{grid=[[
|
@@ -427,7 +422,7 @@ local function test_cmdline(linegrid)
firstc = ":",
content = {{"yank"}},
pos = 4,
- }}}
+ }}, reset=true}
feed("<c-c>")
screen:expect{grid=[[
diff --git a/test/functional/ui/highlight_spec.lua b/test/functional/ui/highlight_spec.lua
index 7f3bf3e97b..521b1e0b8a 100644
--- a/test/functional/ui/highlight_spec.lua
+++ b/test/functional/ui/highlight_spec.lua
@@ -870,7 +870,7 @@ describe("'winhighlight' highlight", function()
eq('Vim(set):E474: Invalid argument: winhl=xxx:yyy',
exc_exec("set winhl=xxx:yyy"))
eq('Normal:Background1', eval('&winhl'))
- screen:expect([[
+ screen:expect{grid=[[
{1:^ }|
{2:~ }|
{2:~ }|
@@ -879,7 +879,7 @@ describe("'winhighlight' highlight", function()
{2:~ }|
{2:~ }|
|
- ]])
+ ]], unchanged=true}
end)
diff --git a/test/functional/ui/inccommand_spec.lua b/test/functional/ui/inccommand_spec.lua
index 6a17448582..0983f6f399 100644
--- a/test/functional/ui/inccommand_spec.lua
+++ b/test/functional/ui/inccommand_spec.lua
@@ -495,6 +495,18 @@ describe(":substitute, 'inccommand' preserves undo", function()
for _, case in pairs(cases) do
clear()
common_setup(screen, case, default_text)
+ screen:expect([[
+ Inc substitution on |
+ two lines |
+ ^ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ |
+ ]])
feed_command("set undolevels=1")
feed("1G0")
@@ -757,8 +769,23 @@ describe(":substitute, inccommand=split", function()
-- non-modifier prefix
feed(':silent tabedit %s/tw/to')
- screen:expect{any=[[two lines]]}
- feed('<Esc>')
+ screen:expect([[
+ Inc substitution on |
+ two lines |
+ Inc substitution on |
+ two lines |
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ :silent tabedit %s/tw/to^ |
+ ]])
end)
it('shows split window when typing the pattern', function()
@@ -866,7 +893,6 @@ describe(":substitute, inccommand=split", function()
it('does not show split window for :s/', function()
feed("2gg")
feed(":s/tw")
- screen:sleep(1)
screen:expect([[
Inc substitution on |
{12:tw}o lines |
@@ -1234,8 +1260,18 @@ describe("inccommand=nosplit", function()
-- non-modifier prefix
feed(':silent tabedit %s/tw/to')
- screen:expect{any=[[two lines]]}
- feed('<Esc>')
+ screen:expect([[
+ two lines |
+ Inc substitution on |
+ two lines |
+ |
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ {15:~ }|
+ :silent tabedit %s/t|
+ w/to^ |
+ ]])
end)
it("does not show window after toggling :set inccommand", function()
diff --git a/test/functional/ui/mouse_spec.lua b/test/functional/ui/mouse_spec.lua
index debd324977..ff395adeb9 100644
--- a/test/functional/ui/mouse_spec.lua
+++ b/test/functional/ui/mouse_spec.lua
@@ -168,13 +168,13 @@ describe('ui/mouse/input', function()
|
]])
feed('<LeftMouse><11,0>')
- screen:expect([[
+ screen:expect{grid=[[
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
this is ba^r |
{0:~ }|
{0:~ }|
|
- ]])
+ ]], unchanged=true}
feed('<LeftDrag><6,0>')
screen:expect([[
{sel: + bar }{tab: + foo }{fill: }{tab:X}|
@@ -236,13 +236,13 @@ describe('ui/mouse/input', function()
|
]])
feed('<LeftDrag><4,1>')
- screen:expect([[
+ screen:expect{grid=[[
{sel: + foo }{tab: + bar }{fill: }{tab:X}|
this is fo^o |
{0:~ }|
{0:~ }|
|
- ]])
+ ]], unchanged=true}
feed('<LeftDrag><14,1>')
screen:expect([[
{tab: + bar }{sel: + foo }{fill: }{tab:X}|
@@ -254,13 +254,6 @@ describe('ui/mouse/input', function()
end)
it('out of tabline to the left moves tab left', function()
- if helpers.skip_fragile(pending,
- os.getenv("TRAVIS") and (helpers.os_name() == "osx"
- or os.getenv("CLANG_SANITIZER") == "ASAN_UBSAN")) -- #4874
- then
- return
- end
-
feed_command('%delete')
insert('this is foo')
feed_command('silent file foo | tabnew | file bar')
@@ -273,21 +266,21 @@ describe('ui/mouse/input', function()
|
]])
feed('<LeftMouse><11,0>')
- screen:expect([[
+ screen:expect{grid=[[
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
this is ba^r |
{0:~ }|
{0:~ }|
|
- ]])
+ ]], unchanged=true}
feed('<LeftDrag><11,1>')
- screen:expect([[
+ screen:expect{grid=[[
{tab: + foo }{sel: + bar }{fill: }{tab:X}|
this is ba^r |
{0:~ }|
{0:~ }|
|
- ]])
+ ]], unchanged=true}
feed('<LeftDrag><6,1>')
screen:expect([[
{sel: + bar }{tab: + foo }{fill: }{tab:X}|
@@ -319,13 +312,13 @@ describe('ui/mouse/input', function()
|
]])
feed('<LeftDrag><4,1>')
- screen:expect([[
+ screen:expect{grid=[[
{sel: + foo }{tab: + bar }{fill: }{tab:X}|
this is fo^o |
{0:~ }|
{0:~ }|
|
- ]])
+ ]], unchanged=true}
feed('<LeftDrag><7,1>')
screen:expect([[
{tab: + bar }{sel: + foo }{fill: }{tab:X}|
diff --git a/test/functional/ui/output_spec.lua b/test/functional/ui/output_spec.lua
index 0f076eac26..1850d436ac 100644
--- a/test/functional/ui/output_spec.lua
+++ b/test/functional/ui/output_spec.lua
@@ -51,25 +51,20 @@ describe("shell command :!", function()
end)
it("throttles shell-command output greater than ~10KB", function()
- if os.getenv("TRAVIS") and helpers.os_name() == "osx" then
- pending("[Unreliable on Travis macOS.]", function() end)
- return
- end
-
- screen.timeout = 20000 -- Avoid false failure on slow systems.
child_session.feed_data(
- ":!for i in $(seq 2 3000); do echo XXXXXXXXXX $i; done\n")
+ ":!for i in $(seq 2 30000); do echo XXXXXXXXXX $i; done\n")
-- If we observe any line starting with a dot, then throttling occurred.
- screen:expect{any="\n."}
+ -- 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([[
- XXXXXXXXXX 2997 |
- XXXXXXXXXX 2998 |
- XXXXXXXXXX 2999 |
- XXXXXXXXXX 3000 |
+ XXXXXXXXXX 29997 |
+ XXXXXXXXXX 29998 |
+ XXXXXXXXXX 29999 |
+ XXXXXXXXXX 30000 |
|
{10:Press ENTER or type command to continue}{1: } |
{3:-- TERMINAL --} |
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index 691bf9f64c..af036913d8 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -89,15 +89,17 @@ Screen.__index = Screen
local debug_screen
-local default_screen_timeout = 3500
+local default_timeout_factor = 1
if os.getenv('VALGRIND') then
- default_screen_timeout = default_screen_timeout * 3
+ default_timeout_factor = default_timeout_factor * 3
end
if os.getenv('CI') then
- default_screen_timeout = default_screen_timeout * 3
+ default_timeout_factor = default_timeout_factor * 3
end
+local default_screen_timeout = default_timeout_factor * 3500
+
do
local spawn, nvim_prog = helpers.spawn, helpers.nvim_prog
local session = spawn({nvim_prog, '-u', 'NONE', '-i', 'NONE', '-N', '--embed'})
@@ -160,12 +162,13 @@ function Screen.new(width, height)
_attr_table = {[0]={{},{}}},
_clear_attrs = {},
_new_attrs = false,
+ _width = width,
+ _height = height,
_cursor = {
row = 1, col = 1
},
_busy = false
}, Screen)
- self:_handle_resize(width, height)
return self
end
@@ -190,6 +193,7 @@ function Screen:attach(options)
end
self._options = options
self._clear_attrs = (options.ext_linegrid and {{},{}}) or {}
+ self:_handle_resize(self._width, self._height)
uimeths.attach(self._width, self._height, options)
if self._options.rgb == nil then
-- nvim defaults to rgb=true internally,
@@ -243,8 +247,27 @@ local ext_keys = {
-- nothing is ignored.
-- condition: Function asserting some arbitrary condition. Return value is
-- ignored, throw an error (use eq() or similar) to signal failure.
--- any: Lua pattern string expected to match a screen line.
+-- any: Lua pattern string expected to match a screen line. NB: the
+-- following chars are magic characters
+-- ( ) . % + - * ? [ ^ $
+-- and must be escaped with a preceding % for a literal match.
-- mode: Expected mode as signaled by "mode_change" event
+-- unchanged: Test that the screen state is unchanged since the previous
+-- expect(...). Any flush event resulting in a different state is
+-- considered an error. Not observing any events until timeout
+-- is acceptable.
+-- intermediate:Test that the final state is the same as the previous expect,
+-- but expect an intermediate state that is different. If possible
+-- it is better to use an explicit screen:expect(...) for this
+-- intermediate state.
+-- reset: Reset the state internal to the test Screen before starting to
+-- receive updates. This should be used after command("redraw!")
+-- or some other mechanism that will invoke "redraw!", to check
+-- that all screen state is transmitted again. This includes
+-- state related to ext_ features as mentioned below.
+-- timeout: maximum time that will be waited until the expected state is
+-- seen (or maximum time to observe an incorrect change when
+-- `unchanged` flag is used)
--
-- The following keys should be used to expect the state of various ext_
-- features. Note that an absent key will assert that the item is currently
@@ -262,7 +285,8 @@ function Screen:expect(expected, attr_ids, attr_ignore)
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,
- any=true, mode=true}
+ any=true, mode=true, unchanged=true, intermediate=true,
+ reset=true, timeout=true}
for _, v in ipairs(ext_keys) do
is_key[v] = true
end
@@ -304,7 +328,7 @@ function Screen:expect(expected, attr_ids, attr_ignore)
attr_state.id_to_index = self:hlstate_check_attrs(attr_state.ids or {})
end
self._new_attrs = false
- self:wait(function()
+ self:_wait(function()
if condition ~= nil then
local status, res = pcall(condition)
if not status then
@@ -361,7 +385,7 @@ screen:redraw_debug() to show all intermediate screen states. ]])
-- Extension features. The default expectations should cover the case of
-- the ext_ feature being disabled, or the feature currently not activated
-- (for instance no external cmdline visible). Some extensions require
- -- preprocessing to prepresent highlights in a reproducible way.
+ -- preprocessing to represent highlights in a reproducible way.
local extstate = self:_extstate_repr(attr_state)
-- convert assertion errors into invalid screen state descriptions
@@ -379,14 +403,48 @@ screen:redraw_debug() to show all intermediate screen states. ]])
if not status then
return tostring(res)
end
- end)
+ end, expected)
end
-function Screen:wait(check, timeout)
- local err, checked = false
+function Screen:_wait(check, flags)
+ local err, checked = false, false
local success_seen = false
local failure_after_success = false
local did_flush = true
+ local warn_immediate = not (flags.unchanged or flags.intermediate)
+
+ if flags.intermediate and flags.unchanged then
+ error("Choose only one of 'intermediate' and 'unchanged', not both")
+ end
+
+ if flags.reset then
+ -- throw away all state, we expect it to be retransmitted
+ self:_reset()
+ end
+
+ -- Maximum timeout, after which a incorrect state will be regarded as a
+ -- failure
+ local timeout = flags.timeout or self.timeout
+
+ -- Minimal timeout before the loop is allowed to be stopped so we
+ -- always do some check for failure after success.
+ local minimal_timeout = default_timeout_factor * 2
+
+ local immediate_seen, intermediate_seen = false, false
+ if not check() then
+ minimal_timeout = default_timeout_factor * 20
+ immediate_seen = true
+ end
+
+ -- for an unchanged test, flags.timeout means the time during the state is
+ -- expected to be unchanged, so always wait this full time.
+ if (flags.unchanged or flags.intermediate) and flags.timeout ~= nil then
+ minimal_timeout = timeout
+ end
+
+ assert(timeout >= minimal_timeout)
+ local did_miminal_timeout = false
+
local function notification_cb(method, args)
assert(method == 'redraw')
did_flush = self:_redraw(args)
@@ -395,9 +453,15 @@ function Screen:wait(check, timeout)
end
err = check()
checked = true
+ if err and immediate_seen then
+ intermediate_seen = true
+ end
+
if not err then
success_seen = true
- helpers.stop()
+ if did_miminal_timeout then
+ helpers.stop()
+ end
elseif success_seen and #args > 0 then
failure_after_success = true
--print(require('inspect')(args))
@@ -405,35 +469,83 @@ function Screen:wait(check, timeout)
return true
end
- run(nil, notification_cb, nil, timeout or self.timeout)
+ run(nil, notification_cb, nil, minimal_timeout)
if not did_flush then
err = "no flush received"
elseif not checked then
err = check()
+ if not err and flags.unchanged then
+ -- expecting NO screen change: use a shorter timout
+ success_seen = true
+ end
+ end
+
+ if not success_seen then
+ did_miminal_timeout = true
+ run(nil, notification_cb, nil, timeout-minimal_timeout)
+ end
+
+ local did_warn = false
+ if warn_immediate and immediate_seen then
+ print([[
+
+Warning: A screen test has immediate success. Try to avoid this unless the
+purpose of the test really requires it.]])
+ if intermediate_seen then
+ print([[
+There are intermediate states between the two identical expects.
+Use screen:snapshot_util() or screen:redraw_debug() to find them, and add them
+to the test if they make sense.
+]])
+ else
+ print([[If necessary, silence this warning by
+supplying the 'unchanged' argument to screen:expect.]])
+ end
+ did_warn = true
end
if failure_after_success then
print([[
Warning: Screen changes were received after the expected state. This indicates
-indeterminism in the test. Try adding wait() (or screen:expect(...)) between
+indeterminism in the test. Try adding screen:expect(...) (or wait()) between
asynchronous (feed(), nvim_input()) and synchronous API calls.
- - Use Screen:redraw_debug() to investigate the problem.
+ - Use Screen:redraw_debug() to investigate the problem. It might find
+ relevant intermediate states that should be added to the test to make it
+ more robust.
+ - If the point of the test is to assert the state after some user input
+ sent with feed(...), also adding an screen:expect(...) before the feed(...)
+ will help ensure the input is sent to nvim when nvim is in a predictable
+ state. This is preferable to using wait(), as it is more closely emulates
+ real user interaction.
- wait() can trigger redraws and consequently generate more indeterminism.
In that case try removing every wait().
]])
+ did_warn = true
+ end
+
+
+ if err then
+ assert(false, err)
+ elseif did_warn then
local tb = debug.traceback()
local index = string.find(tb, '\n%s*%[C]')
print(string.sub(tb,1,index))
end
- if err then
- assert(false, err)
+ if flags.intermediate then
+ assert(intermediate_seen, "expected intermediate screen state before final screen state")
+ elseif flags.unchanged then
+ assert(not intermediate_seen, "expected screen state to be unchanged")
end
end
function Screen:sleep(ms)
- pcall(function() self:wait(function() return "error" end, ms) end)
+ local function notification_cb(method, args)
+ assert(method == 'redraw')
+ self:_redraw(args)
+ end
+ run(nil, notification_cb, nil, ms)
end
function Screen:_redraw(updates)
@@ -486,12 +598,23 @@ end
function Screen:_handle_flush()
end
-
function Screen:_handle_grid_resize(grid, width, height)
assert(grid == 1)
self:_handle_resize(width, height)
end
+function Screen:_reset()
+ -- TODO: generalize to multigrid later
+ self:_handle_grid_clear(1)
+
+ -- TODO: share with initialization, so it generalizes?
+ self.popupmenu = nil
+ self.cmdline = {}
+ self.cmdline_block = {}
+ self.wildmenu_items = nil
+ self.wildmenu_pos = nil
+end
+
function Screen:_handle_mode_info_set(cursor_style_enabled, mode_info)
self._cursor_style_enabled = cursor_style_enabled
diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua
index 31825bdbf4..3e930b0ae7 100644
--- a/test/functional/ui/screen_basic_spec.lua
+++ b/test/functional/ui/screen_basic_spec.lua
@@ -394,7 +394,7 @@ local function screen_tests(linegrid)
end)
it('redraws properly with :tab split right after scroll', function()
- feed('30Ofoo<esc>gg')
+ feed('15Ofoo<esc>15Obar<esc>gg')
command('vsplit')
screen:expect([[
@@ -420,18 +420,17 @@ local function screen_tests(linegrid)
foo {3:│}foo |
foo {3:│}foo |
foo {3:│}foo |
- foo {3:│}foo |
- foo {3:│}foo |
- foo {3:│}foo |
- foo {3:│}foo |
- foo {3:│}foo |
- foo {3:│}foo |
- foo {3:│}foo |
- foo {3:│}foo |
+ bar {3:│}foo |
+ bar {3:│}foo |
+ bar {3:│}foo |
+ bar {3:│}foo |
+ bar {3:│}foo |
+ bar {3:│}foo |
+ bar {3:│}foo |
+ bar {3:│}foo |
{1:[No Name] [+] }{3:[No Name] [+] }|
|
]])
-
command('tab split')
screen:expect([[
{4: }{5:2}{4:+ [No Name] }{2: + [No Name] }{3: }{4:X}|
@@ -439,14 +438,14 @@ local function screen_tests(linegrid)
foo |
foo |
foo |
- foo |
- foo |
- foo |
- foo |
- foo |
- foo |
- foo |
- foo |
+ bar |
+ bar |
+ bar |
+ bar |
+ bar |
+ bar |
+ bar |
+ bar |
|
]])
end)
diff --git a/test/functional/ui/searchhl_spec.lua b/test/functional/ui/searchhl_spec.lua
index b535092ab9..a46670d8a2 100644
--- a/test/functional/ui/searchhl_spec.lua
+++ b/test/functional/ui/searchhl_spec.lua
@@ -324,7 +324,17 @@ describe('search highlighting', function()
]])
-- same, for C-t
- feed('<ESC>/<C-t>')
+ feed('<ESC>')
+ screen:expect([[
+ the first line |
+ in a ^little file |
+ |
+ {1:~ }|
+ {1:~ }|
+ {1:~ }|
+ |
+ ]])
+ feed('/<C-t>')
screen:expect([[
the first line |
in a little file |
diff --git a/test/functional/ui/wildmode_spec.lua b/test/functional/ui/wildmode_spec.lua
index 72dbef9538..8931d9245b 100644
--- a/test/functional/ui/wildmode_spec.lua
+++ b/test/functional/ui/wildmode_spec.lua
@@ -1,3 +1,5 @@
+local global_helpers = require('test.helpers')
+local shallowcopy = global_helpers.shallowcopy
local helpers = require('test.functional.helpers')(after_each)
local Screen = require('test.functional.ui.screen')
local clear, feed, command = helpers.clear, helpers.feed, helpers.command
@@ -18,6 +20,14 @@ describe("'wildmenu'", function()
screen:detach()
end)
+ -- expect the screen stayed unchanged some time after first seen success
+ local function expect_stay_unchanged(args)
+ screen:expect(args)
+ args = shallowcopy(args)
+ args.unchanged = true
+ screen:expect(args)
+ end
+
it(':sign <tab> shows wildmenu completions', function()
command('set wildmode=full')
command('set wildmenu')
@@ -76,10 +86,6 @@ describe("'wildmenu'", function()
end)
it('is preserved during :terminal activity', function()
- -- Because this test verifies a _lack_ of activity after screen:sleep(), we
- -- must wait the full timeout. So make it reasonable.
- screen.timeout = 1000
-
command('set wildmenu wildmode=full')
command('set scrollback=4')
if iswin() then
@@ -90,26 +96,24 @@ describe("'wildmenu'", function()
feed([[<C-\><C-N>gg]])
feed([[:sign <Tab>]]) -- Invoke wildmenu.
- screen:sleep(50) -- Allow some terminal output.
- screen:expect([[
+ expect_stay_unchanged{grid=[[
foo |
foo |
foo |
define jump list > |
:sign define^ |
- ]])
+ ]]}
-- cmdline CTRL-D display should also be preserved.
feed([[<C-\><C-N>]])
feed([[:sign <C-D>]]) -- Invoke cmdline CTRL-D.
- screen:sleep(50) -- Allow some terminal output.
- screen:expect([[
+ expect_stay_unchanged{grid=[[
:sign |
define place |
jump undefine |
list unplace |
:sign ^ |
- ]])
+ ]]}
-- Exiting cmdline should show the buffer.
feed([[<C-\><C-N>]])
@@ -123,22 +127,17 @@ describe("'wildmenu'", function()
end)
it('ignores :redrawstatus called from a timer #7108', function()
- -- Because this test verifies a _lack_ of activity after screen:sleep(), we
- -- must wait the full timeout. So make it reasonable.
- screen.timeout = 1000
-
command('set wildmenu wildmode=full')
command([[call timer_start(10, {->execute('redrawstatus')}, {'repeat':-1})]])
feed([[<C-\><C-N>]])
feed([[:sign <Tab>]]) -- Invoke wildmenu.
- screen:sleep(30) -- Allow some timer activity.
- screen:expect([[
+ expect_stay_unchanged{grid=[[
|
~ |
~ |
define jump list > |
:sign define^ |
- ]])
+ ]]}
end)
it('with laststatus=0, :vsplit, :term #2255', function()
@@ -164,10 +163,9 @@ describe("'wildmenu'", function()
feed([[<C-\><C-N>]])
feed([[:<Tab>]]) -- Invoke wildmenu.
- screen:sleep(10) -- Flush
-- Check only the last 2 lines, because the shell output is
-- system-dependent.
- screen:expect{any='! # & < = > @ > \n:!^'}
+ expect_stay_unchanged{any='! # & < = > @ > \n:!^'}
end)
end)
diff --git a/test/functional/viml/completion_spec.lua b/test/functional/viml/completion_spec.lua
index 3222e5783d..70b4717c32 100644
--- a/test/functional/viml/completion_spec.lua
+++ b/test/functional/viml/completion_spec.lua
@@ -757,7 +757,7 @@ describe('completion', function()
eval('1 + 1')
-- popupmenu still visible
- screen:expect([[
+ screen:expect{grid=[[
foobar fooegg |
fooegg^ |
{1:foobar }{0: }|
@@ -766,7 +766,7 @@ describe('completion', function()
{0:~ }|
{0:~ }|
{3:-- Keyword completion (^N^P) }{4:match 1 of 2} |
- ]])
+ ]], unchanged=true}
feed('<c-p>')
-- Didn't restart completion: old matches still used