diff options
author | Justin M. Keyes <justinkz@gmail.com> | 2022-03-27 10:25:55 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-03-27 10:25:55 -0700 |
commit | 72652cbc46f568128bfc296ba63fb2d26941da8e (patch) | |
tree | 45883e033228aacc55df313edb7acac1e1d76698 | |
parent | 05edab85d7edad63c3b449689b57f9f658782c11 (diff) | |
download | rneovim-72652cbc46f568128bfc296ba63fb2d26941da8e.tar.gz rneovim-72652cbc46f568128bfc296ba63fb2d26941da8e.tar.bz2 rneovim-72652cbc46f568128bfc296ba63fb2d26941da8e.zip |
feat(test): use nvim_exec in helpers.source() #16064
helpers.source() was a hack to work around the lack of anonymous
:source. Its "create tempfile" behavior is not a required part of most
tests that use it.
Some tests still need the old "create tempfile" behavior either because
they test SID behavior, or because of missing nvim_exec features: #16071
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | runtime/doc/options.txt | 3 | ||||
-rw-r--r-- | runtime/doc/repeat.txt | 3 | ||||
-rw-r--r-- | runtime/doc/vim_diff.txt | 1 | ||||
-rw-r--r-- | src/nvim/eval.c | 3 | ||||
-rw-r--r-- | test/functional/api/command_spec.lua | 7 | ||||
-rw-r--r-- | test/functional/ex_cmds/cmd_map_spec.lua | 58 | ||||
-rw-r--r-- | test/functional/ex_cmds/echo_spec.lua | 14 | ||||
-rw-r--r-- | test/functional/ex_cmds/script_spec.lua | 14 | ||||
-rw-r--r-- | test/functional/helpers.lua | 26 | ||||
-rw-r--r-- | test/functional/legacy/assert_spec.lua | 12 | ||||
-rw-r--r-- | test/functional/legacy/memory_usage_spec.lua | 17 | ||||
-rw-r--r-- | test/functional/vimscript/lang_spec.lua | 1 |
13 files changed, 93 insertions, 70 deletions
@@ -1,4 +1,6 @@ -[](https://neovim.io) +<h1 align="center"> + <img src="https://raw.githubusercontent.com/neovim/neovim.github.io/master/logos/neovim-logo-300x87.png" alt="Neovim"> +</h1> [Documentation](https://neovim.io/doc/general/) | [Chat](https://app.element.io/#/room/#neovim:matrix.org) | diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 8323ec3e9d..c0a7b73438 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -3670,8 +3670,7 @@ A jump table for the options with a short description can be found at |Q_op|. 0: never 1: only if there are at least two windows 2: always - 3: have a global statusline at the bottom instead of one for - each window + 3: always and ONLY the last window The screen looks nicer with a status line if you have several windows, but it takes another screen line. |status-line| diff --git a/runtime/doc/repeat.txt b/runtime/doc/repeat.txt index 994f97bba0..508565dea4 100644 --- a/runtime/doc/repeat.txt +++ b/runtime/doc/repeat.txt @@ -182,8 +182,7 @@ For writing a Vim script, see chapter 41 of the user manual |usr_41.txt|. *:so* *:source* *load-vim-script* :[range]so[urce] [file] Runs |Ex| commands or Lua code (".lua" files) from - [file], or from the current buffer if no [file] is - given. + [file], or current buffer if no [file]. Triggers the |SourcePre| autocommand. *:source!* :[range]so[urce]! {file} diff --git a/runtime/doc/vim_diff.txt b/runtime/doc/vim_diff.txt index 9ca5faf112..59f085977b 100644 --- a/runtime/doc/vim_diff.txt +++ b/runtime/doc/vim_diff.txt @@ -180,6 +180,7 @@ Commands: |:Man| is available by default, with many improvements such as completion |:sign-define| accepts a `numhl` argument, to highlight the line number |:match| can be invoked before highlight group is defined + |:source| works with Lua and anonymous (no file) scripts Events: |RecordingEnter| diff --git a/src/nvim/eval.c b/src/nvim/eval.c index fbbc543893..6c72c2866e 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -9217,6 +9217,8 @@ dictitem_T *find_var_in_ht(hashtab_T *const ht, int htname, const char *const va /// Finds the dict (g:, l:, s:, …) and hashtable used for a variable. /// +/// Assigns SID if s: scope is accessed from Lua or anonymous Vimscript. #15994 +/// /// @param[in] name Variable name, possibly with scope prefix. /// @param[in] name_len Variable name length. /// @param[out] varname Will be set to the start of the name without scope @@ -9304,6 +9306,7 @@ static hashtab_T *find_var_ht_dict(const char *name, const size_t name_len, cons } } if (current_sctx.sc_sid == SID_STR || current_sctx.sc_sid == SID_LUA) { + // Create SID if s: scope is accessed from Lua or anon Vimscript. #15994 new_script_item(NULL, ¤t_sctx.sc_sid); } *d = &SCRIPT_SV(current_sctx.sc_sid)->sv_dict; diff --git a/test/functional/api/command_spec.lua b/test/functional/api/command_spec.lua index b80004f67c..94176fc2ce 100644 --- a/test/functional/api/command_spec.lua +++ b/test/functional/api/command_spec.lua @@ -65,6 +65,7 @@ describe('nvim_get_commands', function() local cmd3 = { addr=NIL, bang=false, bar=true, complete=NIL, complete_arg=NIL, count=NIL, definition='call \128\253R3_ohyeah()', name='Cmd3', nargs='0', range=NIL, register=false, keepscript=false, script_id=3, } local cmd4 = { addr=NIL, bang=false, bar=false, complete=NIL, complete_arg=NIL, count=NIL, definition='call \128\253R4_just_great()', name='Cmd4', nargs='0', range=NIL, register=true, keepscript=false, script_id=4, } source([[ + let s:foo = 1 command -complete=custom,ListUsers -nargs=+ Finger !finger <args> ]]) eq({Finger=cmd1}, meths.get_commands({builtin=false})) @@ -72,12 +73,18 @@ describe('nvim_get_commands', function() eq({Finger=cmd1, TestCmd=cmd0}, meths.get_commands({builtin=false})) source([[ + function! s:foo() abort + endfunction command -bang -nargs=* Cmd2 call <SID>foo(<q-args>) ]]) source([[ + function! s:ohyeah() abort + endfunction command -bar -nargs=0 Cmd3 call <SID>ohyeah() ]]) source([[ + function! s:just_great() abort + endfunction command -register Cmd4 call <SID>just_great() ]]) -- TODO(justinmk): Order is stable but undefined. Sort before return? diff --git a/test/functional/ex_cmds/cmd_map_spec.lua b/test/functional/ex_cmds/cmd_map_spec.lua index 0b2190bbcf..64cf53dfa9 100644 --- a/test/functional/ex_cmds/cmd_map_spec.lua +++ b/test/functional/ex_cmds/cmd_map_spec.lua @@ -1,21 +1,23 @@ local helpers = require('test.functional.helpers')(after_each) local clear = helpers.clear -local feed_command = helpers.feed_command local feed = helpers.feed local eq = helpers.eq local expect = helpers.expect local eval = helpers.eval local funcs = helpers.funcs local insert = helpers.insert +local write_file = helpers.write_file local exc_exec = helpers.exc_exec -local source = helpers.source +local command = helpers.command local Screen = require('test.functional.ui.screen') describe('mappings with <Cmd>', function() local screen + local tmpfile = 'X_ex_cmds_cmd_map' + local function cmdmap(lhs, rhs) - feed_command('noremap '..lhs..' <Cmd>'..rhs..'<cr>') - feed_command('noremap! '..lhs..' <Cmd>'..rhs..'<cr>') + command('noremap '..lhs..' <Cmd>'..rhs..'<cr>') + command('noremap! '..lhs..' <Cmd>'..rhs..'<cr>') end before_each(function() @@ -39,7 +41,7 @@ describe('mappings with <Cmd>', function() cmdmap('<F4>', 'normal! ww') cmdmap('<F5>', 'normal! "ay') cmdmap('<F6>', 'throw "very error"') - feed_command([[ + command([[ function! TextObj() if mode() !=# "v" normal! v @@ -55,11 +57,15 @@ describe('mappings with <Cmd>', function() feed('gg') cmdmap('<F8>', 'startinsert') cmdmap('<F9>', 'stopinsert') - feed_command("abbr foo <Cmd>let g:y = 17<cr>bar") + command("abbr foo <Cmd>let g:y = 17<cr>bar") + end) + + after_each(function() + os.remove(tmpfile) end) it('can be displayed', function() - feed_command('map <F3>') + command('map <F3>') screen:expect([[ ^some short lines | of test text | @@ -73,8 +79,8 @@ describe('mappings with <Cmd>', function() end) it('handles invalid mappings', function() - feed_command('let x = 0') - feed_command('noremap <F3> <Cmd><Cmd>let x = 1<cr>') + command('let x = 0') + command('noremap <F3> <Cmd><Cmd>let x = 1<cr>') feed('<F3>') screen:expect([[ ^some short lines | @@ -87,7 +93,7 @@ describe('mappings with <Cmd>', function() {2:E5521: <Cmd> mapping must end with <CR> before second <Cmd>} | ]]) - feed_command('noremap <F3> <Cmd><F3>let x = 2<cr>') + command('noremap <F3> <Cmd><F3>let x = 2<cr>') feed('<F3>') screen:expect([[ ^some short lines | @@ -100,7 +106,7 @@ describe('mappings with <Cmd>', function() {2:E5522: <Cmd> mapping must not include <F3> key} | ]]) - feed_command('noremap <F3> <Cmd>let x = 3') + command('noremap <F3> <Cmd>let x = 3') feed('<F3>') screen:expect([[ ^some short lines | @@ -137,7 +143,7 @@ describe('mappings with <Cmd>', function() eq('n', eval('mode(1)')) -- select mode mapping - feed_command('snoremap <F3> <Cmd>let m = mode(1)<cr>') + command('snoremap <F3> <Cmd>let m = mode(1)<cr>') feed('gh<F3>') eq('s', eval('m')) -- didn't leave select mode @@ -184,8 +190,8 @@ describe('mappings with <Cmd>', function() eq('n', eval('mode(1)')) -- terminal mode - feed_command('tnoremap <F3> <Cmd>let m = mode(1)<cr>') - feed_command('split | terminal') + command('tnoremap <F3> <Cmd>let m = mode(1)<cr>') + command('split | terminal') feed('i') eq('t', eval('mode(1)')) feed('<F3>') @@ -264,11 +270,11 @@ describe('mappings with <Cmd>', function() end) it('works in :normal command', function() - feed_command('noremap ,x <Cmd>call append(1, "xx")\\| call append(1, "aa")<cr>') - feed_command('noremap ,f <Cmd>nosuchcommand<cr>') - feed_command('noremap ,e <Cmd>throw "very error"\\| call append(1, "yy")<cr>') - feed_command('noremap ,m <Cmd>echoerr "The message."\\| call append(1, "zz")<cr>') - feed_command('noremap ,w <Cmd>for i in range(5)\\|if i==1\\|echoerr "Err"\\|endif\\|call append(1, i)\\|endfor<cr>') + command('noremap ,x <Cmd>call append(1, "xx")\\| call append(1, "aa")<cr>') + command('noremap ,f <Cmd>nosuchcommand<cr>') + command('noremap ,e <Cmd>throw "very error"\\| call append(1, "yy")<cr>') + command('noremap ,m <Cmd>echoerr "The message."\\| call append(1, "zz")<cr>') + command('noremap ,w <Cmd>for i in range(5)\\|if i==1\\|echoerr "Err"\\|endif\\|call append(1, i)\\|endfor<cr>') feed(":normal ,x<cr>") screen:expect([[ @@ -297,7 +303,7 @@ describe('mappings with <Cmd>', function() :normal ,x | ]]) - feed_command(':%d') + command(':%d') eq('Vim(echoerr):Err', exc_exec("normal ,w")) screen:expect([[ ^ | @@ -310,8 +316,8 @@ describe('mappings with <Cmd>', function() --No lines in buffer-- | ]]) - feed_command(':%d') - feed_command(':normal ,w') + command(':%d') + feed(':normal ,w<cr>') screen:expect([[ ^ | 4 | @@ -401,8 +407,8 @@ describe('mappings with <Cmd>', function() end) it('works in select mode', function() - feed_command('snoremap <F1> <cmd>throw "very error"<cr>') - feed_command('snoremap <F2> <cmd>normal! <c-g>"by<cr>') + command('snoremap <F1> <cmd>throw "very error"<cr>') + command('snoremap <F2> <cmd>normal! <c-g>"by<cr>') -- can extend select mode feed('gh<F4>') screen:expect([[ @@ -830,12 +836,14 @@ describe('mappings with <Cmd>', function() end) it("works with <SID> mappings", function() - source([[ + command('new!') + write_file(tmpfile, [[ map <f2> <Cmd>call <SID>do_it()<Cr> function! s:do_it() let g:x = 10 endfunction ]]) + command('source '..tmpfile) feed('<f2>') eq('', eval('v:errmsg')) eq(10, eval('g:x')) diff --git a/test/functional/ex_cmds/echo_spec.lua b/test/functional/ex_cmds/echo_spec.lua index d320425de1..a6be04138b 100644 --- a/test/functional/ex_cmds/echo_spec.lua +++ b/test/functional/ex_cmds/echo_spec.lua @@ -181,9 +181,9 @@ describe(':echo :echon :echomsg :echoerr', function() end) it('dumps references to script functions', function() - eq('<SNR>2_Test2', eval('String(Test2_f)')) - eq("function('<SNR>2_Test2')", eval('StringMsg(Test2_f)')) - eq("function('<SNR>2_Test2')", eval('StringErr(Test2_f)')) + eq('<SNR>1_Test2', eval('String(Test2_f)')) + eq("function('<SNR>1_Test2')", eval('StringMsg(Test2_f)')) + eq("function('<SNR>1_Test2')", eval('StringErr(Test2_f)')) end) it('dump references to lambdas', function() @@ -205,11 +205,11 @@ describe(':echo :echon :echomsg :echoerr', function() it('dumps automatically created partials', function() assert_same_echo_dump( - "function('<SNR>2_Test2', {'f': function('<SNR>2_Test2')})", + "function('<SNR>1_Test2', {'f': function('<SNR>1_Test2')})", '{"f": Test2_f}.f', true) assert_same_echo_dump( - "function('<SNR>2_Test2', [1], {'f': function('<SNR>2_Test2', [1])})", + "function('<SNR>1_Test2', [1], {'f': function('<SNR>1_Test2', [1])})", '{"f": function(Test2_f, [1])}.f', true) end) @@ -227,7 +227,7 @@ describe(':echo :echon :echomsg :echoerr', function() function() meths.set_var('d', {v=true}) eq(dedent([[ - {'p': function('<SNR>2_Test2', {...@0}), 'f': function('<SNR>2_Test2'), 'v': v:true}]]), + {'p': function('<SNR>1_Test2', {...@0}), 'f': function('<SNR>1_Test2'), 'v': v:true}]]), exec_capture('echo String(extend(extend(g:d, {"f": g:Test2_f}), {"p": g:d.f}))')) end) @@ -264,7 +264,7 @@ describe(':echo :echon :echomsg :echoerr', function() eval('add(l, function("Test1", l))') eval('add(l, function("Test1", d))') eq(dedent([=[ - {'p': function('<SNR>2_Test2', [[[...@3], function('Test1', [[...@3]]), function('Test1', {...@0})], function('Test1', [[[...@5], function('Test1', [[...@5]]), function('Test1', {...@0})]]), function('Test1', {...@0})], {...@0}), 'f': function('<SNR>2_Test2'), 'v': v:true}]=]), + {'p': function('<SNR>1_Test2', [[[...@3], function('Test1', [[...@3]]), function('Test1', {...@0})], function('Test1', [[[...@5], function('Test1', [[...@5]]), function('Test1', {...@0})]]), function('Test1', {...@0})], {...@0}), 'f': function('<SNR>1_Test2'), 'v': v:true}]=]), exec_capture('echo String(extend(extend(g:d, {"f": g:Test2_f}), {"p": function(g:d.f, l)}))')) end) end) diff --git a/test/functional/ex_cmds/script_spec.lua b/test/functional/ex_cmds/script_spec.lua index f249b9ba7c..bf69ada820 100644 --- a/test/functional/ex_cmds/script_spec.lua +++ b/test/functional/ex_cmds/script_spec.lua @@ -2,18 +2,30 @@ local helpers = require('test.functional.helpers')(after_each) local eq = helpers.eq local neq = helpers.neq +local command = helpers.command +local write_file = helpers.write_file local meths = helpers.meths local clear = helpers.clear local dedent = helpers.dedent -local source = helpers.source local exc_exec = helpers.exc_exec local missing_provider = helpers.missing_provider +local tmpfile = 'X_ex_cmds_script' + before_each(clear) +local function source(code) + write_file(tmpfile, code) + command('source '..tmpfile) +end + describe('script_get-based command', function() local garbage = ')}{+*({}]*[;(+}{&[]}{*])(' + after_each(function() + os.remove(tmpfile) + end) + local function test_garbage_exec(cmd, check_neq) describe(cmd, function() it('works correctly when skipping oneline variant', function() diff --git a/test/functional/helpers.lua b/test/functional/helpers.lua index 1845786c4b..173fc54af5 100644 --- a/test/functional/helpers.lua +++ b/test/functional/helpers.lua @@ -21,7 +21,6 @@ local map = global_helpers.tbl_map local ok = global_helpers.ok local sleep = global_helpers.sleep local tbl_contains = global_helpers.tbl_contains -local write_file = global_helpers.write_file local fail = global_helpers.fail local module = { @@ -54,7 +53,6 @@ if module.nvim_dir == module.nvim_prog then module.nvim_dir = "." end -local tmpname = global_helpers.tmpname local iswin = global_helpers.iswin local prepend_argv @@ -494,24 +492,9 @@ function module.feed_command(...) end end -local sourced_fnames = {} +-- @deprecated use nvim_exec() function module.source(code) - local fname = tmpname() - write_file(fname, code) - module.command('source '..fname) - -- DO NOT REMOVE FILE HERE. - -- do_source() has a habit of checking whether files are “same” by using inode - -- and device IDs. If you run two source() calls in quick succession there is - -- a good chance that underlying filesystem will reuse the inode, making files - -- appear as “symlinks” to do_source when it checks FileIDs. With current - -- setup linux machines (both QB, travis and mine(ZyX-I) with XFS) do reuse - -- inodes, Mac OS machines (again, both QB and travis) do not. - -- - -- Files appearing as “symlinks” mean that both the first and the second - -- source() calls will use same SID, which may fail some tests which check for - -- exact numbers after `<SNR>` in e.g. function names. - sourced_fnames[#sourced_fnames + 1] = fname - return fname + module.exec(dedent(code)) end function module.has_powershell() @@ -525,7 +508,7 @@ function module.set_shell_powershell() local cmd = set_encoding..'Remove-Item -Force '..table.concat(iswin() and {'alias:cat', 'alias:echo', 'alias:sleep'} or {'alias:echo'}, ',')..';' - module.source([[ + module.exec([[ let &shell = ']]..shell..[[' set shellquote= shellxquote= let &shellpipe = '2>&1 | Out-File -Encoding UTF8 %s; exit $LastExitCode' @@ -887,9 +870,6 @@ module = global_helpers.tbl_extend('error', module, global_helpers) return function(after_each) if after_each then after_each(function() - for _, fname in ipairs(sourced_fnames) do - os.remove(fname) - end check_logs() check_cores('build/bin/nvim') if session then diff --git a/test/functional/legacy/assert_spec.lua b/test/functional/legacy/assert_spec.lua index dd6a9d0bde..4829a0bbe1 100644 --- a/test/functional/legacy/assert_spec.lua +++ b/test/functional/legacy/assert_spec.lua @@ -136,19 +136,19 @@ describe('assert function:', function() end) it('should have file names and passed messages', function() - local tmpname_one = source([[ + source([[ call assert_equal(1, 100, 'equal assertion failed') call assert_false('true', 'true assertion failed') call assert_true('false', 'false assertion failed') ]]) - local tmpname_two = source([[ + source([[ call assert_true('', 'file two') ]]) expected_errors({ - tmpname_one .. " line 1: equal assertion failed: Expected 1 but got 100", - tmpname_one .. " line 2: true assertion failed: Expected False but got 'true'", - tmpname_one .. " line 3: false assertion failed: Expected True but got 'false'", - tmpname_two .. " line 1: file two: Expected True but got ''", + "nvim_exec(): equal assertion failed: Expected 1 but got 100", + "nvim_exec(): true assertion failed: Expected False but got 'true'", + "nvim_exec(): false assertion failed: Expected True but got 'false'", + "nvim_exec(): file two: Expected True but got ''", }) end) end) diff --git a/test/functional/legacy/memory_usage_spec.lua b/test/functional/legacy/memory_usage_spec.lua index 8d25b9d927..eec89aa919 100644 --- a/test/functional/legacy/memory_usage_spec.lua +++ b/test/functional/legacy/memory_usage_spec.lua @@ -10,6 +10,7 @@ local source = helpers.source local poke_eventloop = helpers.poke_eventloop local uname = helpers.uname local load_adjust = helpers.load_adjust +local write_file = helpers.write_file local isCI = helpers.isCI local function isasan() @@ -84,6 +85,12 @@ setmetatable(monitor_memory_usage, end}) describe('memory usage', function() + local tmpfile = 'X_memory_usage' + + after_each(function() + os.remove(tmpfile) + end) + local function check_result(tbl, status, result) if not status then print('') @@ -103,7 +110,7 @@ describe('memory usage', function() it('function capture vargs', function() local pid = eval('getpid()') local before = monitor_memory_usage(pid) - source([[ + write_file(tmpfile, [[ func s:f(...) let x = a:000 endfunc @@ -111,6 +118,8 @@ describe('memory usage', function() call s:f(0) endfor ]]) + -- TODO: check_result fails if command() is used here. Why? #16064 + feed_command('source '..tmpfile) poke_eventloop() local after = monitor_memory_usage(pid) -- Estimate the limit of max usage as 2x initial usage. @@ -136,7 +145,7 @@ describe('memory usage', function() it('function capture lvars', function() local pid = eval('getpid()') local before = monitor_memory_usage(pid) - local fname = source([[ + write_file(tmpfile, [[ if !exists('s:defined_func') func s:f() let x = l: @@ -147,10 +156,12 @@ describe('memory usage', function() call s:f() endfor ]]) + feed_command('source '..tmpfile) poke_eventloop() local after = monitor_memory_usage(pid) for _ = 1, 3 do - feed_command('so '..fname) + -- TODO: check_result fails if command() is used here. Why? #16064 + feed_command('source '..tmpfile) poke_eventloop() end local last = monitor_memory_usage(pid) diff --git a/test/functional/vimscript/lang_spec.lua b/test/functional/vimscript/lang_spec.lua index d5254986ab..90437f2ee1 100644 --- a/test/functional/vimscript/lang_spec.lua +++ b/test/functional/vimscript/lang_spec.lua @@ -11,6 +11,7 @@ describe('vimscript', function() return end source([[ + let s:foo = 1 func! <sid>_dummy_function() echo 1 endfunc |