overrides_spec.lua 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. -- Test for Vim overrides of lua built-ins
  2. local helpers = require('test.functional.helpers')(after_each)
  3. local Screen = require('test.functional.ui.screen')
  4. local eq = helpers.eq
  5. local NIL = helpers.NIL
  6. local feed = helpers.feed
  7. local clear = helpers.clear
  8. local funcs = helpers.funcs
  9. local meths = helpers.meths
  10. local iswin = helpers.iswin
  11. local command = helpers.command
  12. local write_file = helpers.write_file
  13. local redir_exec = helpers.redir_exec
  14. local exec_lua = helpers.exec_lua
  15. local screen
  16. local fname = 'Xtest-functional-lua-overrides-luafile'
  17. before_each(clear)
  18. after_each(function()
  19. os.remove(fname)
  20. end)
  21. describe('print', function()
  22. it('returns nothing', function()
  23. eq(NIL, funcs.luaeval('print("abc")'))
  24. eq(0, funcs.luaeval('select("#", print("abc"))'))
  25. end)
  26. it('allows catching printed text with :execute', function()
  27. eq('\nabc', funcs.execute('lua print("abc")'))
  28. eq('\nabc', funcs.execute('luado print("abc")'))
  29. eq('\nabc', funcs.execute('call luaeval("print(\'abc\')")'))
  30. write_file(fname, 'print("abc")')
  31. eq('\nabc', funcs.execute('luafile ' .. fname))
  32. eq('\nabc', redir_exec('lua print("abc")'))
  33. eq('\nabc', redir_exec('luado print("abc")'))
  34. eq('\nabc', redir_exec('call luaeval("print(\'abc\')")'))
  35. write_file(fname, 'print("abc")')
  36. eq('\nabc', redir_exec('luafile ' .. fname))
  37. end)
  38. it('handles errors in __tostring', function()
  39. write_file(fname, [[
  40. local meta_nilerr = { __tostring = function() error(nil) end }
  41. local meta_abcerr = { __tostring = function() error("abc") end }
  42. local meta_tblout = { __tostring = function() return {"TEST"} end }
  43. v_nilerr = setmetatable({}, meta_nilerr)
  44. v_abcerr = setmetatable({}, meta_abcerr)
  45. v_tblout = setmetatable({}, meta_tblout)
  46. ]])
  47. eq('', redir_exec('luafile ' .. fname))
  48. -- TODO(bfredl): these look weird, print() should not use "E5114:" style errors..
  49. eq('\nE5108: Error executing lua E5114: Error while converting print argument #2: [NULL]',
  50. redir_exec('lua print("foo", v_nilerr, "bar")'))
  51. eq('\nE5108: Error executing lua E5114: Error while converting print argument #2: Xtest-functional-lua-overrides-luafile:2: abc',
  52. redir_exec('lua print("foo", v_abcerr, "bar")'))
  53. eq('\nE5108: Error executing lua E5114: Error while converting print argument #2: <Unknown error: lua_tolstring returned NULL for tostring result>',
  54. redir_exec('lua print("foo", v_tblout, "bar")'))
  55. end)
  56. it('prints strings with NULs and NLs correctly', function()
  57. meths.set_option('more', true)
  58. eq('\nabc ^@ def\nghi^@^@^@jkl\nTEST\n\n\nT\n',
  59. redir_exec([[lua print("abc \0 def\nghi\0\0\0jkl\nTEST\n\n\nT\n")]]))
  60. eq('\nabc ^@ def\nghi^@^@^@jkl\nTEST\n\n\nT^@',
  61. redir_exec([[lua print("abc \0 def\nghi\0\0\0jkl\nTEST\n\n\nT\0")]]))
  62. eq('\nT^@', redir_exec([[lua print("T\0")]]))
  63. eq('\nT\n', redir_exec([[lua print("T\n")]]))
  64. end)
  65. it('prints empty strings correctly', function()
  66. -- Regression: first test used to crash
  67. eq('', redir_exec('lua print("")'))
  68. eq('\n def', redir_exec('lua print("", "def")'))
  69. eq('\nabc ', redir_exec('lua print("abc", "")'))
  70. eq('\nabc def', redir_exec('lua print("abc", "", "def")'))
  71. end)
  72. it('defers printing in luv event handlers', function()
  73. exec_lua([[
  74. local cmd = ...
  75. function test()
  76. local timer = vim.loop.new_timer()
  77. local done = false
  78. timer:start(10, 0, function()
  79. print("very fast")
  80. timer:close()
  81. done = true
  82. end)
  83. -- be kind to slow travis OS X jobs:
  84. -- loop until we know for sure the callback has been executed
  85. while not done do
  86. os.execute(cmd)
  87. vim.loop.run("nowait") -- fake os_breakcheck()
  88. end
  89. print("very slow")
  90. vim.api.nvim_command("sleep 1m") -- force deferred event processing
  91. end
  92. ]], (iswin() and "timeout 1") or "sleep 0.1")
  93. eq('\nvery slow\nvery fast',redir_exec('lua test()'))
  94. end)
  95. end)
  96. describe('debug.debug', function()
  97. before_each(function()
  98. screen = Screen.new()
  99. screen:attach()
  100. screen:set_default_attr_ids({
  101. [0] = {bold=true, foreground=255},
  102. E = {foreground = Screen.colors.Grey100, background = Screen.colors.Red},
  103. cr = {bold = true, foreground = Screen.colors.SeaGreen4},
  104. })
  105. command("set display-=msgsep")
  106. end)
  107. it('works', function()
  108. command([[lua
  109. function Test(a)
  110. print(a)
  111. debug.debug()
  112. print(a * 100)
  113. end
  114. ]])
  115. feed(':lua Test()\n')
  116. screen:expect([[
  117. {0:~ }|
  118. {0:~ }|
  119. {0:~ }|
  120. {0:~ }|
  121. {0:~ }|
  122. {0:~ }|
  123. {0:~ }|
  124. {0:~ }|
  125. {0:~ }|
  126. {0:~ }|
  127. {0:~ }|
  128. {0:~ }|
  129. nil |
  130. lua_debug> ^ |
  131. ]])
  132. feed('print("TEST")\n')
  133. screen:expect([[
  134. {0:~ }|
  135. {0:~ }|
  136. {0:~ }|
  137. {0:~ }|
  138. {0:~ }|
  139. {0:~ }|
  140. {0:~ }|
  141. {0:~ }|
  142. {0:~ }|
  143. {0:~ }|
  144. nil |
  145. lua_debug> print("TEST") |
  146. TEST |
  147. lua_debug> ^ |
  148. ]])
  149. feed('<C-c>')
  150. screen:expect{grid=[[
  151. {0:~ }|
  152. {0:~ }|
  153. {0:~ }|
  154. {0:~ }|
  155. {0:~ }|
  156. {0:~ }|
  157. {0:~ }|
  158. nil |
  159. lua_debug> print("TEST") |
  160. TEST |
  161. |
  162. {E:E5108: Error executing lua [string ":lua"]:5: attempt}|
  163. {E: to perform arithmetic on local 'a' (a nil value)} |
  164. Interrupt: {cr:Press ENTER or type command to continue}^ |
  165. ]]}
  166. feed('<C-l>:lua Test()\n')
  167. screen:expect([[
  168. {0:~ }|
  169. {0:~ }|
  170. {0:~ }|
  171. {0:~ }|
  172. {0:~ }|
  173. {0:~ }|
  174. {0:~ }|
  175. {0:~ }|
  176. {0:~ }|
  177. {0:~ }|
  178. {0:~ }|
  179. {0:~ }|
  180. nil |
  181. lua_debug> ^ |
  182. ]])
  183. feed('\n')
  184. screen:expect{grid=[[
  185. {0:~ }|
  186. {0:~ }|
  187. {0:~ }|
  188. {0:~ }|
  189. {0:~ }|
  190. {0:~ }|
  191. {0:~ }|
  192. {0:~ }|
  193. {0:~ }|
  194. nil |
  195. lua_debug> |
  196. {E:E5108: Error executing lua [string ":lua"]:5: attempt}|
  197. {E: to perform arithmetic on local 'a' (a nil value)} |
  198. {cr:Press ENTER or type command to continue}^ |
  199. ]]}
  200. end)
  201. it("can be safely exited with 'cont'", function()
  202. feed('<cr>')
  203. feed(':lua debug.debug() print("x")<cr>')
  204. screen:expect{grid=[[
  205. |
  206. {0:~ }|
  207. {0:~ }|
  208. {0:~ }|
  209. {0:~ }|
  210. {0:~ }|
  211. {0:~ }|
  212. {0:~ }|
  213. {0:~ }|
  214. {0:~ }|
  215. {0:~ }|
  216. {0:~ }|
  217. {0:~ }|
  218. lua_debug> ^ |
  219. ]]}
  220. feed("conttt<cr>") -- misspelled cont; invalid syntax
  221. screen:expect{grid=[[
  222. {0:~ }|
  223. {0:~ }|
  224. {0:~ }|
  225. {0:~ }|
  226. {0:~ }|
  227. {0:~ }|
  228. {0:~ }|
  229. {0:~ }|
  230. {0:~ }|
  231. {0:~ }|
  232. lua_debug> conttt |
  233. {E:E5115: Error while loading debug string: (debug comma}|
  234. {E:nd):1: '=' expected near '<eof>'} |
  235. lua_debug> ^ |
  236. ]]}
  237. feed("cont<cr>") -- exactly "cont", exit now
  238. screen:expect{grid=[[
  239. {0:~ }|
  240. {0:~ }|
  241. {0:~ }|
  242. {0:~ }|
  243. {0:~ }|
  244. {0:~ }|
  245. {0:~ }|
  246. {0:~ }|
  247. lua_debug> conttt |
  248. {E:E5115: Error while loading debug string: (debug comma}|
  249. {E:nd):1: '=' expected near '<eof>'} |
  250. lua_debug> cont |
  251. x |
  252. {cr:Press ENTER or type command to continue}^ |
  253. ]]}
  254. feed('<cr>')
  255. screen:expect{grid=[[
  256. ^ |
  257. {0:~ }|
  258. {0:~ }|
  259. {0:~ }|
  260. {0:~ }|
  261. {0:~ }|
  262. {0:~ }|
  263. {0:~ }|
  264. {0:~ }|
  265. {0:~ }|
  266. {0:~ }|
  267. {0:~ }|
  268. {0:~ }|
  269. |
  270. ]]}
  271. end)
  272. end)
  273. describe('os.getenv', function()
  274. it('returns nothing for undefined env var', function()
  275. eq(NIL, funcs.luaeval('os.getenv("XTEST_1")'))
  276. end)
  277. it('returns env var set by the parent process', function()
  278. local value = 'foo'
  279. clear({env = {['XTEST_1']=value}})
  280. eq(value, funcs.luaeval('os.getenv("XTEST_1")'))
  281. end)
  282. it('returns env var set by let', function()
  283. local value = 'foo'
  284. meths.command('let $XTEST_1 = "'..value..'"')
  285. eq(value, funcs.luaeval('os.getenv("XTEST_1")'))
  286. end)
  287. end)