mirror of
https://github.com/neovim/neovim.git
synced 2025-09-12 22:38:16 +00:00
eval: add v:_null_string
Replacement for Vim's test_null_string(). Vim uses it to verify that its codebase handles null strings. Preparation for the Test_null_list() in patch v8.2.1822. Use v:_null_string, not non-existent env var, for null string tests. Mention v:_null_string in id() because id(v:_null_string) returns (nil).
This commit is contained in:
@@ -5563,13 +5563,14 @@ id({expr}) *id()*
|
|||||||
Returns a |String| which is a unique identifier of the
|
Returns a |String| which is a unique identifier of the
|
||||||
container type (|List|, |Dict| and |Partial|). It is
|
container type (|List|, |Dict| and |Partial|). It is
|
||||||
guaranteed that for the mentioned types `id(v1) ==# id(v2)`
|
guaranteed that for the mentioned types `id(v1) ==# id(v2)`
|
||||||
returns true iff `type(v1) == type(v2) && v1 is v2` (note:
|
returns true iff `type(v1) == type(v2) && v1 is v2`.
|
||||||
|v:_null_list| and |v:_null_dict| have the same `id()` with
|
Note that |v:_null_string|, |v:_null_list|, and |v:_null_dict|
|
||||||
different types because they are internally represented as
|
have the same `id()` with different types because they are
|
||||||
a NULL pointers). Currently `id()` returns a hexadecimal
|
internally represented as a NULL pointers. `id()` returns a
|
||||||
representanion of the pointers to the containers (i.e. like
|
hexadecimal representanion of the pointers to the containers
|
||||||
`0x994a40`), same as `printf("%p", {expr})`, but it is advised
|
(i.e. like `0x994a40`), same as `printf("%p", {expr})`,
|
||||||
against counting on exact format of return value.
|
but it is advised against counting on the exact format of
|
||||||
|
return value.
|
||||||
|
|
||||||
It is not guaranteed that `id(no_longer_existing_container)`
|
It is not guaranteed that `id(no_longer_existing_container)`
|
||||||
will not be equal to some other `id()`: new containers may
|
will not be equal to some other `id()`: new containers may
|
||||||
|
@@ -229,6 +229,7 @@ static struct vimvar {
|
|||||||
// Neovim
|
// Neovim
|
||||||
VV(VV_STDERR, "stderr", VAR_NUMBER, VV_RO),
|
VV(VV_STDERR, "stderr", VAR_NUMBER, VV_RO),
|
||||||
VV(VV_MSGPACK_TYPES, "msgpack_types", VAR_DICT, VV_RO),
|
VV(VV_MSGPACK_TYPES, "msgpack_types", VAR_DICT, VV_RO),
|
||||||
|
VV(VV__NULL_STRING, "_null_string", VAR_STRING, VV_RO),
|
||||||
VV(VV__NULL_LIST, "_null_list", VAR_LIST, VV_RO),
|
VV(VV__NULL_LIST, "_null_list", VAR_LIST, VV_RO),
|
||||||
VV(VV__NULL_DICT, "_null_dict", VAR_DICT, VV_RO),
|
VV(VV__NULL_DICT, "_null_dict", VAR_DICT, VV_RO),
|
||||||
VV(VV_LUA, "lua", VAR_PARTIAL, VV_RO),
|
VV(VV_LUA, "lua", VAR_PARTIAL, VV_RO),
|
||||||
|
@@ -158,6 +158,7 @@ typedef enum {
|
|||||||
// Neovim
|
// Neovim
|
||||||
VV_STDERR,
|
VV_STDERR,
|
||||||
VV_MSGPACK_TYPES,
|
VV_MSGPACK_TYPES,
|
||||||
|
VV__NULL_STRING, // String with NULL value. For test purposes only.
|
||||||
VV__NULL_LIST, // List with NULL value. For test purposes only.
|
VV__NULL_LIST, // List with NULL value. For test purposes only.
|
||||||
VV__NULL_DICT, // Dictionary with NULL value. For test purposes only.
|
VV__NULL_DICT, // Dictionary with NULL value. For test purposes only.
|
||||||
VV_LUA,
|
VV_LUA,
|
||||||
|
@@ -14,7 +14,8 @@ describe('NULL', function()
|
|||||||
clear()
|
clear()
|
||||||
command('let L = v:_null_list')
|
command('let L = v:_null_list')
|
||||||
command('let D = v:_null_dict')
|
command('let D = v:_null_dict')
|
||||||
command('let S = $XXX_NONEXISTENT_VAR_XXX')
|
command('let S = v:_null_string')
|
||||||
|
command('let V = $XXX_NONEXISTENT_VAR_XXX')
|
||||||
end)
|
end)
|
||||||
local tmpfname = 'Xtest-functional-viml-null'
|
local tmpfname = 'Xtest-functional-viml-null'
|
||||||
after_each(function()
|
after_each(function()
|
||||||
@@ -129,6 +130,7 @@ describe('NULL', function()
|
|||||||
null_expr_test('is accepted by setloclist()', 'setloclist(1, L)', 0, 0)
|
null_expr_test('is accepted by setloclist()', 'setloclist(1, L)', 0, 0)
|
||||||
null_test('is accepted by :cexpr', 'cexpr L', 0)
|
null_test('is accepted by :cexpr', 'cexpr L', 0)
|
||||||
null_test('is accepted by :lexpr', 'lexpr L', 0)
|
null_test('is accepted by :lexpr', 'lexpr L', 0)
|
||||||
|
null_expr_test('does not crash execute()', 'execute(L)', 0, '')
|
||||||
end)
|
end)
|
||||||
describe('dict', function()
|
describe('dict', function()
|
||||||
it('does not crash when indexing NULL dict', function()
|
it('does not crash when indexing NULL dict', function()
|
||||||
@@ -142,4 +144,26 @@ describe('NULL', function()
|
|||||||
null_expr_test('makes map() return v:_null_dict', 'map(D, "v:val") is# D', 0, 1)
|
null_expr_test('makes map() return v:_null_dict', 'map(D, "v:val") is# D', 0, 1)
|
||||||
null_expr_test('makes filter() return v:_null_dict', 'filter(D, "1") is# D', 0, 1)
|
null_expr_test('makes filter() return v:_null_dict', 'filter(D, "1") is# D', 0, 1)
|
||||||
end)
|
end)
|
||||||
|
describe('string', function()
|
||||||
|
null_test('does not crash :echomsg', 'echomsg S', 0)
|
||||||
|
null_test('does not crash :execute', 'execute S', 0)
|
||||||
|
null_expr_test('does not crash execute()', 'execute(S)', 0, '')
|
||||||
|
null_expr_test('makes executable() error out', 'executable(S)', 'E928: String required', 0)
|
||||||
|
null_expr_test('does not crash filereadable()', 'filereadable(S)', 0, 0)
|
||||||
|
null_expr_test('does not crash filewritable()', 'filewritable(S)', 0, 0)
|
||||||
|
null_expr_test('does not crash fnamemodify()', 'fnamemodify(S, S)', 0, '')
|
||||||
|
null_expr_test('does not crash getfperm()', 'getfperm(S)', 0, '')
|
||||||
|
null_expr_test('does not crash getfsize()', 'getfsize(S)', 0, -1)
|
||||||
|
null_expr_test('does not crash getftime()', 'getftime(S)', 0, -1)
|
||||||
|
null_expr_test('does not crash getftype()', 'getftype(S)', 0, '')
|
||||||
|
null_expr_test('does not crash glob()', 'glob(S)', 0, '')
|
||||||
|
null_expr_test('does not crash globpath()', 'globpath(S, S)', 0, '')
|
||||||
|
null_expr_test('does not crash mkdir()', 'mkdir(S)', 0, 0)
|
||||||
|
null_expr_test('does not crash sort()', 'sort(["b", S, "a"])', 0, {'', 'a', 'b'})
|
||||||
|
null_expr_test('does not crash split()', 'split(S)', 0, {})
|
||||||
|
|
||||||
|
null_test('can be used to set an option', 'let &grepprg = S', 0)
|
||||||
|
|
||||||
|
null_expr_test('is equal to non-existent variable', 'S == V', 0, 1)
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
@@ -59,6 +59,16 @@ describe('writefile()', function()
|
|||||||
eq('\n', read_file(fname))
|
eq('\n', read_file(fname))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('writes list with a null string to a file', function()
|
||||||
|
eq(0, exc_exec(
|
||||||
|
('call writefile([v:_null_string], "%s", "b")'):format(
|
||||||
|
fname)))
|
||||||
|
eq('', read_file(fname))
|
||||||
|
eq(0, exc_exec(('call writefile([v:_null_string], "%s")'):format(
|
||||||
|
fname)))
|
||||||
|
eq('\n', read_file(fname))
|
||||||
|
end)
|
||||||
|
|
||||||
it('appends to a file', function()
|
it('appends to a file', function()
|
||||||
eq(nil, read_file(fname))
|
eq(nil, read_file(fname))
|
||||||
eq(0, funcs.writefile({'abc', 'def', 'ghi'}, fname))
|
eq(0, funcs.writefile({'abc', 'def', 'ghi'}, fname))
|
||||||
|
Reference in New Issue
Block a user