tests: improve robustness of immediate successes in screen tests

This commit is contained in:
Björn Linse 2017-06-26 14:49:15 +02:00
parent 8fd092f3ff
commit c8810a51a3
20 changed files with 314 additions and 147 deletions

View File

@ -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()

View File

@ -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)

View File

@ -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')

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -36,6 +36,13 @@ describe("'fillchars'", function()
]])
end)
it('supports whitespace', function()
screen:expect([[
^ |
~ |
~ |
~ |
|
]])
command('set fillchars=eob:\\ ')
screen:expect([[
^ |

View File

@ -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

View File

@ -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()

View File

@ -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)

View File

@ -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=[[

View File

@ -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)

View File

@ -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()

View File

@ -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}|

View File

@ -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 --} |

View File

@ -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
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

View File

@ -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)

View File

@ -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 |

View File

@ -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)

View File

@ -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