From bda63d5b97dfb333de6f4bd757dbb978906062a2 Mon Sep 17 00:00:00 2001 From: bfredl Date: Tue, 25 Jun 2024 15:33:47 +0200 Subject: refactor(typval)!: remove distinction of binary and nonbinary strings This is a breaking change which will make refactor of typval and shada code a lot easier. In particular, code that would use or check for v:msgpack_types.binary in the wild would be broken. This appears to be rarely used in existing plugins. Also some cases where v:msgpack_type.string would be used to represent a binary string of "string" type, we use a BLOB instead, which is vimscripts native type for binary blobs, and already was used for BIN formats when necessary. msgpackdump(msgpackparse(data)) no longer preserves the distinction of BIN and STR strings. This is very common behavior for language-specific msgpack bindings. Nvim uses msgpack as a tool to serialize its data. Nvim is not a tool to bit-perfectly manipulate arbitrary msgpack data out in the wild. The changed tests should indicate how behavior changes in various edge cases. --- test/functional/vimscript/json_functions_spec.lua | 32 ++++------------------ .../vimscript/msgpack_functions_spec.lua | 29 ++++++++++---------- 2 files changed, 20 insertions(+), 41 deletions(-) (limited to 'test/functional/vimscript') diff --git a/test/functional/vimscript/json_functions_spec.lua b/test/functional/vimscript/json_functions_spec.lua index ae56e8873d..c6e0e75bdc 100644 --- a/test/functional/vimscript/json_functions_spec.lua +++ b/test/functional/vimscript/json_functions_spec.lua @@ -502,9 +502,9 @@ describe('json_decode() function', function() end it('parses strings with NUL properly', function() - sp_decode_eq({ _TYPE = 'string', _VAL = { '\n' } }, '"\\u0000"') - sp_decode_eq({ _TYPE = 'string', _VAL = { '\n', '\n' } }, '"\\u0000\\n\\u0000"') - sp_decode_eq({ _TYPE = 'string', _VAL = { '\n«\n' } }, '"\\u0000\\u00AB\\u0000"') + sp_decode_eq('\000', '"\\u0000"') + sp_decode_eq('\000\n\000', '"\\u0000\\n\\u0000"') + sp_decode_eq('\000«\000', '"\\u0000\\u00AB\\u0000"') end) it('parses dictionaries with duplicate keys to special maps', function() @@ -580,14 +580,8 @@ describe('json_decode() function', function() end) it('parses dictionaries with keys with NUL bytes to special maps', function() - sp_decode_eq( - { _TYPE = 'map', _VAL = { { { _TYPE = 'string', _VAL = { 'a\n', 'b' } }, 4 } } }, - '{"a\\u0000\\nb": 4}' - ) - sp_decode_eq( - { _TYPE = 'map', _VAL = { { { _TYPE = 'string', _VAL = { 'a\n', 'b', '' } }, 4 } } }, - '{"a\\u0000\\nb\\n": 4}' - ) + sp_decode_eq({ _TYPE = 'map', _VAL = { { 'a\000\nb', 4 } } }, '{"a\\u0000\\nb": 4}') + sp_decode_eq({ _TYPE = 'map', _VAL = { { 'a\000\nb\n', 4 } } }, '{"a\\u0000\\nb\\n": 4}') sp_decode_eq({ _TYPE = 'map', _VAL = { @@ -595,10 +589,7 @@ describe('json_decode() function', function() { 'a', 1 }, { 'c', 4 }, { 'd', 2 }, - { - { _TYPE = 'string', _VAL = { '\n' } }, - 4, - }, + { '\000', 4 }, }, }, '{"b": 3, "a": 1, "c": 4, "d": 2, "\\u0000": 4}') end) @@ -738,22 +729,11 @@ describe('json_encode() function', function() eq('{"\\u0000": 1}', eval('json_encode(todump)')) end) - it('can dump generic mapping with BIN special key and NUL', function() - command('let todump = {"_TYPE": v:msgpack_types.binary, "_VAL": ["\\n"]}') - command('let todump = {"_TYPE": v:msgpack_types.map, "_VAL": [[todump, 1]]}') - eq('{"\\u0000": 1}', eval('json_encode(todump)')) - end) - it('can dump STR special mapping with NUL and NL', function() command('let todump = {"_TYPE": v:msgpack_types.string, "_VAL": ["\\n", ""]}') eq('"\\u0000\\n"', eval('json_encode(todump)')) end) - it('can dump BIN special mapping with NUL and NL', function() - command('let todump = {"_TYPE": v:msgpack_types.binary, "_VAL": ["\\n", ""]}') - eq('"\\u0000\\n"', eval('json_encode(todump)')) - end) - it('cannot dump special ext mapping', function() command('let todump = {"_TYPE": v:msgpack_types.ext, "_VAL": [5, ["",""]]}') eq('Vim(call):E474: Unable to convert EXT string to JSON', exc_exec('call json_encode(todump)')) diff --git a/test/functional/vimscript/msgpack_functions_spec.lua b/test/functional/vimscript/msgpack_functions_spec.lua index d59dceef31..6b77811e35 100644 --- a/test/functional/vimscript/msgpack_functions_spec.lua +++ b/test/functional/vimscript/msgpack_functions_spec.lua @@ -371,13 +371,14 @@ describe('msgpack*() functions', function() eq(1, eval('dumped ==# dumped2')) end) - it('can restore and dump STR string with zero byte', function() + it('can restore and dump STR string contents with zero byte', function() command('let dumped = ["\\xA1\\n"]') command('let parsed = msgpackparse(dumped)') command('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')) + eq({ '\000' }, eval('parsed')) + eq(eval('v:t_blob'), eval('type(parsed[0])')) + -- type is not preserved: prefer BIN for binary contents + eq(0, eval('dumped ==# dumped2')) end) it('can restore and dump BIN string with NL', function() @@ -428,9 +429,8 @@ describe('msgpackparse() function', function() parse_eq({ true }, { '\195' }) end) - it('restores FIXSTR as special dict', function() - parse_eq({ { _TYPE = {}, _VAL = { 'ab' } } }, { '\162ab' }) - eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.string')) + it('restores FIXSTR as string', function() + parse_eq({ 'ab' }, { '\162ab' }) end) it('restores BIN 8 as string', function() @@ -442,9 +442,8 @@ describe('msgpackparse() function', function() eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.ext')) end) - it('restores MAP with BIN key as special dictionary', function() - parse_eq({ { _TYPE = {}, _VAL = { { 'a', '' } } } }, { '\129\196\001a\196\n' }) - eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map')) + it('restores MAP with BIN key as ordinary dictionary', function() + parse_eq({ { a = '' } }, { '\129\196\001a\196\n' }) end) it('restores MAP with duplicate STR keys as special dictionary', function() @@ -455,14 +454,14 @@ describe('msgpackparse() function', function() { _TYPE = {}, _VAL = { - { { _TYPE = {}, _VAL = { 'a' } }, '' }, - { { _TYPE = {}, _VAL = { 'a' } }, '' }, + { 'a', '' }, + { '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')) + eq(eval('v:t_string'), eval('type(g:parsed[0]._VAL[0][0])')) + eq(eval('v:t_string'), eval('type(g:parsed[0]._VAL[1][0])')) end) it('restores MAP with MAP key as special dictionary', function() @@ -802,7 +801,7 @@ describe('msgpackdump() function', function() it('can dump NULL string', function() dump_eq({ '\196\n' }, '[$XXX_UNEXISTENT_VAR_XXX]') - dump_eq({ '\196\n' }, '[{"_TYPE": v:msgpack_types.binary, "_VAL": [$XXX_UNEXISTENT_VAR_XXX]}]') + dump_eq({ '\196\n' }, '[v:_null_blob]') dump_eq({ '\160' }, '[{"_TYPE": v:msgpack_types.string, "_VAL": [$XXX_UNEXISTENT_VAR_XXX]}]') end) -- cgit From aa6b9c677d83d76d448c3bb0973bf8d14bfdf922 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 8 Jun 2024 21:40:18 +0200 Subject: refactor: use `vim._with` where possible This mostly means replacing `nvim_buf_call` and `nvim_win_call` with `vim._with`. --- test/functional/vimscript/api_functions_spec.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'test/functional/vimscript') diff --git a/test/functional/vimscript/api_functions_spec.lua b/test/functional/vimscript/api_functions_spec.lua index b2865d2b4c..30d6c969ca 100644 --- a/test/functional/vimscript/api_functions_spec.lua +++ b/test/functional/vimscript/api_functions_spec.lua @@ -115,7 +115,7 @@ describe('eval-API', function() exec_lua, [[ local cmdwin_buf = vim.api.nvim_get_current_buf() - vim.api.nvim_buf_call(vim.api.nvim_create_buf(false, true), function() + vim._with({buf = vim.api.nvim_create_buf(false, true)}, function() vim.api.nvim_open_term(cmdwin_buf, {}) end) ]] -- cgit From 033ea63b2fa2c0ce1a47bafd97df482871aafef5 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 4 Jul 2024 09:54:51 +0800 Subject: refactor: add assertion for v_blob in tv_ptr() (#29554) Also add test for using printf() and id() with a Blob. --- test/functional/vimscript/printf_spec.lua | 3 +++ 1 file changed, 3 insertions(+) (limited to 'test/functional/vimscript') diff --git a/test/functional/vimscript/printf_spec.lua b/test/functional/vimscript/printf_spec.lua index 3c66e07618..1fd5c3c9b6 100644 --- a/test/functional/vimscript/printf_spec.lua +++ b/test/functional/vimscript/printf_spec.lua @@ -84,10 +84,13 @@ describe('printf()', function() end api.nvim_del_var('__result') end + check_printf('v:_null_string', true) check_printf('v:_null_list', true) check_printf('v:_null_dict', true) + check_printf('v:_null_blob', true) check_printf('[]') check_printf('{}') + check_printf('0z') check_printf('function("tr", ["a"])') end) end) -- cgit From 96128a5076b7e45fc01163151401a9e2acdff565 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 2 Sep 2024 15:57:07 +0200 Subject: feat(startup): validate --listen address Problem: `nvim --listen` does not error on EADDRINUSE. #30123 Solution: Now that `$NVIM_LISTEN_ADDRESS` is deprecated and input *only* (instead of the old, ambiguous situation where it was both an input *and* an output), we can be fail fast instead of trying to "recover". This reverts the "recovery" behavior of 704ba4151e7f67999510ee0ac19fdabb595d530c, but that was basically a workaround for the fragility of `$NVIM_LISTEN_ADDRESS`. --- test/functional/vimscript/server_spec.lua | 67 ++++++++++++++++++++----------- 1 file changed, 43 insertions(+), 24 deletions(-) (limited to 'test/functional/vimscript') diff --git a/test/functional/vimscript/server_spec.lua b/test/functional/vimscript/server_spec.lua index 4b0dc087f6..836d841f69 100644 --- a/test/functional/vimscript/server_spec.lua +++ b/test/functional/vimscript/server_spec.lua @@ -4,7 +4,6 @@ local n = require('test.functional.testnvim')() local assert_log = t.assert_log local eq, neq, eval = t.eq, t.neq, n.eval local clear, fn, api = n.clear, n.fn, n.api -local ok = t.ok local matches = t.matches local pcall_err = t.pcall_err local check_close = n.check_close @@ -49,15 +48,6 @@ describe('server', function() eq('', eval('$NVIM_LISTEN_ADDRESS')) end) - it('sets new v:servername if $NVIM_LISTEN_ADDRESS is invalid', function() - clear({ env = { NVIM_LISTEN_ADDRESS = '.' } }) - -- Cleared on startup. - eq('', eval('$NVIM_LISTEN_ADDRESS')) - local servers = fn.serverlist() - eq(1, #servers) - ok(string.len(servers[1]) > 4) -- "~/.local/state/nvim…/…" or "\\.\pipe\…" - end) - it('sets v:servername at startup or if all servers were stopped', function() clear() local initial_server = api.nvim_get_vvar('servername') @@ -89,20 +79,26 @@ describe('server', function() end) it('serverstop() returns false for invalid input', function() - clear { env = { - NVIM_LOG_FILE = testlog, - NVIM_LISTEN_ADDRESS = '.', - } } + clear { + args_rm = { '--listen' }, + env = { + NVIM_LOG_FILE = testlog, + NVIM_LISTEN_ADDRESS = '', + }, + } eq(0, eval("serverstop('')")) eq(0, eval("serverstop('bogus-socket-name')")) assert_log('Not listening on bogus%-socket%-name', testlog, 10) end) it('parses endpoints', function() - clear { env = { - NVIM_LOG_FILE = testlog, - NVIM_LISTEN_ADDRESS = '.', - } } + clear { + args_rm = { '--listen' }, + env = { + NVIM_LOG_FILE = testlog, + NVIM_LISTEN_ADDRESS = '', + }, + } clear_serverlist() eq({}, fn.serverlist()) @@ -178,18 +174,41 @@ end) describe('startup --listen', function() it('validates', function() clear() - local cmd = { unpack(n.nvim_argv) } - table.insert(cmd, '--listen') - matches('nvim.*: Argument missing after: "%-%-listen"', fn.system(cmd)) - cmd = { unpack(n.nvim_argv) } - table.insert(cmd, '--listen2') - matches('nvim.*: Garbage after option argument: "%-%-listen2"', fn.system(cmd)) + -- Tests args with and without "--headless". + local function _test(args, expected) + -- XXX: clear v:shell_error, sigh... + fn.system({ n.nvim_prog, '-es', '+qall!' }) + assert(0 == eval('v:shell_error')) + local cmd = vim.list_extend({ unpack(n.nvim_argv) }, vim.list_extend({ '--headless' }, args)) + local output = fn.system(cmd) + assert(0 ~= eval('v:shell_error')) + -- TODO(justinmk): output not properly captured on Windows? + if is_os('win') then + return + end + matches(expected, output) + cmd = vim.list_extend({ unpack(n.nvim_argv) }, args) + matches(expected, fn.system(cmd)) + end + + _test({ '--listen' }, 'nvim.*: Argument missing after: "%-%-listen"') + _test({ '--listen2' }, 'nvim.*: Garbage after option argument: "%-%-listen2"') + _test({ '--listen', n.eval('v:servername') }, 'nvim.*: Failed to %-%-listen: ".* already .*"') + _test({ '--listen', '/' }, 'nvim.*: Failed to %-%-listen: ".*"') + _test( + { '--listen', 'https://example.com' }, + ('nvim.*: Failed to %%-%%-listen: "%s"'):format( + (is_os('mac') or is_os('win')) and 'unknown node or service' + or 'service not available for socket type' + ) + ) end) it('sets v:servername, overrides $NVIM_LISTEN_ADDRESS', function() local addr = (is_os('win') and [[\\.\pipe\Xtest-listen-pipe]] or './Xtest-listen-pipe') clear({ env = { NVIM_LISTEN_ADDRESS = './Xtest-env-pipe' }, args = { '--listen', addr } }) + eq('', eval('$NVIM_LISTEN_ADDRESS')) -- Cleared on startup. eq(addr, api.nvim_get_vvar('servername')) -- Address without slashes is a "name" which is appended to a generated path. #8519 -- cgit From ea2d9493514a82bb5077e73957a22648cb5d7d14 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 3 Sep 2024 02:18:17 -0700 Subject: test: tmpname(create:boolean) #30242 Problem: 137f98cf6428 added the `create` parameter to `tmpname()` but didn't fully implement it. Solution: - Update impl for the `os.tmpname()` codepath. - Inspect all usages of `tmpname()`, update various tests. --- test/functional/vimscript/server_spec.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'test/functional/vimscript') diff --git a/test/functional/vimscript/server_spec.lua b/test/functional/vimscript/server_spec.lua index 836d841f69..2dabe1afc1 100644 --- a/test/functional/vimscript/server_spec.lua +++ b/test/functional/vimscript/server_spec.lua @@ -188,8 +188,7 @@ describe('startup --listen', function() return end matches(expected, output) - cmd = vim.list_extend({ unpack(n.nvim_argv) }, args) - matches(expected, fn.system(cmd)) + matches(expected, fn.system(vim.list_extend({ unpack(n.nvim_argv) }, args))) end _test({ '--listen' }, 'nvim.*: Argument missing after: "%-%-listen"') -- cgit From 975aeee537375a14c0e16916e1ef312aae90b85f Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 5 Sep 2024 02:39:58 -0700 Subject: test: avoid noise in CI logs #30264 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: Since 96128a5076b7 the test logs have noise from tests that *expect* failures: $NVIM_LOG_FILE: /tmp/cirrus-ci-build/build/.nvimlog (last 100 lines) ERR 2024-09-04T13:38:45.181 T949.28335.0/c terminfo_start:486: uv_pipe_open failed: no such device or address ERR 2024-09-04T13:38:45.181 T949.28335.0/c flush_buf:2527: uv_write failed: bad file descriptor ERR 2024-09-04T13:38:45.181 T949.28335.0/c flush_buf:2527: uv_write failed: bad file descriptor WRN 2024-09-04T13:43:43.294 ?.35904 server_start:173: Failed to start server: address already in use: /…/Xtest_tmpdir/…/T7159.35895.0 WRN 2024-09-04T13:43:43.314 ?.35907 server_start:173: Failed to start server: illegal operation on a directory: / ERR 2024-09-04T13:43:43.332 ?.35909 socket_watcher_init:60: Host lookup failed: https://example.com Solution: Rewrite the test to use `vim.system()`. Set NVIM_LOG_FILE in the child process to a "throwaway" logfile. --- test/functional/vimscript/server_spec.lua | 54 +++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 17 deletions(-) (limited to 'test/functional/vimscript') diff --git a/test/functional/vimscript/server_spec.lua b/test/functional/vimscript/server_spec.lua index 2dabe1afc1..8d2025e822 100644 --- a/test/functional/vimscript/server_spec.lua +++ b/test/functional/vimscript/server_spec.lua @@ -1,7 +1,6 @@ local t = require('test.testutil') local n = require('test.functional.testnvim')() -local assert_log = t.assert_log local eq, neq, eval = t.eq, t.neq, n.eval local clear, fn, api = n.clear, n.fn, n.api local matches = t.matches @@ -88,7 +87,7 @@ describe('server', function() } eq(0, eval("serverstop('')")) eq(0, eval("serverstop('bogus-socket-name')")) - assert_log('Not listening on bogus%-socket%-name', testlog, 10) + t.assert_log('Not listening on bogus%-socket%-name', testlog, 10) end) it('parses endpoints', function() @@ -122,7 +121,7 @@ describe('server', function() if status then table.insert(expected, v4) pcall(fn.serverstart, v4) -- exists already; ignore - assert_log('Failed to start server: address already in use: 127%.0%.0%.1', testlog, 10) + t.assert_log('Failed to start server: address already in use: 127%.0%.0%.1', testlog, 10) end local v6 = '::1:12345' @@ -130,7 +129,7 @@ describe('server', function() if status then table.insert(expected, v6) pcall(fn.serverstart, v6) -- exists already; ignore - assert_log('Failed to start server: address already in use: ::1', testlog, 10) + t.assert_log('Failed to start server: address already in use: ::1', testlog, 10) end eq(expected, fn.serverlist()) clear_serverlist() @@ -173,24 +172,43 @@ end) describe('startup --listen', function() it('validates', function() - clear() + os.remove(testlog) + clear { env = { NVIM_LOG_FILE = testlog } } -- Tests args with and without "--headless". local function _test(args, expected) - -- XXX: clear v:shell_error, sigh... - fn.system({ n.nvim_prog, '-es', '+qall!' }) - assert(0 == eval('v:shell_error')) - local cmd = vim.list_extend({ unpack(n.nvim_argv) }, vim.list_extend({ '--headless' }, args)) - local output = fn.system(cmd) - assert(0 ~= eval('v:shell_error')) - -- TODO(justinmk): output not properly captured on Windows? + local function run(cmd) + return n.exec_lua(function(cmd_) + return vim + .system(cmd_, { + text = true, + env = { + -- Avoid noise in the logs; we expect failures for these tests. + NVIM_LOG_FILE = testlog, + }, + }) + :wait() + end, cmd) --[[@as vim.SystemCompleted]] + end + + local cmd = vim.list_extend({ n.nvim_prog, '+qall!', '--headless' }, args) + local r = run(cmd) + eq(1, r.code) + matches(expected, (r.stderr .. r.stdout):gsub('\\n', ' ')) + if is_os('win') then - return + return -- On Windows, output without --headless is garbage. end - matches(expected, output) - matches(expected, fn.system(vim.list_extend({ unpack(n.nvim_argv) }, args))) + table.remove(cmd, 3) -- Remove '--headless'. + assert(not vim.tbl_contains(cmd, '--headless')) + r = run(cmd) + eq(1, r.code) + matches(expected, (r.stderr .. r.stdout):gsub('\\n', ' ')) end + t.assert_nolog('Failed to start server', testlog, 100) + t.assert_nolog('Host lookup failed', testlog, 100) + _test({ '--listen' }, 'nvim.*: Argument missing after: "%-%-listen"') _test({ '--listen2' }, 'nvim.*: Garbage after option argument: "%-%-listen2"') _test({ '--listen', n.eval('v:servername') }, 'nvim.*: Failed to %-%-listen: ".* already .*"') @@ -198,10 +216,12 @@ describe('startup --listen', function() _test( { '--listen', 'https://example.com' }, ('nvim.*: Failed to %%-%%-listen: "%s"'):format( - (is_os('mac') or is_os('win')) and 'unknown node or service' - or 'service not available for socket type' + is_os('mac') and 'unknown node or service' or 'service not available for socket type' ) ) + + t.assert_log('Failed to start server', testlog, 100) + t.assert_log('Host lookup failed', testlog, 100) end) it('sets v:servername, overrides $NVIM_LISTEN_ADDRESS', function() -- cgit From 76aa3e52be7a5a8b53b3775981c35313284230ac Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 5 Sep 2024 05:56:00 -0700 Subject: feat(defaults): popupmenu "Open in browser", "Go to definition" #30261 - Use the popup to expose more features such as LSP and gx. - Move the copy/paste items lower in the menu, they are lower priority. --- test/functional/vimscript/server_spec.lua | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'test/functional/vimscript') diff --git a/test/functional/vimscript/server_spec.lua b/test/functional/vimscript/server_spec.lua index 8d2025e822..f3c72b7da8 100644 --- a/test/functional/vimscript/server_spec.lua +++ b/test/functional/vimscript/server_spec.lua @@ -18,12 +18,16 @@ local function clear_serverlist() end end -describe('server', function() - after_each(function() - check_close() - os.remove(testlog) - end) +after_each(function() + check_close() + os.remove(testlog) +end) +before_each(function() + os.remove(testlog) +end) + +describe('server', function() it('serverstart() stores sockets in $XDG_RUNTIME_DIR', function() local dir = 'Xtest_xdg_run' mkdir(dir) @@ -172,7 +176,6 @@ end) describe('startup --listen', function() it('validates', function() - os.remove(testlog) clear { env = { NVIM_LOG_FILE = testlog } } -- Tests args with and without "--headless". -- cgit From 08153ddd1c149c867948f4681846531d53ba7759 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 8 Sep 2024 07:07:19 -0700 Subject: fix(startup): ignore broken $XDG_RUNTIME_DIR #30285 Problem: $XDG_RUNTIME_DIR may be broken on WSL, which prevents starting (and even building) Nvim. #30282 Solution: - When startup fails, mention the servername in the error message. - If an autogenerated server address fails, log an error and continue with an empty `v:servername`. It's only fatal if a user provides a bad `--listen` or `$NVIM_LISTEN_ADDRESS` address. Before: $ nvim --headless --listen ./hello.sock nvim: Failed to --listen: "address already in use" $ NVIM_LISTEN_ADDRESS='./hello.sock' ./build/bin/nvim --headless nvim: Failed to --listen: "address already in use" After: $ nvim --headless --listen ./hello.sock nvim: Failed to --listen: address already in use: "./hello.sock" $ NVIM_LISTEN_ADDRESS='./hello.sock' ./build/bin/nvim --headless nvim: Failed $NVIM_LISTEN_ADDRESS: address already in use: "./hello.sock" --- test/functional/vimscript/server_spec.lua | 110 ++++++++++++++++++++---------- 1 file changed, 74 insertions(+), 36 deletions(-) (limited to 'test/functional/vimscript') diff --git a/test/functional/vimscript/server_spec.lua b/test/functional/vimscript/server_spec.lua index f3c72b7da8..85a179b3d5 100644 --- a/test/functional/vimscript/server_spec.lua +++ b/test/functional/vimscript/server_spec.lua @@ -41,6 +41,21 @@ describe('server', function() end end) + it('broken $XDG_RUNTIME_DIR is not fatal #30282', function() + clear { + args_rm = { '--listen' }, + env = { NVIM_LOG_FILE = testlog, XDG_RUNTIME_DIR = '/non-existent-dir/subdir//' }, + } + + if is_os('win') then + -- Windows pipes have a special namespace and thus aren't decided by $XDG_RUNTIME_DIR. + matches('nvim', api.nvim_get_vvar('servername')) + else + eq('', api.nvim_get_vvar('servername')) + t.assert_log('Failed to start server%: no such file or directory', testlog, 100) + end + end) + it('serverstart(), serverstop() does not set $NVIM', function() clear() local s = eval('serverstart()') @@ -175,56 +190,79 @@ describe('server', function() end) describe('startup --listen', function() - it('validates', function() - clear { env = { NVIM_LOG_FILE = testlog } } + -- Tests Nvim output when failing to start, with and without "--headless". + -- TODO(justinmk): clear() should have a way to get stdout if Nvim fails to start. + local function _test(args, env, expected) + local function run(cmd) + return n.exec_lua(function(cmd_, env_) + return vim + .system(cmd_, { + text = true, + env = vim.tbl_extend( + 'force', + -- Avoid noise in the logs; we expect failures for these tests. + { NVIM_LOG_FILE = testlog }, + env_ or {} + ), + }) + :wait() + end, cmd, env) --[[@as vim.SystemCompleted]] + end + + local cmd = vim.list_extend({ n.nvim_prog, '+qall!', '--headless' }, args) + local r = run(cmd) + eq(1, r.code) + matches(expected, (r.stderr .. r.stdout):gsub('\\n', ' ')) - -- Tests args with and without "--headless". - local function _test(args, expected) - local function run(cmd) - return n.exec_lua(function(cmd_) - return vim - .system(cmd_, { - text = true, - env = { - -- Avoid noise in the logs; we expect failures for these tests. - NVIM_LOG_FILE = testlog, - }, - }) - :wait() - end, cmd) --[[@as vim.SystemCompleted]] - end - - local cmd = vim.list_extend({ n.nvim_prog, '+qall!', '--headless' }, args) - local r = run(cmd) - eq(1, r.code) - matches(expected, (r.stderr .. r.stdout):gsub('\\n', ' ')) - - if is_os('win') then - return -- On Windows, output without --headless is garbage. - end - table.remove(cmd, 3) -- Remove '--headless'. - assert(not vim.tbl_contains(cmd, '--headless')) - r = run(cmd) - eq(1, r.code) - matches(expected, (r.stderr .. r.stdout):gsub('\\n', ' ')) + if is_os('win') then + return -- On Windows, output without --headless is garbage. end + table.remove(cmd, 3) -- Remove '--headless'. + assert(not vim.tbl_contains(cmd, '--headless')) + r = run(cmd) + eq(1, r.code) + matches(expected, (r.stderr .. r.stdout):gsub('\\n', ' ')) + end + + it('validates', function() + clear { env = { NVIM_LOG_FILE = testlog } } + local in_use = n.eval('v:servername') ---@type string Address already used by another server. t.assert_nolog('Failed to start server', testlog, 100) t.assert_nolog('Host lookup failed', testlog, 100) - _test({ '--listen' }, 'nvim.*: Argument missing after: "%-%-listen"') - _test({ '--listen2' }, 'nvim.*: Garbage after option argument: "%-%-listen2"') - _test({ '--listen', n.eval('v:servername') }, 'nvim.*: Failed to %-%-listen: ".* already .*"') - _test({ '--listen', '/' }, 'nvim.*: Failed to %-%-listen: ".*"') + _test({ '--listen' }, nil, 'nvim.*: Argument missing after: "%-%-listen"') + _test({ '--listen2' }, nil, 'nvim.*: Garbage after option argument: "%-%-listen2"') + _test( + { '--listen', in_use }, + nil, + ('nvim.*: Failed to %%-%%-listen: [^:]+ already [^:]+: "%s"'):format(vim.pesc(in_use)) + ) + _test({ '--listen', '/' }, nil, 'nvim.*: Failed to %-%-listen: [^:]+: "/"') _test( { '--listen', 'https://example.com' }, - ('nvim.*: Failed to %%-%%-listen: "%s"'):format( + nil, + ('nvim.*: Failed to %%-%%-listen: %s: "https://example.com"'):format( is_os('mac') and 'unknown node or service' or 'service not available for socket type' ) ) t.assert_log('Failed to start server', testlog, 100) t.assert_log('Host lookup failed', testlog, 100) + + _test( + {}, + { NVIM_LISTEN_ADDRESS = in_use }, + ('nvim.*: Failed $NVIM_LISTEN_ADDRESS: [^:]+ already [^:]+: "%s"'):format(vim.pesc(in_use)) + ) + _test({}, { NVIM_LISTEN_ADDRESS = '/' }, 'nvim.*: Failed $NVIM_LISTEN_ADDRESS: [^:]+: "/"') + _test( + {}, + { NVIM_LISTEN_ADDRESS = 'https://example.com' }, + ('nvim.*: Failed $NVIM_LISTEN_ADDRESS: %s: "https://example.com"'):format( + is_os('mac') and 'unknown node or service' or 'service not available for socket type' + ) + ) end) it('sets v:servername, overrides $NVIM_LISTEN_ADDRESS', function() -- cgit From 8a2aec99748229ad9d1e12c1cbc0768d063e8eed Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 8 Sep 2024 12:48:32 -0700 Subject: fix(startup): server fails if $NVIM_APPNAME is relative dir #30310 Problem: If $NVIM_APPNAME is a relative dir path, Nvim fails to start its primary/default server, and `v:servername` is empty. Root cause is d34c64e342dfba9248d1055e702d02620a1b31a8, but this wasn't noticed until 96128a5076b7 started reporting the error more loudly. Solution: - `server_address_new`: replace slashes "/" in the appname before using it as a servername. - `vim_mktempdir`: always prefer the system-wide top-level "nvim.user/" directory. That isn't intended to be specific to NVIM_APPNAME; rather, each *subdirectory* ("nvim.user/xxx") is owned by each Nvim instance. Nvim "apps" can be identified by the server socket(s) stored in those per-Nvim subdirs. fix #30256 --- test/functional/vimscript/server_spec.lua | 278 ------------------------------ 1 file changed, 278 deletions(-) delete mode 100644 test/functional/vimscript/server_spec.lua (limited to 'test/functional/vimscript') diff --git a/test/functional/vimscript/server_spec.lua b/test/functional/vimscript/server_spec.lua deleted file mode 100644 index 85a179b3d5..0000000000 --- a/test/functional/vimscript/server_spec.lua +++ /dev/null @@ -1,278 +0,0 @@ -local t = require('test.testutil') -local n = require('test.functional.testnvim')() - -local eq, neq, eval = t.eq, t.neq, n.eval -local clear, fn, api = n.clear, n.fn, n.api -local matches = t.matches -local pcall_err = t.pcall_err -local check_close = n.check_close -local mkdir = t.mkdir -local rmdir = n.rmdir -local is_os = t.is_os - -local testlog = 'Xtest-server-log' - -local function clear_serverlist() - for _, server in pairs(fn.serverlist()) do - fn.serverstop(server) - end -end - -after_each(function() - check_close() - os.remove(testlog) -end) - -before_each(function() - os.remove(testlog) -end) - -describe('server', function() - it('serverstart() stores sockets in $XDG_RUNTIME_DIR', function() - local dir = 'Xtest_xdg_run' - mkdir(dir) - finally(function() - rmdir(dir) - end) - clear({ env = { XDG_RUNTIME_DIR = dir } }) - matches(dir, fn.stdpath('run')) - if not is_os('win') then - matches(dir, fn.serverstart()) - end - end) - - it('broken $XDG_RUNTIME_DIR is not fatal #30282', function() - clear { - args_rm = { '--listen' }, - env = { NVIM_LOG_FILE = testlog, XDG_RUNTIME_DIR = '/non-existent-dir/subdir//' }, - } - - if is_os('win') then - -- Windows pipes have a special namespace and thus aren't decided by $XDG_RUNTIME_DIR. - matches('nvim', api.nvim_get_vvar('servername')) - else - eq('', api.nvim_get_vvar('servername')) - t.assert_log('Failed to start server%: no such file or directory', testlog, 100) - end - end) - - it('serverstart(), serverstop() does not set $NVIM', function() - clear() - local s = eval('serverstart()') - assert(s ~= nil and s:len() > 0, 'serverstart() returned empty') - eq('', eval('$NVIM')) - eq('', eval('$NVIM_LISTEN_ADDRESS')) - eq(1, eval("serverstop('" .. s .. "')")) - eq('', eval('$NVIM_LISTEN_ADDRESS')) - end) - - it('sets v:servername at startup or if all servers were stopped', function() - clear() - local initial_server = api.nvim_get_vvar('servername') - assert(initial_server ~= nil and initial_server:len() > 0, 'v:servername was not initialized') - - -- v:servername is readonly so we cannot unset it--but we can test that it - -- does not get set again thereafter. - local s = fn.serverstart() - assert(s ~= nil and s:len() > 0, 'serverstart() returned empty') - neq(initial_server, s) - - -- serverstop() does _not_ modify v:servername... - eq(1, fn.serverstop(s)) - eq(initial_server, api.nvim_get_vvar('servername')) - - -- ...unless we stop _all_ servers. - eq(1, fn.serverstop(fn.serverlist()[1])) - eq('', api.nvim_get_vvar('servername')) - - -- v:servername and $NVIM take the next available server. - local servername = ( - is_os('win') and [[\\.\pipe\Xtest-functional-server-pipe]] - or './Xtest-functional-server-socket' - ) - fn.serverstart(servername) - eq(servername, api.nvim_get_vvar('servername')) - -- Not set in the current process, only in children. - eq('', eval('$NVIM')) - end) - - it('serverstop() returns false for invalid input', function() - clear { - args_rm = { '--listen' }, - env = { - NVIM_LOG_FILE = testlog, - NVIM_LISTEN_ADDRESS = '', - }, - } - eq(0, eval("serverstop('')")) - eq(0, eval("serverstop('bogus-socket-name')")) - t.assert_log('Not listening on bogus%-socket%-name', testlog, 10) - end) - - it('parses endpoints', function() - clear { - args_rm = { '--listen' }, - env = { - NVIM_LOG_FILE = testlog, - NVIM_LISTEN_ADDRESS = '', - }, - } - clear_serverlist() - eq({}, fn.serverlist()) - - local s = fn.serverstart('127.0.0.1:0') -- assign random port - if #s > 0 then - matches('127.0.0.1:%d+', s) - eq(s, fn.serverlist()[1]) - clear_serverlist() - end - - s = fn.serverstart('127.0.0.1:') -- assign random port - if #s > 0 then - matches('127.0.0.1:%d+', s) - eq(s, fn.serverlist()[1]) - clear_serverlist() - end - - local expected = {} - local v4 = '127.0.0.1:12345' - local status, _ = pcall(fn.serverstart, v4) - if status then - table.insert(expected, v4) - pcall(fn.serverstart, v4) -- exists already; ignore - t.assert_log('Failed to start server: address already in use: 127%.0%.0%.1', testlog, 10) - end - - local v6 = '::1:12345' - status, _ = pcall(fn.serverstart, v6) - if status then - table.insert(expected, v6) - pcall(fn.serverstart, v6) -- exists already; ignore - t.assert_log('Failed to start server: address already in use: ::1', testlog, 10) - end - eq(expected, fn.serverlist()) - clear_serverlist() - - -- Address without slashes is a "name" which is appended to a generated path. #8519 - matches([[.*[/\\]xtest1%.2%.3%.4[^/\\]*]], fn.serverstart('xtest1.2.3.4')) - clear_serverlist() - - eq('Vim:Failed to start server: invalid argument', pcall_err(fn.serverstart, '127.0.0.1:65536')) -- invalid port - eq({}, fn.serverlist()) - end) - - it('serverlist() returns the list of servers', function() - clear() - -- There should already be at least one server. - local _n = eval('len(serverlist())') - - -- Add some servers. - local servs = ( - is_os('win') and { [[\\.\pipe\Xtest-pipe0934]], [[\\.\pipe\Xtest-pipe4324]] } - or { [[./Xtest-pipe0934]], [[./Xtest-pipe4324]] } - ) - for _, s in ipairs(servs) do - eq(s, eval("serverstart('" .. s .. "')")) - end - - local new_servs = eval('serverlist()') - - -- Exactly #servs servers should be added. - eq(_n + #servs, #new_servs) - -- The new servers should be at the end of the list. - for i = 1, #servs do - eq(servs[i], new_servs[i + _n]) - eq(1, eval("serverstop('" .. servs[i] .. "')")) - end - -- After serverstop() the servers should NOT be in the list. - eq(_n, eval('len(serverlist())')) - end) -end) - -describe('startup --listen', function() - -- Tests Nvim output when failing to start, with and without "--headless". - -- TODO(justinmk): clear() should have a way to get stdout if Nvim fails to start. - local function _test(args, env, expected) - local function run(cmd) - return n.exec_lua(function(cmd_, env_) - return vim - .system(cmd_, { - text = true, - env = vim.tbl_extend( - 'force', - -- Avoid noise in the logs; we expect failures for these tests. - { NVIM_LOG_FILE = testlog }, - env_ or {} - ), - }) - :wait() - end, cmd, env) --[[@as vim.SystemCompleted]] - end - - local cmd = vim.list_extend({ n.nvim_prog, '+qall!', '--headless' }, args) - local r = run(cmd) - eq(1, r.code) - matches(expected, (r.stderr .. r.stdout):gsub('\\n', ' ')) - - if is_os('win') then - return -- On Windows, output without --headless is garbage. - end - table.remove(cmd, 3) -- Remove '--headless'. - assert(not vim.tbl_contains(cmd, '--headless')) - r = run(cmd) - eq(1, r.code) - matches(expected, (r.stderr .. r.stdout):gsub('\\n', ' ')) - end - - it('validates', function() - clear { env = { NVIM_LOG_FILE = testlog } } - local in_use = n.eval('v:servername') ---@type string Address already used by another server. - - t.assert_nolog('Failed to start server', testlog, 100) - t.assert_nolog('Host lookup failed', testlog, 100) - - _test({ '--listen' }, nil, 'nvim.*: Argument missing after: "%-%-listen"') - _test({ '--listen2' }, nil, 'nvim.*: Garbage after option argument: "%-%-listen2"') - _test( - { '--listen', in_use }, - nil, - ('nvim.*: Failed to %%-%%-listen: [^:]+ already [^:]+: "%s"'):format(vim.pesc(in_use)) - ) - _test({ '--listen', '/' }, nil, 'nvim.*: Failed to %-%-listen: [^:]+: "/"') - _test( - { '--listen', 'https://example.com' }, - nil, - ('nvim.*: Failed to %%-%%-listen: %s: "https://example.com"'):format( - is_os('mac') and 'unknown node or service' or 'service not available for socket type' - ) - ) - - t.assert_log('Failed to start server', testlog, 100) - t.assert_log('Host lookup failed', testlog, 100) - - _test( - {}, - { NVIM_LISTEN_ADDRESS = in_use }, - ('nvim.*: Failed $NVIM_LISTEN_ADDRESS: [^:]+ already [^:]+: "%s"'):format(vim.pesc(in_use)) - ) - _test({}, { NVIM_LISTEN_ADDRESS = '/' }, 'nvim.*: Failed $NVIM_LISTEN_ADDRESS: [^:]+: "/"') - _test( - {}, - { NVIM_LISTEN_ADDRESS = 'https://example.com' }, - ('nvim.*: Failed $NVIM_LISTEN_ADDRESS: %s: "https://example.com"'):format( - is_os('mac') and 'unknown node or service' or 'service not available for socket type' - ) - ) - end) - - it('sets v:servername, overrides $NVIM_LISTEN_ADDRESS', function() - local addr = (is_os('win') and [[\\.\pipe\Xtest-listen-pipe]] or './Xtest-listen-pipe') - clear({ env = { NVIM_LISTEN_ADDRESS = './Xtest-env-pipe' }, args = { '--listen', addr } }) - eq('', eval('$NVIM_LISTEN_ADDRESS')) -- Cleared on startup. - eq(addr, api.nvim_get_vvar('servername')) - - -- Address without slashes is a "name" which is appended to a generated path. #8519 - clear({ args = { '--listen', 'test-name' } }) - matches([[.*[/\\]test%-name[^/\\]*]], api.nvim_get_vvar('servername')) - end) -end) -- cgit From ed832b9ddf45705abe9d7f4a50cedc27072c8e16 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Sun, 8 Sep 2024 21:29:20 +0200 Subject: refactor(test): rename alter_slashes, invert its behavior - `alter_slashes` belongs in `testutil.lua`, not `testnvim.lua`. - `alter_slashes` is an unusual name. Rename it to `fix_slashes`. - invert its behavior, to emphasize that `/` slashes are the preferred, pervasive convention, not `\` slashes. --- test/functional/vimscript/fnamemodify_spec.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'test/functional/vimscript') diff --git a/test/functional/vimscript/fnamemodify_spec.lua b/test/functional/vimscript/fnamemodify_spec.lua index 51b1e8489a..f2cee9b83e 100644 --- a/test/functional/vimscript/fnamemodify_spec.lua +++ b/test/functional/vimscript/fnamemodify_spec.lua @@ -7,11 +7,10 @@ local fnamemodify = n.fn.fnamemodify local getcwd = n.fn.getcwd local command = n.command local write_file = t.write_file -local alter_slashes = n.alter_slashes local is_os = t.is_os local function eq_slashconvert(expected, got) - eq(alter_slashes(expected), alter_slashes(got)) + eq(t.fix_slashes(expected), t.fix_slashes(got)) end describe('fnamemodify()', function() -- cgit From 737f58e23230ea14f1648ac1fc7f442ea0f8563c Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Fri, 20 Sep 2024 07:34:50 +0200 Subject: refactor(api)!: rename Dictionary => Dict In the api_info() output: :new|put =map(filter(api_info().functions, '!has_key(v:val,''deprecated_since'')'), 'v:val') ... {'return_type': 'ArrayOf(Integer, 2)', 'name': 'nvim_win_get_position', 'method': v:true, 'parameters': [['Window', 'window']], 'since': 1} The `ArrayOf(Integer, 2)` return type didn't break clients when we added it, which is evidence that clients don't use the `return_type` field, thus renaming Dictionary => Dict in api_info() is not (in practice) a breaking change. --- test/functional/vimscript/changedtick_spec.lua | 4 ++-- test/functional/vimscript/ctx_functions_spec.lua | 6 +++--- test/functional/vimscript/input_spec.lua | 8 ++++---- test/functional/vimscript/json_functions_spec.lua | 2 +- test/functional/vimscript/map_functions_spec.lua | 4 ++-- test/functional/vimscript/msgpack_functions_spec.lua | 14 +++++++------- test/functional/vimscript/string_spec.lua | 8 ++++---- 7 files changed, 23 insertions(+), 23 deletions(-) (limited to 'test/functional/vimscript') diff --git a/test/functional/vimscript/changedtick_spec.lua b/test/functional/vimscript/changedtick_spec.lua index baea53a700..ef9d6b1a69 100644 --- a/test/functional/vimscript/changedtick_spec.lua +++ b/test/functional/vimscript/changedtick_spec.lua @@ -38,7 +38,7 @@ describe('b:changedtick', function() -- Somehow undo counts as two changes eq(5, changedtick()) end) - it('is present in b: dictionary', function() + it('is present in b: dict', function() eq(2, changedtick()) command('let d = b:') eq(2, api.nvim_get_var('d').changedtick) @@ -168,7 +168,7 @@ describe('b:changedtick', function() ) eq(2, changedtick()) end) - it('does not inherit VAR_FIXED when copying dictionary over', function() + it('does not inherit VAR_FIXED when copying dict over', function() eq(2, changedtick()) eq('', exec_capture('let d1 = copy(b:)|let d1.changedtick = 42')) eq('', exec_capture('let d2 = copy(b:)|unlet d2.changedtick')) diff --git a/test/functional/vimscript/ctx_functions_spec.lua b/test/functional/vimscript/ctx_functions_spec.lua index 5e9a803b5d..873e4f820d 100644 --- a/test/functional/vimscript/ctx_functions_spec.lua +++ b/test/functional/vimscript/ctx_functions_spec.lua @@ -295,7 +295,7 @@ describe('context functions', function() eq(outofbounds, pcall_err(call, 'ctxget', 0)) end) - it('returns context dictionary at index in context stack', function() + it('returns context dict at index in context stack', function() feed('i123ddddddqahjklq') command('edit! ' .. fname1) feed('G') @@ -404,7 +404,7 @@ describe('context functions', function() eq(outofbounds, pcall_err(call, 'ctxset', { dummy = 1 }, 0)) end) - it('errors when context dictionary is invalid', function() + it('errors when context dict is invalid', function() call('ctxpush') eq( 'Vim:E474: Failed to convert list to msgpack string buffer', @@ -412,7 +412,7 @@ describe('context functions', function() ) end) - it('sets context dictionary at index in context stack', function() + it('sets context dict at index in context stack', function() api.nvim_set_var('one', 1) api.nvim_set_var('Two', 2) api.nvim_set_var('THREE', 3) diff --git a/test/functional/vimscript/input_spec.lua b/test/functional/vimscript/input_spec.lua index 552ae6d5cc..0b774404eb 100644 --- a/test/functional/vimscript/input_spec.lua +++ b/test/functional/vimscript/input_spec.lua @@ -108,7 +108,7 @@ describe('input()', function() {T:1}^ | ]]) end) - it('allows unequal numeric values when using {opts} dictionary', function() + it('allows unequal numeric values when using {opts} dict', function() command('echohl Test') api.nvim_set_var('opts', { prompt = 1, default = 2, cancelreturn = 3 }) feed([[:echo input(opts)]]) @@ -164,7 +164,7 @@ describe('input()', function() reset = true, } end) - it('allows omitting everything with dictionary argument', function() + it('allows omitting everything with dict argument', function() command('echohl Test') feed([[:call input({})]]) screen:expect([[ @@ -290,7 +290,7 @@ describe('inputdialog()', function() {T:1}^ | ]]) end) - it('allows unequal numeric values when using {opts} dictionary', function() + it('allows unequal numeric values when using {opts} dict', function() command('echohl Test') api.nvim_set_var('opts', { prompt = 1, default = 2, cancelreturn = 3 }) feed([[:echo input(opts)]]) @@ -346,7 +346,7 @@ describe('inputdialog()', function() reset = true, } end) - it('allows omitting everything with dictionary argument', function() + it('allows omitting everything with dict argument', function() command('echohl Test') feed(':echo inputdialog({})') screen:expect([[ diff --git a/test/functional/vimscript/json_functions_spec.lua b/test/functional/vimscript/json_functions_spec.lua index c6e0e75bdc..895e722e96 100644 --- a/test/functional/vimscript/json_functions_spec.lua +++ b/test/functional/vimscript/json_functions_spec.lua @@ -911,7 +911,7 @@ describe('json_encode() function', function() eq('[]', eval('json_encode(v:_null_list)')) end) - it('can dump NULL dictionary', function() + it('can dump NULL dict', function() eq('{}', eval('json_encode(v:_null_dict)')) end) diff --git a/test/functional/vimscript/map_functions_spec.lua b/test/functional/vimscript/map_functions_spec.lua index 44be5b3185..b69b7dbd57 100644 --- a/test/functional/vimscript/map_functions_spec.lua +++ b/test/functional/vimscript/map_functions_spec.lua @@ -36,7 +36,7 @@ describe('maparg()', function() lnum = 0, } - it('returns a dictionary', function() + it('returns a dict', function() command('nnoremap foo bar') eq('bar', fn.maparg('foo')) eq(foo_bar_map_table, fn.maparg('foo', 'n', false, true)) @@ -54,7 +54,7 @@ describe('maparg()', function() eq('', fn.maparg('not a mapping')) end) - it('returns an empty dictionary when no map is present and dict is requested', function() + it('returns an empty dict when no map is present and dict is requested', function() eq({}, fn.maparg('not a mapping', 'n', false, true)) end) diff --git a/test/functional/vimscript/msgpack_functions_spec.lua b/test/functional/vimscript/msgpack_functions_spec.lua index 6b77811e35..d2011f9fec 100644 --- a/test/functional/vimscript/msgpack_functions_spec.lua +++ b/test/functional/vimscript/msgpack_functions_spec.lua @@ -437,16 +437,16 @@ describe('msgpackparse() function', function() parse_eq({ 'ab' }, { '\196\002ab' }) end) - it('restores FIXEXT1 as special dictionary', function() + it('restores FIXEXT1 as special dict', function() parse_eq({ { _TYPE = {}, _VAL = { 0x10, { '', '' } } } }, { '\212\016', '' }) eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.ext')) end) - it('restores MAP with BIN key as ordinary dictionary', function() + it('restores MAP with BIN key as ordinary dict', function() parse_eq({ { a = '' } }, { '\129\196\001a\196\n' }) end) - it('restores MAP with duplicate STR keys as special dictionary', function() + it('restores MAP with duplicate STR keys as special dict', function() command('let dumped = ["\\x82\\xA1a\\xC4\\n\\xA1a\\xC4\\n"]') -- FIXME Internal error bug, can't use parse_eq() here command('silent! let parsed = msgpackparse(dumped)') @@ -464,7 +464,7 @@ describe('msgpackparse() function', function() eq(eval('v:t_string'), eval('type(g:parsed[0]._VAL[1][0])')) end) - it('restores MAP with MAP key as special dictionary', function() + it('restores MAP with MAP key as special dict', function() parse_eq({ { _TYPE = {}, _VAL = { { {}, '' } } } }, { '\129\128\196\n' }) eq(1, eval('g:parsed[0]._TYPE is v:msgpack_types.map')) end) @@ -510,7 +510,7 @@ describe('msgpackparse() function', function() ) end) - it('fails to parse a dictionary', function() + it('fails to parse a dict', function() eq( 'Vim(call):E899: Argument of msgpackparse() must be a List or Blob', exc_exec('call msgpackparse({})') @@ -764,7 +764,7 @@ describe('msgpackdump() function', function() ) end) - it('fails to dump a dictionary', function() + it('fails to dump a dict', function() eq('Vim(call):E686: Argument of msgpackdump() must be a List', exc_exec('call msgpackdump({})')) end) @@ -813,7 +813,7 @@ describe('msgpackdump() function', function() eq({ '\144' }, eval('msgpackdump([v:_null_list])')) end) - it('can dump NULL dictionary', function() + it('can dump NULL dict', function() eq({ '\128' }, eval('msgpackdump([v:_null_dict])')) end) end) diff --git a/test/functional/vimscript/string_spec.lua b/test/functional/vimscript/string_spec.lua index 32aa04c0d0..4df9104e1e 100644 --- a/test/functional/vimscript/string_spec.lua +++ b/test/functional/vimscript/string_spec.lua @@ -170,9 +170,9 @@ describe('string() function', function() ) end) - it('does not show errors when dumping partials referencing the same dictionary', function() + it('does not show errors when dumping partials referencing the same dict', function() command('let d = {}') - -- Regression for “eval/typval_encode: Dump empty dictionary before + -- Regression for “eval/typval_encode: Dump empty dict before -- checking for refcycle”, results in error. eq( "[function('tr', {}), function('tr', {})]", @@ -256,7 +256,7 @@ describe('string() function', function() end) describe('used to represent dictionaries', function() - it('dumps empty dictionary', function() + it('dumps empty dict', function() eq('{}', eval('string({})')) end) @@ -267,7 +267,7 @@ describe('string() function', function() eq("[{}, function('tr', {})]", eval('string([d, function("tr", d)])')) end) - it('dumps non-empty dictionary', function() + it('dumps non-empty dict', function() eq("{'t''est': 1}", fn.string({ ["t'est"] = 1 })) end) -- cgit