diff options
Diffstat (limited to 'test/functional/lua')
29 files changed, 2501 insertions, 359 deletions
diff --git a/test/functional/lua/api_spec.lua b/test/functional/lua/api_spec.lua index 03832978a4..d808693a9e 100644 --- a/test/functional/lua/api_spec.lua +++ b/test/functional/lua/api_spec.lua @@ -9,6 +9,7 @@ local eval = helpers.eval local NIL = helpers.NIL local eq = helpers.eq local exec_lua = helpers.exec_lua +local pcall_err = helpers.pcall_err before_each(clear) @@ -33,7 +34,7 @@ describe('luaeval(vim.api.…)', function() describe('with errors', function() it('transforms API error from nvim_buf_set_lines into lua error', function() funcs.setline(1, {"abc", "def", "a\nb", "ttt"}) - eq({false, 'String cannot contain newlines'}, + eq({false, "'replacement string' item contains newlines"}, funcs.luaeval('{pcall(vim.api.nvim_buf_set_lines, 1, 1, 2, false, {"b\\na"})}')) end) @@ -103,9 +104,9 @@ describe('luaeval(vim.api.…)', function() eq(NIL, funcs.luaeval('vim.api.nvim__id(nil)')) -- API strings from Blobs can work as NUL-terminated C strings - eq('Vim(call):E5555: API call: Vim:E15: Invalid expression: ', + eq('Vim(call):E5555: API call: Vim:E15: Invalid expression: ""', exc_exec('call nvim_eval(v:_null_blob)')) - eq('Vim(call):E5555: API call: Vim:E15: Invalid expression: ', + eq('Vim(call):E5555: API call: Vim:E15: Invalid expression: ""', exc_exec('call nvim_eval(0z)')) eq(1, eval('nvim_eval(0z31)')) @@ -171,9 +172,32 @@ describe('luaeval(vim.api.…)', function() eq(4, eval([[type(luaeval('vim.api.nvim__id_dictionary({})'))]])) end) + it('converts booleans in positional args', function() + eq({''}, exec_lua [[ return vim.api.nvim_buf_get_lines(0, 0, 10, false) ]]) + eq({''}, exec_lua [[ return vim.api.nvim_buf_get_lines(0, 0, 10, nil) ]]) + eq('Index out of bounds', pcall_err(exec_lua, [[ return vim.api.nvim_buf_get_lines(0, 0, 10, true) ]])) + eq('Index out of bounds', pcall_err(exec_lua, [[ return vim.api.nvim_buf_get_lines(0, 0, 10, 1) ]])) + + -- this follows lua conventions for bools (not api convention for Boolean) + eq('Index out of bounds', pcall_err(exec_lua, [[ return vim.api.nvim_buf_get_lines(0, 0, 10, 0) ]])) + eq('Index out of bounds', pcall_err(exec_lua, [[ return vim.api.nvim_buf_get_lines(0, 0, 10, {}) ]])) + end) + + it('converts booleans in optional args', function() + eq({}, exec_lua [[ return vim.api.nvim_exec2("echo 'foobar'", {output=false}) ]]) + eq({}, exec_lua [[ return vim.api.nvim_exec2("echo 'foobar'", {}) ]]) -- same as {output=nil} + + -- API conventions (not lua conventions): zero is falsy + eq({}, exec_lua [[ return vim.api.nvim_exec2("echo 'foobar'", {output=0}) ]]) + + eq({output='foobar'}, exec_lua [[ return vim.api.nvim_exec2("echo 'foobar'", {output=true}) ]]) + eq({output='foobar'}, exec_lua [[ return vim.api.nvim_exec2("echo 'foobar'", {output=1}) ]]) + eq([[Invalid 'output': not a boolean]], pcall_err(exec_lua, [[ return vim.api.nvim_exec2("echo 'foobar'", {output={}}) ]])) + end) + it('errors out correctly when working with API', function() -- Conversion errors - eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Cannot convert given lua table', + eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'obj': Cannot convert given Lua table]], remove_trace(exc_exec([[call luaeval("vim.api.nvim__id({1, foo=42})")]]))) -- Errors in number of arguments eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected 1 argument', @@ -183,32 +207,32 @@ describe('luaeval(vim.api.…)', function() eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected 2 arguments', remove_trace(exc_exec([[call luaeval("vim.api.nvim_set_var(1, 2, 3)")]]))) -- Error in argument types - eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected lua string', + eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'name': Expected Lua string]], remove_trace(exc_exec([[call luaeval("vim.api.nvim_set_var(1, 2)")]]))) - eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected lua number', + eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'start': Expected Lua number]], remove_trace(exc_exec([[call luaeval("vim.api.nvim_buf_get_lines(0, 'test', 1, false)")]]))) - eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Number is not integral', + eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'start': Number is not integral]], remove_trace(exc_exec([[call luaeval("vim.api.nvim_buf_get_lines(0, 1.5, 1, false)")]]))) - eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected Lua number', + eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'window': Expected Lua number]], remove_trace(exc_exec([[call luaeval("vim.api.nvim_win_is_valid(nil)")]]))) - eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected lua table', + eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'flt': Expected Lua number]], remove_trace(exc_exec([[call luaeval("vim.api.nvim__id_float('test')")]]))) - eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Unexpected type', + eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'flt': Expected Float-like Lua table]], remove_trace(exc_exec([[call luaeval("vim.api.nvim__id_float({[vim.type_idx]=vim.types.dictionary})")]]))) - eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected lua table', + eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'arr': Expected Lua table]], remove_trace(exc_exec([[call luaeval("vim.api.nvim__id_array(1)")]]))) - eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Unexpected type', + eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'arr': Expected Array-like Lua table]], remove_trace(exc_exec([[call luaeval("vim.api.nvim__id_array({[vim.type_idx]=vim.types.dictionary})")]]))) - eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected lua table', + eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'dct': Expected Lua table]], remove_trace(exc_exec([[call luaeval("vim.api.nvim__id_dictionary(1)")]]))) - eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Unexpected type', + eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Invalid 'dct': Expected Dict-like Lua table]], remove_trace(exc_exec([[call luaeval("vim.api.nvim__id_dictionary({[vim.type_idx]=vim.types.array})")]]))) - eq('Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected lua table', + eq([[Vim(call):E5108: Error executing lua [string "luaeval()"]:1: Expected Lua table]], remove_trace(exc_exec([[call luaeval("vim.api.nvim_set_keymap('', '', '', '')")]]))) -- TODO: check for errors with Tabpage argument diff --git a/test/functional/lua/base64_spec.lua b/test/functional/lua/base64_spec.lua new file mode 100644 index 0000000000..f0d112c23e --- /dev/null +++ b/test/functional/lua/base64_spec.lua @@ -0,0 +1,105 @@ +local helpers = require('test.functional.helpers')(after_each) +local clear = helpers.clear +local exec_lua = helpers.exec_lua +local eq = helpers.eq +local pcall_err = helpers.pcall_err +local matches = helpers.matches + +describe('vim.base64', function() + before_each(clear) + + local function encode(s) + return exec_lua([[return vim.base64.encode(...)]], s) + end + + local function decode(s) + return exec_lua([[return vim.base64.decode(...)]], s) + end + + it('works', function() + local values = { + '', + 'Many hands make light work.', + [[ + Call me Ishmael. Some years ago—never mind how long precisely—having little or no money in + my purse, and nothing particular to interest me on shore, I thought I would sail about a + little and see the watery part of the world. + ]], + [[ + It is a truth universally acknowledged, that a single man in possession of a good fortune, + must be in want of a wife. + ]], + 'Happy families are all alike; every unhappy family is unhappy in its own way.', + 'ЁЂЃЄЅІЇЈЉЊЋЌЍЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя', + 'ÅÍÎÏ˝ÓÔÒÚÆ☃', + '𐐜 𐐔𐐇𐐝𐐀𐐡𐐇𐐓 𐐙𐐊𐐡𐐝𐐓/𐐝𐐇𐐗𐐊𐐤𐐔 𐐒𐐋𐐗 𐐒𐐌 𐐜 𐐡𐐀𐐖𐐇𐐤𐐓𐐝 𐐱𐑂 𐑄 𐐔𐐇𐐝𐐀𐐡𐐇𐐓 𐐏𐐆𐐅𐐤𐐆𐐚𐐊𐐡𐐝𐐆𐐓𐐆', + '👨👩👦 👨👩👧👦 👨👨👦 👩👩👧 👨👦 👨👧👦 👩👦 👩👧👦', + 'مُنَاقَشَةُ سُبُلِ اِسْتِخْدَامِ اللُّغَةِ فِي النُّظُمِ الْقَائِمَةِ وَفِيم يَخُصَّ التَّطْبِيقَاتُ الْحاسُوبِيَّةُ،', + [[ + Ṱ̺̺̕o͞ ̷i̲̬͇̪͙n̝̗͕v̟̜̘̦͟o̶̙̰̠kè͚̮̺̪̹̱̤ ̖t̝͕̳̣̻̪͞h̼͓̲̦̳̘̲e͇̣̰̦̬͎ ̢̼̻̱̘h͚͎͙̜̣̲ͅi̦̲̣̰̤v̻͍e̺̭̳̪̰-m̢iͅn̖̺̞̲̯̰d̵̼̟͙̩̼̘̳ ̞̥̱̳̭r̛̗̘e͙p͠r̼̞̻̭̗e̺̠̣͟s̘͇̳͍̝͉e͉̥̯̞̲͚̬͜ǹ̬͎͎̟̖͇̤t͍̬̤͓̼̭͘ͅi̪̱n͠g̴͉ ͏͉ͅc̬̟h͡a̫̻̯͘o̫̟̖͍̙̝͉s̗̦̲.̨̹͈̣ + ̡͓̞ͅI̗̘̦͝n͇͇͙v̮̫ok̲̫̙͈i̖͙̭̹̠̞n̡̻̮̣̺g̲͈͙̭͙̬͎ ̰t͔̦h̞̲e̢̤ ͍̬̲͖f̴̘͕̣è͖ẹ̥̩l͖͔͚i͓͚̦͠n͖͍̗͓̳̮g͍ ̨o͚̪͡f̘̣̬ ̖̘͖̟͙̮c҉͔̫͖͓͇͖ͅh̵̤̣͚͔á̗̼͕ͅo̼̣̥s̱͈̺̖̦̻͢.̛̖̞̠̫̰ + ̗̺͖̹̯͓Ṯ̤͍̥͇͈h̲́e͏͓̼̗̙̼̣͔ ͇̜̱̠͓͍ͅN͕͠e̗̱z̘̝̜̺͙p̤̺̹͍̯͚e̠̻̠͜r̨̤͍̺̖͔̖̖d̠̟̭̬̝͟i̦͖̩͓͔̤a̠̗̬͉̙n͚͜ ̻̞̰͚ͅh̵͉i̳̞v̢͇ḙ͎͟-҉̭̩̼͔m̤̭̫i͕͇̝̦n̗͙ḍ̟ ̯̲͕͞ǫ̟̯̰̲͙̻̝f ̪̰̰̗̖̭̘͘c̦͍̲̞͍̩̙ḥ͚a̮͎̟̙͜ơ̩̹͎s̤.̝̝ ҉Z̡̖̜͖̰̣͉̜a͖̰͙̬͡l̲̫̳͍̩g̡̟̼̱͚̞̬ͅo̗͜.̟ + ̦H̬̤̗̤͝e͜ ̜̥̝̻͍̟́w̕h̖̯͓o̝͙̖͎̱̮ ҉̺̙̞̟͈W̷̼̭a̺̪͍į͈͕̭͙̯̜t̶̼̮s̘͙͖̕ ̠̫̠B̻͍͙͉̳ͅe̵h̵̬͇̫͙i̹͓̳̳̮͎̫̕n͟d̴̪̜̖ ̰͉̩͇͙̲͞ͅT͖̼͓̪͢h͏͓̮̻e̬̝̟ͅ ̤̹̝W͙̞̝͔͇͝ͅa͏͓͔̹̼̣l̴͔̰̤̟͔ḽ̫.͕ + Z̮̞̠͙͔ͅḀ̗̞͈̻̗Ḷ͙͎̯̹̞͓G̻O̭̗̮ + ]], + } + + for _, v in ipairs(values) do + eq(v, decode(encode(v))) + end + + -- Explicitly check encoded output + eq('VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZwo=', encode('The quick brown fox jumps over the lazy dog\n')) + + -- Test vectors from rfc4648 + local rfc4648 = { + { '', '' }, + { 'f', 'Zg==', }, + { 'fo', 'Zm8=' }, + { 'foo', 'Zm9v' }, + { 'foob', 'Zm9vYg==' }, + { 'fooba', 'Zm9vYmE=' }, + { 'foobar', 'Zm9vYmFy' }, + } + + for _, v in ipairs(rfc4648) do + local input = v[1] + local output = v[2] + eq(output, encode(input)) + eq(input, decode(output)) + end + end) + + it('detects invalid input', function() + local invalid = { + 'A', + 'AA', + 'AAA', + 'A..A', + 'AA=A', + 'AA/=', + 'A/==', + 'A===', + '====', + 'Zm9vYmFyZm9vYmFyA..A', + 'Zm9vYmFyZm9vYmFyAA=A', + 'Zm9vYmFyZm9vYmFyAA/=', + 'Zm9vYmFyZm9vYmFyA/==', + 'Zm9vYmFyZm9vYmFyA===', + 'A..AZm9vYmFyZm9vYmFy', + 'Zm9vYmFyZm9vAA=A', + 'Zm9vYmFyZm9vAA/=', + 'Zm9vYmFyZm9vA/==', + 'Zm9vYmFyZm9vA===', + } + + for _, v in ipairs(invalid) do + eq('Invalid input', pcall_err(decode, v)) + end + + eq('Expected 1 argument', pcall_err(encode)) + eq('Expected 1 argument', pcall_err(decode)) + matches('expected string', pcall_err(encode, 42)) + matches('expected string', pcall_err(decode, 42)) + end) +end) diff --git a/test/functional/lua/buffer_updates_spec.lua b/test/functional/lua/buffer_updates_spec.lua index 2fd44b8b5f..51e4548edb 100644 --- a/test/functional/lua/buffer_updates_spec.lua +++ b/test/functional/lua/buffer_updates_spec.lua @@ -1,6 +1,6 @@ -- Test suite for testing interactions with API bindings local helpers = require('test.functional.helpers')(after_each) -local lfs = require('lfs') +local luv = require('luv') local command = helpers.command local meths = helpers.meths @@ -317,7 +317,18 @@ describe('lua buffer event callbacks: on_lines', function() feed('1G0') feed('P') eq(meths.get_var('linesev'), { "lines", 1, 6, 0, 3, 3, 9 }) + end) + it('calling nvim_buf_call() from callback does not cause Normal mode CTRL-A to misbehave #16729', function() + exec_lua([[ + vim.api.nvim_buf_attach(0, false, { + on_lines = function(...) + vim.api.nvim_buf_call(0, function() end) + end, + }) + ]]) + feed('itest123<Esc><C-A>') + eq('test124', meths.get_current_line()) end) end) @@ -404,7 +415,7 @@ describe('lua: nvim_buf_attach on_bytes', function() it('opening lines', function() local check_events = setup_eventcheck(verify, origlines) - -- meths.buf_set_option(0, 'autoindent', true) + -- meths.set_option_value('autoindent', true, {}) feed 'Go' check_events { { "test1", "bytes", 1, 4, 7, 0, 114, 0, 0, 0, 1, 0, 1 }; @@ -417,7 +428,7 @@ describe('lua: nvim_buf_attach on_bytes', function() it('opening lines with autoindent', function() local check_events = setup_eventcheck(verify, origlines) - meths.buf_set_option(0, 'autoindent', true) + meths.set_option_value('autoindent', true, {}) feed 'Go' check_events { { "test1", "bytes", 1, 4, 7, 0, 114, 0, 0, 0, 1, 0, 5 }; @@ -451,8 +462,8 @@ describe('lua: nvim_buf_attach on_bytes', function() it('continuing comments with fo=or', function() local check_events = setup_eventcheck(verify, {'// Comment'}) - meths.buf_set_option(0, 'formatoptions', 'ro') - meths.buf_set_option(0, 'filetype', 'c') + meths.set_option_value('formatoptions', 'ro', {}) + meths.set_option_value('filetype', 'c', {}) feed 'A<CR>' check_events { { "test1", "bytes", 1, 4, 0, 10, 10, 0, 0, 0, 1, 3, 4 }; @@ -592,7 +603,7 @@ describe('lua: nvim_buf_attach on_bytes', function() it('inccomand=nosplit and substitute', function() local check_events = setup_eventcheck(verify, {"abcde", "12345"}) - meths.set_option('inccommand', 'nosplit') + meths.set_option_value('inccommand', 'nosplit', {}) -- linewise substitute feed(':%s/bcd/') @@ -743,7 +754,8 @@ describe('lua: nvim_buf_attach on_bytes', function() write_file("Xtest-reload", dedent [[ old line 1 old line 2]]) - lfs.touch("Xtest-reload", os.time() - 10) + local atime = os.time() - 10 + luv.fs_utime("Xtest-reload", atime, atime) command "e Xtest-reload" command "set autoread" @@ -814,53 +826,53 @@ describe('lua: nvim_buf_attach on_bytes', function() feed("<esc>u") check_events { - { "test1", "bytes", 1, 8, 0, 0, 0, 0, 1, 1, 0, 4, 4 }, - { "test1", "bytes", 1, 8, 0, 0, 0, 0, 4, 4, 0, 0, 0 } + { "test1", "bytes", 1, 9, 0, 0, 0, 0, 1, 1, 0, 4, 4 }, + { "test1", "bytes", 1, 9, 0, 0, 0, 0, 4, 4, 0, 0, 0 } } -- in REPLACE mode feed("R<tab><tab>") check_events { - { "test1", "bytes", 1, 9, 0, 0, 0, 0, 1, 1, 0, 1, 1 }, - { "test1", "bytes", 1, 10, 0, 1, 1, 0, 0, 0, 0, 1, 1 }, - { "test1", "bytes", 1, 11, 0, 2, 2, 0, 1, 1, 0, 1, 1 }, - { "test1", "bytes", 1, 12, 0, 3, 3, 0, 0, 0, 0, 1, 1 }, - { "test1", "bytes", 1, 13, 0, 0, 0, 0, 4, 4, 0, 1, 1 }, + { "test1", "bytes", 1, 10, 0, 0, 0, 0, 1, 1, 0, 1, 1 }, + { "test1", "bytes", 1, 11, 0, 1, 1, 0, 0, 0, 0, 1, 1 }, + { "test1", "bytes", 1, 12, 0, 2, 2, 0, 1, 1, 0, 1, 1 }, + { "test1", "bytes", 1, 13, 0, 3, 3, 0, 0, 0, 0, 1, 1 }, + { "test1", "bytes", 1, 14, 0, 0, 0, 0, 4, 4, 0, 1, 1 }, } feed("<esc>u") check_events { - { "test1", "bytes", 1, 14, 0, 0, 0, 0, 1, 1, 0, 4, 4 }, - { "test1", "bytes", 1, 14, 0, 2, 2, 0, 2, 2, 0, 1, 1 }, - { "test1", "bytes", 1, 14, 0, 0, 0, 0, 2, 2, 0, 1, 1 } + { "test1", "bytes", 1, 16, 0, 0, 0, 0, 1, 1, 0, 4, 4 }, + { "test1", "bytes", 1, 16, 0, 2, 2, 0, 2, 2, 0, 1, 1 }, + { "test1", "bytes", 1, 16, 0, 0, 0, 0, 2, 2, 0, 1, 1 } } -- in VISUALREPLACE mode feed("gR<tab><tab>") check_events { - { "test1", "bytes", 1, 15, 0, 0, 0, 0, 1, 1, 0, 1, 1 }; - { "test1", "bytes", 1, 16, 0, 1, 1, 0, 1, 1, 0, 1, 1 }; - { "test1", "bytes", 1, 17, 0, 2, 2, 0, 1, 1, 0, 1, 1 }; - { "test1", "bytes", 1, 18, 0, 3, 3, 0, 1, 1, 0, 1, 1 }; - { "test1", "bytes", 1, 19, 0, 3, 3, 0, 1, 1, 0, 0, 0 }; - { "test1", "bytes", 1, 20, 0, 3, 3, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 22, 0, 2, 2, 0, 1, 1, 0, 0, 0 }; - { "test1", "bytes", 1, 23, 0, 2, 2, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 25, 0, 1, 1, 0, 1, 1, 0, 0, 0 }; - { "test1", "bytes", 1, 26, 0, 1, 1, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 28, 0, 0, 0, 0, 1, 1, 0, 0, 0 }; - { "test1", "bytes", 1, 29, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 31, 0, 0, 0, 0, 4, 4, 0, 1, 1 }; + { "test1", "bytes", 1, 17, 0, 0, 0, 0, 1, 1, 0, 1, 1 }; + { "test1", "bytes", 1, 18, 0, 1, 1, 0, 1, 1, 0, 1, 1 }; + { "test1", "bytes", 1, 19, 0, 2, 2, 0, 1, 1, 0, 1, 1 }; + { "test1", "bytes", 1, 20, 0, 3, 3, 0, 1, 1, 0, 1, 1 }; + { "test1", "bytes", 1, 21, 0, 3, 3, 0, 1, 1, 0, 0, 0 }; + { "test1", "bytes", 1, 22, 0, 3, 3, 0, 0, 0, 0, 1, 1 }; + { "test1", "bytes", 1, 24, 0, 2, 2, 0, 1, 1, 0, 0, 0 }; + { "test1", "bytes", 1, 25, 0, 2, 2, 0, 0, 0, 0, 1, 1 }; + { "test1", "bytes", 1, 27, 0, 1, 1, 0, 1, 1, 0, 0, 0 }; + { "test1", "bytes", 1, 28, 0, 1, 1, 0, 0, 0, 0, 1, 1 }; + { "test1", "bytes", 1, 30, 0, 0, 0, 0, 1, 1, 0, 0, 0 }; + { "test1", "bytes", 1, 31, 0, 0, 0, 0, 0, 0, 0, 1, 1 }; + { "test1", "bytes", 1, 33, 0, 0, 0, 0, 4, 4, 0, 1, 1 }; } -- inserting tab after other tabs command("set sw=4") feed("<esc>0a<tab>") check_events { - { "test1", "bytes", 1, 32, 0, 1, 1, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 33, 0, 2, 2, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 34, 0, 3, 3, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 35, 0, 4, 4, 0, 0, 0, 0, 1, 1 }; - { "test1", "bytes", 1, 36, 0, 1, 1, 0, 4, 4, 0, 1, 1 }; + { "test1", "bytes", 1, 34, 0, 1, 1, 0, 0, 0, 0, 1, 1 }; + { "test1", "bytes", 1, 35, 0, 2, 2, 0, 0, 0, 0, 1, 1 }; + { "test1", "bytes", 1, 36, 0, 3, 3, 0, 0, 0, 0, 1, 1 }; + { "test1", "bytes", 1, 37, 0, 4, 4, 0, 0, 0, 0, 1, 1 }; + { "test1", "bytes", 1, 38, 0, 1, 1, 0, 4, 4, 0, 1, 1 }; } end) @@ -986,7 +998,7 @@ describe('lua: nvim_buf_attach on_bytes', function() it("virtual edit", function () local check_events = setup_eventcheck(verify, { "", " " }) - meths.set_option("virtualedit", "all") + meths.set_option_value('virtualedit', "all", {}) feed [[<Right><Right>iab<ESC>]] @@ -1152,12 +1164,36 @@ describe('lua: nvim_buf_attach on_bytes', function() end) it("works with accepting spell suggestions", function() - local check_events = setup_eventcheck(verify, {"hallo"}) + local check_events = setup_eventcheck(verify, {"hallo world", "hallo world"}) feed("gg0z=4<cr><cr>") -- accepts 'Hello' check_events { { "test1", "bytes", 1, 3, 0, 0, 0, 0, 2, 2, 0, 2, 2 }; } + + command("spellrepall") -- replaces whole words + check_events { + { "test1", "bytes", 1, 4, 1, 0, 12, 0, 5, 5, 0, 5, 5 }; + } + end) + + it('works with :diffput and :diffget', function() + local check_events = setup_eventcheck(verify, {"AAA"}) + command('diffthis') + command('new') + command('diffthis') + meths.buf_set_lines(0, 0, -1, true, {"AAA", "BBB"}) + feed('G') + command('diffput') + check_events { + { "test1", "bytes", 1, 3, 1, 0, 4, 0, 0, 0, 1, 0, 4 }; + } + meths.buf_set_lines(0, 0, -1, true, {"AAA", "CCC"}) + feed('<C-w>pG') + command('diffget') + check_events { + { "test1", "bytes", 1, 4, 1, 0, 4, 1, 0, 4, 1, 0, 4 }; + } end) local function test_lockmarks(mode) diff --git a/test/functional/lua/command_line_completion_spec.lua b/test/functional/lua/command_line_completion_spec.lua index 3a5966755e..177e077f4a 100644 --- a/test/functional/lua/command_line_completion_spec.lua +++ b/test/functional/lua/command_line_completion_spec.lua @@ -5,7 +5,7 @@ local eq = helpers.eq local exec_lua = helpers.exec_lua local get_completions = function(input, env) - return exec_lua("return {vim._expand_pat(...)}", '^' .. input, env) + return exec_lua("return {vim._expand_pat(...)}", input, env) end local get_compl_parts = function(parts) @@ -31,14 +31,12 @@ describe('nlua_expand_pat', function() eq( {{ 'nvim_buf_set_lines', - 'nvim_buf_set_option' }, 8 }, get_completions('vim.api.nvim_buf_', { vim = { api = { nvim_buf_set_lines = true, - nvim_buf_set_option = true, nvim_win_doesnt_match = true, }, other_key = true, @@ -68,14 +66,12 @@ describe('nlua_expand_pat', function() eq( {{ 'nvim_buf_set_lines', - 'nvim_buf_set_option' }, 11 }, get_completions('vim["api"].nvim_buf_', { vim = { api = { nvim_buf_set_lines = true, - nvim_buf_set_option = true, nvim_win_doesnt_match = true, }, other_key = true, @@ -88,7 +84,6 @@ describe('nlua_expand_pat', function() eq( {{ 'nvim_buf_set_lines', - 'nvim_buf_set_option' }, 21 }, get_completions('vim["nested"]["api"].nvim_buf_', { @@ -96,7 +91,6 @@ describe('nlua_expand_pat', function() nested = { api = { nvim_buf_set_lines = true, - nvim_buf_set_option = true, nvim_win_doesnt_match = true, }, }, @@ -107,9 +101,12 @@ describe('nlua_expand_pat', function() end) it('should work with lazy submodules of "vim" global', function() - eq({{ 'inspect' }, 4 }, + eq({{ 'inspect', 'inspect_pos' }, 4 }, get_completions('vim.inspec')) + eq({{ 'treesitter' }, 4 }, + get_completions('vim.treesi')) + eq({{ 'set' }, 11 }, get_completions('vim.keymap.se')) end) @@ -118,7 +115,6 @@ describe('nlua_expand_pat', function() eq( {{ 'nvim_buf_set_lines', - 'nvim_buf_set_option' }, 12 }, get_completions('vim[MY_VAR].nvim_buf_', { @@ -126,7 +122,6 @@ describe('nlua_expand_pat', function() vim = { api = { nvim_buf_set_lines = true, - nvim_buf_set_option = true, nvim_win_doesnt_match = true, }, other_key = true, diff --git a/test/functional/lua/commands_spec.lua b/test/functional/lua/commands_spec.lua index b8346df290..fca619348d 100644 --- a/test/functional/lua/commands_spec.lua +++ b/test/functional/lua/commands_spec.lua @@ -7,7 +7,10 @@ local NIL = helpers.NIL local eval = helpers.eval local feed = helpers.feed local clear = helpers.clear +local matches = helpers.matches local meths = helpers.meths +local exec_lua = helpers.exec_lua +local exec_capture = helpers.exec_capture local funcs = helpers.funcs local source = helpers.source local dedent = helpers.dedent @@ -15,7 +18,6 @@ local command = helpers.command local exc_exec = helpers.exc_exec local pcall_err = helpers.pcall_err local write_file = helpers.write_file -local exec_capture = helpers.exec_capture local curbufmeths = helpers.curbufmeths local remove_trace = helpers.remove_trace @@ -26,22 +28,27 @@ describe(':lua command', function() eq('', exec_capture( 'lua vim.api.nvim_buf_set_lines(1, 1, 2, false, {"TEST"})')) eq({'', 'TEST'}, curbufmeths.get_lines(0, 100, false)) - source(dedent([[ + source([[ lua << EOF vim.api.nvim_buf_set_lines(1, 1, 2, false, {"TSET"}) - EOF]])) + EOF]]) eq({'', 'TSET'}, curbufmeths.get_lines(0, 100, false)) - source(dedent([[ + source([[ lua << EOF - vim.api.nvim_buf_set_lines(1, 1, 2, false, {"SETT"})]])) + vim.api.nvim_buf_set_lines(1, 1, 2, false, {"SETT"})]]) eq({'', 'SETT'}, curbufmeths.get_lines(0, 100, false)) - source(dedent([[ + source([[ lua << EOF vim.api.nvim_buf_set_lines(1, 1, 2, false, {"ETTS"}) vim.api.nvim_buf_set_lines(1, 2, 3, false, {"TTSE"}) vim.api.nvim_buf_set_lines(1, 3, 4, false, {"STTE"}) - EOF]])) + EOF]]) eq({'', 'ETTS', 'TTSE', 'STTE'}, curbufmeths.get_lines(0, 100, false)) + matches('.*Vim%(lua%):E15: Invalid expression: .*', pcall_err(source, [[ + lua << eval EOF + {} + EOF + ]])) end) it('throws catchable errors', function() eq([[Vim(lua):E5107: Error loading lua [string ":lua"]:0: unexpected symbol near ')']], @@ -142,22 +149,30 @@ describe(':lua command', function() ]]} end) - it('Can print results of =expr', function() - helpers.exec_lua("x = 5") - eq("5", helpers.exec_capture(':lua =x')) - helpers.exec_lua("function x() return 'hello' end") - eq([["hello"]], helpers.exec_capture(':lua = x()')) - helpers.exec_lua("x = {a = 1, b = 2}") - eq("{\n a = 1,\n b = 2\n}", helpers.exec_capture(':lua =x')) - helpers.exec_lua([[function x(success) + it('prints result of =expr', function() + exec_lua("x = 5") + eq("5", exec_capture(':lua =x')) + eq("5", exec_capture('=x')) + exec_lua("function x() return 'hello' end") + eq('hello', exec_capture(':lua = x()')) + exec_lua("x = {a = 1, b = 2}") + eq("{\n a = 1,\n b = 2\n}", exec_capture(':lua =x')) + exec_lua([[function x(success) if success then return true, "Return value" else return false, nil, "Error message" end end]]) - eq([[true "Return value"]], helpers.exec_capture(':lua =x(true)')) - eq([[false nil "Error message"]], helpers.exec_capture(':lua =x(false)')) + eq(dedent[[ + true + Return value]], + exec_capture(':lua =x(true)')) + eq(dedent[[ + false + nil + Error message]], + exec_capture('=x(false)')) end) end) @@ -183,7 +198,7 @@ describe(':luado command', function() end) it('works correctly when changing lines out of range', function() curbufmeths.set_lines(0, 1, false, {"ABC", "def", "gHi"}) - eq('Vim(luado):E322: line number out of range: 1 past the end', + eq('Vim(luado):E322: Line number out of range: 1 past the end', pcall_err(command, '2,$luado vim.api.nvim_command("%d") return linenr')) eq({''}, curbufmeths.get_lines(0, -1, false)) end) @@ -199,7 +214,7 @@ describe(':luado command', function() end) it('fails in sandbox when needed', function() curbufmeths.set_lines(0, 1, false, {"ABC", "def", "gHi"}) - eq('Vim(luado):E48: Not allowed in sandbox', + eq('Vim(luado):E48: Not allowed in sandbox: sandbox luado runs = (runs or 0) + 1', pcall_err(command, 'sandbox luado runs = (runs or 0) + 1')) eq(NIL, funcs.luaeval('runs')) end) diff --git a/test/functional/lua/diagnostic_spec.lua b/test/functional/lua/diagnostic_spec.lua index d364986ad7..f061fac50a 100644 --- a/test/functional/lua/diagnostic_spec.lua +++ b/test/functional/lua/diagnostic_spec.lua @@ -79,13 +79,10 @@ describe('vim.diagnostic', function() ]]) end) - after_each(function() - clear() - end) - it('creates highlight groups', function() command('runtime plugin/diagnostic.vim') eq({ + 'DiagnosticDeprecated', 'DiagnosticError', 'DiagnosticFloatingError', 'DiagnosticFloatingHint', @@ -105,6 +102,7 @@ describe('vim.diagnostic', function() 'DiagnosticUnderlineInfo', 'DiagnosticUnderlineOk', 'DiagnosticUnderlineWarn', + 'DiagnosticUnnecessary', 'DiagnosticVirtualTextError', 'DiagnosticVirtualTextHint', 'DiagnosticVirtualTextInfo', @@ -183,6 +181,18 @@ describe('vim.diagnostic', function() eq(0, #diagnostics) end) + it('always returns a copy of diagnostic tables', function() + local result = exec_lua [[ + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error('Diagnostic #1', 1, 1, 1, 1), + }) + local diag = vim.diagnostic.get() + diag[1].col = 10000 + return vim.diagnostic.get()[1].col == 10000 + ]] + eq(result, false) + end) + it('resolves buffer number 0 to the current buffer', function() eq(2, exec_lua [[ vim.api.nvim_set_current_buf(diagnostic_bufnr) @@ -862,7 +872,7 @@ end) ]]) end) - it('returns only requested diagnostics when severity is supplied', function() + it('returns only requested diagnostics when severity range is supplied', function() eq({2, 3, 2}, exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { make_error("Error 1", 1, 1, 1, 5), @@ -884,6 +894,28 @@ end) ]]) end) + it('returns only requested diagnostics when severities are supplied', function() + eq({1, 1, 2}, exec_lua [[ + vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { + make_error("Error 1", 1, 1, 1, 5), + make_warning("Warning on Server 1", 1, 1, 2, 3), + make_info("Ignored information", 1, 1, 2, 3), + make_hint("Here's a hint", 1, 1, 2, 3), + }) + + return { + #vim.diagnostic.get(diagnostic_bufnr, { severity = {vim.diagnostic.severity.WARN} }), + #vim.diagnostic.get(diagnostic_bufnr, { severity = {vim.diagnostic.severity.ERROR} }), + #vim.diagnostic.get(diagnostic_bufnr, { + severity = { + vim.diagnostic.severity.INFO, + vim.diagnostic.severity.WARN, + } + }), + } + ]]) + end) + it('allows filtering by line', function() eq(1, exec_lua [[ vim.diagnostic.set(diagnostic_ns, diagnostic_bufnr, { @@ -1044,7 +1076,7 @@ end) local virt_text = get_virt_ |