neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

overrides_spec.lua (12783B)


      1 -- Test for Vim overrides of lua built-ins
      2 local t = require('test.testutil')
      3 local n = require('test.functional.testnvim')()
      4 local Screen = require('test.functional.ui.screen')
      5 
      6 local eq = t.eq
      7 local NIL = vim.NIL
      8 local feed = n.feed
      9 local clear = n.clear
     10 local fn = n.fn
     11 local api = n.api
     12 local command = n.command
     13 local write_file = t.write_file
     14 local exec_capture = n.exec_capture
     15 local exec_lua = n.exec_lua
     16 local pcall_err = t.pcall_err
     17 local is_os = t.is_os
     18 
     19 local fname = 'Xtest-functional-lua-overrides-luafile'
     20 
     21 before_each(clear)
     22 
     23 after_each(function()
     24  os.remove(fname)
     25 end)
     26 
     27 describe('print', function()
     28  it('returns nothing', function()
     29    eq(NIL, fn.luaeval('print("abc")'))
     30    eq(0, fn.luaeval('select("#", print("abc"))'))
     31  end)
     32  it('allows catching printed text with :execute', function()
     33    eq('\nabc', fn.execute('lua print("abc")'))
     34    eq('\nabc', fn.execute('luado print("abc")'))
     35    eq('\nabc', fn.execute('call luaeval("print(\'abc\')")'))
     36    write_file(fname, 'print("abc")')
     37    eq('\nabc', fn.execute('luafile ' .. fname))
     38 
     39    eq('abc', exec_capture('lua print("abc")'))
     40    eq('abc', exec_capture('luado print("abc")'))
     41    eq('abc', exec_capture('call luaeval("print(\'abc\')")'))
     42    write_file(fname, 'print("abc")')
     43    eq('abc', exec_capture('luafile ' .. fname))
     44  end)
     45  it('handles errors in __tostring', function()
     46    write_file(
     47      fname,
     48      [[
     49      local meta_nilerr = { __tostring = function() error(nil) end }
     50      local meta_abcerr = { __tostring = function() error("abc") end }
     51      local meta_tblout = { __tostring = function() return {"TEST"} end }
     52      v_nilerr = setmetatable({}, meta_nilerr)
     53      v_abcerr = setmetatable({}, meta_abcerr)
     54      v_tblout = setmetatable({}, meta_tblout)
     55    ]]
     56    )
     57    eq('', exec_capture('luafile ' .. fname))
     58    -- TODO(bfredl): these look weird, print() should not use "E5114:" style errors..
     59    eq(
     60      'Vim(lua):E5108: Lua: E5114: Converting print argument #2: [NULL]',
     61      pcall_err(command, 'lua print("foo", v_nilerr, "bar")')
     62    )
     63    eq(
     64      'Vim(lua):E5108: Lua: E5114: Converting print argument #2: Xtest-functional-lua-overrides-luafile:2: abc',
     65      pcall_err(command, 'lua print("foo", v_abcerr, "bar")')
     66    )
     67    eq(
     68      'Vim(lua):E5108: Lua: E5114: Converting print argument #2: <Unknown error: lua_tolstring returned NULL for tostring result>',
     69      pcall_err(command, 'lua print("foo", v_tblout, "bar")')
     70    )
     71  end)
     72  it('coerces error values into strings', function()
     73    write_file(
     74      fname,
     75      [[
     76    function string_error() error("my mistake") end
     77    function number_error() error(1234) end
     78    function nil_error() error(nil) end
     79    function table_error() error({message = "my mistake"}) end
     80    function custom_error()
     81      local err = {message = "my mistake", code = 11234}
     82      setmetatable(err, {
     83        __tostring = function(t)
     84          return "Internal Error [" .. t.code .. "] " .. t.message
     85        end
     86      })
     87      error(err)
     88    end
     89    function bad_custom_error()
     90      local err = {message = "my mistake", code = 11234}
     91      setmetatable(err, {
     92        -- intentionally not a function, downstream programmer has made an mistake
     93        __tostring = "Internal Error [" .. err.code .. "] " .. err.message
     94      })
     95      error(err)
     96    end
     97    ]]
     98    )
     99    eq('', exec_capture('luafile ' .. fname))
    100    eq(
    101      'Vim(lua):E5108: Lua: Xtest-functional-lua-overrides-luafile:1: my mistake',
    102      pcall_err(command, 'lua string_error()')
    103    )
    104    eq(
    105      'Vim(lua):E5108: Lua: Xtest-functional-lua-overrides-luafile:2: 1234',
    106      pcall_err(command, 'lua number_error()')
    107    )
    108    eq('Vim(lua):E5108: Lua: [NULL]', pcall_err(command, 'lua nil_error()'))
    109    eq('Vim(lua):E5108: Lua: [NULL]', pcall_err(command, 'lua table_error()'))
    110    eq(
    111      'Vim(lua):E5108: Lua: Internal Error [11234] my mistake',
    112      pcall_err(command, 'lua custom_error()')
    113    )
    114    eq('Vim(lua):E5108: Lua: [NULL]', pcall_err(command, 'lua bad_custom_error()'))
    115  end)
    116  it('prints strings with NULs and NLs correctly', function()
    117    api.nvim_set_option_value('more', true, {})
    118    eq(
    119      'abc ^@ def\nghi^@^@^@jkl\nTEST\n\n\nT\n',
    120      exec_capture([[lua print("abc \0 def\nghi\0\0\0jkl\nTEST\n\n\nT\n")]])
    121    )
    122    eq(
    123      'abc ^@ def\nghi^@^@^@jkl\nTEST\n\n\nT^@',
    124      exec_capture([[lua print("abc \0 def\nghi\0\0\0jkl\nTEST\n\n\nT\0")]])
    125    )
    126    eq('T^@', exec_capture([[lua print("T\0")]]))
    127    eq('T\n', exec_capture([[lua print("T\n")]]))
    128  end)
    129  it('prints empty strings correctly', function()
    130    -- Regression: first test used to crash
    131    eq('', exec_capture('lua print("")'))
    132    eq(' def', exec_capture('lua print("", "def")'))
    133    eq('abc ', exec_capture('lua print("abc", "")'))
    134    eq('abc  def', exec_capture('lua print("abc", "", "def")'))
    135  end)
    136  it('defers printing in luv event handlers', function()
    137    exec_lua(function(cmd)
    138      function test()
    139        local timer = vim.uv.new_timer()
    140        local done = false
    141        timer:start(10, 0, function()
    142          print('very fast')
    143          timer:close()
    144          done = true
    145        end)
    146        -- be kind to slow travis OS X jobs:
    147        -- loop until we know for sure the callback has been executed
    148        while not done do
    149          os.execute(cmd)
    150          vim.uv.run('nowait') -- fake os_breakcheck()
    151        end
    152        print('very slow')
    153        vim.api.nvim_command('sleep 1m') -- force deferred event processing
    154      end
    155    end, (is_os('win') and 'timeout 1') or 'sleep 0.1')
    156    eq('very slow\nvery fast', exec_capture('lua test()'))
    157  end)
    158 
    159  it('blank line in message works', function()
    160    local screen = Screen.new(40, 8)
    161    screen:set_default_attr_ids({
    162      [0] = { bold = true, foreground = Screen.colors.Blue },
    163      [1] = { bold = true, foreground = Screen.colors.SeaGreen },
    164      [2] = { bold = true, reverse = true },
    165    })
    166    feed([[:lua print('\na')<CR>]])
    167    screen:expect {
    168      grid = [[
    169                                              |
    170      {0:~                                       }|*3
    171      {2:                                        }|
    172                                              |
    173      a                                       |
    174      {1:Press ENTER or type command to continue}^ |
    175    ]],
    176    }
    177    feed('<CR>')
    178    feed([[:lua print('b\n\nc')<CR>]])
    179    screen:expect {
    180      grid = [[
    181                                              |
    182      {0:~                                       }|*2
    183      {2:                                        }|
    184      b                                       |
    185                                              |
    186      c                                       |
    187      {1:Press ENTER or type command to continue}^ |
    188    ]],
    189    }
    190  end)
    191 end)
    192 
    193 describe('debug.debug', function()
    194  local screen --- @type test.functional.ui.screen
    195 
    196  before_each(function()
    197    screen = Screen.new()
    198    screen:set_default_attr_ids {
    199      [0] = { bold = true, foreground = 255 },
    200      [1] = { bold = true, reverse = true },
    201      E = { foreground = Screen.colors.Grey100, background = Screen.colors.Red },
    202      cr = { bold = true, foreground = Screen.colors.SeaGreen4 },
    203    }
    204  end)
    205 
    206  it('works', function()
    207    command([[lua
    208      function Test(a)
    209        print(a)
    210        debug.debug()
    211        print(a * 100)
    212      end
    213    ]])
    214    feed(':lua Test()\n')
    215    screen:expect {
    216      grid = [[
    217                                                           |
    218      {0:~                                                    }|*10
    219      {1:                                                     }|
    220      nil                                                  |
    221      lua_debug> ^                                          |
    222    ]],
    223    }
    224    feed('print("TEST")\n')
    225    screen:expect([[
    226                                                           |
    227      {0:~                                                    }|*8
    228      {1:                                                     }|
    229      nil                                                  |
    230      lua_debug> print("TEST")                             |
    231      TEST                                                 |
    232      lua_debug> ^                                          |
    233    ]])
    234    feed('<C-c>')
    235    screen:expect([[
    236                                                           |
    237      {0:~                                                    }|*2
    238      {1:                                                     }|
    239      nil                                                  |
    240      lua_debug> print("TEST")                             |
    241      TEST                                                 |
    242                                                           |
    243      {E:E5108: Lua: [string ":lua"]:5: attempt to perform ari}|
    244      {E:thmetic on local 'a' (a nil value)}                   |
    245      {E:stack traceback:}                                     |
    246      {E:        [string ":lua"]:5: in function 'Test'}        |
    247      {E:        [string ":lua"]:1: in main chunk}             |
    248      Interrupt: {cr:Press ENTER or type command to continue}^   |
    249    ]])
    250    feed('<C-l>:lua Test()\n')
    251    screen:expect([[
    252                                                           |
    253      {0:~                                                    }|*10
    254      {1:                                                     }|
    255      nil                                                  |
    256      lua_debug> ^                                          |
    257    ]])
    258    feed('\n')
    259    screen:expect([[
    260                                                           |
    261      {0:~                                                    }|*4
    262      {1:                                                     }|
    263      nil                                                  |
    264      lua_debug>                                           |
    265      {E:E5108: Lua: [string ":lua"]:5: attempt to perform ari}|
    266      {E:thmetic on local 'a' (a nil value)}                   |
    267      {E:stack traceback:}                                     |
    268      {E:        [string ":lua"]:5: in function 'Test'}        |
    269      {E:        [string ":lua"]:1: in main chunk}             |
    270      {cr:Press ENTER or type command to continue}^              |
    271    ]])
    272  end)
    273 
    274  it("can be safely exited with 'cont'", function()
    275    feed('<cr>')
    276    feed(':lua debug.debug() print("x")<cr>')
    277    screen:expect {
    278      grid = [[
    279                                                           |
    280      {0:~                                                    }|*12
    281      lua_debug> ^                                          |
    282    ]],
    283    }
    284 
    285    feed('conttt<cr>') -- misspelled cont; invalid syntax
    286    screen:expect([[
    287                                                           |
    288      {0:~                                                    }|*8
    289      {1:                                                     }|
    290      lua_debug> conttt                                    |
    291      {E:E5115: Loading Lua debug string: (debug command):1: '}|
    292      {E:=' expected near '<eof>'}                             |
    293      lua_debug> ^                                          |
    294    ]])
    295 
    296    feed('cont<cr>') -- exactly "cont", exit now
    297    screen:expect([[
    298                                                           |
    299      {0:~                                                    }|*6
    300      {1:                                                     }|
    301      lua_debug> conttt                                    |
    302      {E:E5115: Loading Lua debug string: (debug command):1: '}|
    303      {E:=' expected near '<eof>'}                             |
    304      lua_debug> cont                                      |
    305      x                                                    |
    306      {cr:Press ENTER or type command to continue}^              |
    307    ]])
    308 
    309    feed('<cr>')
    310    screen:expect {
    311      grid = [[
    312      ^                                                     |
    313      {0:~                                                    }|*12
    314                                                           |
    315    ]],
    316    }
    317  end)
    318 end)
    319 
    320 describe('os.getenv', function()
    321  it('returns nothing for undefined env var', function()
    322    eq(NIL, fn.luaeval('os.getenv("XTEST_1")'))
    323  end)
    324  it('returns env var set by the parent process', function()
    325    local value = 'foo'
    326    clear({ env = { ['XTEST_1'] = value } })
    327    eq(value, fn.luaeval('os.getenv("XTEST_1")'))
    328  end)
    329  it('returns env var set by let', function()
    330    local value = 'foo'
    331    command('let $XTEST_1 = "' .. value .. '"')
    332    eq(value, fn.luaeval('os.getenv("XTEST_1")'))
    333  end)
    334 end)
    335 
    336 -- "bit" module is always available, regardless if nvim is built with
    337 -- luajit or PUC lua 5.1.
    338 describe('bit module', function()
    339  it('works', function()
    340    eq(9, exec_lua [[ return require'bit'.band(11,13) ]])
    341  end)
    342 end)