aboutsummaryrefslogtreecommitdiff
path: root/test/functional
diff options
context:
space:
mode:
Diffstat (limited to 'test/functional')
-rw-r--r--test/functional/eval/timer_spec.lua129
-rw-r--r--test/functional/ex_cmds/cd_spec.lua162
-rw-r--r--test/functional/legacy/010_errorformat_spec.lua156
-rw-r--r--test/functional/legacy/027_expand_file_names_spec.lua37
-rw-r--r--test/functional/legacy/061_undo_tree_spec.lua13
-rw-r--r--test/functional/legacy/arglist_spec.lua268
-rw-r--r--test/functional/legacy/argument_0count_spec.lua28
-rw-r--r--test/functional/legacy/argument_count_spec.lua47
-rw-r--r--test/functional/legacy/assert_spec.lua18
-rw-r--r--test/functional/legacy/expand_spec.lua65
-rw-r--r--test/functional/legacy/listlbr_spec.lua195
-rw-r--r--test/functional/legacy/quickfix_spec.lua296
-rw-r--r--test/functional/provider/python_spec.lua82
-rw-r--r--test/functional/ui/screen.lua6
14 files changed, 1323 insertions, 179 deletions
diff --git a/test/functional/eval/timer_spec.lua b/test/functional/eval/timer_spec.lua
new file mode 100644
index 0000000000..611113f560
--- /dev/null
+++ b/test/functional/eval/timer_spec.lua
@@ -0,0 +1,129 @@
+local helpers = require('test.functional.helpers')
+local Screen = require('test.functional.ui.screen')
+local ok, feed, eq, eval = helpers.ok, helpers.feed, helpers.eq, helpers.eval
+local source, nvim_async, run = helpers.source, helpers.nvim_async, helpers.run
+local clear, execute, funcs = helpers.clear, helpers.execute, helpers.funcs
+
+describe('timers', function()
+ before_each(function()
+ clear()
+ source([[
+ let g:val = 0
+ func MyHandler(timer)
+ let g:val += 1
+ endfunc
+ ]])
+ end)
+
+ it('works one-shot', function()
+ execute("call timer_start(50, 'MyHandler')")
+ eq(0,eval("g:val"))
+ run(nil, nil, nil, 200)
+ eq(1,eval("g:val"))
+ end)
+
+ it('works with repeat two', function()
+ execute("call timer_start(50, 'MyHandler', {'repeat': 2})")
+ eq(0,eval("g:val"))
+ run(nil, nil, nil, 300)
+ eq(2,eval("g:val"))
+ end)
+
+ it('are triggered during sleep', function()
+ execute("call timer_start(50, 'MyHandler', {'repeat': 2})")
+ nvim_async("command", "sleep 10")
+ eq(0,eval("g:val"))
+ run(nil, nil, nil, 300)
+ eq(2,eval("g:val"))
+ 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, 300)
+ eq(2,eval("g:val"))
+ end)
+
+ it('are paused when event processing is disabled', function()
+ -- this is not the intended behavior, but at least there will
+ -- not be a burst of queued up callbacks
+ execute("call timer_start(50, 'MyHandler', {'repeat': 2})")
+ run(nil, nil, nil, 100)
+ local count = eval("g:val")
+ nvim_async("command", "let g:c = getchar()")
+ run(nil, nil, nil, 300)
+ feed("c")
+ local diff = eval("g:val") - count
+ ok(0 <= diff and diff <= 2)
+ eq(99, eval("g:c"))
+ end)
+
+ it('can be stopped', function()
+ local t = eval("timer_start(50, 'MyHandler', {'repeat': -1})")
+ eq(0,eval("g:val"))
+ run(nil, nil, nil, 300)
+ funcs.timer_stop(t)
+ local count = eval("g:val")
+ run(nil, nil, nil, 300)
+ local count2 = eval("g:val")
+ ok(4 <= count and count <= 7)
+ -- when count is eval:ed after timer_stop this should be non-racy
+ eq(count, count2)
+ end)
+
+ it('can be stopped from the handler', function()
+ source([[
+ func! MyHandler(timer)
+ let g:val += 1
+ if g:val == 3
+ call timer_stop(a:timer)
+ " check double stop is ignored
+ call timer_stop(a:timer)
+ endif
+ endfunc
+ ]])
+ execute("call timer_start(50, 'MyHandler', {'repeat': -1})")
+ eq(0,eval("g:val"))
+ run(nil, nil, nil, 300)
+ eq(3,eval("g:val"))
+ end)
+
+ it('can have two timers', function()
+ source([[
+ let g:val2 = 0
+ func! MyHandler2(timer)
+ let g:val2 += 1
+ endfunc
+ ]])
+ execute("call timer_start(50, 'MyHandler', {'repeat': 3})")
+ execute("call timer_start(100, 'MyHandler2', {'repeat': 2})")
+ run(nil, nil, nil, 300)
+ eq(3,eval("g:val"))
+ eq(2,eval("g:val2"))
+ end)
+
+ it("doesn't mess up the cmdline", function()
+ local screen = Screen.new(40, 6)
+ screen:attach()
+ screen:set_default_attr_ignore({{bold=true, foreground=Screen.colors.Blue}})
+ source([[
+ func! MyHandler(timer)
+ echo "evil"
+ endfunc
+ ]])
+ execute("call timer_start(100, 'MyHandler', {'repeat': 1})")
+ feed(":good")
+ screen:sleep(200)
+ screen:expect([[
+ |
+ ~ |
+ ~ |
+ ~ |
+ ~ |
+ :good^ |
+ ]])
+ end)
+
+end)
diff --git a/test/functional/ex_cmds/cd_spec.lua b/test/functional/ex_cmds/cd_spec.lua
index 69467632a4..00b3b083d1 100644
--- a/test/functional/ex_cmds/cd_spec.lua
+++ b/test/functional/ex_cmds/cd_spec.lua
@@ -1,49 +1,145 @@
-- Specs for :cd, :tcd, :lcd and getcwd()
-local helpers = require('test.functional.helpers')
-local execute, eq, clear, eval, exc_exec =
- helpers.execute, helpers.eq, helpers.clear, helpers.eval, helpers.exc_exec
local lfs = require('lfs')
+local helpers = require('test.functional.helpers')
+
+local eq = helpers.eq
+local call = helpers.call
+local clear = helpers.clear
+local execute = helpers.execute
+local exc_exec = helpers.exc_exec
-- These directories will be created for testing
local directories = {
- 'Xtest-functional-ex_cmds-cd_spec.1', -- Tab
- 'Xtest-functional-ex_cmds-cd_spec.2', -- Window
- 'Xtest-functional-ex_cmds-cd_spec.3', -- New global
+ tab = 'Xtest-functional-ex_cmds-cd_spec.tab', -- Tab
+ window = 'Xtest-functional-ex_cmds-cd_spec.window', -- Window
+ global = 'Xtest-functional-ex_cmds-cd_spec.global', -- New global
}
-- Shorthand writing to get the current working directory
-local cwd = function() return eval('getcwd( )') end -- effective working dir
-local wcwd = function() return eval('getcwd( 0 )') end -- window dir
-local tcwd = function() return eval('getcwd(-1, 0)') end -- tab dir
---local gcwd = function() return eval('getcwd(-1, -1)') end -- global dir
+local cwd = function(...) return call('getcwd', ...) end -- effective working dir
+local wcwd = function() return cwd(0) end -- window dir
+local tcwd = function() return cwd(-1, 0) end -- tab dir
-- Same, except these tell us if there is a working directory at all
---local lwd = function() return eval('haslocaldir( )') end -- effective working dir
-local wlwd = function() return eval('haslocaldir( 0 )') end -- window dir
-local tlwd = function() return eval('haslocaldir(-1, 0)') end -- tab dir
+local lwd = function(...) return call('haslocaldir', ...) end -- effective working dir
+local wlwd = function() return lwd(0) end -- window dir
+local tlwd = function() return lwd(-1, 0) end -- tab dir
--local glwd = function() return eval('haslocaldir(-1, -1)') end -- global dir
-- Test both the `cd` and `chdir` variants
for _, cmd in ipairs {'cd', 'chdir'} do
- describe(':*' .. cmd, function()
+ describe(':' .. cmd, function()
before_each(function()
clear()
- for _, d in ipairs(directories) do
+ for _, d in pairs(directories) do
lfs.mkdir(d)
end
+ directories.start = cwd()
end)
after_each(function()
- for _, d in ipairs(directories) do
+ for _, d in pairs(directories) do
lfs.rmdir(d)
end
end)
- it('works', function()
- -- Store the initial working directory
- local globalDir = cwd()
+ describe('using explicit scope', function()
+ it('for window', function()
+ local globalDir = directories.start
+ local globalwin = call('winnr')
+ local tabnr = call('tabpagenr')
+
+ -- Everything matches globalDir to start
+ eq(globalDir, cwd(globalwin))
+ eq(globalDir, cwd(globalwin, tabnr))
+ eq(0, lwd(globalwin))
+ eq(0, lwd(globalwin, tabnr))
+
+ execute('bot split')
+ local localwin = call('winnr')
+ -- Initial window is still using globalDir
+ eq(globalDir, cwd(localwin))
+ eq(globalDir, cwd(localwin, tabnr))
+ eq(0, lwd(globalwin))
+ eq(0, lwd(globalwin, tabnr))
+
+ execute('silent l' .. cmd .. ' ' .. directories.window)
+ -- From window with local dir, the original window
+ -- is still reporting the global dir
+ eq(globalDir, cwd(globalwin))
+ eq(globalDir, cwd(globalwin, tabnr))
+ eq(0, lwd(globalwin))
+ eq(0, lwd(globalwin, tabnr))
+
+ -- Window with local dir reports as such
+ eq(globalDir .. '/' .. directories.window, cwd(localwin))
+ eq(globalDir .. '/' .. directories.window, cwd(localwin, tabnr))
+ eq(1, lwd(localwin))
+ eq(1, lwd(localwin, tabnr))
+
+ execute('tabnew')
+ -- From new tab page, original window reports global dir
+ eq(globalDir, cwd(globalwin, tabnr))
+ eq(0, lwd(globalwin, tabnr))
+
+ -- From new tab page, local window reports as such
+ eq(globalDir .. '/' .. directories.window, cwd(localwin, tabnr))
+ eq(1, lwd(localwin, tabnr))
+ end)
+
+ it('for tab page', function()
+ local globalDir = directories.start
+ local globaltab = call('tabpagenr')
+
+ -- Everything matches globalDir to start
+ eq(globalDir, cwd(-1, 0))
+ eq(globalDir, cwd(-1, globaltab))
+ eq(0, lwd(-1, 0))
+ eq(0, lwd(-1, globaltab))
+
+ execute('tabnew')
+ execute('silent t' .. cmd .. ' ' .. directories.tab)
+ local localtab = call('tabpagenr')
+
+ -- From local tab page, original tab reports globalDir
+ eq(globalDir, cwd(-1, globaltab))
+ eq(0, lwd(-1, globaltab))
+
+ -- new tab reports local
+ eq(globalDir .. '/' .. directories.tab, cwd(-1, 0))
+ eq(globalDir .. '/' .. directories.tab, cwd(-1, localtab))
+ eq(1, lwd(-1, 0))
+ eq(1, lwd(-1, localtab))
+
+ execute('tabnext')
+ -- From original tab page, local reports as such
+ eq(globalDir .. '/' .. directories.tab, cwd(-1, localtab))
+ eq(1, lwd(-1, localtab))
+ end)
+ end)
+
+ describe('getcwd(-1, -1)', function()
+ it('works', function()
+ eq(directories.start, cwd(-1, -1))
+ eq(0, lwd(-1, -1))
+ end)
+
+ it('works with tab-local pwd', function()
+ execute('silent t' .. cmd .. ' ' .. directories.tab)
+ eq(directories.start, cwd(-1, -1))
+ eq(0, lwd(-1, -1))
+ end)
+
+ it('works with window-local pwd', function()
+ execute('silent l' .. cmd .. ' ' .. directories.window)
+ eq(directories.start, cwd(-1, -1))
+ eq(0, lwd(-1, -1))
+ end)
+ end)
+ it('works', function()
+ local globalDir = directories.start
-- Create a new tab first and verify that is has the same working dir
execute('tabnew')
eq(globalDir, cwd())
@@ -53,8 +149,8 @@ for _, cmd in ipairs {'cd', 'chdir'} do
eq(0, wlwd())
-- Change tab-local working directory and verify it is different
- execute('silent t' .. cmd .. ' ' .. directories[1])
- eq(globalDir .. '/' .. directories[1], cwd())
+ execute('silent t' .. cmd .. ' ' .. directories.tab)
+ eq(globalDir .. '/' .. directories.tab, cwd())
eq(cwd(), tcwd()) -- working directory maches tab directory
eq(1, tlwd())
eq(cwd(), wcwd()) -- still no window-directory
@@ -64,16 +160,16 @@ for _, cmd in ipairs {'cd', 'chdir'} do
execute('new')
eq(1, tlwd()) -- Still tab-local working directory
eq(0, wlwd()) -- Still no window-local working directory
- eq(globalDir .. '/' .. directories[1], cwd())
- execute('silent l' .. cmd .. ' ../' .. directories[2])
- eq(globalDir .. '/' .. directories[2], cwd())
- eq(globalDir .. '/' .. directories[1], tcwd())
+ eq(globalDir .. '/' .. directories.tab, cwd())
+ execute('silent l' .. cmd .. ' ../' .. directories.window)
+ eq(globalDir .. '/' .. directories.window, cwd())
+ eq(globalDir .. '/' .. directories.tab, tcwd())
eq(1, wlwd())
-- Verify the first window still has the tab local directory
execute('wincmd w')
- eq(globalDir .. '/' .. directories[1], cwd())
- eq(globalDir .. '/' .. directories[1], tcwd())
+ eq(globalDir .. '/' .. directories.tab, cwd())
+ eq(globalDir .. '/' .. directories.tab, tcwd())
eq(0, wlwd()) -- No window-local directory
-- Change back to initial tab and verify working directory has stayed
@@ -83,11 +179,11 @@ for _, cmd in ipairs {'cd', 'chdir'} do
eq(0, wlwd())
-- Verify global changes don't affect local ones
- execute('silent ' .. cmd .. ' ' .. directories[3])
- eq(globalDir .. '/' .. directories[3], cwd())
+ execute('silent ' .. cmd .. ' ' .. directories.global)
+ eq(globalDir .. '/' .. directories.global, cwd())
execute('tabnext')
- eq(globalDir .. '/' .. directories[1], cwd())
- eq(globalDir .. '/' .. directories[1], tcwd())
+ eq(globalDir .. '/' .. directories.tab, cwd())
+ eq(globalDir .. '/' .. directories.tab, tcwd())
eq(0, wlwd()) -- Still no window-local directory in this window
-- Unless the global change happened in a tab with local directory
@@ -101,9 +197,9 @@ for _, cmd in ipairs {'cd', 'chdir'} do
-- But not in a window with its own local directory
execute('tabnext | wincmd w')
- eq(globalDir .. '/' .. directories[2], cwd() )
+ eq(globalDir .. '/' .. directories.window, cwd() )
eq(0 , tlwd())
- eq(globalDir .. '/' .. directories[2], wcwd())
+ eq(globalDir .. '/' .. directories.window, wcwd())
end)
end)
end
diff --git a/test/functional/legacy/010_errorformat_spec.lua b/test/functional/legacy/010_errorformat_spec.lua
new file mode 100644
index 0000000000..f427204f82
--- /dev/null
+++ b/test/functional/legacy/010_errorformat_spec.lua
@@ -0,0 +1,156 @@
+-- Test for 'errorformat'. This will fail if the quickfix feature was
+-- disabled.
+
+local helpers = require('test.functional.helpers')
+local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local clear, execute, expect, write_file = helpers.clear, helpers.execute, helpers.expect, helpers.write_file
+
+describe('errorformat', function()
+ setup(function()
+ clear()
+ local error_file_text = [[
+ start of errorfile
+ "Xtestfile", line 4.12: 1506-045 (S) Undeclared identifier fd_set.
+ "Xtestfile", line 6 col 19; this is an error
+ gcc -c -DHAVE_CONFIsing-prototypes -I/usr/X11R6/include version.c
+ Xtestfile:9: parse error before `asd'
+ make: *** [vim] Error 1
+ in file "Xtestfile" linenr 10: there is an error
+
+ 2 returned
+ "Xtestfile", line 11 col 1; this is an error
+ "Xtestfile", line 12 col 2; this is another error
+ "Xtestfile", line 14:10; this is an error in column 10
+ =Xtestfile=, line 15:10; this is another error, but in vcol 10 this time
+ "Xtestfile", linenr 16: yet another problem
+ Error in "Xtestfile" at line 17:
+ x should be a dot
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
+ ^
+ Error in "Xtestfile" at line 18:
+ x should be a dot
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
+ .............^
+ Error in "Xtestfile" at line 19:
+ x should be a dot
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
+ --------------^
+ Error in "Xtestfile" at line 20:
+ x should be a dot
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
+ ^
+
+ Does anyone know what is the problem and how to correction it?
+ "Xtestfile", line 21 col 9: What is the title of the quickfix window?
+ "Xtestfile", line 22 col 9: What is the title of the quickfix window?
+ ]]
+ write_file('Xerrorfile1', error_file_text .. 'end of errorfile\n')
+ write_file('Xerrorfile2', error_file_text)
+ write_file('Xtestfile', [[
+ start of testfile
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 4
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 6
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 9
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 10
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 12
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 14
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 15
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 17
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 18
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 19
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 20
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 21
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 22
+ end of testfile
+ ]])
+ end)
+ teardown(function()
+ os.remove('Xerrorfile1')
+ os.remove('Xerrorfile2')
+ os.remove('Xtestfile')
+ end)
+
+ it('is working', function()
+ -- Also test a BOM is ignored.
+ execute(
+ 'set encoding=utf-8',
+ [[set efm+==%f=\\,\ line\ %l%*\\D%v%*[^\ ]\ %m]],
+ [[set efm^=%AError\ in\ \"%f\"\ at\ line\ %l:,%Z%p^,%C%m]],
+ 'cf Xerrorfile2',
+ 'clast',
+ 'copen',
+ 'let a=w:quickfix_title',
+ 'wincmd p'
+ )
+ feed('lgR<C-R>=a<CR><esc>')
+ execute('cf Xerrorfile1')
+ feed('grA<cr>')
+ execute('cn')
+ feed('gRLINE 6, COL 19<esc>')
+ execute('cn')
+ feed('gRNO COLUMN SPECIFIED<esc>')
+ execute('cn')
+ feed('gRAGAIN NO COLUMN<esc>')
+ execute('cn')
+ feed('gRCOL 1<esc>')
+ execute('cn')
+ feed('gRCOL 2<esc>')
+ execute('cn')
+ feed('gRCOL 10<esc>')
+ execute('cn')
+ feed('gRVCOL 10<esc>')
+ execute('cn')
+ feed('grI<cr>')
+ execute('cn')
+ feed('gR. SPACE POINTER<esc>')
+ execute('cn')
+ feed('gR. DOT POINTER<esc>')
+ execute('cn')
+ feed('gR. DASH POINTER<esc>')
+ execute('cn')
+ feed('gR. TAB-SPACE POINTER<esc>')
+ execute(
+ 'clast',
+ 'cprev',
+ 'cprev',
+ 'wincmd w',
+ 'let a=w:quickfix_title',
+ 'wincmd p'
+ )
+ feed('lgR<C-R>=a<CR><esc>')
+
+ -- Assert buffer contents.
+ expect([[
+ start of testfile
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 2
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 3
+ xxxxxxxxxxAxxxxxxxxxxxxxxxxxxx line 4
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 5
+ xxxxxxxxxxxxxxxxxLINE 6, COL 19 line 6
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 7
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 8
+ NO COLUMN SPECIFIEDxxxxxxxxxxx line 9
+ AGAIN NO COLUMNxxxxxxxxxxxxxxx line 10
+ COL 1 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 11
+ COL 2xxxxxxxxxxxxxxxxxxxxxxxxx line 12
+ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 13
+ xxxxxxxxCOL 10xxxxxxxxxxxxxxxx line 14
+ xVCOL 10xxxxxxxxxxxxxxxxxxxxxx line 15
+ Ixxxxxxxxxxxxxxxxxxxxxxxxxxxxx line 16
+ xxxx. SPACE POINTERxxxxxxxxxxx line 17
+ xxxxx. DOT POINTERxxxxxxxxxxxx line 18
+ xxxxxx. DASH POINTERxxxxxxxxxx line 19
+ xxxxxxx. TAB-SPACE POINTERxxxx line 20
+ xxxxxxxx:cf Xerrorfile1xxxxxxx line 21
+ xxxxxxxx:cf Xerrorfile2xxxxxxx line 22
+ end of testfile]])
+ end)
+end)
diff --git a/test/functional/legacy/027_expand_file_names_spec.lua b/test/functional/legacy/027_expand_file_names_spec.lua
deleted file mode 100644
index 4778d16d43..0000000000
--- a/test/functional/legacy/027_expand_file_names_spec.lua
+++ /dev/null
@@ -1,37 +0,0 @@
--- Test for expanding file names
-
-local helpers = require('test.functional.helpers')
-local clear, feed = helpers.clear, helpers.feed
-local execute = helpers.execute
-local curbuf_contents = helpers.curbuf_contents
-local eq = helpers.eq
-
-describe('expand file name', function()
- setup(clear)
-
- it('is working', function()
- execute('!mkdir Xdir1')
- execute('!mkdir Xdir2')
- execute('!mkdir Xdir3')
- execute('cd Xdir3')
- execute('!mkdir Xdir4')
- execute('cd ..')
- execute('w Xdir1/file')
- execute('w Xdir3/Xdir4/file')
- execute('n Xdir?/*/file')
-
- -- Yank current file path to @a register
- feed('i<C-R>%<Esc>V"ad')
-
- -- Put @a and current file path in the current buffer
- execute('n! Xdir?/*/nofile')
- feed('V"ap')
- feed('o<C-R>%<Esc>')
-
- eq("Xdir3/Xdir4/file\nXdir?/*/nofile", curbuf_contents())
- end)
-
- teardown(function()
- os.execute('rm -rf Xdir1 Xdir2 Xdir3')
- end)
-end)
diff --git a/test/functional/legacy/061_undo_tree_spec.lua b/test/functional/legacy/061_undo_tree_spec.lua
index 6db37bf1ff..350a77b2c5 100644
--- a/test/functional/legacy/061_undo_tree_spec.lua
+++ b/test/functional/legacy/061_undo_tree_spec.lua
@@ -1,10 +1,9 @@
-- Tests for undo tree and :earlier and :later.
local helpers = require('test.functional.helpers')
-local feed, source, eq, eval, clear, execute, expect, wait, write_file =
- helpers.feed, helpers.source, helpers.eq, helpers.eval,
- helpers.clear, helpers.execute, helpers.expect, helpers.wait,
- helpers.write_file
+local expect, feed, source = helpers.expect, helpers.feed, helpers.source
+local eval, clear, execute = helpers.eval, helpers.clear, helpers.execute
+local write_file, command, eq = helpers.write_file, helpers.command, helpers.eq
local function expect_empty_buffer()
-- The space will be removed by helpers.dedent but is needed because dedent
@@ -57,8 +56,7 @@ describe('undo tree:', function()
-- Delete three other characters and go back in time step by step.
feed('$xxx')
expect_line('123456')
- execute('sleep 1')
- wait()
+ command('sleep 1')
feed('g-')
expect_line('1234567')
feed('g-')
@@ -79,8 +77,7 @@ describe('undo tree:', function()
expect_line('123456')
-- Delay for two seconds and go some seconds forward and backward.
- execute('sleep 2')
- wait()
+ command('sleep 2')
feed('Aa<esc>')
feed('Ab<esc>')
feed('Ac<esc>')
diff --git a/test/functional/legacy/arglist_spec.lua b/test/functional/legacy/arglist_spec.lua
new file mode 100644
index 0000000000..b13b621b2c
--- /dev/null
+++ b/test/functional/legacy/arglist_spec.lua
@@ -0,0 +1,268 @@
+-- Test argument list commands
+
+local helpers = require('test.functional.helpers')
+local clear, execute, eq = helpers.clear, helpers.execute, helpers.eq
+local eval, exc_exec, neq = helpers.eval, helpers.exc_exec, helpers.neq
+
+describe('argument list commands', function()
+ before_each(clear)
+
+ local function init_abc()
+ execute('args a b c')
+ execute('next')
+ end
+
+ local function reset_arglist()
+ execute('arga a | %argd')
+ end
+
+ local function assert_fails(cmd, err)
+ neq(exc_exec(cmd):find(err), nil)
+ end
+
+ it('test that argidx() works', function()
+ execute('args a b c')
+ execute('last')
+ eq(2, eval('argidx()'))
+ execute('%argdelete')
+ eq(0, eval('argidx()'))
+
+ execute('args a b c')
+ eq(0, eval('argidx()'))
+ execute('next')
+ eq(1, eval('argidx()'))
+ execute('next')
+ eq(2, eval('argidx()'))
+ execute('1argdelete')
+ eq(1, eval('argidx()'))
+ execute('1argdelete')
+ eq(0, eval('argidx()'))
+ execute('1argdelete')
+ eq(0, eval('argidx()'))
+ end)
+
+ it('test that argadd() works', function()
+ execute('%argdelete')
+ execute('argadd a b c')
+ eq(0, eval('argidx()'))
+
+ execute('%argdelete')
+ execute('argadd a')
+ eq(0, eval('argidx()'))
+ execute('argadd b c d')
+ eq(0, eval('argidx()'))
+
+ init_abc()
+ execute('argadd x')
+ eq({'a', 'b', 'x', 'c'}, eval('argv()'))
+ eq(1, eval('argidx()'))
+
+ init_abc()
+ execute('0argadd x')
+ eq({'x', 'a', 'b', 'c'}, eval('argv()'))
+ eq(2, eval('argidx()'))
+
+ init_abc()
+ execute('1argadd x')
+ eq({'a', 'x', 'b', 'c'}, eval('argv()'))
+ eq(2, eval('argidx()'))
+
+ init_abc()
+ execute('$argadd x')
+ eq({'a', 'b', 'c', 'x'}, eval('argv()'))
+ eq(1, eval('argidx()'))
+
+ init_abc()
+ execute('$argadd x')
+ execute('+2argadd y')
+ eq({'a', 'b', 'c', 'x', 'y'}, eval('argv()'))
+ eq(1, eval('argidx()'))
+
+ execute('%argd')
+ execute('edit d')
+ execute('arga')
+ eq(1, eval('len(argv())'))
+ eq('d', eval('get(argv(), 0, "")'))
+
+ execute('%argd')
+ execute('new')
+ execute('arga')
+ eq(0, eval('len(argv())'))
+ end)
+
+ it('test for [count]argument and [count]argdelete commands', function()
+ reset_arglist()
+ execute('let save_hidden = &hidden')
+ execute('set hidden')
+ execute('let g:buffers = []')
+ execute('augroup TEST')
+ execute([[au BufEnter * call add(buffers, expand('%:t'))]])
+ execute('augroup END')
+
+ execute('argadd a b c d')
+ execute('$argu')
+ execute('$-argu')
+ execute('-argu')
+ execute('1argu')
+ execute('+2argu')
+
+ execute('augroup TEST')
+ execute('au!')
+ execute('augroup END')
+
+ eq({'d', 'c', 'b', 'a', 'c'}, eval('g:buffers'))
+
+ execute('redir => result')
+ execute('ar')
+ execute('redir END')
+ eq(1, eval([[result =~# 'a b \[c] d']]))
+
+ execute('.argd')
+ eq({'a', 'b', 'd'}, eval('argv()'))
+
+ execute('-argd')
+ eq({'a', 'd'}, eval('argv()'))
+
+ execute('$argd')
+ eq({'a'}, eval('argv()'))
+
+ execute('1arga c')
+ execute('1arga b')
+ execute('$argu')
+ execute('$arga x')
+ eq({'a', 'b', 'c', 'x'}, eval('argv()'))
+
+ execute('0arga Y')
+ eq({'Y', 'a', 'b', 'c', 'x'}, eval('argv()'))
+
+ execute('%argd')
+ eq({}, eval('argv()'))
+
+ execute('arga a b c d e f')
+ execute('2,$-argd')
+ eq({'a', 'f'}, eval('argv()'))
+
+ execute('let &hidden = save_hidden')
+
+ -- Setting the argument list should fail when the current buffer has
+ -- unsaved changes
+ execute('%argd')
+ execute('enew!')
+ execute('set modified')
+ assert_fails('args x y z', 'E37:')
+ execute('args! x y z')
+ eq({'x', 'y', 'z'}, eval('argv()'))
+ eq('x', eval('expand("%:t")'))
+
+ execute('%argdelete')
+ assert_fails('argument', 'E163:')
+ end)
+
+ it('test for 0argadd and 0argedit', function()
+ reset_arglist()
+
+ execute('arga a b c d')
+ execute('2argu')
+ execute('0arga added')
+ eq({'added', 'a', 'b', 'c', 'd'}, eval('argv()'))
+
+ execute('%argd')
+ execute('arga a b c d')
+ execute('2argu')
+ execute('0arge edited')
+ eq({'edited', 'a', 'b', 'c', 'd'}, eval('argv()'))
+
+ execute('2argu')
+ execute('arga third')
+ eq({'edited', 'a', 'third', 'b', 'c', 'd'}, eval('argv()'))
+ end)
+
+ it('test for argc()', function()
+ reset_arglist()
+ eq(0, eval('argc()'))
+ execute('argadd a b')
+ eq(2, eval('argc()'))
+ end)
+
+ it('test for arglistid()', function()
+ reset_arglist()
+ execute('arga a b')
+ eq(0, eval('arglistid()'))
+ execute('split')
+ execute('arglocal')
+ eq(1, eval('arglistid()'))
+ execute('tabnew | tabfirst')
+ eq(0, eval('arglistid(2)'))
+ eq(1, eval('arglistid(1, 1)'))
+ eq(0, eval('arglistid(2, 1)'))
+ eq(1, eval('arglistid(1, 2)'))
+ execute('tabonly | only | enew!')
+ execute('argglobal')
+ eq(0, eval('arglistid()'))
+ end)
+
+ it('test for argv()', function()
+ reset_arglist()
+ eq({}, eval('argv()'))
+ eq('', eval('argv(2)'))
+ execute('argadd a b c d')
+ eq('c', eval('argv(2)'))
+ end)
+
+ it('test for :argedit command', function()
+ reset_arglist()
+ execute('argedit a')
+ eq({'a'}, eval('argv()'))
+ eq('a', eval('expand("%:t")'))
+ execute('argedit b')
+ eq({'a', 'b'}, eval('argv()'))
+ eq('b', eval('expand("%:t")'))
+ execute('argedit a')
+ eq({'a', 'b'}, eval('argv()'))
+ eq('a', eval('expand("%:t")'))
+ assert_fails('argedit a b', 'E172:')
+ execute('argedit c')
+ eq({'a', 'c', 'b'}, eval('argv()'))
+ execute('0argedit x')
+ eq({'x', 'a', 'c', 'b'}, eval('argv()'))
+ execute('enew! | set modified')
+ assert_fails('argedit y', 'E37:')
+ execute('argedit! y')
+ eq({'x', 'y', 'a', 'c', 'b'}, eval('argv()'))
+ execute('%argd')
+ end)
+
+ it('test for :argdelete command', function()
+ reset_arglist()
+ execute('args aa a aaa b bb')
+ execute('argdelete a*')
+ eq({'b', 'bb'}, eval('argv()'))
+ eq('aa', eval('expand("%:t")'))
+ execute('last')
+ execute('argdelete %')
+ eq({'b'}, eval('argv()'))
+ assert_fails('argdelete', 'E471:')
+ assert_fails('1,100argdelete', 'E16:')
+ execute('%argd')
+ end)
+
+ it('test for the :next, :prev, :first, :last, :rewind commands', function()
+ reset_arglist()
+ execute('args a b c d')
+ execute('last')
+ eq(3, eval('argidx()'))
+ assert_fails('next', 'E165:')
+ execute('prev')
+ eq(2, eval('argidx()'))
+ execute('Next')
+ eq(1, eval('argidx()'))
+ execute('first')
+ eq(0, eval('argidx()'))
+ assert_fails('prev', 'E164:')
+ execute('3next')
+ eq(3, eval('argidx()'))
+ execute('rewind')
+ eq(0, eval('argidx()'))
+ execute('%argd')
+ end)
+end)
diff --git a/test/functional/legacy/argument_0count_spec.lua b/test/functional/legacy/argument_0count_spec.lua
deleted file mode 100644
index 6e8b60547b..0000000000
--- a/test/functional/legacy/argument_0count_spec.lua
+++ /dev/null
@@ -1,28 +0,0 @@
--- Tests for :0argadd and :0argedit
-
-local helpers = require('test.functional.helpers')
-local eq, eval, clear, execute =
- helpers.eq, helpers.eval, helpers.clear, helpers.execute
-
-describe('argument_0count', function()
- setup(clear)
-
- it('is working', function()
- execute('arga a b c d')
- eq({'a', 'b', 'c', 'd'}, eval('argv()'))
- execute('2argu')
- execute('0arga added')
- eq({'added', 'a', 'b', 'c', 'd'}, eval('argv()'))
- execute('2argu')
- execute('arga third')
- eq({'added', 'a', 'third', 'b', 'c', 'd'}, eval('argv()'))
- execute('%argd')
- execute('arga a b c d')
- execute('2argu')
- execute('0arge edited')
- eq({'edited', 'a', 'b', 'c', 'd'}, eval('argv()'))
- execute('2argu')
- execute('arga third')
- eq({'edited', 'a', 'third', 'b', 'c', 'd'}, eval('argv()'))
- end)
-end)
diff --git a/test/functional/legacy/argument_count_spec.lua b/test/functional/legacy/argument_count_spec.lua
deleted file mode 100644
index 182cce9475..0000000000
--- a/test/functional/legacy/argument_count_spec.lua
+++ /dev/null
@@ -1,47 +0,0 @@
--- Tests for :[count]argument! and :[count]argdelete
-
-local helpers = require('test.functional.helpers')
-local clear, execute, eq, eval =
- helpers.clear, helpers.execute, helpers.eq, helpers.eval
-
-describe('argument_count', function()
- setup(clear)
-
- it('is working', function()
- execute('%argd')
- execute('argadd a b c d')
- eq({'a', 'b', 'c', 'd'}, eval('argv()'))
- execute('set hidden')
- execute('let buffers = []')
- execute('augroup TEST')
- execute([[au BufEnter * call add(buffers, expand('%:t'))]])
- execute('augroup END')
- execute('$argu')
- execute('$-argu')
- execute('-argu')
- execute('1argu')
- execute('+2argu')
- execute('augroup TEST')
- execute('au!')
- execute('augroup END')
- eq({'d', 'c', 'b', 'a', 'c'}, eval('buffers'))
- execute('.argd')
- eq({'a', 'b', 'd'}, eval('argv()'))
- execute('-argd')
- eq({'a', 'd'}, eval('argv()'))
- execute('$argd')
- eq({'a'}, eval('argv()'))
- execute('1arga c')
- execute('1arga b')
- execute('$argu')
- execute('$arga x')
- eq({'a', 'b', 'c', 'x'}, eval('argv()'))
- execute('0arga Y')
- eq({'Y', 'a', 'b', 'c', 'x'}, eval('argv()'))
- execute('%argd')
- eq({}, eval('argv()'))
- execute('arga a b c d e f')
- execute('2,$-argd')
- eq({'a', 'f'}, eval('argv()'))
- end)
-end)
diff --git a/test/functional/legacy/assert_spec.lua b/test/functional/legacy/assert_spec.lua
index 1ce665360d..63699387c1 100644
--- a/test/functional/legacy/assert_spec.lua
+++ b/test/functional/legacy/assert_spec.lua
@@ -142,4 +142,22 @@ describe('assert function:', function()
})
end)
end)
+
+ -- assert_fails({cmd}, [, {error}])
+ describe('assert_fails', function()
+ it('should change v:errors when error does not match v:errmsg', function()
+ execute([[call assert_fails('xxx', {})]])
+ expected_errors({"Expected {} but got 'E731: using Dictionary as a String'"})
+ end)
+
+ it('should not change v:errors when cmd errors', function()
+ call('assert_fails', 'NonexistentCmd')
+ expected_empty()
+ end)
+
+ it('should change v:errors when cmd succeeds', function()
+ call('assert_fails', 'call empty("")')
+ expected_errors({'command did not fail: call empty("")'})
+ end)
+ end)
end)
diff --git a/test/functional/legacy/expand_spec.lua b/test/functional/legacy/expand_spec.lua
new file mode 100644
index 0000000000..04701e8ba6
--- /dev/null
+++ b/test/functional/legacy/expand_spec.lua
@@ -0,0 +1,65 @@
+-- Test for expanding file names
+
+local helpers = require('test.functional.helpers')
+local eq = helpers.eq
+local call = helpers.call
+local nvim = helpers.meths
+local clear = helpers.clear
+local source = helpers.source
+
+local function expected_empty()
+ eq({}, nvim.get_vvar('errors'))
+end
+
+describe('expand file name', function()
+ before_each(function()
+ clear()
+
+ source([[
+ func Test_with_directories()
+ call mkdir('Xdir1')
+ call mkdir('Xdir2')
+ call mkdir('Xdir3')
+ cd Xdir3
+ call mkdir('Xdir4')
+ cd ..
+
+ split Xdir1/file
+ call setline(1, ['a', 'b'])
+ w
+ w Xdir3/Xdir4/file
+ close
+
+ next Xdir?/*/file
+ call assert_equal('Xdir3/Xdir4/file', expand('%'))
+ next! Xdir?/*/nofile
+ call assert_equal('Xdir?/*/nofile', expand('%'))
+
+ call delete('Xdir1', 'rf')
+ call delete('Xdir2', 'rf')
+ call delete('Xdir3', 'rf')
+ endfunc
+
+ func Test_with_tilde()
+ let dir = getcwd()
+ call mkdir('Xdir ~ dir')
+ call assert_true(isdirectory('Xdir ~ dir'))
+ cd Xdir\ ~\ dir
+ call assert_true(getcwd() =~ 'Xdir \~ dir')
+ exe 'cd ' . fnameescape(dir)
+ call delete('Xdir ~ dir', 'd')
+ call assert_false(isdirectory('Xdir ~ dir'))
+ endfunc
+ ]])
+ end)
+
+ it('works with directories', function()
+ call('Test_with_directories')
+ expected_empty()
+ end)
+
+ it('works with tilde', function()
+ call('Test_with_tilde')
+ expected_empty()
+ end)
+end)
diff --git a/test/functional/legacy/listlbr_spec.lua b/test/functional/legacy/listlbr_spec.lua
new file mode 100644
index 0000000000..6601a922ef
--- /dev/null
+++ b/test/functional/legacy/listlbr_spec.lua
@@ -0,0 +1,195 @@
+-- Test for linebreak and list option (non-utf8)
+
+local helpers = require('test.functional.helpers')
+local feed, insert, source = helpers.feed, helpers.insert, helpers.source
+local clear, execute, expect = helpers.clear, helpers.execute, helpers.expect
+
+describe('listlbr', function()
+ setup(clear)
+
+ it('is working', function()
+ insert([[
+ dummy text]])
+
+ execute('set wildchar=^E')
+ execute('10new')
+ execute('vsp')
+ execute('vert resize 20')
+ execute([[put =\"\tabcdef hijklmn\tpqrstuvwxyz_1060ABCDEFGHIJKLMNOP \"]])
+ execute('norm! zt')
+ execute('set ts=4 sw=4 sts=4 linebreak sbr=+ wrap')
+ source([[
+ fu! ScreenChar(width)
+ let c=''
+ for j in range(1,4)
+ for i in range(1,a:width)
+ let c.=nr2char(screenchar(j, i))
+ endfor
+ let c.="\n"
+ endfor
+ return c
+ endfu
+ fu! DoRecordScreen()
+ wincmd l
+ $put =printf(\"\n%s\", g:test)
+ $put =g:line
+ wincmd p
+ endfu
+ ]])
+ execute('let g:test="Test 1: set linebreak"')
+ execute('redraw!')
+ execute('let line=ScreenChar(winwidth(0))')
+ execute('call DoRecordScreen()')
+
+ execute('let g:test="Test 2: set linebreak + set list"')
+ execute('set linebreak list listchars=')
+ execute('redraw!')
+ execute('let line=ScreenChar(winwidth(0))')
+ execute('call DoRecordScreen()')
+
+ execute('let g:test ="Test 3: set linebreak nolist"')
+ execute('set nolist linebreak')
+ execute('redraw!')
+ execute('let line=ScreenChar(winwidth(0))')
+ execute('call DoRecordScreen()')
+
+ execute('let g:test ="Test 4: set linebreak with tab and 1 line as long as screen: should break!"')
+ execute('set nolist linebreak ts=8')
+ execute([[let line="1\t".repeat('a', winwidth(0)-2)]])
+ execute('$put =line')
+ execute('$')
+ execute('norm! zt')
+ execute('redraw!')
+ execute('let line=ScreenChar(winwidth(0))')
+ execute('call DoRecordScreen()')
+ execute([[let line="_S_\t bla"]])
+ execute('$put =line')
+ execute('$')
+ execute('norm! zt')
+
+ execute('let g:test ="Test 5: set linebreak with conceal and set list and tab displayed by different char (line may not be truncated)"')
+ execute('set cpo&vim list linebreak conceallevel=2 concealcursor=nv listchars=tab:ab')
+ execute('syn match ConcealVar contained /_/ conceal')
+ execute('syn match All /.*/ contains=ConcealVar')
+ execute('let line=ScreenChar(winwidth(0))')
+ execute('call DoRecordScreen()')
+ execute('set cpo&vim linebreak')
+
+ execute('let g:test ="Test 6: set linebreak with visual block mode"')
+ execute('let line="REMOVE: this not"')
+ execute('$put =g:test')
+ execute('$put =line')
+ execute('let line="REMOVE: aaaaaaaaaaaaa"')
+ execute('$put =line')
+ execute('1/^REMOVE:')
+ feed('0<C-V>jf x')
+ execute('$put')
+ execute('set cpo&vim linebreak')
+
+ execute('let g:test ="Test 7: set linebreak with visual block mode and v_b_A"')
+ execute('$put =g:test')
+ feed('Golong line: <esc>40afoobar <esc>aTARGET at end<esc>')
+ execute([[exe "norm! $3B\<C-v>eAx\<Esc>"]])
+ execute('set cpo&vim linebreak sbr=')
+
+ execute('let g:test ="Test 8: set linebreak with visual char mode and changing block"')
+ execute('$put =g:test')
+ feed('Go1111-1111-1111-11-1111-1111-1111<esc>0f-lv3lc2222<esc>bgj.')
+
+ execute('let g:test ="Test 9: using redo after block visual mode"')
+ execute('$put =g:test')
+ feed('Go<CR>')
+ feed('aaa<CR>')
+ feed('aaa<CR>')
+ feed('a<ESC>2k<C-V>2j~e.<CR>')
+
+ execute('let g:test ="Test 10: using normal commands after block-visual"')
+ execute('$put =g:test')
+ execute('set linebreak')
+ feed('Go<cr>')
+ feed('abcd{ef<cr>')
+ feed('ghijklm<cr>')
+ feed('no}pqrs<esc>2k0f{<C-V><C-V>c%<esc>')
+
+ execute('let g:test ="Test 11: using block replace mode after wrapping"')
+ execute('$put =g:test')
+ execute('set linebreak wrap')
+ feed('Go<esc>150aa<esc>yypk147|<C-V>jr0<cr>')
+
+ execute('let g:test ="Test 12: set linebreak list listchars=space:_,tab:>-,tail:-,eol:$"')
+ execute('set list listchars=space:_,trail:-,tab:>-,eol:$')
+ execute('$put =g:test')
+ execute([[let line="a aaaaaaaaaaaaaaaaaaaaaa\ta "]])
+ execute('$put =line')
+ execute('$')
+ execute('norm! zt')
+ execute('redraw!')
+ execute('let line=ScreenChar(winwidth(0))')
+ execute('call DoRecordScreen()')
+
+ -- Assert buffer contents.
+ expect([[
+
+ abcdef hijklmn pqrstuvwxyz_1060ABCDEFGHIJKLMNOP
+
+ Test 1: set linebreak
+ abcdef
+ +hijklmn
+ +pqrstuvwxyz_1060ABC
+ +DEFGHIJKLMNOP
+
+ Test 2: set linebreak + set list
+ ^Iabcdef hijklmn^I
+ +pqrstuvwxyz_1060ABC
+ +DEFGHIJKLMNOP
+
+
+ Test 3: set linebreak nolist
+ abcdef
+ +hijklmn
+ +pqrstuvwxyz_1060ABC
+ +DEFGHIJKLMNOP
+ 1 aaaaaaaaaaaaaaaaaa
+
+ Test 4: set linebreak with tab and 1 line as long as screen: should break!
+ 1
+ +aaaaaaaaaaaaaaaaaa
+ ~
+ ~
+ _S_ bla
+
+ Test 5: set linebreak with conceal and set list and tab displayed by different char (line may not be truncated)
+ Sabbbbbb bla
+ ~
+ ~
+ ~
+ Test 6: set linebreak with visual block mode
+ this not
+ aaaaaaaaaaaaa
+ REMOVE:
+ REMOVE:
+ Test 7: set linebreak with visual block mode and v_b_A
+ long line: foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar foobar TARGETx at end
+ Test 8: set linebreak with visual char mode and changing block
+ 1111-2222-1111-11-1111-2222-1111
+ Test 9: using redo after block visual mode
+
+ AaA
+ AaA
+ A
+ Test 10: using normal commands after block-visual
+
+ abcdpqrs
+ Test 11: using block replace mode after wrapping
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0aaa
+ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa0aaa
+ Test 12: set linebreak list listchars=space:_,tab:>-,tail:-,eol:$
+ a aaaaaaaaaaaaaaaaaaaaaa a
+
+ Test 12: set linebreak list listchars=space:_,tab:>-,tail:-,eol:$
+ a_
+ aaaaaaaaaaaaaaaaaaaa
+ aa>-----a-$
+ ~ ]])
+ end)
+end)
diff --git a/test/functional/legacy/quickfix_spec.lua b/test/functional/legacy/quickfix_spec.lua
index 88f86815b3..315b8ca682 100644
--- a/test/functional/legacy/quickfix_spec.lua
+++ b/test/functional/legacy/quickfix_spec.lua
@@ -2,11 +2,264 @@
local helpers = require('test.functional.helpers')
local source, clear = helpers.source, helpers.clear
+local eq, nvim, call = helpers.eq, helpers.meths, helpers.call
+
+local function expected_empty()
+ eq({}, nvim.get_vvar('errors'))
+end
describe('helpgrep', function()
- before_each(clear)
+ before_each(function()
+ clear()
- it('works', function()
+ source([[
+ " Tests for the :clist and :llist commands
+ function XlistTests(cchar)
+ let Xlist = a:cchar . 'list'
+ let Xgetexpr = a:cchar . 'getexpr'
+
+ " With an empty list, command should return error
+ exe Xgetexpr . ' []'
+ exe 'silent! ' . Xlist
+ call assert_true(v:errmsg ==# 'E42: No Errors')
+
+ " Populate the list and then try
+ exe Xgetexpr . " ['non-error 1', 'Xtestfile1:1:3:Line1',
+ \ 'non-error 2', 'Xtestfile2:2:2:Line2',
+ \ 'non-error 3', 'Xtestfile3:3:1:Line3']"
+
+ " List only valid entries
+ redir => result
+ exe 'silent ' . Xlist
+ redir END
+ let l = split(result, "\n")
+ call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
+ \ ' 4 Xtestfile2:2 col 2: Line2',
+ \ ' 6 Xtestfile3:3 col 1: Line3'], l)
+
+ " List all the entries
+ redir => result
+ exe 'silent ' . Xlist . "!"
+ redir END
+ let l = split(result, "\n")
+ call assert_equal([' 1: non-error 1', ' 2 Xtestfile1:1 col 3: Line1',
+ \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2',
+ \ ' 5: non-error 3', ' 6 Xtestfile3:3 col 1: Line3'], l)
+
+ " List a range of errors
+ redir => result
+ exe 'silent '. Xlist . " 3,6"
+ redir END
+ let l = split(result, "\n")
+ call assert_equal([' 4 Xtestfile2:2 col 2: Line2',
+ \ ' 6 Xtestfile3:3 col 1: Line3'], l)
+
+ redir => result
+ exe 'silent ' . Xlist . "! 3,4"
+ redir END
+ let l = split(result, "\n")
+ call assert_equal([' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
+
+ redir => result
+ exe 'silent ' . Xlist . " -6,-4"
+ redir END
+ let l = split(result, "\n")
+ call assert_equal([' 2 Xtestfile1:1 col 3: Line1'], l)
+
+ redir => result
+ exe 'silent ' . Xlist . "! -5,-3"
+ redir END
+ let l = split(result, "\n")
+ call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
+ \ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
+ endfunction
+
+ " Tests for the :colder, :cnewer, :lolder and :lnewer commands
+ " Note that this test assumes that a quickfix/location list is
+ " already set by the caller
+ function XageTests(cchar)
+ let Xolder = a:cchar . 'older'
+ let Xnewer = a:cchar . 'newer'
+ let Xgetexpr = a:cchar . 'getexpr'
+ if a:cchar == 'c'
+ let Xgetlist = 'getqflist()'
+ else
+ let Xgetlist = 'getloclist(0)'
+ endif
+
+ " Jumping to a non existent list should return error
+ exe 'silent! ' . Xolder . ' 99'
+ call assert_true(v:errmsg ==# 'E380: At bottom of quickfix stack')
+
+ exe 'silent! ' . Xnewer . ' 99'
+ call assert_true(v:errmsg ==# 'E381: At top of quickfix stack')
+
+ " Add three quickfix/location lists
+ exe Xgetexpr . " ['Xtestfile1:1:3:Line1']"
+ exe Xgetexpr . " ['Xtestfile2:2:2:Line2']"
+ exe Xgetexpr . " ['Xtestfile3:3:1:Line3']"
+
+ " Go back two lists
+ exe Xolder
+ exe 'let l = ' . Xgetlist
+ call assert_equal('Line2', l[0].text)
+
+ " Go forward two lists
+ exe Xnewer
+ exe 'let l = ' . Xgetlist
+ call assert_equal('Line3', l[0].text)
+
+ " Test for the optional count argument
+ exe Xolder . ' 2'
+ exe 'let l = ' . Xgetlist
+ call assert_equal('Line1', l[0].text)
+
+ exe Xnewer . ' 2'
+ exe 'let l = ' . Xgetlist
+ call assert_equal('Line3', l[0].text)
+ endfunction
+
+ " Tests for the :cwindow, :lwindow :cclose, :lclose, :copen and :lopen
+ " commands
+ function XwindowTests(cchar)
+ let Xwindow = a:cchar . 'window'
+ let Xclose = a:cchar . 'close'
+ let Xopen = a:cchar . 'open'
+ let Xgetexpr = a:cchar . 'getexpr'
+
+ " Create a list with no valid entries
+ exe Xgetexpr . " ['non-error 1', 'non-error 2', 'non-error 3']"
+
+ " Quickfix/Location window should not open with no valid errors
+ exe Xwindow
+ call assert_true(winnr('$') == 1)
+
+ " Create a list with valid entries
+ exe Xgetexpr . " ['Xtestfile1:1:3:Line1', 'Xtestfile2:2:2:Line2',
+ \ 'Xtestfile3:3:1:Line3']"
+
+ " Open the window
+ exe Xwindow
+ call assert_true(winnr('$') == 2 && winnr() == 2 &&
+ \ getline('.') ==# 'Xtestfile1|1 col 3| Line1')
+
+ " Close the window
+ exe Xclose
+ call assert_true(winnr('$') == 1)
+
+ " Create a list with no valid entries
+ exe Xgetexpr . " ['non-error 1', 'non-error 2', 'non-error 3']"
+
+ " Open the window
+ exe Xopen . ' 5'
+ call assert_true(winnr('$') == 2 && getline('.') ==# '|| non-error 1'
+ \ && winheight('.') == 5)
+
+ " Opening the window again, should move the cursor to that window
+ wincmd t
+ exe Xopen . ' 7'
+ call assert_true(winnr('$') == 2 && winnr() == 2 &&
+ \ winheight('.') == 7 &&
+ \ getline('.') ==# '|| non-error 1')
+
+
+ " Calling cwindow should close the quickfix window with no valid errors
+ exe Xwindow
+ call assert_true(winnr('$') == 1)
+ endfunction
+
+ " Tests for the :cfile, :lfile, :caddfile, :laddfile, :cgetfile and :lgetfile
+ " commands.
+ function XfileTests(cchar)
+ let Xfile = a:cchar . 'file'
+ let Xgetfile = a:cchar . 'getfile'
+ let Xaddfile = a:cchar . 'addfile'
+ if a:cchar == 'c'
+ let Xgetlist = 'getqflist()'
+ else
+ let Xgetlist = 'getloclist(0)'
+ endif
+
+ call writefile(['Xtestfile1:700:10:Line 700',
+ \ 'Xtestfile2:800:15:Line 800'], 'Xqftestfile1')
+
+ enew!
+ exe Xfile . ' Xqftestfile1'
+ exe 'let l = ' . Xgetlist
+ call assert_true(len(l) == 2 &&
+ \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
+ \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
+
+ " Run cfile/lfile from a modified buffer
+ enew!
+ silent! put ='Quickfix'
+ exe 'silent! ' . Xfile . ' Xqftestfile1'
+ call assert_true(v:errmsg ==# 'E37: No write since last change (add ! to override)')
+
+ call writefile(['Xtestfile3:900:30:Line 900'], 'Xqftestfile1')
+ exe Xaddfile . ' Xqftestfile1'
+ exe 'let l = ' . Xgetlist
+ call assert_true(len(l) == 3 &&
+ \ l[2].lnum == 900 && l[2].col == 30 && l[2].text ==# 'Line 900')
+
+ call writefile(['Xtestfile1:222:77:Line 222',
+ \ 'Xtestfile2:333:88:Line 333'], 'Xqftestfile1')
+
+ enew!
+ exe Xgetfile . ' Xqftestfile1'
+ exe 'let l = ' . Xgetlist
+ call assert_true(len(l) == 2 &&
+ \ l[0].lnum == 222 && l[0].col == 77 && l[0].text ==# 'Line 222' &&
+ \ l[1].lnum == 333 && l[1].col == 88 && l[1].text ==# 'Line 333')
+
+ call delete('Xqftestfile1')
+ endfunction
+
+ " Tests for the :cbuffer, :lbuffer, :caddbuffer, :laddbuffer, :cgetbuffer and
+ " :lgetbuffer commands.
+ function XbufferTests(cchar)
+ let Xbuffer = a:cchar . 'buffer'
+ let Xgetbuffer = a:cchar . 'getbuffer'
+ let Xaddbuffer = a:cchar . 'addbuffer'
+ if a:cchar == 'c'
+ let Xgetlist = 'getqflist()'
+ else
+ let Xgetlist = 'getloclist(0)'
+ endif
+
+ enew!
+ silent! call setline(1, ['Xtestfile7:700:10:Line 700',
+ \ 'Xtestfile8:800:15:Line 800'])
+ exe Xbuffer . "!"
+ exe 'let l = ' . Xgetlist
+ call assert_true(len(l) == 2 &&
+ \ l[0].lnum == 700 && l[0].col == 10 && l[0].text ==# 'Line 700' &&
+ \ l[1].lnum == 800 && l[1].col == 15 && l[1].text ==# 'Line 800')
+
+ enew!
+ silent! call setline(1, ['Xtestfile9:900:55:Line 900',
+ \ 'Xtestfile10:950:66:Line 950'])
+ exe Xgetbuffer
+ exe 'let l = ' . Xgetlist
+ call assert_true(len(l) == 2 &&
+ \ l[0].lnum == 900 && l[0].col == 55 && l[0].text ==# 'Line 900' &&
+ \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950')
+
+ enew!
+ silent! call setline(1, ['Xtestfile11:700:20:Line 700',
+ \ 'Xtestfile12:750:25:Line 750'])
+ exe Xaddbuffer
+ exe 'let l = ' . Xgetlist
+ call assert_true(len(l) == 4 &&
+ \ l[1].lnum == 950 && l[1].col == 66 && l[1].text ==# 'Line 950' &&
+ \ l[2].lnum == 700 && l[2].col == 20 && l[2].text ==# 'Line 700' &&
+ \ l[3].lnum == 750 && l[3].col == 25 && l[3].text ==# 'Line 750')
+
+ endfunction
+ ]])
+ end)
+
+ it('copen/cclose work', function()
source([[
helpgrep quickfix
copen
@@ -14,4 +267,43 @@ describe('helpgrep', function()
cclose
]])
end)
+
+ it('clist/llist work', function()
+ call('XlistTests', 'c')
+ expected_empty()
+ call('XlistTests', 'l')
+ expected_empty()
+ end)
+
+ it('colder/cnewer and lolder/lnewer work', function()
+ local list = {{bufnr = 1, lnum = 1}}
+ call('setqflist', list)
+ call('XageTests', 'c')
+ expected_empty()
+
+ call('setloclist', 0, list)
+ call('XageTests', 'l')
+ expected_empty()
+ end)
+
+ it('quickfix/location list window commands work', function()
+ call('XwindowTests', 'c')
+ expected_empty()
+ call('XwindowTests', 'l')
+ expected_empty()
+ end)
+
+ it('quickfix/location list file commands work', function()
+ call('XfileTests', 'c')
+ expected_empty()
+ call('XfileTests', 'l')
+ expected_empty()
+ end)
+
+ it('quickfix/location list buffer commands work', function()
+ call('XbufferTests', 'c')
+ expected_empty()
+ call('XbufferTests', 'l')
+ expected_empty()
+ end)
end)
diff --git a/test/functional/provider/python_spec.lua b/test/functional/provider/python_spec.lua
index da45d6aa00..06fdbef669 100644
--- a/test/functional/provider/python_spec.lua
+++ b/test/functional/provider/python_spec.lua
@@ -1,12 +1,22 @@
local helpers = require('test.functional.helpers')
-local eval, command, feed = helpers.eval, helpers.command, helpers.feed
-local eq, clear, insert = helpers.eq, helpers.clear, helpers.insert
-local expect, write_file = helpers.expect, helpers.write_file
+
+local eq = helpers.eq
+local neq = helpers.neq
+local feed = helpers.feed
+local clear = helpers.clear
+local funcs = helpers.funcs
+local meths = helpers.meths
+local insert = helpers.insert
+local expect = helpers.expect
+local command = helpers.command
+local exc_exec = helpers.exc_exec
+local write_file = helpers.write_file
+local curbufmeths = helpers.curbufmeths
do
clear()
command('let [g:interp, g:errors] = provider#pythonx#Detect(2)')
- local errors = eval('g:errors')
+ local errors = meths.get_var('errors')
if errors ~= '' then
pending(
'Python 2 (or the Python 2 neovim module) is broken or missing:\n' .. errors,
@@ -15,49 +25,58 @@ do
end
end
-describe('python commands and functions', function()
- before_each(function()
- clear()
- command('python import vim')
- end)
+before_each(function()
+ clear()
+ command('python import vim')
+end)
- it('feature test', function()
- eq(1, eval('has("python")'))
+describe('python feature test', function()
+ it('works', function()
+ eq(1, funcs.has('python'))
end)
+end)
- it('python_execute', function()
+describe(':python command', function()
+ it('works with a line', function()
command('python vim.vars["set_by_python"] = [100, 0]')
- eq({100, 0}, eval('g:set_by_python'))
+ eq({100, 0}, meths.get_var('set_by_python'))
end)
- it('python_execute with nested commands', function()
+ -- TODO(ZyX-I): works with << EOF
+ -- TODO(ZyX-I): works with execute 'python' line1."\n".line2."\n"…
+
+ it('supports nesting', function()
command([[python vim.command('python vim.command("python vim.command(\'let set_by_nested_python = 555\')")')]])
- eq(555, eval('g:set_by_nested_python'))
+ eq(555, meths.get_var('set_by_nested_python'))
end)
- it('python_execute with range', function()
+ it('supports range', function()
insert([[
line1
line2
line3
line4]])
feed('ggjvj:python vim.vars["range"] = vim.current.range[:]<CR>')
- eq({'line2', 'line3'}, eval('g:range'))
+ eq({'line2', 'line3'}, meths.get_var('range'))
end)
+end)
- it('pyfile', function()
+describe(':pyfile command', function()
+ it('works', function()
local fname = 'pyfile.py'
write_file(fname, 'vim.command("let set_by_pyfile = 123")')
command('pyfile pyfile.py')
- eq(123, eval('g:set_by_pyfile'))
+ eq(123, meths.get_var('set_by_pyfile'))
os.remove(fname)
end)
+end)
- it('pydo', function()
+describe(':pydo command', function()
+ it('works', function()
-- :pydo 42 returns None for all lines,
-- the buffer should not be changed
command('normal :pydo 42')
- eq(0, eval('&mod'))
+ eq(false, curbufmeths.get_option('modified'))
-- insert some text
insert('abc\ndef\nghi')
expect([[
@@ -71,8 +90,25 @@ describe('python commands and functions', function()
2
ghi]])
end)
+end)
+
+describe('pyeval()', function()
+ it('works', function()
+ eq({1, 2, {['key'] = 'val'}}, funcs.pyeval('[1, 2, {"key": "val"}]'))
+ end)
+
+ it('errors out when given non-string', function()
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(10)'))
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(v:_null_dict)'))
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(v:_null_list)'))
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(0.0)'))
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(function("tr"))'))
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(v:true)'))
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(v:false)'))
+ eq('Vim(call):E474: Invalid argument', exc_exec('call pyeval(v:null)'))
+ end)
- it('pyeval', function()
- eq({1, 2, {['key'] = 'val'}}, eval([[pyeval('[1, 2, {"key": "val"}]')]]))
+ it('accepts NULL string', function()
+ neq(0, exc_exec('call pyeval($XXX_NONEXISTENT_VAR_XXX)'))
end)
end)
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index 6372cbe081..99b85caf10 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -290,6 +290,10 @@ If everything else fails, use Screen:redraw_debug to help investigate what is
end
end
+function Screen:sleep(ms)
+ pcall(function() self:wait(function() return "error" end, ms) end)
+end
+
function Screen:_redraw(updates)
for _, update in ipairs(updates) do
-- print('--')
@@ -501,7 +505,7 @@ end
function Screen:snapshot_util(attrs, ignore)
-- util to generate screen test
- pcall(function() self:wait(function() return "error" end, 250) end)
+ self:sleep(250)
self:print_snapshot(attrs, ignore)
end