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