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