1" Tests for Lua. 2 3source check.vim 4 5" This test also works without the lua feature. 6func Test_skip_lua() 7 if 0 8 lua print("Not executed") 9 endif 10endfunc 11 12CheckFeature lua 13CheckFeature float 14 15" Depending on the lua version, the error messages are different. 16let [s:major, s:minor, s:patch] = luaeval('vim.lua_version')->split('\.')->map({-> str2nr(v:val)}) 17let s:lua_53_or_later = 0 18let s:lua_543_or_later = 0 19if (s:major == 5 && s:minor >= 3) || s:major > 5 20 let s:lua_53_or_later = 1 21 if (s:major == 5 22 \ && ((s:minor == 4 && s:patch >= 3) || s:minor > 4)) 23 \ || s:major > 5 24 let s:lua_543_or_later = 1 25 endif 26endif 27 28func TearDown() 29 " Run garbage collection after each test to exercise luaV_setref(). 30 call test_garbagecollect_now() 31endfunc 32 33" Check that switching to another buffer does not trigger ml_get error. 34func Test_lua_command_new_no_ml_get_error() 35 new 36 let wincount = winnr('$') 37 call setline(1, ['one', 'two', 'three']) 38 luado vim.command("new") 39 call assert_equal(wincount + 1, winnr('$')) 40 %bwipe! 41endfunc 42 43" Test vim.command() 44func Test_lua_command() 45 new 46 call setline(1, ['one', 'two', 'three']) 47 luado vim.command("1,2d_") 48 call assert_equal(['three'], getline(1, '$')) 49 bwipe! 50endfunc 51 52func Test_lua_luado() 53 new 54 call setline(1, ['one', 'two']) 55 luado return(linenr) 56 call assert_equal(['1', '2'], getline(1, '$')) 57 close! 58 59 " Error cases 60 call assert_fails('luado string.format()', 61 \ "[string \"vim chunk\"]:1: bad argument #1 to 'format' (string expected, got no value)") 62 if s:lua_543_or_later 63 let msg = "[string \"vim chunk\"]:1: global 'func' is not callable (a nil value)" 64 elseif s:lua_53_or_later 65 let msg = "[string \"vim chunk\"]:1: attempt to call a nil value (global 'func')" 66 else 67 let msg = "[string \"vim chunk\"]:1: attempt to call global 'func' (a nil value)" 68 endif 69 call assert_fails('luado func()', msg) 70 call assert_fails('luado error("failed")', "[string \"vim chunk\"]:1: failed") 71endfunc 72 73" Test vim.eval() 74func Test_lua_eval() 75 " lua.eval with a number 76 lua v = vim.eval('123') 77 call assert_equal('number', luaeval('vim.type(v)')) 78 call assert_equal(123, luaeval('v')) 79 80 " lua.eval with a string 81 lua v = vim.eval('"abc"') 82 call assert_equal('string', 'vim.type(v)'->luaeval()) 83 call assert_equal('abc', luaeval('v')) 84 85 " lua.eval with a list 86 lua v = vim.eval("['a']") 87 call assert_equal('list', luaeval('vim.type(v)')) 88 call assert_equal(['a'], luaeval('v')) 89 90 " lua.eval with a dict 91 lua v = vim.eval("{'a':'b'}") 92 call assert_equal('dict', luaeval('vim.type(v)')) 93 call assert_equal({'a':'b'}, luaeval('v')) 94 95 " lua.eval with a blob 96 lua v = vim.eval("0z00112233.deadbeef") 97 call assert_equal('blob', luaeval('vim.type(v)')) 98 call assert_equal(0z00112233.deadbeef, luaeval('v')) 99 100 " lua.eval with a float 101 lua v = vim.eval('3.14') 102 call assert_equal('number', luaeval('vim.type(v)')) 103 call assert_equal(3.14, luaeval('v')) 104 105 " lua.eval with a bool 106 lua v = vim.eval('v:true') 107 call assert_equal('number', luaeval('vim.type(v)')) 108 call assert_equal(1, luaeval('v')) 109 lua v = vim.eval('v:false') 110 call assert_equal('number', luaeval('vim.type(v)')) 111 call assert_equal(0, luaeval('v')) 112 113 " lua.eval with a null 114 lua v = vim.eval('v:null') 115 call assert_equal('nil', luaeval('vim.type(v)')) 116 call assert_equal(v:null, luaeval('v')) 117 118 call assert_fails('lua v = vim.eval(nil)', 119 \ "[string \"vim chunk\"]:1: bad argument #1 to 'eval' (string expected, got nil)") 120 call assert_fails('lua v = vim.eval(true)', 121 \ "[string \"vim chunk\"]:1: bad argument #1 to 'eval' (string expected, got boolean)") 122 call assert_fails('lua v = vim.eval({})', 123 \ "[string \"vim chunk\"]:1: bad argument #1 to 'eval' (string expected, got table)") 124 call assert_fails('lua v = vim.eval(print)', 125 \ "[string \"vim chunk\"]:1: bad argument #1 to 'eval' (string expected, got function)") 126 call assert_fails('lua v = vim.eval(vim.buffer())', 127 \ "[string \"vim chunk\"]:1: bad argument #1 to 'eval' (string expected, got userdata)") 128 129 lua v = nil 130endfunc 131 132" Test luaeval() with lambda 133func Test_luaeval_with_lambda() 134 lua function hello_luaeval_lambda(a, cb) return a .. cb() end 135 call assert_equal('helloworld', 136 \ luaeval('hello_luaeval_lambda(_A[1], _A[2])', 137 \ ['hello', {->'world'}])) 138 lua hello_luaeval_lambda = nil 139endfunc 140 141" Test vim.window() 142func Test_lua_window() 143 e Xfoo2 144 new Xfoo1 145 146 " Window 1 (top window) contains Xfoo1 147 " Window 2 (bottom window) contains Xfoo2 148 call assert_equal('Xfoo1', luaeval('vim.window(1):buffer().name')) 149 call assert_equal('Xfoo2', luaeval('vim.window(2):buffer().name')) 150 151 " Window 3 does not exist so vim.window(3) should return nil 152 call assert_equal('nil', luaeval('tostring(vim.window(3))')) 153 154 if s:lua_543_or_later 155 let msg = "[string \"luaeval\"]:1: field 'xyz' is not callable (a nil value)" 156 elseif s:lua_53_or_later 157 let msg = "[string \"luaeval\"]:1: attempt to call a nil value (field 'xyz')" 158 else 159 let msg = "[string \"luaeval\"]:1: attempt to call field 'xyz' (a nil value)" 160 endif 161 call assert_fails("let n = luaeval('vim.window().xyz()')", msg) 162 call assert_fails('lua vim.window().xyz = 1', 163 \ "[string \"vim chunk\"]:1: invalid window property: `xyz'") 164 165 %bwipe! 166endfunc 167 168" Test vim.window().height 169func Test_lua_window_height() 170 new 171 lua vim.window().height = 2 172 call assert_equal(2, winheight(0)) 173 lua vim.window().height = vim.window().height + 1 174 call assert_equal(3, winheight(0)) 175 bwipe! 176endfunc 177 178" Test vim.window().width 179func Test_lua_window_width() 180 vert new 181 lua vim.window().width = 2 182 call assert_equal(2, winwidth(0)) 183 lua vim.window().width = vim.window().width + 1 184 call assert_equal(3, winwidth(0)) 185 bwipe! 186endfunc 187 188" Test vim.window().line and vim.window.col 189func Test_lua_window_line_col() 190 new 191 call setline(1, ['line1', 'line2', 'line3']) 192 lua vim.window().line = 2 193 lua vim.window().col = 4 194 call assert_equal([0, 2, 4, 0], getpos('.')) 195 lua vim.window().line = vim.window().line + 1 196 lua vim.window().col = vim.window().col - 1 197 call assert_equal([0, 3, 3, 0], getpos('.')) 198 199 call assert_fails('lua vim.window().line = 10', 200 \ '[string "vim chunk"]:1: line out of range') 201 bwipe! 202endfunc 203 204" Test vim.call 205func Test_lua_call() 206 call assert_equal(has('lua'), luaeval('vim.call("has", "lua")')) 207 call assert_equal(printf("Hello %s", "vim"), luaeval('vim.call("printf", "Hello %s", "vim")')) 208 209 " Error cases 210 call assert_fails("call luaeval('vim.call(\"min\", 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)')", 211 \ s:lua_53_or_later 212 \ ? '[string "luaeval"]:1: Function called with too many arguments' 213 \ : 'Function called with too many arguments') 214 lua co = coroutine.create(function () print("hi") end) 215 call assert_fails("call luaeval('vim.call(\"type\", co)')", 216 \ s:lua_53_or_later 217 \ ? '[string "luaeval"]:1: lua: cannot convert value' 218 \ : 'lua: cannot convert value') 219 lua co = nil 220 call assert_fails("call luaeval('vim.call(\"abc\")')", 221 \ ['E117:', s:lua_53_or_later ? '\[string "luaeval"]:1: lua: call_vim_function failed' 222 \ : 'lua: call_vim_function failed']) 223endfunc 224 225" Test vim.fn.* 226func Test_lua_fn() 227 call assert_equal(has('lua'), luaeval('vim.fn.has("lua")')) 228 call assert_equal(printf("Hello %s", "vim"), luaeval('vim.fn.printf("Hello %s", "vim")')) 229endfunc 230 231" Test setting the current window 232func Test_lua_window_set_current() 233 new Xfoo1 234 lua w1 = vim.window() 235 new Xfoo2 236 lua w2 = vim.window() 237 238 call assert_equal('Xfoo2', bufname('%')) 239 lua w1() 240 call assert_equal('Xfoo1', bufname('%')) 241 lua w2() 242 call assert_equal('Xfoo2', bufname('%')) 243 244 lua w1, w2 = nil 245 %bwipe! 246endfunc 247 248" Test vim.window().buffer 249func Test_lua_window_buffer() 250 new Xfoo1 251 lua w1 = vim.window() 252 lua b1 = w1.buffer() 253 new Xfoo2 254 lua w2 = vim.window() 255 lua b2 = w2.buffer() 256 257 lua b1() 258 call assert_equal('Xfoo1', bufname('%')) 259 lua b2() 260 call assert_equal('Xfoo2', bufname('%')) 261 262 lua b1, b2, w1, w2 = nil 263 %bwipe! 264endfunc 265 266" Test vim.window():previous() and vim.window():next() 267func Test_lua_window_next_previous() 268 new Xfoo1 269 new Xfoo2 270 new Xfoo3 271 wincmd j 272 273 call assert_equal('Xfoo2', luaeval('vim.window().buffer().name')) 274 call assert_equal('Xfoo1', luaeval('vim.window():next():buffer().name')) 275 call assert_equal('Xfoo3', luaeval('vim.window():previous():buffer().name')) 276 277 %bwipe! 278endfunc 279 280" Test vim.window():isvalid() 281func Test_lua_window_isvalid() 282 new Xfoo 283 lua w = vim.window() 284 call assert_true(luaeval('w:isvalid()')) 285 286 " FIXME: how to test the case when isvalid() returns v:false? 287 " isvalid() gives errors when the window is deleted. Is it a bug? 288 289 lua w = nil 290 bwipe! 291endfunc 292 293" Test vim.buffer() with and without argument 294func Test_lua_buffer() 295 new Xfoo1 296 let bn1 = bufnr('%') 297 new Xfoo2 298 let bn2 = bufnr('%') 299 300 " Test vim.buffer() without argument. 301 call assert_equal('Xfoo2', luaeval("vim.buffer().name")) 302 303 " Test vim.buffer() with string argument. 304 call assert_equal('Xfoo1', luaeval("vim.buffer('Xfoo1').name")) 305 call assert_equal('Xfoo2', luaeval("vim.buffer('Xfoo2').name")) 306 307 " Test vim.buffer() with integer argument. 308 call assert_equal('Xfoo1', luaeval("vim.buffer(" . bn1 . ").name")) 309 call assert_equal('Xfoo2', luaeval("vim.buffer(" . bn2 . ").name")) 310 311 lua bn1, bn2 = nil 312 %bwipe! 313endfunc 314 315" Test vim.buffer().name and vim.buffer().fname 316func Test_lua_buffer_name() 317 new 318 call assert_equal('', luaeval('vim.buffer().name')) 319 call assert_equal('', luaeval('vim.buffer().fname')) 320 bwipe! 321 322 new Xfoo 323 call assert_equal('Xfoo', luaeval('vim.buffer().name')) 324 call assert_equal(expand('%:p'), luaeval('vim.buffer().fname')) 325 bwipe! 326endfunc 327 328" Test vim.buffer().number 329func Test_lua_buffer_number() 330 " All numbers in Lua are floating points number (no integers). 331 call assert_equal(bufnr('%'), float2nr(luaeval('vim.buffer().number'))) 332endfunc 333 334" Test inserting lines in buffer. 335func Test_lua_buffer_insert() 336 new 337 lua vim.buffer()[1] = '3' 338 lua vim.buffer():insert('1', 0) 339 lua vim.buffer():insert('2', 1) 340 lua vim.buffer():insert('4', 10) 341 342 call assert_equal(['1', '2', '3', '4'], getline(1, '$')) 343 call assert_equal('4', luaeval('vim.buffer()[4]')) 344 call assert_equal(v:null, luaeval('vim.buffer()[5]')) 345 call assert_equal(v:null, luaeval('vim.buffer()[{}]')) 346 if s:lua_543_or_later 347 let msg = "[string \"vim chunk\"]:1: method 'xyz' is not callable (a nil value)" 348 elseif s:lua_53_or_later 349 let msg = "[string \"vim chunk\"]:1: attempt to call a nil value (method 'xyz')" 350 else 351 let msg = "[string \"vim chunk\"]:1: attempt to call method 'xyz' (a nil value)" 352 endif 353 call assert_fails('lua vim.buffer():xyz()', msg) 354 call assert_fails('lua vim.buffer()[1] = {}', 355 \ '[string "vim chunk"]:1: wrong argument to change') 356 bwipe! 357endfunc 358 359" Test deleting line in buffer 360func Test_lua_buffer_delete() 361 new 362 call setline(1, ['1', '2', '3']) 363 call cursor(3, 1) 364 lua vim.buffer()[2] = nil 365 call assert_equal(['1', '3'], getline(1, '$')) 366 367 call assert_fails('lua vim.buffer()[3] = nil', 368 \ '[string "vim chunk"]:1: invalid line number') 369 bwipe! 370endfunc 371 372" Test #vim.buffer() i.e. number of lines in buffer 373func Test_lua_buffer_number_lines() 374 new 375 call setline(1, ['a', 'b', 'c']) 376 call assert_equal(3, luaeval('#vim.buffer()')) 377 bwipe! 378endfunc 379 380" Test vim.buffer():next() and vim.buffer():previous() 381" Note that these functions get the next or previous buffers 382" but do not switch buffer. 383func Test_lua_buffer_next_previous() 384 new Xfoo1 385 new Xfoo2 386 new Xfoo3 387 b Xfoo2 388 389 lua bn = vim.buffer():next() 390 lua bp = vim.buffer():previous() 391 392 call assert_equal('Xfoo2', luaeval('vim.buffer().name')) 393 call assert_equal('Xfoo1', luaeval('bp.name')) 394 call assert_equal('Xfoo3', luaeval('bn.name')) 395 396 call assert_equal('Xfoo2', bufname('%')) 397 398 lua bn() 399 call assert_equal('Xfoo3', luaeval('vim.buffer().name')) 400 call assert_equal('Xfoo3', bufname('%')) 401 402 lua bp() 403 call assert_equal('Xfoo1', luaeval('vim.buffer().name')) 404 call assert_equal('Xfoo1', bufname('%')) 405 406 lua bn, bp = nil 407 %bwipe! 408endfunc 409 410" Test vim.buffer():isvalid() 411func Test_lua_buffer_isvalid() 412 new Xfoo 413 lua b = vim.buffer() 414 call assert_true(luaeval('b:isvalid()')) 415 416 " FIXME: how to test the case when isvalid() returns v:false? 417 " isvalid() gives errors when the buffer is wiped. Is it a bug? 418 419 lua b = nil 420 bwipe! 421endfunc 422 423func Test_lua_list() 424 call assert_equal([], luaeval('vim.list()')) 425 426 let l = [] 427 lua l = vim.eval('l') 428 lua l:add(123) 429 lua l:add('abc') 430 lua l:add(true) 431 lua l:add(false) 432 lua l:add(nil) 433 lua l:add(vim.eval("[1, 2, 3]")) 434 lua l:add(vim.eval("{'a':1, 'b':2, 'c':3}")) 435 call assert_equal([123, 'abc', v:true, v:false, v:null, [1, 2, 3], {'a': 1, 'b': 2, 'c': 3}], l) 436 call assert_equal(7, luaeval('#l')) 437 call assert_match('^list: \%(0x\)\?\x\+$', luaeval('tostring(l)')) 438 439 lua l[1] = 124 440 lua l[6] = nil 441 lua l:insert('first') 442 lua l:insert('xx', 3) 443 call assert_fails('lua l:insert("xx", -20)', 444 \ '[string "vim chunk"]:1: invalid position') 445 call assert_equal(['first', 124, 'abc', 'xx', v:true, v:false, v:null, {'a': 1, 'b': 2, 'c': 3}], l) 446 447 lockvar 1 l 448 call assert_fails('lua l:add("x")', '[string "vim chunk"]:1: list is locked') 449 call assert_fails('lua l:insert(2)', '[string "vim chunk"]:1: list is locked') 450 call assert_fails('lua l[9] = 1', '[string "vim chunk"]:1: list is locked') 451 452 unlockvar l 453 let l = [1, 2] 454 lua ll = vim.eval('l') 455 let x = luaeval("ll[3]") 456 call assert_equal(v:null, x) 457 if s:lua_543_or_later 458 let msg = "[string \"luaeval\"]:1: method 'xyz' is not callable (a nil value)" 459 elseif s:lua_53_or_later 460 let msg = "[string \"luaeval\"]:1: attempt to call a nil value (method 'xyz')" 461 else 462 let msg = "[string \"luaeval\"]:1: attempt to call method 'xyz' (a nil value)" 463 endif 464 call assert_fails('let x = luaeval("ll:xyz(3)")', msg) 465 let y = luaeval("ll[{}]") 466 call assert_equal(v:null, y) 467 468 lua l = nil 469endfunc 470 471func Test_lua_list_table() 472 " See :help lua-vim 473 " Non-numeric keys should not be used to initialize the list 474 " so say = 'hi' should be ignored. 475 lua t = {3.14, 'hello', false, true, say = 'hi'} 476 call assert_equal([3.14, 'hello', v:false, v:true], luaeval('vim.list(t)')) 477 lua t = nil 478 479 call assert_fails('lua vim.list(1)', '[string "vim chunk"]:1: table expected, got number') 480 call assert_fails('lua vim.list("x")', '[string "vim chunk"]:1: table expected, got string') 481 call assert_fails('lua vim.list(print)', '[string "vim chunk"]:1: table expected, got function') 482 call assert_fails('lua vim.list(true)', '[string "vim chunk"]:1: table expected, got boolean') 483endfunc 484 485func Test_lua_list_table_insert_remove() 486 if !s:lua_53_or_later 487 throw 'Skipped: Lua version < 5.3' 488 endif 489 490 let l = [1, 2] 491 lua t = vim.eval('l') 492 lua table.insert(t, 10) 493 lua t[#t + 1] = 20 494 lua table.insert(t, 2, 30) 495 call assert_equal(l, [1, 30, 2, 10, 20]) 496 lua table.remove(t, 2) 497 call assert_equal(l, [1, 2, 10, 20]) 498 lua t[3] = nil 499 call assert_equal(l, [1, 2, 20]) 500 lua removed_value = table.remove(t, 3) 501 call assert_equal(luaeval('removed_value'), 20) 502 lua t = nil 503 lua removed_value = nil 504 unlet l 505endfunc 506 507" Test l() i.e. iterator on list 508func Test_lua_list_iter() 509 lua l = vim.list():add('foo'):add('bar') 510 lua str = '' 511 lua for v in l() do str = str .. v end 512 call assert_equal('foobar', luaeval('str')) 513 514 lua str, l = nil 515endfunc 516 517func Test_lua_recursive_list() 518 lua l = vim.list():add(1):add(2) 519 lua l = l:add(l) 520 521 call assert_equal(1, luaeval('l[1]')) 522 call assert_equal(2, luaeval('l[2]')) 523 524 call assert_equal(1, luaeval('l[3][1]')) 525 call assert_equal(2, luaeval('l[3][2]')) 526 527 call assert_equal(1, luaeval('l[3][3][1]')) 528 call assert_equal(2, luaeval('l[3][3][2]')) 529 530 call assert_equal('[1, 2, [...]]', string(luaeval('l'))) 531 532 call assert_match('^list: \%(0x\)\?\x\+$', luaeval('tostring(l)')) 533 call assert_equal(luaeval('tostring(l)'), luaeval('tostring(l[3])')) 534 535 call assert_equal(luaeval('l'), luaeval('l[3]')) 536 call assert_equal(luaeval('l'), luaeval('l[3][3]')) 537 538 lua l = nil 539endfunc 540 541func Test_lua_dict() 542 call assert_equal({}, luaeval('vim.dict()')) 543 544 let d = {} 545 lua d = vim.eval('d') 546 lua d[0] = 123 547 lua d[1] = "abc" 548 lua d[2] = true 549 lua d[3] = false 550 lua d[4] = vim.eval("[1, 2, 3]") 551 lua d[5] = vim.eval("{'a':1, 'b':2, 'c':3}") 552 call assert_equal({'0':123, '1':'abc', '2':v:true, '3':v:false, '4': [1, 2, 3], '5': {'a':1, 'b':2, 'c':3}}, d) 553 call assert_equal(6, luaeval('#d')) 554 call assert_match('^dict: \%(0x\)\?\x\+$', luaeval('tostring(d)')) 555 556 call assert_equal('abc', luaeval('d[1]')) 557 call assert_equal(v:null, luaeval('d[22]')) 558 559 lua d[0] = 124 560 lua d[4] = nil 561 call assert_equal({'0':124, '1':'abc', '2':v:true, '3':v:false, '5': {'a':1, 'b':2, 'c':3}}, d) 562 563 lockvar 1 d 564 call assert_fails('lua d[6] = 1', '[string "vim chunk"]:1: dict is locked') 565 unlockvar d 566 567 " Error case 568 lua d = {} 569 lua d[''] = 10 570 call assert_fails("let t = luaeval('vim.dict(d)')", 571 \ s:lua_53_or_later 572 \ ? '[string "luaeval"]:1: table has empty key' 573 \ : 'table has empty key') 574 let d = {} 575 lua x = vim.eval('d') 576 call assert_fails("lua x[''] = 10", '[string "vim chunk"]:1: empty key') 577 lua x['a'] = nil 578 call assert_equal({}, d) 579 580 " cannot assign funcrefs in the global scope 581 lua x = vim.eval('g:') 582 call assert_fails("lua x['min'] = vim.funcref('max')", 583 \ '[string "vim chunk"]:1: cannot assign funcref to builtin scope') 584 585 lua d = nil 586endfunc 587 588func Test_lua_dict_table() 589 lua t = {key1 = 'x', key2 = 3.14, key3 = true, key4 = false} 590 call assert_equal({'key1': 'x', 'key2': 3.14, 'key3': v:true, 'key4': v:false}, 591 \ luaeval('vim.dict(t)')) 592 593 " Same example as in :help lua-vim. 594 lua t = {math.pi, false, say = 'hi'} 595 " FIXME: commented out as it currently does not work as documented: 596 " Expected {'say': 'hi'} 597 " but got {'1': 3.141593, '2': v:false, 'say': 'hi'} 598 " Is the documentation or the code wrong? 599 "call assert_equal({'say' : 'hi'}, luaeval('vim.dict(t)')) 600 lua t = nil 601 602 call assert_fails('lua vim.dict(1)', '[string "vim chunk"]:1: table expected, got number') 603 call assert_fails('lua vim.dict("x")', '[string "vim chunk"]:1: table expected, got string') 604 call assert_fails('lua vim.dict(print)', '[string "vim chunk"]:1: table expected, got function') 605 call assert_fails('lua vim.dict(true)', '[string "vim chunk"]:1: table expected, got boolean') 606endfunc 607 608" Test d() i.e. iterator on dictionary 609func Test_lua_dict_iter() 610 let d = {'a': 1, 'b':2} 611 lua d = vim.eval('d') 612 lua str = '' 613 lua for k,v in d() do str = str .. k ..':' .. v .. ',' end 614 call assert_equal('a:1,b:2,', luaeval('str')) 615 616 lua str, d = nil 617endfunc 618 619func Test_lua_blob() 620 call assert_equal(0z, luaeval('vim.blob("")')) 621 call assert_equal(0z31326162, luaeval('vim.blob("12ab")')) 622 call assert_equal(0z00010203, luaeval('vim.blob("\x00\x01\x02\x03")')) 623 call assert_equal(0z8081FEFF, luaeval('vim.blob("\x80\x81\xfe\xff")')) 624 625 lua b = vim.blob("\x00\x00\x00\x00") 626 call assert_equal(0z00000000, luaeval('b')) 627 call assert_equal(4, luaeval('#b')) 628 lua b[0], b[1], b[2], b[3] = 1, 32, 256, 0xff 629 call assert_equal(0z012000ff, luaeval('b')) 630 lua b[4] = string.byte("z", 1) 631 call assert_equal(0z012000ff.7a, luaeval('b')) 632 call assert_equal(5, luaeval('#b')) 633 call assert_fails('lua b[#b+1] = 0x80', '[string "vim chunk"]:1: index out of range') 634 lua b:add("12ab") 635 call assert_equal(0z012000ff.7a313261.62, luaeval('b')) 636 call assert_equal(9, luaeval('#b')) 637 call assert_fails('lua b:add(nil)', '[string "vim chunk"]:1: string expected, got nil') 638 call assert_fails('lua b:add(true)', '[string "vim chunk"]:1: string expected, got boolean') 639 call assert_fails('lua b:add({})', '[string "vim chunk"]:1: string expected, got table') 640 lua b = nil 641 642 let b = 0z0102 643 lua lb = vim.eval('b') 644 let n = luaeval('lb[1]') 645 call assert_equal(2, n) 646 let n = luaeval('lb[6]') 647 call assert_equal(v:null, n) 648 if s:lua_543_or_later 649 let msg = "[string \"luaeval\"]:1: method 'xyz' is not callable (a nil value)" 650 elseif s:lua_53_or_later 651 let msg = "[string \"luaeval\"]:1: attempt to call a nil value (method 'xyz')" 652 else 653 let msg = "[string \"luaeval\"]:1: attempt to call method 'xyz' (a nil value)" 654 endif 655 call assert_fails('let x = luaeval("lb:xyz(3)")', msg) 656 let y = luaeval("lb[{}]") 657 call assert_equal(v:null, y) 658 659 lockvar b 660 call assert_fails('lua lb[1] = 2', '[string "vim chunk"]:1: blob is locked') 661 call assert_fails('lua lb:add("12")', '[string "vim chunk"]:1: blob is locked') 662 663 " Error cases 664 lua t = {} 665 call assert_fails('lua b = vim.blob(t)', 666 \ '[string "vim chunk"]:1: string expected, got table') 667endfunc 668 669func Test_lua_funcref() 670 function I(x) 671 return a:x 672 endfunction 673 let R = function('I') 674 lua i1 = vim.funcref"I" 675 lua i2 = vim.eval"R" 676 lua msg = "funcref|test|" .. (#i2(i1) == #i1(i2) and "OK" or "FAIL") 677 lua msg = vim.funcref"tr"(msg, "|", " ") 678 call assert_equal("funcref test OK", luaeval('msg')) 679 680 " Error cases 681 call assert_fails('lua f1 = vim.funcref("")', 682 \ '[string "vim chunk"]:1: invalid function name: ') 683 call assert_fails('lua f1 = vim.funcref("10")', 684 \ '[string "vim chunk"]:1: invalid function name: 10') 685 let fname = test_null_string() 686 call assert_fails('lua f1 = vim.funcref(fname)', 687 \ "[string \"vim chunk\"]:1: bad argument #1 to 'funcref' (string expected, got nil)") 688 call assert_fails('lua vim.funcref("abc")()', 689 \ ['E117:', '\[string "vim chunk"]:1: cannot call funcref']) 690 691 " dict funcref 692 function Mylen() dict 693 return len(self.data) 694 endfunction 695 let l = [0, 1, 2, 3] 696 let mydict = {'data': l} 697 lua d = vim.eval"mydict" 698 lua d.len = vim.funcref"Mylen" -- assign d as 'self' 699 lua res = (d.len() == vim.funcref"len"(vim.eval"l")) and "OK" or "FAIL" 700 call assert_equal("OK", luaeval('res')) 701 call assert_equal(function('Mylen', {'data': l, 'len': function('Mylen')}), mydict.len) 702 703 lua i1, i2, msg, d, res = nil 704endfunc 705 706" Test vim.type() 707func Test_lua_type() 708 " The following values are identical to Lua's type function. 709 call assert_equal('string', luaeval('vim.type("foo")')) 710 call assert_equal('number', luaeval('vim.type(1)')) 711 call assert_equal('number', luaeval('vim.type(1.2)')) 712 call assert_equal('function', luaeval('vim.type(print)')) 713 call assert_equal('table', luaeval('vim.type({})')) 714 call assert_equal('boolean', luaeval('vim.type(true)')) 715 call assert_equal('boolean', luaeval('vim.type(false)')) 716 call assert_equal('nil', luaeval('vim.type(nil)')) 717 718 " The following values are specific to Vim. 719 call assert_equal('window', luaeval('vim.type(vim.window())')) 720 call assert_equal('buffer', luaeval('vim.type(vim.buffer())')) 721 call assert_equal('list', luaeval('vim.type(vim.list())')) 722 call assert_equal('dict', luaeval('vim.type(vim.dict())')) 723 call assert_equal('funcref', luaeval('vim.type(vim.funcref("Test_type"))')) 724endfunc 725 726" Test vim.open() 727func Test_lua_open() 728 call assert_notmatch('XOpen', execute('ls')) 729 730 " Open a buffer XOpen1, but do not jump to it. 731 lua b = vim.open('XOpen1') 732 call assert_equal('XOpen1', luaeval('b.name')) 733 call assert_equal('', bufname('%')) 734 735 call assert_match('XOpen1', execute('ls')) 736 call assert_notequal('XOpen2', bufname('%')) 737 738 " Open a buffer XOpen2 and jump to it. 739 lua b = vim.open('XOpen2')() 740 call assert_equal('XOpen2', luaeval('b.name')) 741 call assert_equal('XOpen2', bufname('%')) 742 743 lua b = nil 744 %bwipe! 745endfunc 746 747func Test_update_package_paths() 748 set runtimepath+=./testluaplugin 749 call assert_equal("hello from lua", luaeval("require('testluaplugin').hello()")) 750endfunc 751 752func Vim_func_call_lua_callback(Concat, Cb) 753 let l:message = a:Concat("hello", "vim") 754 call a:Cb(l:message) 755endfunc 756 757func Test_pass_lua_callback_to_vim_from_lua() 758 lua pass_lua_callback_to_vim_from_lua_result = "" 759 call assert_equal("", luaeval("pass_lua_callback_to_vim_from_lua_result")) 760 lua <<EOF 761 vim.funcref('Vim_func_call_lua_callback')( 762 function(greeting, message) 763 return greeting .. " " .. message 764 end, 765 function(message) 766 pass_lua_callback_to_vim_from_lua_result = message 767 end) 768EOF 769 call assert_equal("hello vim", luaeval("pass_lua_callback_to_vim_from_lua_result")) 770endfunc 771 772func Vim_func_call_metatable_lua_callback(Greet) 773 return a:Greet("world") 774endfunc 775 776func Test_pass_lua_metatable_callback_to_vim_from_lua() 777 let result = luaeval("vim.funcref('Vim_func_call_metatable_lua_callback')(setmetatable({ space = ' '}, { __call = function(tbl, msg) return 'hello' .. tbl.space .. msg end }) )") 778 call assert_equal("hello world", result) 779endfunc 780 781" Test vim.line() 782func Test_lua_line() 783 new 784 call setline(1, ['first line', 'second line']) 785 1 786 call assert_equal('first line', luaeval('vim.line()')) 787 2 788 call assert_equal('second line', luaeval('vim.line()')) 789 bwipe! 790endfunc 791 792" Test vim.beep() 793func Test_lua_beep() 794 call assert_beeps('lua vim.beep()') 795endfunc 796 797" Test errors in luaeval() 798func Test_luaeval_error() 799 " Compile error 800 call assert_fails("call luaeval('-nil')", 801 \ '[string "luaeval"]:1: attempt to perform arithmetic on a nil value') 802 call assert_fails("call luaeval(']')", 803 \ "[string \"luaeval\"]:1: unexpected symbol near ']'") 804 lua co = coroutine.create(function () print("hi") end) 805 call assert_fails('let i = luaeval("co")', 'luaeval: cannot convert value') 806 lua co = nil 807 call assert_fails('let m = luaeval("{}")', 'luaeval: cannot convert value') 808endfunc 809 810" Test :luafile foo.lua 811func Test_luafile() 812 call delete('Xlua_file') 813 call writefile(["str = 'hello'", "num = 123" ], 'Xlua_file') 814 call setfperm('Xlua_file', 'r-xr-xr-x') 815 816 luafile Xlua_file 817 call assert_equal('hello', luaeval('str')) 818 call assert_equal(123, luaeval('num')) 819 820 lua str, num = nil 821 call delete('Xlua_file') 822endfunc 823 824" Test :luafile % 825func Test_luafile_percent() 826 new Xlua_file 827 append 828 str, num = 'foo', 321.0 829 print(string.format('str=%s, num=%d', str, num)) 830. 831 w! 832 luafile % 833 let msg = split(execute('message'), "\n")[-1] 834 call assert_equal('str=foo, num=321', msg) 835 836 lua str, num = nil 837 call delete('Xlua_file') 838 bwipe! 839endfunc 840 841" Test :luafile with syntax error 842func Test_luafile_error() 843 new Xlua_file 844 call writefile(['nil = 0' ], 'Xlua_file') 845 call setfperm('Xlua_file', 'r-xr-xr-x') 846 847 call assert_fails('luafile Xlua_file', "Xlua_file:1: unexpected symbol near 'nil'") 848 849 call delete('Xlua_file') 850 bwipe! 851endfunc 852 853" Test for dealing with strings containing newlines and null character 854func Test_lua_string_with_newline() 855 let x = execute('lua print("Hello\nWorld")') 856 call assert_equal("\nHello\nWorld", x) 857 new 858 lua k = vim.buffer(vim.eval('bufnr()')) 859 lua k:insert("Hello\0World", 0) 860 call assert_equal(["Hello\nWorld", ''], getline(1, '$')) 861 close! 862endfunc 863 864func Test_lua_set_cursor() 865 " Check that setting the cursor position works. 866 new 867 call setline(1, ['first line', 'second line']) 868 normal gg 869 lua << trim EOF 870 w = vim.window() 871 w.line = 1 872 w.col = 5 873 EOF 874 call assert_equal([1, 5], [line('.'), col('.')]) 875 876 " Check that movement after setting cursor position keeps current column. 877 normal j 878 call assert_equal([2, 5], [line('.'), col('.')]) 879endfunc 880 881" Test for various heredoc syntax 882func Test_lua_heredoc() 883 lua << END 884vim.command('let s = "A"') 885END 886 lua << 887vim.command('let s ..= "B"') 888. 889 lua << trim END 890 vim.command('let s ..= "C"') 891 END 892 lua << trim 893 vim.command('let s ..= "D"') 894 . 895 lua << trim eof 896 vim.command('let s ..= "E"') 897 eof 898 call assert_equal('ABCDE', s) 899endfunc 900 901" vim: shiftwidth=2 sts=2 expandtab 902