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