1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
|
local helpers = require('test.functional.helpers')(after_each)
local eq = helpers.eq
local clear = helpers.clear
local command = helpers.command
local eval = helpers.eval
local api = helpers.api
local exec = helpers.exec
local exec_capture = helpers.exec_capture
local expect_exit = helpers.expect_exit
local source = helpers.source
local testprg = helpers.testprg
before_each(clear)
describe(':let', function()
it('correctly lists variables with curly-braces', function()
api.nvim_set_var('v', { 0 })
eq('v [0]', exec_capture('let {"v"}'))
end)
it('correctly lists variables with subscript', function()
api.nvim_set_var('v', { 0 })
eq('v[0] #0', exec_capture('let v[0]'))
eq('g:["v"][0] #0', exec_capture('let g:["v"][0]'))
eq('{"g:"}["v"][0] #0', exec_capture('let {"g:"}["v"][0]'))
end)
it(':unlet self-referencing node in a List graph #6070', function()
-- :unlet-ing a self-referencing List must not allow GC on indirectly
-- referenced in-scope Lists. Before #6070 this caused use-after-free.
expect_exit(
1000,
source,
[=[
let [l1, l2] = [[], []]
echo 'l1:' . id(l1)
echo 'l2:' . id(l2)
echo ''
let [l3, l4] = [[], []]
call add(l4, l4)
call add(l4, l3)
call add(l3, 1)
call add(l2, l2)
call add(l2, l1)
call add(l1, 1)
unlet l2
unlet l4
call garbagecollect(1)
call feedkeys(":\e:echo l1 l3\n:echo 42\n:cq\n", "t")
]=]
)
end)
it('multibyte env var #8398 #9267', function()
command("let $NVIM_TEST_LET = 'AìaB'")
eq('AìaB', eval('$NVIM_TEST_LET'))
command("let $NVIM_TEST_LET = 'AaあB'")
eq('AaあB', eval('$NVIM_TEST_LET'))
local mbyte = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ
.ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ
.ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]]
command("let $NVIM_TEST_LET = '" .. mbyte .. "'")
eq(mbyte, eval('$NVIM_TEST_LET'))
end)
it('multibyte env var to child process #8398 #9267', function()
local cmd_get_child_env = ("let g:env_from_child = system(['%s', 'NVIM_TEST_LET'])"):format(
testprg('printenv-test')
)
command("let $NVIM_TEST_LET = 'AìaB'")
command(cmd_get_child_env)
eq(eval('$NVIM_TEST_LET'), eval('g:env_from_child'))
command("let $NVIM_TEST_LET = 'AaあB'")
command(cmd_get_child_env)
eq(eval('$NVIM_TEST_LET'), eval('g:env_from_child'))
local mbyte = [[\p* .ม .ม .ม .ม่ .ม่ .ม่ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ ֹֻ
.ֹֻ .ֹֻ .ֹֻ ֹֻ ֹֻ ֹֻ .ֹֻ .ֹֻ .ֹֻ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹ ֹ ֹ .ֹ .ֹ .ֹ ֹֻ ֹֻ
.ֹֻ .ֹֻ .ֹֻ a a a ca ca ca à à à]]
command("let $NVIM_TEST_LET = '" .. mbyte .. "'")
command(cmd_get_child_env)
eq(eval('$NVIM_TEST_LET'), eval('g:env_from_child'))
end)
it('release of list assigned to l: variable does not trigger assertion #12387, #12430', function()
source([[
func! s:f()
let l:x = [1]
let g:x = l:
endfunc
for _ in range(2)
call s:f()
endfor
call garbagecollect()
call feedkeys('i', 't')
]])
eq(1, eval('1'))
end)
it('can apply operator to boolean option', function()
eq(true, api.nvim_get_option_value('equalalways', {}))
command('let &equalalways -= 1')
eq(false, api.nvim_get_option_value('equalalways', {}))
command('let &equalalways += 1')
eq(true, api.nvim_get_option_value('equalalways', {}))
command('let &equalalways *= 1')
eq(true, api.nvim_get_option_value('equalalways', {}))
command('let &equalalways /= 1')
eq(true, api.nvim_get_option_value('equalalways', {}))
command('let &equalalways %= 1')
eq(false, api.nvim_get_option_value('equalalways', {}))
end)
end)
describe(':let and :const', function()
it('have the same output when called without arguments', function()
eq(exec_capture('let'), exec_capture('const'))
end)
it('can be used in sandbox', function()
exec([[
func Func()
let l:foo = 'foo'
const l:bar = 'bar'
endfunc
sandbox call Func()
]])
end)
end)
|