aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/functional/api/buffer_spec.lua35
-rw-r--r--test/functional/api/vim_spec.lua9
-rw-r--r--test/functional/clipboard/clipboard_provider_spec.lua103
-rw-r--r--test/functional/eval/glob_spec.lua25
-rw-r--r--test/functional/eval/msgpack_functions_spec.lua615
-rw-r--r--test/functional/ex_cmds/grep_spec.lua22
-rw-r--r--test/functional/ex_cmds/menu_spec.lua38
-rw-r--r--test/functional/ex_cmds/recover_spec.lua4
-rw-r--r--test/functional/fixtures/autoload/provider/clipboard.vim (renamed from test/functional/clipboard/autoload/provider/clipboard.vim)16
-rw-r--r--test/functional/helpers.lua26
-rw-r--r--test/functional/job/job_spec.lua2
-rw-r--r--test/functional/legacy/057_sort_spec.lua603
-rw-r--r--test/functional/legacy/060_exists_and_has_functions_spec.lua28
-rw-r--r--test/functional/legacy/062_tab_pages_spec.lua240
-rw-r--r--test/functional/legacy/077_mf_hash_grow_spec.lua2
-rw-r--r--test/functional/legacy/080_substitute_spec.lua162
-rw-r--r--test/functional/legacy/mapping_spec.lua13
-rw-r--r--test/functional/provider/define_spec.lua (renamed from test/functional/runtime/autoload/remote/define_spec.lua)0
-rw-r--r--test/functional/provider/python3_spec.lua (renamed from test/functional/runtime/autoload/provider/python3_spec.lua)10
-rw-r--r--test/functional/provider/python_spec.lua (renamed from test/functional/runtime/autoload/provider/python_spec.lua)10
-rw-r--r--test/functional/shell/viml_system_spec.lua4
-rw-r--r--test/functional/terminal/highlight_spec.lua25
-rw-r--r--test/functional/ui/screen.lua16
-rw-r--r--test/functional/ui/screen_basic_spec.lua24
-rw-r--r--test/unit/fixtures/queue.c16
-rw-r--r--test/unit/fixtures/queue.h4
-rw-r--r--test/unit/os/fs_spec.lua129
-rw-r--r--test/unit/os/shell_spec.lua2
-rw-r--r--test/unit/queue_spec.lua123
29 files changed, 2247 insertions, 59 deletions
diff --git a/test/functional/api/buffer_spec.lua b/test/functional/api/buffer_spec.lua
index b85594f7af..c924988d06 100644
--- a/test/functional/api/buffer_spec.lua
+++ b/test/functional/api/buffer_spec.lua
@@ -35,6 +35,20 @@ describe('buffer_* functions', function()
eq('', curbuf('get_line', 0))
end)
+ it('get_line: out-of-bounds returns empty string', function()
+ curbuf('set_line', 0, 'line1.a')
+ eq('', curbuf('get_line', 1))
+ eq('', curbuf('get_line', -2))
+ end)
+
+ it('set_line, del_line: out-of-bounds is an error', function()
+ curbuf('set_line', 0, 'line1.a')
+ eq(false, pcall(curbuf, 'set_line', 1, 'line1.b'))
+ eq(false, pcall(curbuf, 'set_line', -2, 'line1.b'))
+ eq(false, pcall(curbuf, 'del_line', 2))
+ eq(false, pcall(curbuf, 'del_line', -3))
+ end)
+
it('can handle NULs', function()
curbuf('set_line', 0, 'ab\0cd')
eq('ab\0cd', curbuf('get_line', 0))
@@ -43,6 +57,27 @@ describe('buffer_* functions', function()
describe('{get,set}_line_slice', function()
+ it('get_line_slice: out-of-bounds returns empty array', function()
+ curbuf('set_line_slice', 0, 0, true, true, {'a', 'b', 'c'})
+ eq({'a', 'b', 'c'}, curbuf('get_line_slice', 0, 2, true, true)) --sanity
+
+ eq({}, curbuf('get_line_slice', 2, 3, false, true))
+ eq({}, curbuf('get_line_slice', 3, 9, true, true))
+ eq({}, curbuf('get_line_slice', 3, -1, true, true))
+ eq({}, curbuf('get_line_slice', -3, -4, false, true))
+ eq({}, curbuf('get_line_slice', -4, -5, true, true))
+ end)
+
+ it('set_line_slice: out-of-bounds is an error', function()
+ curbuf('set_line_slice', 0, 0, true, true, {'a', 'b', 'c'})
+ eq({'a', 'b', 'c'}, curbuf('get_line_slice', 0, 2, true, true)) --sanity
+
+ eq({'c'}, curbuf('get_line_slice', -1, 4, true, true))
+ eq({'a', 'b', 'c'}, curbuf('get_line_slice', 0, 5, true, true))
+ eq(false, pcall(curbuf, 'set_line_slice', 4, 5, true, true, {'d'}))
+ eq(false, pcall(curbuf, 'set_line_slice', -4, -5, true, true, {'d'}))
+ end)
+
it('works', function()
eq({''}, curbuf('get_line_slice', 0, -1, true, true))
-- Replace buffer
diff --git a/test/functional/api/vim_spec.lua b/test/functional/api/vim_spec.lua
index c158c26341..9e880a4f04 100644
--- a/test/functional/api/vim_spec.lua
+++ b/test/functional/api/vim_spec.lua
@@ -34,6 +34,15 @@ describe('vim_* functions', function()
end)
end)
+ describe('call_function', function()
+ it('works', function()
+ nvim('call_function', 'setqflist', {{{ filename = 'something', lnum = 17}}, 'r'})
+ eq(17, nvim('call_function', 'getqflist', {})[1].lnum)
+ eq(17, nvim('call_function', 'eval', {17}))
+ eq('foo', nvim('call_function', 'simplify', {'this/./is//redundant/../../../foo'}))
+ end)
+ end)
+
describe('strwidth', function()
it('works', function()
eq(3, nvim('strwidth', 'abc'))
diff --git a/test/functional/clipboard/clipboard_provider_spec.lua b/test/functional/clipboard/clipboard_provider_spec.lua
index 9282a66240..0550d22fa6 100644
--- a/test/functional/clipboard/clipboard_provider_spec.lua
+++ b/test/functional/clipboard/clipboard_provider_spec.lua
@@ -92,7 +92,7 @@ end)
describe('clipboard usage', function()
before_each(function()
clear()
- execute('let &rtp = "test/functional/clipboard,".&rtp')
+ execute('let &rtp = "test/functional/fixtures,".&rtp')
execute('call getreg("*")') -- force load of provider
end)
@@ -197,6 +197,17 @@ describe('clipboard usage', function()
expect('some more')
end)
+ it('pastes unnamed register if the provider fails', function()
+ insert('the text')
+ feed('yy')
+ execute("let g:cliperror = 1")
+ feed('"*p')
+ expect([[
+ the text
+ the text]])
+ end)
+
+
describe('with clipboard=unnamed', function()
-- the basic behavior of unnamed register should be the same
-- even when handled by clipboard provider
@@ -221,12 +232,15 @@ describe('clipboard usage', function()
expect('words')
eq({{'words'}, 'v'}, eval("g:test_clip['*']"))
+ -- "+ shouldn't have changed
+ eq({''}, eval("g:test_clip['+']"))
+
execute("let g:test_clip['*'] = ['linewise stuff','']")
feed('p')
expect([[
words
linewise stuff]])
- end)
+ end)
it('does not clobber "0 when pasting', function()
insert('a line')
@@ -261,6 +275,60 @@ describe('clipboard usage', function()
expect("indeed star")
end)
+ it('unamed operations work even if the provider fails', function()
+ insert('the text')
+ feed('yy')
+ execute("let g:cliperror = 1")
+ feed('p')
+ expect([[
+ the text
+ the text]])
+ end)
+
+ end)
+
+ describe('with clipboard=unnamedplus', function()
+ before_each(function()
+ execute('set clipboard=unnamedplus')
+ end)
+
+ it('links the "+ and unnamed registers', function()
+ insert("one two")
+ feed('^"+dwdw"+P')
+ expect('two')
+ eq({{'two'}, 'v'}, eval("g:test_clip['+']"))
+
+ -- "* shouldn't have changed
+ eq({''}, eval("g:test_clip['*']"))
+
+ execute("let g:test_clip['+'] = ['three']")
+ feed('p')
+ expect('twothree')
+ end)
+
+ it('and unnamed, yanks to both', function()
+ execute('set clipboard=unnamedplus,unnamed')
+ insert([[
+ really unnamed
+ text]])
+ feed('ggdd"*p"+p')
+ expect([[
+ text
+ really unnamed
+ really unnamed]])
+ eq({{'really unnamed', ''}, 'V'}, eval("g:test_clip['+']"))
+ eq({{'really unnamed', ''}, 'V'}, eval("g:test_clip['*']"))
+
+ -- unnamedplus takes predecence when pasting
+ execute("let g:test_clip['+'] = ['the plus','']")
+ execute("let g:test_clip['*'] = ['the star','']")
+ feed("p")
+ expect([[
+ text
+ really unnamed
+ really unnamed
+ the plus]])
+ end)
end)
it('supports :put', function()
@@ -301,6 +369,7 @@ describe('clipboard usage', function()
[2] = {foreground = Screen.colors.Blue},
[3] = {bold = true, foreground = Screen.colors.SeaGreen}},
{{bold = true, foreground = Screen.colors.Blue}})
+ feed('<cr>') -- clear out of Press ENTER screen
end)
it('can paste "* to the commandline', function()
@@ -335,4 +404,34 @@ describe('clipboard usage', function()
'Howdy!',
}, 'v'}, eval("g:test_clip['*']"))
end)
+
+ it('handles middleclick correctly', function()
+ local screen = Screen.new(30, 5)
+ screen:attach()
+ insert([[
+ the source
+ a target]])
+ feed('gg"*ywwyw')
+ -- clicking depends on the exact visual layout, so expect it:
+ screen:expect([[
+ the ^source |
+ a target |
+ ~ |
+ ~ |
+ |
+ ]], nil, {{bold = true, foreground = Screen.colors.Blue}})
+
+ feed('<MiddleMouse><0,1>')
+ expect([[
+ the source
+ the a target]])
+
+ -- on error, fall back to unnamed register
+ execute("let g:cliperror = 1")
+ feed('<MiddleMouse><6,1>')
+ expect([[
+ the source
+ the a sourcetarget]])
+ end)
+
end)
diff --git a/test/functional/eval/glob_spec.lua b/test/functional/eval/glob_spec.lua
new file mode 100644
index 0000000000..136417249c
--- /dev/null
+++ b/test/functional/eval/glob_spec.lua
@@ -0,0 +1,25 @@
+local helpers = require('test.functional.helpers')
+local clear, execute, eval, eq = helpers.clear, helpers.execute, helpers.eval, helpers.eq
+
+before_each(function()
+ clear()
+ lfs.mkdir('test-glob')
+ execute('cd test-glob')
+end)
+
+after_each(function()
+ lfs.rmdir('test-glob')
+end)
+
+describe('glob()', function()
+ it("glob('.*') returns . and .. ", function()
+ eq({'.', '..'}, eval("glob('.*', 0, 1)"))
+ -- Do it again to verify scandir_next_with_dots() internal state.
+ eq({'.', '..'}, eval("glob('.*', 0, 1)"))
+ end)
+ it("glob('*') returns an empty list ", function()
+ eq({}, eval("glob('*', 0, 1)"))
+ -- Do it again to verify scandir_next_with_dots() internal state.
+ eq({}, eval("glob('*', 0, 1)"))
+ end)
+end)
diff --git a/test/functional/eval/msgpack_functions_spec.lua b/test/functional/eval/msgpack_functions_spec.lua
new file mode 100644
index 0000000000..8ca2cca32c
--- /dev/null
+++ b/test/functional/eval/msgpack_functions_spec.lua
@@ -0,0 +1,615 @@
+local helpers = require('test.functional.helpers')
+local clear, feed, execute = helpers.clear, helpers.feed, helpers.execute
+local eval, eq, neq = helpers.eval, helpers.eq, helpers.neq
+local execute, source = helpers.execute, helpers.source
+local nvim = helpers.nvim
+describe('msgpack*() functions', function()
+ before_each(function()
+ clear()
+ end)
+ local obj_test = function(msg, obj)
+ it(msg, function()
+ nvim('set_var', 'obj', obj)
+ eq(obj, eval('msgpackparse(msgpackdump(g:obj))'))
+ end)
+ end
+ -- Regression test: msgpack_list_write was failing to write buffer with zero
+ -- length.
+ obj_test('are able to dump and restore {"file": ""}', {{file=''}})
+ -- Regression test: msgpack_list_write was failing to write buffer with NL at
+ -- the end.
+ obj_test('are able to dump and restore {0, "echo mpack"}', {{0, 'echo mpack'}})
+ obj_test('are able to dump and restore "Test\\n"', {'Test\n'})
+ -- Regression test: msgpack_list_write was failing to write buffer with NL
+ -- inside.
+ obj_test('are able to dump and restore "Test\\nTest 2"', {'Test\nTest 2'})
+ -- Test that big objects (requirement: dump to something that is bigger then
+ -- IOSIZE) are also fine. This particular object is obtained by concatenating
+ -- 5 identical shada files.
+ local big_obj = {
+ 1, 1436711454, 78, {
+ encoding="utf-8",
+ max_kbyte=10,
+ pid=19269,
+ version="NVIM 0.0.0-alpha+201507121634"
+ },
+ 8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
+ 8, 1436711391, 8, { file="" },
+ 4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
+ 4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
+ 4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
+ 4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
+ 4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
+ 4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
+ 4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
+ 4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
+ 4, 1436708966, 6, { 0, "cq" },
+ 4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
+ 4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
+ 4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
+ 4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
+ 4, 1436709634, 57, {
+ 0,
+ "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
+ },
+ 4, 1436709651, 67, {
+ 0,
+ "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
+ },
+ 4, 1436709660, 70, {
+ 0,
+ "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
+ },
+ 4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
+ 4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
+ 4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
+ 4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
+ 4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
+ 4, 1436711142, 14, { 0, "echo mpack" },
+ 4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
+ 4, 1436711206, 16, { 0, "echo lengths" },
+ 4, 1436711244, 92, {
+ 0,
+ ("let sum = len(lengths) - 1 | call map(copy(lengths), "
+ .. "'extend(g:, {\"sum\": sum + v:val})')")
+ },
+ 4, 1436711245, 12, { 0, "echo sum" },
+ 4, 1436711398, 10, { 0, "echo s" },
+ 4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
+ 4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
+ 4, 1436711415, 22, { 0, "echo shada_objects" },
+ 4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
+ 4, 1436711454, 6, { 0, "qa" },
+ 4, 1436711442, 9, { 1, "test", 47 },
+ 4, 1436711443, 15, { 1, "aontsuesan", 47 },
+ 2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
+ 2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
+ 3, 0, 3, { "" },
+ 10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
+ 1, 1436711454, 78, {
+ encoding="utf-8",
+ max_kbyte=10,
+ pid=19269,
+ version="NVIM 0.0.0-alpha+201507121634"
+ },
+ 8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
+ 8, 1436711391, 8, { file="" },
+ 4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
+ 4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
+ 4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
+ 4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
+ 4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
+ 4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
+ 4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
+ 4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
+ 4, 1436708966, 6, { 0, "cq" },
+ 4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
+ 4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
+ 4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
+ 4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
+ 4, 1436709634, 57, {
+ 0,
+ "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
+ },
+ 4, 1436709651, 67, {
+ 0,
+ "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
+ },
+ 4, 1436709660, 70, {
+ 0,
+ "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
+ },
+ 4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
+ 4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
+ 4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
+ 4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
+ 4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
+ 4, 1436711142, 14, { 0, "echo mpack" },
+ 4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
+ 4, 1436711206, 16, { 0, "echo lengths" },
+ 4, 1436711244, 92, {
+ 0,
+ ("let sum = len(lengths) - 1 | call map(copy(lengths), "
+ .. "'extend(g:, {\"sum\": sum + v:val})')")
+ },
+ 4, 1436711245, 12, { 0, "echo sum" },
+ 4, 1436711398, 10, { 0, "echo s" },
+ 4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
+ 4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
+ 4, 1436711415, 22, { 0, "echo shada_objects" },
+ 4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
+ 4, 1436711454, 6, { 0, "qa" },
+ 4, 1436711442, 9, { 1, "test", 47 },
+ 4, 1436711443, 15, { 1, "aontsuesan", 47 },
+ 2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
+ 2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
+ 3, 0, 3, { "" },
+ 10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
+ 1, 1436711454, 78, {
+ encoding="utf-8",
+ max_kbyte=10,
+ pid=19269,
+ version="NVIM 0.0.0-alpha+201507121634"
+ },
+ 8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
+ 8, 1436711391, 8, { file="" },
+ 4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
+ 4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
+ 4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
+ 4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
+ 4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
+ 4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
+ 4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
+ 4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
+ 4, 1436708966, 6, { 0, "cq" },
+ 4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
+ 4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
+ 4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
+ 4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
+ 4, 1436709634, 57, {
+ 0,
+ "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
+ },
+ 4, 1436709651, 67, {
+ 0,
+ "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
+ },
+ 4, 1436709660, 70, {
+ 0,
+ "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
+ },
+ 4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
+ 4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
+ 4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
+ 4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
+ 4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
+ 4, 1436711142, 14, { 0, "echo mpack" },
+ 4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
+ 4, 1436711206, 16, { 0, "echo lengths" },
+ 4, 1436711244, 92, {
+ 0,
+ ("let sum = len(lengths) - 1 | call map(copy(lengths), "
+ .. "'extend(g:, {\"sum\": sum + v:val})')")
+ },
+ 4, 1436711245, 12, { 0, "echo sum" },
+ 4, 1436711398, 10, { 0, "echo s" },
+ 4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
+ 4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
+ 4, 1436711415, 22, { 0, "echo shada_objects" },
+ 4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
+ 4, 1436711454, 6, { 0, "qa" },
+ 4, 1436711442, 9, { 1, "test", 47 },
+ 4, 1436711443, 15, { 1, "aontsuesan", 47 },
+ 2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
+ 2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
+ 3, 0, 3, { "" },
+ 10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
+ 1, 1436711454, 78, {
+ encoding="utf-8",
+ max_kbyte=10,
+ pid=19269,
+ version="NVIM 0.0.0-alpha+201507121634"
+ },
+ 8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
+ 8, 1436711391, 8, { file="" },
+ 4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
+ 4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
+ 4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
+ 4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
+ 4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
+ 4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
+ 4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
+ 4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
+ 4, 1436708966, 6, { 0, "cq" },
+ 4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
+ 4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
+ 4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
+ 4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
+ 4, 1436709634, 57, {
+ 0,
+ "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
+ },
+ 4, 1436709651, 67, {
+ 0,
+ "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
+ },
+ 4, 1436709660, 70, {
+ 0,
+ "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
+ },
+ 4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
+ 4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
+ 4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
+ 4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
+ 4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
+ 4, 1436711142, 14, { 0, "echo mpack" },
+ 4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
+ 4, 1436711206, 16, { 0, "echo lengths" },
+ 4, 1436711244, 92, {
+ 0,
+ ("let sum = len(lengths) - 1 | call map(copy(lengths), "
+ .. "'extend(g:, {\"sum\": sum + v:val})')")
+ },
+ 4, 1436711245, 12, { 0, "echo sum" },
+ 4, 1436711398, 10, { 0, "echo s" },
+ 4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
+ 4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
+ 4, 1436711415, 22, { 0, "echo shada_objects" },
+ 4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
+ 4, 1436711454, 6, { 0, "qa" },
+ 4, 1436711442, 9, { 1, "test", 47 },
+ 4, 1436711443, 15, { 1, "aontsuesan", 47 },
+ 2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
+ 2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
+ 3, 0, 3, { "" },
+ 10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
+ 1, 1436711454, 78, {
+ encoding="utf-8",
+ max_kbyte=10,
+ pid=19269,
+ version="NVIM 0.0.0-alpha+201507121634"
+ },
+ 8, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" },
+ 8, 1436711391, 8, { file="" },
+ 4, 1436700940, 30, { 0, "call mkdir('/tmp/tty/tty')" },
+ 4, 1436701355, 35, { 0, "call mkdir('/tmp/tty/tty', 'p')" },
+ 4, 1436701368, 24, { 0, "call mkdir('/', 'p')" },
+ 4, 1436701375, 26, { 0, "call mkdir('/tty/tty')" },
+ 4, 1436701383, 30, { 0, "call mkdir('/tty/tty/tty')" },
+ 4, 1436701407, 35, { 0, "call mkdir('/usr/tty/tty', 'p')" },
+ 4, 1436701666, 35, { 0, "call mkdir('/tty/tty/tty', 'p')" },
+ 4, 1436708101, 25, { 0, "echo msgpackdump([1])" },
+ 4, 1436708966, 6, { 0, "cq" },
+ 4, 1436709606, 25, { 0, "echo msgpackdump([5])" },
+ 4, 1436709610, 26, { 0, "echo msgpackdump([10])" },
+ 4, 1436709615, 31, { 0, "echo msgpackdump([5, 5, 5])" },
+ 4, 1436709618, 35, { 0, "echo msgpackdump([5, 5, 5, 10])" },
+ 4, 1436709634, 57, {
+ 0,
+ "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1}]])"
+ },
+ 4, 1436709651, 67, {
+ 0,
+ "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}]])"
+ },
+ 4, 1436709660, 70, {
+ 0,
+ "echo msgpackdump([5, 5, 5, 10, [10, 20, {\"abc\": 1, \"def\": 0}], 0])"
+ },
+ 4, 1436710095, 29, { 0, "echo msgpackparse([\"\\n\"])" },
+ 4, 1436710100, 28, { 0, "echo msgpackparse([\"j\"])" },
+ 4, 1436710109, 31, { 0, "echo msgpackparse([\"\", \"\"])" },
+ 4, 1436710424, 33, { 0, "echo msgpackparse([\"\", \"\\n\"])" },
+ 4, 1436710428, 32, { 0, "echo msgpackparse([\"\", \"j\"])" },
+ 4, 1436711142, 14, { 0, "echo mpack" },
+ 4, 1436711196, 45, { 0, "let lengths = map(mpack[:], 'len(v:val)')" },
+ 4, 1436711206, 16, { 0, "echo lengths" },
+ 4, 1436711244, 92, {
+ 0,
+ ("let sum = len(lengths) - 1 | call map(copy(lengths), "
+ .. "'extend(g:, {\"sum\": sum + v:val})')")
+ },
+ 4, 1436711245, 12, { 0, "echo sum" },
+ 4, 1436711398, 10, { 0, "echo s" },
+ 4, 1436711404, 41, { 0, "let mpack = readfile('/tmp/foo', 'b')" },
+ 4, 1436711408, 41, { 0, "let shada_objects=msgpackparse(mpack)" },
+ 4, 1436711415, 22, { 0, "echo shada_objects" },
+ 4, 1436711451, 30, { 0, "e ~/.nvim/shada/main.shada" },
+ 4, 1436711454, 6, { 0, "qa" },
+ 4, 1436711442, 9, { 1, "test", 47 },
+ 4, 1436711443, 15, { 1, "aontsuesan", 47 },
+ 2, 1436711443, 38, { hlsearch=1, pat="aontsuesan", smartcase=1 },
+ 2, 0, 31, { islast=0, pat="", smartcase=1, sub=1 },
+ 3, 0, 3, { "" },
+ 10, 1436711451, 40, { file="/home/zyx/.nvim/shada/main.shada" }
+ }
+ obj_test('are able to dump and restore rather big object', big_obj)
+
+ obj_test('are able to dump and restore floating-point value', {0.125})
+
+ it('restore nil as special dict', function()
+ execute('let dumped = ["\\xC0"]')
+ execute('let parsed = msgpackparse(dumped)')
+ eq({{_TYPE={}, _VAL=0}}, eval('parsed'))
+ eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.nil'))
+ end)
+
+ it('restore boolean false as zero', function()
+ execute('let dumped = ["\\xC2"]')
+ execute('let parsed = msgpackparse(dumped)')
+ eq({{_TYPE={}, _VAL=0}}, eval('parsed'))
+ eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.boolean'))
+ end)
+
+ it('restore boolean true as one', function()
+ execute('let dumped = ["\\xC3"]')
+ execute('let parsed = msgpackparse(dumped)')
+ eq({{_TYPE={}, _VAL=1}}, eval('parsed'))
+ eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.boolean'))
+ end)
+
+ it('dump string as BIN 8', function()
+ nvim('set_var', 'obj', {'Test'})
+ eq({"\196\004Test"}, eval('msgpackdump(obj)'))
+ end)
+
+ it('restore FIXSTR as special dict', function()
+ execute('let dumped = ["\\xa2ab"]')
+ execute('let parsed = msgpackparse(dumped)')
+ eq({{_TYPE={}, _VAL={'ab'}}}, eval('parsed'))
+ eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.string'))
+ end)
+
+ it('restore BIN 8 as string', function()
+ execute('let dumped = ["\\xC4\\x02ab"]')
+ eq({'ab'}, eval('msgpackparse(dumped)'))
+ end)
+
+ it('restore FIXEXT1 as special dictionary', function()
+ execute('let dumped = ["\\xD4\\x10", ""]')
+ execute('let parsed = msgpackparse(dumped)')
+ eq({{_TYPE={}, _VAL={0x10, {"", ""}}}}, eval('parsed'))
+ eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.ext'))
+ end)
+
+ it('restore MAP with BIN key as special dictionary', function()
+ execute('let dumped = ["\\x81\\xC4\\x01a\\xC4\\n"]')
+ execute('let parsed = msgpackparse(dumped)')
+ eq({{_TYPE={}, _VAL={{'a', ''}}}}, eval('parsed'))
+ eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
+ end)
+
+ it('restore MAP with duplicate STR keys as special dictionary', function()
+ execute('let dumped = ["\\x82\\xA1a\\xC4\\n\\xA1a\\xC4\\n"]')
+ execute('let parsed = msgpackparse(dumped)')
+ eq({{_TYPE={}, _VAL={{{_TYPE={}, _VAL={'a'}}, ''},
+ {{_TYPE={}, _VAL={'a'}}, ''}}}}, eval('parsed'))
+ eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
+ eq(1, eval('g:parsed[0]._VAL[0][0]._TYPE is v:msgpack_types.string'))
+ eq(1, eval('g:parsed[0]._VAL[1][0]._TYPE is v:msgpack_types.string'))
+ end)
+
+ it('restore MAP with MAP key as special dictionary', function()
+ execute('let dumped = ["\\x81\\x80\\xC4\\n"]')
+ execute('let parsed = msgpackparse(dumped)')
+ eq({{_TYPE={}, _VAL={{{}, ''}}}}, eval('parsed'))
+ eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map'))
+ end)
+
+ it('can restore and dump UINT64_MAX', function()
+ execute('let dumped = ["\\xCF" . repeat("\\xFF", 8)]')
+ execute('let parsed = msgpackparse(dumped)')
+ execute('let dumped2 = msgpackdump(parsed)')
+ eq(1, eval('type(parsed[0]) == type(0) ' ..
+ '|| parsed[0]._TYPE is v:msgpack_types.integer'))
+ if eval('type(parsed[0]) == type(0)') == 1 then
+ eq(1, eval('0xFFFFFFFFFFFFFFFF == parsed[0]'))
+ else
+ eq({_TYPE={}, _VAL={1, 3, 0x7FFFFFFF, 0x7FFFFFFF}}, eval('parsed[0]'))
+ end
+ eq(1, eval('dumped ==# dumped2'))
+ end)
+
+ it('can restore and dump INT64_MIN', function()
+ execute('let dumped = ["\\xD3\\x80" . repeat("\\n", 7)]')
+ execute('let parsed = msgpackparse(dumped)')
+ execute('let dumped2 = msgpackdump(parsed)')
+ eq(1, eval('type(parsed[0]) == type(0) ' ..
+ '|| parsed[0]._TYPE is v:msgpack_types.integer'))
+ if eval('type(parsed[0]) == type(0)') == 1 then
+ eq(1, eval('-0x8000000000000000 == parsed[0]'))
+ else
+ eq({_TYPE={}, _VAL={-1, 2, 0, 0}}, eval('parsed[0]'))
+ end
+ eq(1, eval('dumped ==# dumped2'))
+ end)
+
+ it('can restore and dump BIN string with zero byte', function()
+ execute('let dumped = ["\\xC4\\x01\\n"]')
+ execute('let parsed = msgpackparse(dumped)')
+ execute('let dumped2 = msgpackdump(parsed)')
+ eq({{_TYPE={}, _VAL={'\n'}}}, eval('parsed'))
+ eq(1, eval('parsed[0]._TYPE is v:msgpack_types.binary'))
+ eq(1, eval('dumped ==# dumped2'))
+ end)
+
+ it('can restore and dump STR string with zero byte', function()
+ execute('let dumped = ["\\xA1\\n"]')
+ execute('let parsed = msgpackparse(dumped)')
+ execute('let dumped2 = msgpackdump(parsed)')
+ eq({{_TYPE={}, _VAL={'\n'}}}, eval('parsed'))
+ eq(1, eval('parsed[0]._TYPE is v:msgpack_types.string'))
+ eq(1, eval('dumped ==# dumped2'))
+ end)
+
+ it('can restore and dump BIN string with NL', function()
+ execute('let dumped = ["\\xC4\\x01", ""]')
+ execute('let parsed = msgpackparse(dumped)')
+ execute('let dumped2 = msgpackdump(parsed)')
+ eq({"\n"}, eval('parsed'))
+ eq(1, eval('dumped ==# dumped2'))
+ end)
+
+ it('can dump generic mapping with generic mapping keys and values', function()
+ execute('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
+ execute('let todumpv1 = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
+ execute('let todumpv2 = {"_TYPE": v:msgpack_types.map, "_VAL": []}')
+ execute('call add(todump._VAL, [todumpv1, todumpv2])')
+ eq({'\129\128\128'}, eval('msgpackdump([todump])'))
+ end)
+
+ it('can dump generic mapping with ext', function()
+ execute('let todump = {"_TYPE": v:msgpack_types.ext, "_VAL": [5, ["",""]]}')
+ eq({'\212\005', ''}, eval('msgpackdump([todump])'))
+ end)
+
+ it('can dump generic mapping with array', function()
+ execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": [5, [""]]}')
+ eq({'\146\005\145\196\n'}, eval('msgpackdump([todump])'))
+ end)
+
+ it('can dump generic mapping with UINT64_MAX', function()
+ execute('let todump = {"_TYPE": v:msgpack_types.integer}')
+ execute('let todump._VAL = [1, 3, 0x7FFFFFFF, 0x7FFFFFFF]')
+ eq({'\207\255\255\255\255\255\255\255\255'}, eval('msgpackdump([todump])'))
+ end)
+
+ it('can dump generic mapping with INT64_MIN', function()
+ execute('let todump = {"_TYPE": v:msgpack_types.integer}')
+ execute('let todump._VAL = [-1, 2, 0, 0]')
+ eq({'\211\128\n\n\n\n\n\n\n'}, eval('msgpackdump([todump])'))
+ end)
+
+ it('dump and restore generic mapping with floating-point value', function()
+ execute('let todump = {"_TYPE": v:msgpack_types.float, "_VAL": 0.125}')
+ eq({0.125}, eval('msgpackparse(msgpackdump([todump]))'))
+ end)
+
+ it('fails to dump a function reference', function()
+ execute('let Todump = function("tr")')
+ execute([[
+ try
+ let dumped = msgpackdump([Todump])
+ let exception = 0
+ catch
+ let exception = v:exception
+ endtry
+ ]])
+ eq('Vim(let):E475: Invalid argument: attempt to dump function reference',
+ eval('exception'))
+ end)
+
+ it('fails to dump a function reference in a list', function()
+ execute('let todump = [function("tr")]')
+ execute([[
+ try
+ let dumped = msgpackdump([todump])
+ let exception = 0
+ catch
+ let exception = v:exception
+ endtry
+ ]])
+ eq('Vim(let):E475: Invalid argument: attempt to dump function reference',
+ eval('exception'))
+ end)
+
+ it('fails to dump a recursive list', function()
+ execute('let todump = [[[]]]')
+ execute('call add(todump[0][0], todump)')
+ execute([[
+ try
+ let dumped = msgpackdump([todump])
+ let exception = 0
+ catch
+ let exception = v:exception
+ endtry
+ ]])
+ eq('Vim(let):E475: Invalid argument: container references itself',
+ eval('exception'))
+ end)
+
+ it('fails to dump a recursive dict', function()
+ execute('let todump = {"d": {"d": {}}}')
+ execute('call extend(todump.d.d, {"d": todump})')
+ execute([[
+ try
+ let dumped = msgpackdump([todump])
+ let exception = 0
+ catch
+ let exception = v:exception
+ endtry
+ ]])
+ eq('Vim(let):E475: Invalid argument: container references itself',
+ eval('exception'))
+ end)
+
+ it('fails to dump a recursive list in a special dict', function()
+ execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
+ execute('call add(todump._VAL, todump)')
+ execute([[
+ try
+ let dumped = msgpackdump([todump])
+ let exception = 0
+ catch
+ let exception = v:exception
+ endtry
+ ]])
+ eq('Vim(let):E475: Invalid argument: container references itself',
+ eval('exception'))
+ end)
+
+ it('fails to dump a recursive (key) map in a special dict', function()
+ execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
+ execute('call add(todump._VAL, [todump, 0])')
+ execute([[
+ try
+ let dumped = msgpackdump([todump])
+ let exception = 0
+ catch
+ let exception = v:exception
+ endtry
+ ]])
+ eq('Vim(let):E475: Invalid argument: container references itself',
+ eval('exception'))
+ end)
+
+ it('fails to dump a recursive (val) map in a special dict', function()
+ execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
+ execute('call add(todump._VAL, [0, todump])')
+ execute([[
+ try
+ let dumped = msgpackdump([todump])
+ let exception = 0
+ catch
+ let exception = v:exception
+ endtry
+ ]])
+ eq('Vim(let):E475: Invalid argument: container references itself',
+ eval('exception'))
+ end)
+
+ it('fails to dump a recursive (val) special list in a special dict',
+ function()
+ execute('let todump = {"_TYPE": v:msgpack_types.array, "_VAL": []}')
+ execute('call add(todump._VAL, [0, todump._VAL])')
+ execute([[
+ try
+ let dumped = msgpackdump([todump])
+ let exception = 0
+ catch
+ let exception = v:exception
+ endtry
+ ]])
+ eq('Vim(let):E475: Invalid argument: container references itself',
+ eval('exception'))
+ end)
+
+ it('msgpackparse(systemlist(...)) does not segfault. #3135', function()
+ local cmd = "msgpackparse(systemlist('"
+ ..helpers.nvim_prog.." --api-info'))['_TYPE']['_VAL'][0][0]"
+ local api_info = eval(cmd)
+ api_info = eval(cmd) -- do it again (try to force segfault)
+ api_info = eval(cmd) -- do it again
+ eq('functions', api_info)
+ end)
+end)
diff --git a/test/functional/ex_cmds/grep_spec.lua b/test/functional/ex_cmds/grep_spec.lua
new file mode 100644
index 0000000000..9c792099c1
--- /dev/null
+++ b/test/functional/ex_cmds/grep_spec.lua
@@ -0,0 +1,22 @@
+local helpers = require('test.functional.helpers')
+local clear, execute, nvim, feed, eq, ok, eval =
+ helpers.clear, helpers.execute, helpers.nvim, helpers.feed,
+ helpers.eq, helpers.ok, helpers.eval
+
+describe(':grep', function()
+ before_each(clear)
+
+ it('does not hang on large input #2983', function()
+ if eval("executable('grep')") == 0 then
+ pending('missing "grep" command')
+ return
+ end
+
+ execute([[set grepprg=grep\ -r]])
+ -- Change to test directory so that the test does not run too long.
+ execute('cd test')
+ execute('grep a **/*')
+ feed('<cr>') -- Press ENTER
+ ok(eval('len(getqflist())') > 9000) -- IT'S OVER 9000!!1
+ end)
+end)
diff --git a/test/functional/ex_cmds/menu_spec.lua b/test/functional/ex_cmds/menu_spec.lua
new file mode 100644
index 0000000000..6af889bf9e
--- /dev/null
+++ b/test/functional/ex_cmds/menu_spec.lua
@@ -0,0 +1,38 @@
+local helpers = require('test.functional.helpers')
+local clear, execute, nvim = helpers.clear, helpers.execute, helpers.nvim
+local expect = helpers.expect
+local feed = helpers.feed
+local command = helpers.command
+
+describe(':emenu', function()
+
+ before_each(function()
+ clear()
+ execute('nnoremenu Test.Test inormal<ESC>')
+ execute('inoremenu Test.Test insert')
+ execute('vnoremenu Test.Test x')
+ end)
+
+ it('executes correct bindings in normal mode without using API', function()
+ execute('emenu Test.Test')
+ expect('normal')
+ end)
+
+ it('executes correct bindings in normal mode', function()
+ command('emenu Test.Test')
+ expect('normal')
+ end)
+
+ it('executes correct bindings in insert mode', function()
+ feed('i')
+ command('emenu Test.Test')
+ expect('insert')
+ end)
+
+ it('executes correct bindings in visual mode', function()
+ feed('iabcde<ESC>0lvll')
+ command('emenu Test.Test')
+ expect('ae')
+ end)
+
+end)
diff --git a/test/functional/ex_cmds/recover_spec.lua b/test/functional/ex_cmds/recover_spec.lua
index d4c9477133..b92739e40e 100644
--- a/test/functional/ex_cmds/recover_spec.lua
+++ b/test/functional/ex_cmds/recover_spec.lua
@@ -20,11 +20,11 @@ describe(':preserve', function()
local swapdir = lfs.currentdir()..'/testdir_recover_spec'
before_each(function()
clear()
- os.remove(swapdir)
+ helpers.rmdir(swapdir)
lfs.mkdir(swapdir)
end)
after_each(function()
- os.remove(swapdir)
+ helpers.rmdir(swapdir)
end)
it("saves to custom 'directory' and (R)ecovers (issue #1836)", function()
diff --git a/test/functional/clipboard/autoload/provider/clipboard.vim b/test/functional/fixtures/autoload/provider/clipboard.vim
index d88b68464e..0935ea45ff 100644
--- a/test/functional/clipboard/autoload/provider/clipboard.vim
+++ b/test/functional/fixtures/autoload/provider/clipboard.vim
@@ -3,18 +3,28 @@ let g:test_clip = { '+': [''], '*': [''], }
let s:methods = {}
let g:cliplossy = 0
+let g:cliperror = 0
function! s:methods.get(reg)
+ if g:cliperror
+ return 0
+ end
+ let reg = a:reg == '"' ? '+' : a:reg
if g:cliplossy
" behave like pure text clipboard
- return g:test_clip[a:reg][0]
+ return g:test_clip[reg][0]
else
- "behave like VIMENC clipboard
- return g:test_clip[a:reg]
+ " behave like VIMENC clipboard
+ return g:test_clip[reg]
end
endfunction
function! s:methods.set(lines, regtype, reg)
+ if a:reg == '"'
+ call s:methods.set(a:lines,a:regtype,'+')
+ call s:methods.set(a:lines,a:regtype,'*')
+ return 0
+ end
let g:test_clip[a:reg] = [a:lines, a:regtype]
endfunction
diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua
index 33d04616a0..1159707282 100644
--- a/test/functional/helpers.lua
+++ b/test/functional/helpers.lua
@@ -6,7 +6,6 @@ local AsyncSession = require('nvim.async_session')
local Session = require('nvim.session')
local nvim_prog = os.getenv('NVIM_PROG') or 'build/bin/nvim'
---- FIXME: 'autoindent' messes up the insert() function
local nvim_argv = {nvim_prog, '-u', 'NONE', '-i', 'NONE', '-N',
'--cmd', 'set shortmess+=I background=light noswapfile noautoindent',
'--embed'}
@@ -290,6 +289,28 @@ local function expect(contents)
return eq(dedent(contents), curbuf_contents())
end
+local function rmdir(path)
+ if lfs.attributes(path, 'mode') ~= 'directory' then
+ return nil
+ end
+ for file in lfs.dir(path) do
+ if file == '.' or file == '..' then
+ goto continue
+ end
+ ret, err = os.remove(path..'/'..file)
+ if not ret then
+ error('os.remove: '..err)
+ return nil
+ end
+ ::continue::
+ end
+ ret, err = os.remove(path)
+ if not ret then
+ error('os.remove: '..err)
+ end
+ return ret
+end
+
return {
clear = clear,
spawn = spawn,
@@ -321,5 +342,6 @@ return {
curbuf_contents = curbuf_contents,
wait = wait,
set_session = set_session,
- write_file = write_file
+ write_file = write_file,
+ rmdir = rmdir
}
diff --git a/test/functional/job/job_spec.lua b/test/functional/job/job_spec.lua
index b60f9ff7a4..7085d61cc7 100644
--- a/test/functional/job/job_spec.lua
+++ b/test/functional/job/job_spec.lua
@@ -304,7 +304,7 @@ describe('jobs', function()
source([[
call rpcnotify(g:channel, 'wait', jobwait([
\ jobstart([&sh, '-c', 'exit 4']),
- \ jobstart([&sh, '-c', 'sleep 10000; exit 5']),
+ \ jobstart([&sh, '-c', 'sleep 10; exit 5']),
\ ], 100))
]])
eq({'notification', 'wait', {{4, -1}}}, next_msg())
diff --git a/test/functional/legacy/057_sort_spec.lua b/test/functional/legacy/057_sort_spec.lua
new file mode 100644
index 0000000000..585b391198
--- /dev/null
+++ b/test/functional/legacy/057_sort_spec.lua
@@ -0,0 +1,603 @@
+-- Tests for :sort command.
+
+local helpers = require('test.functional.helpers')
+local insert, execute, clear, expect, eq, eval, source = helpers.insert,
+ helpers.execute, helpers.clear, helpers.expect, helpers.eq, helpers.eval,
+ helpers.source
+
+describe(':sort', function()
+ local text = [[
+ abc
+ ab
+ a
+ a321
+ a123
+ a122
+ b321
+ b123
+ c123d
+ 123b
+ c321d
+ b322b
+ b321
+ b321b
+ ]]
+ before_each(clear)
+
+ it('alphabetical', function()
+ insert(text)
+ execute('sort')
+ expect([[
+
+ 123b
+ a
+ a122
+ a123
+ a321
+ ab
+ abc
+ b123
+ b321
+ b321
+ b321b
+ b322b
+ c123d
+ c321d]])
+ end)
+
+ it('numerical', function()
+ insert([[
+ abc
+ ab
+ a321
+ a123
+ a122
+ a
+ x-22
+ b321
+ b123
+ c123d
+ -24
+ 123b
+ c321d
+ 0
+ b322b
+ b321
+ b321b
+ ]])
+ execute('sort n')
+ expect([[
+ abc
+ ab
+ a
+
+ -24
+ x-22
+ 0
+ a122
+ a123
+ b123
+ c123d
+ 123b
+ a321
+ b321
+ c321d
+ b321
+ b321b
+ b322b]])
+ end)
+
+ it('hexadecimal', function()
+ insert(text)
+ execute('sort x')
+ expect([[
+
+ a
+ ab
+ abc
+ 123b
+ a122
+ a123
+ a321
+ b123
+ b321
+ b321
+ b321b
+ b322b
+ c123d
+ c321d]])
+ end)
+
+ it('alphabetical, unique', function()
+ insert(text)
+ execute('sort u')
+ expect([[
+
+ 123b
+ a
+ a122
+ a123
+ a321
+ ab
+ abc
+ b123
+ b321
+ b321b
+ b322b
+ c123d
+ c321d]])
+ end)
+
+ it('alphabetical, reverse', function()
+ insert(text)
+ execute('sort!')
+ expect([[
+ c321d
+ c123d
+ b322b
+ b321b
+ b321
+ b321
+ b123
+ abc
+ ab
+ a321
+ a123
+ a122
+ a
+ 123b
+ ]])
+ end)
+
+ it('numerical, reverse', function()
+ insert(text)
+ execute('sort! n')
+ expect([[
+ b322b
+ b321b
+ b321
+ c321d
+ b321
+ a321
+ 123b
+ c123d
+ b123
+ a123
+ a122
+
+ a
+ ab
+ abc]])
+ end)
+
+ it('unique, reverse', function()
+ insert(text)
+ execute('sort! u')
+ expect([[
+ c321d
+ c123d
+ b322b
+ b321b
+ b321
+ b123
+ abc
+ ab
+ a321
+ a123
+ a122
+ a
+ 123b
+ ]])
+ end)
+
+ it('octal', function()
+ insert(text)
+ execute('sort o')
+ expect([[
+ abc
+ ab
+ a
+
+ a122
+ a123
+ b123
+ c123d
+ 123b
+ a321
+ b321
+ c321d
+ b321
+ b321b
+ b322b]])
+ end)
+
+ it('reverse, hexadecimal', function()
+ insert(text)
+ execute('sort! x')
+ expect([[
+ c321d
+ c123d
+ b322b
+ b321b
+ b321
+ b321
+ b123
+ a321
+ a123
+ a122
+ 123b
+ abc
+ ab
+ a
+ ]])
+ end)
+
+ it('alphabetical, skip first character', function()
+ insert(text)
+ execute('sort/./')
+ expect([[
+ a
+
+ a122
+ a123
+ b123
+ 123b
+ c123d
+ a321
+ b321
+ b321
+ b321b
+ c321d
+ b322b
+ ab
+ abc]])
+ end)
+
+ it('alphabetical, skip first 2 characters', function()
+ insert(text)
+ execute('sort/../')
+ expect([[
+ ab
+ a
+
+ a321
+ b321
+ b321
+ b321b
+ c321d
+ a122
+ b322b
+ a123
+ b123
+ 123b
+ c123d
+ abc]])
+ end)
+
+ it('alphabetical, unique, skip first 2 characters', function()
+ insert(text)
+ execute('sort/../u')
+ expect([[
+ ab
+ a
+
+ a321
+ b321
+ b321b
+ c321d
+ a122
+ b322b
+ a123
+ b123
+ 123b
+ c123d
+ abc]])
+ end)
+
+ it('numerical, skip first character', function()
+ insert(text)
+ execute('sort/./n')
+ expect([[
+ abc
+ ab
+ a
+
+ a122
+ a123
+ b123
+ c123d
+ 123b
+ a321
+ b321
+ c321d
+ b321
+ b321b
+ b322b]])
+ end)
+
+ it('alphabetical, sort on first character', function()
+ insert(text)
+ execute('sort/./r')
+ expect([[
+
+ 123b
+ abc
+ ab
+ a
+ a321
+ a123
+ a122
+ b321
+ b123
+ b322b
+ b321
+ b321b
+ c123d
+ c321d]])
+ end)
+
+ it('alphabetical, sort on first 2 characters', function()
+ insert(text)
+ execute('sort/../r')
+ expect([[
+ a
+
+ 123b
+ a123
+ a122
+ a321
+ abc
+ ab
+ b123
+ b321
+ b322b
+ b321
+ b321b
+ c123d
+ c321d]])
+ end)
+
+ it('numerical, sort on first character', function()
+ insert(text)
+ execute('sort/./rn')
+ expect([[
+ abc
+ ab
+ a
+ a321
+ a123
+ a122
+ b321
+ b123
+ c123d
+ 123b
+ c321d
+ b322b
+ b321
+ b321b
+ ]])
+ end)
+
+ it('alphabetical, skip past first digit', function()
+ insert(text)
+ execute([[sort/\d/]])
+ expect([[
+ abc
+ ab
+ a
+
+ a321
+ b321
+ b321
+ b321b
+ c321d
+ a122
+ b322b
+ a123
+ b123
+ 123b
+ c123d]])
+ end)
+
+ it('alphabetical, sort on first digit', function()
+ insert(text)
+ execute([[sort/\d/r]])
+ expect([[
+ abc
+ ab
+ a
+
+ a123
+ a122
+ b123
+ c123d
+ 123b
+ a321
+ b321
+ c321d
+ b322b
+ b321
+ b321b]])
+ end)
+
+ it('numerical, skip past first digit', function()
+ insert(text)
+ execute([[sort/\d/n]])
+ expect([[
+ abc
+ ab
+ a
+
+ a321
+ b321
+ c321d
+ b321
+ b321b
+ a122
+ b322b
+ a123
+ b123
+ c123d
+ 123b]])
+ end)
+
+ it('numerical, sort on first digit', function()
+ insert(text)
+ execute([[sort/\d/rn]])
+ expect([[
+ abc
+ ab
+ a
+
+ a123
+ a122
+ b123
+ c123d
+ 123b
+ a321
+ b321
+ c321d
+ b322b
+ b321
+ b321b]])
+ end)
+
+ it('alphabetical, skip past first 2 digits', function()
+ insert(text)
+ execute([[sort/\d\d/]])
+ expect([[
+ abc
+ ab
+ a
+
+ a321
+ b321
+ b321
+ b321b
+ c321d
+ a122
+ b322b
+ a123
+ b123
+ 123b
+ c123d]])
+ end)
+
+ it('numerical, skip past first 2 digits', function()
+ insert(text)
+ execute([[sort/\d\d/n]])
+ expect([[
+ abc
+ ab
+ a
+
+ a321
+ b321
+ c321d
+ b321
+ b321b
+ a122
+ b322b
+ a123
+ b123
+ c123d
+ 123b]])
+ end)
+
+ it('hexadecimal, skip past first 2 digits', function()
+ insert(text)
+ execute([[sort/\d\d/x]])
+ expect([[
+ abc
+ ab
+ a
+
+ a321
+ b321
+ b321
+ a122
+ a123
+ b123
+ b321b
+ c321d
+ b322b
+ 123b
+ c123d]])
+ end)
+
+ it('alpha, on first 2 digits', function()
+ insert(text)
+ execute([[sort/\d\d/r]])
+ expect([[
+ abc
+ ab
+ a
+
+ a123
+ a122
+ b123
+ c123d
+ 123b
+ a321
+ b321
+ c321d
+ b322b
+ b321
+ b321b]])
+ end)
+
+ it('numeric, on first 2 digits', function()
+ insert(text)
+ execute([[sort/\d\d/rn]])
+ expect([[
+ abc
+ ab
+ a
+
+ a123
+ a122
+ b123
+ c123d
+ 123b
+ a321
+ b321
+ c321d
+ b322b
+ b321
+ b321b]])
+ end)
+
+ it('hexadecimal, on first 2 digits', function()
+ insert(text)
+ execute([[sort/\d\d/rx]])
+ expect([[
+ abc
+ ab
+ a
+
+ a123
+ a122
+ b123
+ c123d
+ 123b
+ a321
+ b321
+ c321d
+ b322b
+ b321
+ b321b]])
+ end)
+
+ it('fails with wrong arguments', function()
+ insert(text)
+ -- This should fail with "E474: Invalid argument".
+ source([[
+ try
+ sort no
+ catch
+ let tmpvar = v:exception
+ endtry]])
+ eq('Vim(sort):E474: Invalid argument', eval('tmpvar'))
+ expect(text)
+ end)
+end)
diff --git a/test/functional/legacy/060_exists_and_has_functions_spec.lua b/test/functional/legacy/060_exists_and_has_functions_spec.lua
index c4d2b01522..e9b79b490d 100644
--- a/test/functional/legacy/060_exists_and_has_functions_spec.lua
+++ b/test/functional/legacy/060_exists_and_has_functions_spec.lua
@@ -1,18 +1,15 @@
--- Tests for the exists() and has() functions. ts=8 sw=2
+-- Tests for the exists() and has() functions.
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
local write_file = helpers.write_file
-local os = require('os')
describe('exists() and has() functions', function()
- setup(clear)
-
- it('is working', function()
-
+ setup(function()
+ clear()
-- Create a temporary script needed for the test.
- write_file('test60.vim', [=[
+ write_file('test60.vim', [[
" Vim script for exists() function test
" Script-local variables are checked here
@@ -110,7 +107,14 @@ describe('exists() and has() functions', function()
echo "FAILED"
endif
unlet str
- ]=])
+ ]])
+ end)
+ teardown(function()
+ os.remove('test.out')
+ os.remove('test60.vim')
+ end)
+
+ it('is working', function()
source([=[
" Add the special directory with test scripts to &rtp
@@ -648,7 +652,7 @@ describe('exists() and has() functions', function()
]=])
-- Assert buffer contents.
- expect([=[
+ expect([[
#myagroup: 1
OK
@@ -859,11 +863,7 @@ describe('exists() and has() functions', function()
has patch 7.1.999: 1
has patch 7.4.123: 1
has patch 9.1.0: 0
- has patch 9.9.1: 0]=])
+ has patch 9.9.1: 0]])
end)
- teardown(function()
- os.remove('test.out')
- os.remove('test60.vim')
- end)
end)
diff --git a/test/functional/legacy/062_tab_pages_spec.lua b/test/functional/legacy/062_tab_pages_spec.lua
new file mode 100644
index 0000000000..6bbb06f9a7
--- /dev/null
+++ b/test/functional/legacy/062_tab_pages_spec.lua
@@ -0,0 +1,240 @@
+-- Tests for tab pages
+
+local helpers = require('test.functional.helpers')
+local feed, insert, source, clear, execute, expect, eval, eq =
+ helpers.feed, helpers.insert, helpers.source, helpers.clear,
+ helpers.execute, helpers.expect, helpers.eval, helpers.eq
+
+describe('tab pages', function()
+ before_each(clear)
+
+ it('can be opened and closed', function()
+ execute('tabnew')
+ eq(2, eval('tabpagenr()'))
+ execute('quit')
+ eq(1, eval('tabpagenr()'))
+ end)
+
+ it('can be iterated with :tabdo', function()
+ source([[
+ 0tabnew
+ 1tabnew
+ $tabnew
+ tabdo call append(line('$'), 'this is tab page ' . tabpagenr())
+ tabclose! 2
+ tabrewind
+ ]])
+ eq('this is tab page 1', eval("getline('$')"))
+ execute('tablast')
+ eq('this is tab page 4', eval("getline('$')"))
+ end)
+
+ it('have local variables accasible with settabvar()/gettabvar()', function()
+ -- Test for settabvar() and gettabvar() functions. Open a new tab page and
+ -- set 3 variables to a number, string and a list. Verify that the
+ -- variables are correctly set.
+ source([[
+ tabnew
+ tabfirst
+ call settabvar(2, 'val_num', 100)
+ call settabvar(2, 'val_str', 'SetTabVar test')
+ call settabvar(2, 'val_list', ['red', 'blue', 'green'])
+ ]])
+
+ eq(100, eval('gettabvar(2, "val_num")'))
+ eq('SetTabVar test', eval('gettabvar(2, "val_str")'))
+ eq({'red', 'blue', 'green'}, eval('gettabvar(2, "val_list")'))
+ execute('tabnext 2')
+ eq(100, eval('t:val_num'))
+ eq('SetTabVar test', eval('t:val_str'))
+ eq({'red', 'blue', 'green'}, eval('t:val_list'))
+ end)
+
+ it('work together with the drop feature and loaded buffers', function()
+ -- Test for ":tab drop exist-file" to keep current window.
+ execute('sp test1')
+ execute('tab drop test1')
+ eq(1, eval('tabpagenr("$")'))
+ eq(2, eval('winnr("$")'))
+ eq(1, eval('winnr()'))
+ end)
+
+ it('work together with the drop feature and new files', function()
+ -- Test for ":tab drop new-file" to keep current window of tabpage 1.
+ execute('split')
+ execute('tab drop newfile')
+ eq(2, eval('tabpagenr("$")'))
+ eq(2, eval('tabpagewinnr(1, "$")'))
+ eq(1, eval('tabpagewinnr(1)'))
+ end)
+
+ it('work together with the drop feature and multi loaded buffers', function()
+ -- Test for ":tab drop multi-opend-file" to keep current tabpage and
+ -- window.
+ execute('new test1')
+ execute('tabnew')
+ execute('new test1')
+ execute('tab drop test1')
+ eq(2, eval('tabpagenr()'))
+ eq(2, eval('tabpagewinnr(2, "$")'))
+ eq(1, eval('tabpagewinnr(2)'))
+ end)
+
+ it('can be navigated with :tabmove', function()
+ execute('lang C')
+ execute('for i in range(9) | tabnew | endfor')
+ feed('1gt')
+ eq(1, eval('tabpagenr()'))
+ execute('tabmove 5')
+ eq(6, eval('tabpagenr()'))
+ execute('tabmove -2')
+ eq(4, eval('tabpagenr()'))
+ execute('tabmove +4')
+ eq(8, eval('tabpagenr()'))
+ execute('tabmove')
+ eq(10, eval('tabpagenr()'))
+ execute('tabmove -20')
+ eq(1, eval('tabpagenr()'))
+ execute('tabmove +20')
+ eq(10, eval('tabpagenr()'))
+ execute('3tabmove')
+ eq(4, eval('tabpagenr()'))
+ execute('7tabmove 5')
+ eq(6, eval('tabpagenr()'))
+ execute('let a="No error caught."')
+ execute('try')
+ execute('tabmove foo')
+ execute('catch E474')
+ execute('let a="E474 caught."')
+ execute('endtry')
+ eq('E474 caught.', eval('a'))
+ end)
+
+ it('can trigger certain autocommands', function()
+ insert('Results:')
+
+ -- Test autocommands.
+ source([[
+ tabonly!
+ let g:r=[]
+ command -nargs=1 -bar C :call add(g:r, '=== '.<q-args>.' ===')|<args>
+ function Test()
+ autocmd TabEnter * :call add(g:r, 'TabEnter')
+ autocmd WinEnter * :call add(g:r, 'WinEnter')
+ autocmd BufEnter * :call add(g:r, 'BufEnter')
+ autocmd TabLeave * :call add(g:r, 'TabLeave')
+ autocmd WinLeave * :call add(g:r, 'WinLeave')
+ autocmd BufLeave * :call add(g:r, 'BufLeave')
+ let t:a='a'
+ C tab split
+ let t:a='b'
+ C tabnew
+ let t:a='c'
+ call add(g:r, join(map(range(1, tabpagenr('$')),
+ \ 'gettabvar(v:val, "a")')))
+ C call map(range(1, tabpagenr('$')),
+ \ 'settabvar(v:val, ''a'', v:val*2)')
+ call add(g:r, join(map(range(1, tabpagenr('$')),
+ \ 'gettabvar(v:val, "a")')))
+ let w:a='a'
+ C vsplit
+ let w:a='a'
+ let tabn=tabpagenr()
+ let winr=range(1, winnr('$'))
+ C tabnext 1
+ call add(g:r, join(map(copy(winr),
+ \ 'gettabwinvar('.tabn.', v:val, "a")')))
+ C call map(copy(winr),
+ \ 'settabwinvar('.tabn.', v:val, ''a'', v:val*2)')
+ call add(g:r, join(map(copy(winr),
+ \ 'gettabwinvar('.tabn.', v:val, "a")')))
+ augroup TabDestructive
+ autocmd TabEnter * :C tabnext 2 | C tabclose 3
+ augroup END
+ C tabnext 3
+ let g:r+=[tabpagenr().'/'.tabpagenr('$')]
+ autocmd! TabDestructive TabEnter
+ C tabnew
+ C tabnext 1
+ autocmd TabDestructive TabEnter * nested
+ \ :C tabnext 2 | C tabclose 3
+ C tabnext 3
+ let g:r+=[tabpagenr().'/'.tabpagenr('$')]
+ endfunction
+ call Test()
+ $ put =g:r
+ ]])
+
+ -- Assert buffer contents.
+ expect([[
+ Results:
+ === tab split ===
+ WinLeave
+ TabLeave
+ WinEnter
+ TabEnter
+ === tabnew ===
+ WinLeave
+ TabLeave
+ WinEnter
+ TabEnter
+ BufLeave
+ BufEnter
+ a b c
+ === call map(range(1, tabpagenr('$')), 'settabvar(v:val, ''a'', v:val*2)') ===
+ 2 4 6
+ === vsplit ===
+ WinLeave
+ WinEnter
+ === tabnext 1 ===
+ BufLeave
+ WinLeave
+ TabLeave
+ WinEnter
+ TabEnter
+ BufEnter
+ a a
+ === call map(copy(winr), 'settabwinvar('.tabn.', v:val, ''a'', v:val*2)') ===
+ 2 4
+ === tabnext 3 ===
+ BufLeave
+ WinLeave
+ TabLeave
+ WinEnter
+ TabEnter
+ === tabnext 2 ===
+ === tabclose 3 ===
+ 2/2
+ === tabnew ===
+ WinLeave
+ TabLeave
+ WinEnter
+ TabEnter
+ BufLeave
+ BufEnter
+ === tabnext 1 ===
+ BufLeave
+ WinLeave
+ TabLeave
+ WinEnter
+ TabEnter
+ BufEnter
+ === tabnext 3 ===
+ BufLeave
+ WinLeave
+ TabLeave
+ WinEnter
+ TabEnter
+ === tabnext 2 ===
+ BufLeave
+ WinLeave
+ TabLeave
+ WinEnter
+ TabEnter
+ === tabnext 2 ===
+ === tabclose 3 ===
+ BufEnter
+ === tabclose 3 ===
+ 2/2]])
+ end)
+end)
diff --git a/test/functional/legacy/077_mf_hash_grow_spec.lua b/test/functional/legacy/077_mf_hash_grow_spec.lua
index 01d916ef04..825f08e968 100644
--- a/test/functional/legacy/077_mf_hash_grow_spec.lua
+++ b/test/functional/legacy/077_mf_hash_grow_spec.lua
@@ -15,7 +15,7 @@ describe('mf_hash_grow()', function()
-- Check to see if cksum exists, otherwise skip the test
if os.execute('which cksum 2>&1 > /dev/null') ~= 0 then
- pending("was not tested because cksum was not found")
+ pending('was not tested because cksum was not found', function() end)
else
it('is working', function()
execute('set fileformat=unix undolevels=-1')
diff --git a/test/functional/legacy/080_substitute_spec.lua b/test/functional/legacy/080_substitute_spec.lua
new file mode 100644
index 0000000000..89ef7a713c
--- /dev/null
+++ b/test/functional/legacy/080_substitute_spec.lua
@@ -0,0 +1,162 @@
+-- Test for *sub-replace-special* and *sub-replace-expression* on substitue().
+-- Test for submatch() on substitue().
+-- Test for *:s%* on :substitute.
+
+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
+local eq, eval = helpers.eq, helpers.eval
+
+describe('substitue()', function()
+ before_each(clear)
+
+ -- The original test contained several TEST_X lines to delimit different
+ -- parts. These where used to split the test into different it() blocks.
+ -- The TEST_X strings are repeated in the description of the blocks to make
+ -- it easier to incorporate upstream changes.
+
+ local function test_1_and_2()
+ eq('AA', eval("substitute('A', 'A', '&&', '')"))
+ eq('&', eval([[substitute('B', 'B', '\&', '')]]))
+ eq('C123456789987654321', eval([[substitute('C123456789', ]] ..
+ [['C\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', ]] ..
+ [['\0\9\8\7\6\5\4\3\2\1', '')]]))
+ eq('d', eval("substitute('D', 'D', 'd', '')"))
+ eq('~', eval("substitute('E', 'E', '~', '')"))
+ eq('~', eval([[substitute('F', 'F', '\~', '')]]))
+ eq('Gg', eval([[substitute('G', 'G', '\ugg', '')]]))
+ eq('Hh', eval([[substitute('H', 'H', '\Uh\Eh', '')]]))
+ eq('iI', eval([[substitute('I', 'I', '\lII', '')]]))
+ eq('jJ', eval([[substitute('J', 'J', '\LJ\EJ', '')]]))
+ eq('Kk', eval([[substitute('K', 'K', '\Uk\ek', '')]]))
+ eq('l\rl', eval("substitute('lLl', 'L', '\r', '')"))
+ eq('m\rm', eval([[substitute('mMm', 'M', '\r', '')]]))
+ eq('n\rn', eval("substitute('nNn', 'N', '\\\r', '')"))
+ eq('o\no', eval([[substitute('oOo', 'O', '\n', '')]]))
+ eq('p\bp', eval([[substitute('pPp', 'P', '\b', '')]]))
+ eq('q\tq', eval([[substitute('qQq', 'Q', '\t', '')]]))
+ eq('r\\r', eval([[substitute('rRr', 'R', '\\', '')]]))
+ eq('scs', eval([[substitute('sSs', 'S', '\c', '')]]))
+ eq('t\rt', eval([[substitute('tTt', 'T', "\r", '')]]))
+ eq('u\nu', eval([[substitute('uUu', 'U', "\n", '')]]))
+ eq('v\bv', eval([[substitute('vVv', 'V', "\b", '')]]))
+ eq('w\\w', eval([[substitute('wWw', 'W', "\\", '')]]))
+ eq('XxxX', eval([[substitute('X', 'X', '\L\uxXx\l\EX', '')]]))
+ eq('yYYy', eval([[substitute('Y', 'Y', '\U\lYyY\u\Ey', '')]]))
+ end
+
+ it('with "set magic" (TEST_1)', function()
+ execute('set magic')
+ test_1_and_2()
+ end)
+
+ it('with "set nomagic" (TEST_2)', function()
+ execute('set nomagic')
+ test_1_and_2()
+ end)
+
+ it('with sub-replace-expression (TEST_3)', function()
+ execute('set magic&')
+ eq('a\\a', eval([[substitute('aAa', 'A', '\="\\"', '')]]))
+ eq('b\\\\b', eval([[substitute('bBb', 'B', '\="\\\\"', '')]]))
+ eq('c\rc', eval([[substitute('cCc', 'C', '\="]]..'\r'..[["', '')]]))
+ eq('d\\\rd', eval([[substitute('dDd', 'D', '\="\\]]..'\r'..[["', '')]]))
+ eq('e\\\\\re',
+ eval([[substitute('eEe', 'E', '\="\\\\]]..'\r'..[["', '')]]))
+ eq('f\\rf', eval([[substitute('fFf', 'F', '\="\\r"', '')]]))
+ eq('j\\nj', eval([[substitute('jJj', 'J', '\="\\n"', '')]]))
+ eq('k\rk', eval([[substitute('kKk', 'K', '\="\r"', '')]]))
+ eq('l\nl', eval([[substitute('lLl', 'L', '\="\n"', '')]]))
+ end)
+
+ it('with submatch() (TEST_4)', function()
+ execute('set magic&')
+ eq('a\\a', eval([[substitute('aAa', 'A', ]] ..
+ [['\=substitute(submatch(0), ".", "\\", "")', '')]]))
+ eq('b\\b', eval([[substitute('bBb', 'B', ]] ..
+ [['\=substitute(submatch(0), ".", "\\\\", "")', '')]]))
+ eq('c\rc', eval([[substitute('cCc', 'C', ]] ..
+ [['\=substitute(submatch(0), ".", "]]..'\r'..[[", "")', '')]]))
+ eq('d\rd', eval([[substitute('dDd', 'D', ]] ..
+ [['\=substitute(submatch(0), ".", "\\]]..'\r'..[[", "")', '')]]))
+ eq('e\\\re', eval([[substitute('eEe', 'E', ]] ..
+ [['\=substitute(submatch(0), ".", "\\\\]]..'\r'..[[", "")', '')]]))
+ eq('f\rf', eval([[substitute('fFf', 'F', ]] ..
+ [['\=substitute(submatch(0), ".", "\\r", "")', '')]]))
+ eq('j\nj', eval([[substitute('jJj', 'J', ]] ..
+ [['\=substitute(submatch(0), ".", "\\n", "")', '')]]))
+ eq('k\rk', eval([[substitute('kKk', 'K', ]] ..
+ [['\=substitute(submatch(0), ".", "\r", "")', '')]]))
+ eq('l\nl', eval([[substitute('lLl', 'L', ]] ..
+ [['\=substitute(submatch(0), ".", "\n", "")', '')]]))
+ end)
+
+ it('with submatch() (TEST_5)', function()
+ execute('set magic&')
+ eq('A123456789987654321', eval([[substitute('A123456789', ]] ..
+ [['A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', ]] ..
+ [['\=submatch(0) . submatch(9) . submatch(8) . submatch(7) . ]] ..
+ [[submatch(6) . submatch(5) . submatch(4) . submatch(3) . ]] ..
+ [[submatch(2) . submatch(1)', '')]]))
+ eq("[['A123456789'], ['9'], ['8'], ['7'], ['6'], ['5'], ['4'], ['3'], " ..
+ "['2'], ['1']]", eval([[substitute('A123456789', ]] ..
+ [['A\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)\(.\)', ]] ..
+ [['\=string([submatch(0, 1), submatch(9, 1), submatch(8, 1), ]] ..
+ [[submatch(7, 1), submatch(6, 1), submatch(5, 1), submatch(4, 1), ]] ..
+ [[submatch(3, 1), submatch(2, 1), submatch(1, 1)])', '')]]))
+ end)
+
+ -- TEST_6 was about the 'cpoptions' flag / which was removed in pull request
+ -- #2943.
+
+ it('with submatch or \\ze (TEST_7)', function()
+ execute('set magic&')
+ eq('A\rA', eval("substitute('A\rA', 'A.', '\\=submatch(0)', '')"))
+ eq('B\nB', eval([[substitute("B\nB", 'B.', '\=submatch(0)', '')]]))
+ eq("['B\n']B",
+ eval([[substitute("B\nB", 'B.', '\=string(submatch(0, 1))', '')]]))
+ eq('-abab', eval([[substitute('-bb', '\zeb', 'a', 'g')]]))
+ eq('c-cbcbc', eval([[substitute('-bb', '\ze', 'c', 'g')]]))
+ end)
+
+ it('with \\zs and \\ze (TEST_10)', function()
+ execute('set magic&')
+ eq('a1a2a3a', eval([[substitute('123', '\zs', 'a', 'g')]]))
+ eq('aaa', eval([[substitute('123', '\zs.', 'a', 'g')]]))
+ eq('1a2a3a', eval([[substitute('123', '.\zs', 'a', 'g')]]))
+ eq('a1a2a3a', eval([[substitute('123', '\ze', 'a', 'g')]]))
+ eq('a1a2a3', eval([[substitute('123', '\ze.', 'a', 'g')]]))
+ eq('aaa', eval([[substitute('123', '.\ze', 'a', 'g')]]))
+ eq('aa2a3a', eval([[substitute('123', '1\|\ze', 'a', 'g')]]))
+ eq('1aaa', eval([[substitute('123', '1\zs\|[23]', 'a', 'g')]]))
+ end)
+end)
+
+describe(':substitue', function()
+ before_each(clear)
+
+ it('with \\ze and \\zs and confirmation dialog (TEST_8)', function()
+ insert([[
+ ,,X
+ ,,Y
+ ,,Z]])
+ execute('set magic&')
+ execute([[1s/\(^\|,\)\ze\(,\|X\)/\1N/g]])
+ execute([[2s/\(^\|,\)\ze\(,\|Y\)/\1N/gc]])
+ feed('a') -- For the dialog of the previous :s command.
+ execute([[3s/\(^\|,\)\ze\(,\|Z\)/\1N/gc]])
+ feed('yy') -- For the dialog of the previous :s command.
+ expect([[
+ N,,NX
+ N,,NY
+ N,,NZ]])
+ end)
+
+ it('with confirmation dialog (TEST_9)', function()
+ insert('xxx')
+ execute('set magic&')
+ execute('s/x/X/gc')
+ feed('yyq') -- For the dialog of the previous :s command.
+ expect('XXx')
+ end)
+end)
diff --git a/test/functional/legacy/mapping_spec.lua b/test/functional/legacy/mapping_spec.lua
index c387d7484c..0843506827 100644
--- a/test/functional/legacy/mapping_spec.lua
+++ b/test/functional/legacy/mapping_spec.lua
@@ -23,16 +23,27 @@ describe('mapping', function()
execute('set langmap=+{ langnoremap')
feed('o+<esc>')
- -- expr mapping with langmap.
+ -- Insert mode expr mapping with langmap.
execute('inoremap <expr> { "FAIL_iexplangmap"')
feed('o+<esc>')
+ -- langmap should not get remapped in cmdline mode.
+ execute('cnoremap { FAIL_clangmap')
+ feed('o+<esc>')
+ execute('cunmap {')
+
+ -- cmdline mode expr mapping with langmap.
+ execute('cnoremap <expr> { "FAIL_cexplangmap"')
+ feed('o+<esc>')
+ execute('cunmap {')
-- Assert buffer contents.
expect([[
test starts here:
vim
+
+ +
+ +
+]])
end)
end)
diff --git a/test/functional/runtime/autoload/remote/define_spec.lua b/test/functional/provider/define_spec.lua
index 9b97ed84d9..9b97ed84d9 100644
--- a/test/functional/runtime/autoload/remote/define_spec.lua
+++ b/test/functional/provider/define_spec.lua
diff --git a/test/functional/runtime/autoload/provider/python3_spec.lua b/test/functional/provider/python3_spec.lua
index 43889b7b2a..5be5390370 100644
--- a/test/functional/runtime/autoload/provider/python3_spec.lua
+++ b/test/functional/provider/python3_spec.lua
@@ -1,19 +1,19 @@
do
- local proc =
- io.popen([[python3 -c 'import neovim, sys; sys.stdout.write("ok")' 2> /dev/null]])
+ local proc = io.popen(
+ [[python3 -c 'import neovim, sys; sys.stdout.write("ok")' 2> /dev/null]])
if proc:read() ~= 'ok' then
- -- Don't run these tests if python3 is not available
+ pending(
+ 'python3 (or the python3 neovim module) is broken or missing',
+ function() end)
return
end
end
-
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
-
describe('python3 commands and functions', function()
before_each(function()
clear()
diff --git a/test/functional/runtime/autoload/provider/python_spec.lua b/test/functional/provider/python_spec.lua
index e71a7a4309..ec1a853546 100644
--- a/test/functional/runtime/autoload/provider/python_spec.lua
+++ b/test/functional/provider/python_spec.lua
@@ -1,19 +1,19 @@
do
- local proc =
- io.popen([[python -c 'import neovim, sys; sys.stdout.write("ok")' 2> /dev/null]])
+ local proc = io.popen(
+ [[python -c 'import neovim, sys; sys.stdout.write("ok")' 2> /dev/null]])
if proc:read() ~= 'ok' then
- -- Don't run these tests if python is not available
+ pending(
+ 'python (or the python neovim module) is broken or missing',
+ function() end)
return
end
end
-
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
-
describe('python commands and functions', function()
before_each(function()
clear()
diff --git a/test/functional/shell/viml_system_spec.lua b/test/functional/shell/viml_system_spec.lua
index 6e10715612..4985c24aec 100644
--- a/test/functional/shell/viml_system_spec.lua
+++ b/test/functional/shell/viml_system_spec.lua
@@ -186,7 +186,7 @@ describe('system()', function()
describe("with a program that doesn't close stdout", function()
if not xclip then
- pending('skipped (missing xclip)')
+ pending('skipped (missing xclip)', function() end)
else
it('will exit properly after passing input', function()
eq('', eval([[system('xclip -i -selection clipboard', 'clip-data')]]))
@@ -365,7 +365,7 @@ describe('systemlist()', function()
describe("with a program that doesn't close stdout", function()
if not xclip then
- pending('skipped (missing xclip)')
+ pending('skipped (missing xclip)', function() end)
else
it('will exit properly after passing input', function()
eq({}, eval(
diff --git a/test/functional/terminal/highlight_spec.lua b/test/functional/terminal/highlight_spec.lua
index b72527e7b6..1a96cb4dba 100644
--- a/test/functional/terminal/highlight_spec.lua
+++ b/test/functional/terminal/highlight_spec.lua
@@ -3,6 +3,7 @@ local Screen = require('test.functional.ui.screen')
local thelpers = require('test.functional.terminal.helpers')
local feed, clear, nvim = helpers.feed, helpers.clear, helpers.nvim
local nvim_dir, execute = helpers.nvim_dir, helpers.execute
+local eq, eval = helpers.eq, helpers.eval
describe('terminal window highlighting', function()
@@ -161,3 +162,27 @@ describe('terminal window highlighting with custom palette', function()
]])
end)
end)
+
+describe('synIDattr()', function()
+ local screen
+
+ before_each(function()
+ clear()
+ screen = Screen.new(50, 7)
+ execute('highlight Normal ctermfg=1 guifg=#ff0000')
+ end)
+
+ after_each(function()
+ screen:detach()
+ end)
+
+ it('returns RGB number if GUI', function()
+ screen:attach(true)
+ eq('#ff0000', eval('synIDattr(hlID("Normal"), "fg")'))
+ end)
+
+ it('returns color number if non-GUI', function()
+ screen:attach(false)
+ eq('1', eval('synIDattr(hlID("Normal"), "fg")'))
+ end)
+end)
diff --git a/test/functional/ui/screen.lua b/test/functional/ui/screen.lua
index 9635f6119c..1d616ed853 100644
--- a/test/functional/ui/screen.lua
+++ b/test/functional/ui/screen.lua
@@ -259,6 +259,13 @@ This is probably due to an indeterminism in the test. Try adding
`wait()` (or even a separate `screen:expect(...)`) at a point of possible
indeterminism, typically in between a `feed()` or `execute()` which is non-
synchronous, and a synchronous api call.
+
+Note that sometimes a `wait` can trigger redraws and consequently generate more
+indeterminism. If adding `wait` calls seems to increase the frequency of these
+messages, try removing every `wait` call in the test.
+
+If everything else fails, use Screen:redraw_debug to help investigate what is
+ causing the problem.
]])
local tb = debug.traceback()
local index = string.find(tb, '\n%s*%[C]')
@@ -333,12 +340,9 @@ function Screen:_handle_mouse_off()
self._mouse_enabled = false
end
-function Screen:_handle_insert_mode()
- self._mode = 'insert'
-end
-
-function Screen:_handle_normal_mode()
- self._mode = 'normal'
+function Screen:_handle_mode_change(mode)
+ assert(mode == 'insert' or mode == 'replace' or mode == 'normal')
+ self._mode = mode
end
function Screen:_handle_set_scroll_region(top, bot, left, right)
diff --git a/test/functional/ui/screen_basic_spec.lua b/test/functional/ui/screen_basic_spec.lua
index d57c1773b1..421c167300 100644
--- a/test/functional/ui/screen_basic_spec.lua
+++ b/test/functional/ui/screen_basic_spec.lua
@@ -63,6 +63,29 @@ describe('Screen', function()
end
end)
end)
+
+ it('has correct default title with unnamed file', function()
+ local expected = '[No Name] - NVIM'
+ execute('set title')
+ screen:wait(function()
+ local actual = screen.title
+ if actual ~= expected then
+ return 'Expected title to be "'..expected..'" but was "'..actual..'"'
+ end
+ end)
+ end)
+
+ it('has correct default title with named file', function()
+ local expected = 'myfile (/mydir) - NVIM'
+ execute('set title')
+ execute('file /mydir/myfile')
+ screen:wait(function()
+ local actual = screen.title
+ if actual ~= expected then
+ return 'Expected title to be "'..expected..'" but was "'..actual..'"'
+ end
+ end)
+ end)
end)
describe(':set icon', function()
@@ -488,7 +511,6 @@ describe('Screen', function()
end)
it('has minimum width/height values', function()
- wait()
screen:try_resize(1, 1)
screen:expect([[
-- INS^ERT --|
diff --git a/test/unit/fixtures/queue.c b/test/unit/fixtures/queue.c
new file mode 100644
index 0000000000..bbb6274b21
--- /dev/null
+++ b/test/unit/fixtures/queue.c
@@ -0,0 +1,16 @@
+#include <string.h>
+#include <stdlib.h>
+#include "nvim/event/queue.h"
+#include "queue.h"
+
+
+void ut_queue_put(Queue *queue, const char *str)
+{
+ queue_put(queue, NULL, 1, str);
+}
+
+const char *ut_queue_get(Queue *queue)
+{
+ Event event = queue_get(queue);
+ return event.argv[0];
+}
diff --git a/test/unit/fixtures/queue.h b/test/unit/fixtures/queue.h
new file mode 100644
index 0000000000..ae949c9f29
--- /dev/null
+++ b/test/unit/fixtures/queue.h
@@ -0,0 +1,4 @@
+#include "nvim/event/queue.h"
+
+void ut_queue_put(Queue *queue, const char *str);
+const char *ut_queue_get(Queue *queue);
diff --git a/test/unit/os/fs_spec.lua b/test/unit/os/fs_spec.lua
index 3d5c6bc885..9cca3ca244 100644
--- a/test/unit/os/fs_spec.lua
+++ b/test/unit/os/fs_spec.lua
@@ -19,7 +19,7 @@ require('bit')
cimport('unistd.h')
cimport('./src/nvim/os/shell.h')
cimport('./src/nvim/option_defs.h')
-cimport('./src/nvim/os/event.h')
+cimport('./src/nvim/main.h')
cimport('./src/nvim/fileio.h')
local fs = cimport('./src/nvim/os/os.h')
cppimport('sys/stat.h')
@@ -32,6 +32,14 @@ local directory = nil
local absolute_executable = nil
local executable_name = nil
+local function set_bit(number, to_set)
+ return bit.bor(number, to_set)
+end
+
+local function unset_bit(number, to_unset)
+ return bit.band(number, (bit.bnot(to_unset)))
+end
+
local function assert_file_exists(filepath)
neq(nil, lfs.attributes(filepath))
end
@@ -40,11 +48,24 @@ local function assert_file_does_not_exist(filepath)
eq(nil, lfs.attributes(filepath))
end
+local function os_setperm(filename, perm)
+ return fs.os_setperm((to_cstr(filename)), perm)
+end
+
+local function os_getperm(filename)
+ local perm = fs.os_getperm((to_cstr(filename)))
+ return tonumber(perm)
+end
+
describe('fs function', function()
+ local orig_test_file_perm
setup(function()
lfs.mkdir('unit-test-directory');
+
io.open('unit-test-directory/test.file', 'w').close()
+ orig_test_file_perm = os_getperm('unit-test-directory/test.file')
+
io.open('unit-test-directory/test_2.file', 'w').close()
lfs.link('test.file', 'unit-test-directory/test_link.file', true)
-- Since the tests are executed, they are called by an executable. We use
@@ -188,6 +209,10 @@ describe('fs function', function()
end)
describe('file permissions', function()
+ before_each(function()
+ os_setperm('unit-test-directory/test.file', orig_test_file_perm)
+ end)
+
local function os_getperm(filename)
local perm = fs.os_getperm((to_cstr(filename)))
return tonumber(perm)
@@ -208,6 +233,10 @@ describe('fs function', function()
return fs.os_file_is_readonly((to_cstr(filename)))
end
+ local function os_file_is_readable(filename)
+ return fs.os_file_is_readable((to_cstr(filename)))
+ end
+
local function os_file_is_writable(filename)
return fs.os_file_is_writable((to_cstr(filename)))
end
@@ -216,14 +245,6 @@ describe('fs function', function()
return 0 ~= (bit.band(number, check_bit))
end
- local function set_bit(number, to_set)
- return bit.bor(number, to_set)
- end
-
- local function unset_bit(number, to_unset)
- return bit.band(number, (bit.bnot(to_unset)))
- end
-
describe('os_getperm', function()
it('returns -1 when the given file does not exist', function()
eq(-1, (os_getperm('non-existing-file')))
@@ -270,7 +291,7 @@ describe('fs function', function()
-- Some systems may not have `id` utility.
if (os.execute('id -G > /dev/null 2>&1') ~= 0) then
- pending('skipped (missing `id` utility)')
+ pending('skipped (missing `id` utility)', function() end)
else
it('owner of a file may change the group of the file to any group of which that owner is a member', function()
local file_gid = lfs.attributes(filename, 'gid')
@@ -296,7 +317,7 @@ describe('fs function', function()
-- On Windows `os_fchown` always returns 0
-- because `uv_fs_chown` is no-op on this platform.
if (ffi.os == 'Windows' or ffi.C.geteuid() == 0) then
- pending('skipped (os_fchown is no-op on Windows)')
+ pending('skipped (os_fchown is no-op on Windows)', function() end)
else
it('returns nonzero if process has not enough permissions', function()
-- chown to root
@@ -322,16 +343,35 @@ describe('fs function', function()
end)
end)
+ describe('os_file_is_readable', function()
+ it('returns false if the file is not readable', function()
+ local perm = os_getperm('unit-test-directory/test.file')
+ perm = unset_bit(perm, ffi.C.kS_IRUSR)
+ perm = unset_bit(perm, ffi.C.kS_IRGRP)
+ perm = unset_bit(perm, ffi.C.kS_IROTH)
+ eq(OK, (os_setperm('unit-test-directory/test.file', perm)))
+ eq(false, os_file_is_readable('unit-test-directory/test.file'))
+ end)
+
+ it('returns false if the file does not exist', function()
+ eq(false, os_file_is_readable(
+ 'unit-test-directory/what_are_you_smoking.gif'))
+ end)
+
+ it('returns true if the file is readable', function()
+ eq(true, os_file_is_readable(
+ 'unit-test-directory/test.file'))
+ end)
+ end)
+
describe('os_file_is_writable', function()
it('returns 0 if the file is readonly', function()
local perm = os_getperm('unit-test-directory/test.file')
- local perm_orig = perm
perm = unset_bit(perm, ffi.C.kS_IWUSR)
perm = unset_bit(perm, ffi.C.kS_IWGRP)
perm = unset_bit(perm, ffi.C.kS_IWOTH)
eq(OK, (os_setperm('unit-test-directory/test.file', perm)))
eq(0, os_file_is_writable('unit-test-directory/test.file'))
- eq(OK, (os_setperm('unit-test-directory/test.file', perm_orig)))
end)
it('returns 1 if the file is writable', function()
@@ -486,6 +526,16 @@ describe('fs function', function()
return fs.os_rmdir(to_cstr(path))
end
+ local function os_mkdir_recurse(path, mode)
+ local failed_str = ffi.new('char *[1]', {nil})
+ local ret = fs.os_mkdir_recurse(path, mode, failed_str)
+ local str = failed_str[0]
+ if str ~= nil then
+ str = ffi.string(str)
+ end
+ return ret, str
+ end
+
describe('os_mkdir', function()
it('returns non-zero when given an already existing directory', function()
local mode = ffi.C.kS_IRUSR + ffi.C.kS_IWUSR + ffi.C.kS_IXUSR
@@ -501,6 +551,59 @@ describe('fs function', function()
end)
end)
+ describe('os_mkdir_recurse', function()
+ it('returns zero when given an already existing directory', function()
+ local mode = ffi.C.kS_IRUSR + ffi.C.kS_IWUSR + ffi.C.kS_IXUSR
+ local ret, failed_str = os_mkdir_recurse('unit-test-directory', mode)
+ eq(0, ret)
+ eq(nil, failed_str)
+ end)
+
+ it('fails to create a directory where there is a file', function()
+ local mode = ffi.C.kS_IRUSR + ffi.C.kS_IWUSR + ffi.C.kS_IXUSR
+ local ret, failed_str = os_mkdir_recurse(
+ 'unit-test-directory/test.file', mode)
+ neq(0, ret)
+ eq('unit-test-directory/test.file', failed_str)
+ end)
+
+ it('fails to create a directory where there is a file in path', function()
+ local mode = ffi.C.kS_IRUSR + ffi.C.kS_IWUSR + ffi.C.kS_IXUSR
+ local ret, failed_str = os_mkdir_recurse(
+ 'unit-test-directory/test.file/test', mode)
+ neq(0, ret)
+ eq('unit-test-directory/test.file', failed_str)
+ end)
+
+ it('succeeds to create a directory', function()
+ local mode = ffi.C.kS_IRUSR + ffi.C.kS_IWUSR + ffi.C.kS_IXUSR
+ local ret, failed_str = os_mkdir_recurse(
+ 'unit-test-directory/new-dir-recurse', mode)
+ eq(0, ret)
+ eq(nil, failed_str)
+ eq(true, os_isdir('unit-test-directory/new-dir-recurse'))
+ lfs.rmdir('unit-test-directory/new-dir-recurse')
+ eq(false, os_isdir('unit-test-directory/new-dir-recurse'))
+ end)
+
+ it('succeeds to create a directory tree', function()
+ local mode = ffi.C.kS_IRUSR + ffi.C.kS_IWUSR + ffi.C.kS_IXUSR
+ local ret, failed_str = os_mkdir_recurse(
+ 'unit-test-directory/new-dir-recurse/1/2/3', mode)
+ eq(0, ret)
+ eq(nil, failed_str)
+ eq(true, os_isdir('unit-test-directory/new-dir-recurse'))
+ eq(true, os_isdir('unit-test-directory/new-dir-recurse/1'))
+ eq(true, os_isdir('unit-test-directory/new-dir-recurse/1/2'))
+ eq(true, os_isdir('unit-test-directory/new-dir-recurse/1/2/3'))
+ lfs.rmdir('unit-test-directory/new-dir-recurse/1/2/3')
+ lfs.rmdir('unit-test-directory/new-dir-recurse/1/2')
+ lfs.rmdir('unit-test-directory/new-dir-recurse/1')
+ lfs.rmdir('unit-test-directory/new-dir-recurse')
+ eq(false, os_isdir('unit-test-directory/new-dir-recurse'))
+ end)
+ end)
+
describe('os_rmdir', function()
it('returns non_zero when given a non-existing directory', function()
neq(0, (os_rmdir('non-existing-directory')))
diff --git a/test/unit/os/shell_spec.lua b/test/unit/os/shell_spec.lua
index 91d807da0b..91123bfd58 100644
--- a/test/unit/os/shell_spec.lua
+++ b/test/unit/os/shell_spec.lua
@@ -14,7 +14,7 @@ local helpers = require('test.unit.helpers')
local shell = helpers.cimport(
'./src/nvim/os/shell.h',
'./src/nvim/option_defs.h',
- './src/nvim/os/event.h',
+ './src/nvim/main.h',
'./src/nvim/misc1.h'
)
local ffi, eq, neq = helpers.ffi, helpers.eq, helpers.neq
diff --git a/test/unit/queue_spec.lua b/test/unit/queue_spec.lua
new file mode 100644
index 0000000000..9326c1cad6
--- /dev/null
+++ b/test/unit/queue_spec.lua
@@ -0,0 +1,123 @@
+local helpers = require("test.unit.helpers")
+
+local ffi = helpers.ffi
+local eq = helpers.eq
+
+local queue = helpers.cimport("./test/unit/fixtures/queue.h")
+
+describe('queue', function()
+ local parent, child1, child2, child3
+
+ local function put(q, str)
+ queue.ut_queue_put(q, str)
+ end
+
+ local function get(q)
+ return ffi.string(queue.ut_queue_get(q))
+ end
+
+ local function free(q)
+ queue.queue_free(q)
+ end
+
+ before_each(function()
+ parent = queue.queue_new_parent(ffi.NULL, ffi.NULL)
+ child1 = queue.queue_new_child(parent)
+ child2 = queue.queue_new_child(parent)
+ child3 = queue.queue_new_child(parent)
+ put(child1, 'c1i1')
+ put(child1, 'c1i2')
+ put(child2, 'c2i1')
+ put(child1, 'c1i3')
+ put(child2, 'c2i2')
+ put(child2, 'c2i3')
+ put(child2, 'c2i4')
+ put(child3, 'c3i1')
+ put(child3, 'c3i2')
+ end)
+
+ it('removing from parent removes from child', function()
+ eq('c1i1', get(parent))
+ eq('c1i2', get(parent))
+ eq('c2i1', get(parent))
+ eq('c1i3', get(parent))
+ eq('c2i2', get(parent))
+ eq('c2i3', get(parent))
+ eq('c2i4', get(parent))
+ end)
+
+ it('removing from child removes from parent', function()
+ eq('c2i1', get(child2))
+ eq('c2i2', get(child2))
+ eq('c1i1', get(child1))
+ eq('c1i2', get(parent))
+ eq('c1i3', get(parent))
+ eq('c2i3', get(parent))
+ eq('c2i4', get(parent))
+ end)
+
+ it('removing from child at the beginning of parent', function()
+ eq('c1i1', get(child1))
+ eq('c1i2', get(child1))
+ eq('c2i1', get(parent))
+ end)
+
+ it('removing from parent after get from parent and put to child', function()
+ eq('c1i1', get(parent))
+ eq('c1i2', get(parent))
+ eq('c2i1', get(parent))
+ eq('c1i3', get(parent))
+ eq('c2i2', get(parent))
+ eq('c2i3', get(parent))
+ eq('c2i4', get(parent))
+ eq('c3i1', get(parent))
+ put(child1, 'c1i11')
+ put(child1, 'c1i22')
+ eq('c3i2', get(parent))
+ eq('c1i11', get(parent))
+ eq('c1i22', get(parent))
+ end)
+
+ it('removing from parent after get and put to child', function()
+ eq('c1i1', get(child1))
+ eq('c1i2', get(child1))
+ eq('c2i1', get(child2))
+ eq('c1i3', get(child1))
+ eq('c2i2', get(child2))
+ eq('c2i3', get(child2))
+ eq('c2i4', get(child2))
+ eq('c3i1', get(child3))
+ eq('c3i2', get(parent))
+ put(child1, 'c1i11')
+ put(child2, 'c2i11')
+ put(child1, 'c1i12')
+ eq('c2i11', get(child2))
+ eq('c1i11', get(parent))
+ eq('c1i12', get(parent))
+ end)
+
+ it('put after removing from child at the end of parent', function()
+ eq('c3i1', get(child3))
+ eq('c3i2', get(child3))
+ put(child1, 'c1i11')
+ put(child2, 'c2i11')
+ eq('c1i1', get(parent))
+ eq('c1i2', get(parent))
+ eq('c2i1', get(parent))
+ eq('c1i3', get(parent))
+ eq('c2i2', get(parent))
+ eq('c2i3', get(parent))
+ eq('c2i4', get(parent))
+ eq('c1i11', get(parent))
+ eq('c2i11', get(parent))
+ end)
+
+ it('removes from parent queue when child is freed', function()
+ free(child2)
+ eq('c1i1', get(parent))
+ eq('c1i2', get(parent))
+ eq('c1i3', get(parent))
+ eq('c3i1', get(child3))
+ eq('c3i2', get(child3))
+ end)
+end)