remote_spec.lua 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. local t = require('test.testutil')
  2. local n = require('test.functional.testnvim')()
  3. local clear = n.clear
  4. local command = n.command
  5. local eq = t.eq
  6. local exec_capture = n.exec_capture
  7. local exec_lua = n.exec_lua
  8. local expect = n.expect
  9. local fn = n.fn
  10. local insert = n.insert
  11. local nvim_prog = n.nvim_prog
  12. local neq = t.neq
  13. local set_session = n.set_session
  14. local tmpname = t.tmpname
  15. local write_file = t.write_file
  16. describe('Remote', function()
  17. local fname, other_fname
  18. local contents = 'The call is coming from outside the process'
  19. local other_contents = "A second file's contents"
  20. before_each(function()
  21. fname = tmpname() .. ' with spaces in the filename'
  22. other_fname = tmpname()
  23. write_file(fname, contents)
  24. write_file(other_fname, other_contents)
  25. end)
  26. describe('connect to server and', function()
  27. local server
  28. before_each(function()
  29. server = n.clear()
  30. end)
  31. after_each(function()
  32. server:close()
  33. end)
  34. -- Run a `nvim --remote*` command and return { stdout, stderr } of the process
  35. local function run_remote(...)
  36. set_session(server)
  37. local addr = fn.serverlist()[1]
  38. -- Create an nvim instance just to run the remote-invoking nvim. We want
  39. -- to wait for the remote instance to exit and calling jobwait blocks
  40. -- the event loop. If the server event loop is blocked, it can't process
  41. -- our incoming --remote calls.
  42. local client_starter = n.new_session(true)
  43. set_session(client_starter)
  44. -- Call jobstart() and jobwait() in the same RPC request to reduce flakiness.
  45. eq(
  46. { 0 },
  47. exec_lua(
  48. [[return vim.fn.jobwait({ vim.fn.jobstart({...}, {
  49. stdout_buffered = true,
  50. stderr_buffered = true,
  51. on_stdout = function(_, data, _)
  52. _G.Remote_stdout = table.concat(data, '\n')
  53. end,
  54. on_stderr = function(_, data, _)
  55. _G.Remote_stderr = table.concat(data, '\n')
  56. end,
  57. }) })]],
  58. nvim_prog,
  59. '--clean',
  60. '--headless',
  61. '--server',
  62. addr,
  63. ...
  64. )
  65. )
  66. local res = exec_lua([[return { _G.Remote_stdout, _G.Remote_stderr }]])
  67. client_starter:close()
  68. set_session(server)
  69. return res
  70. end
  71. it('edit a single file', function()
  72. eq({ '', '' }, run_remote('--remote', fname))
  73. expect(contents)
  74. eq(1, #fn.getbufinfo())
  75. end)
  76. it('tab edit a single file with a non-changed buffer', function()
  77. eq({ '', '' }, run_remote('--remote-tab', fname))
  78. expect(contents)
  79. eq(1, #fn.gettabinfo())
  80. end)
  81. it('tab edit a single file with a changed buffer', function()
  82. insert('hello')
  83. eq({ '', '' }, run_remote('--remote-tab', fname))
  84. expect(contents)
  85. eq(2, #fn.gettabinfo())
  86. end)
  87. it('edit multiple files', function()
  88. eq({ '', '' }, run_remote('--remote', fname, other_fname))
  89. expect(contents)
  90. command('next')
  91. expect(other_contents)
  92. eq(2, #fn.getbufinfo())
  93. end)
  94. it('send keys', function()
  95. eq({ '', '' }, run_remote('--remote-send', ':edit ' .. fname .. '<CR><C-W>v'))
  96. expect(contents)
  97. eq(2, #fn.getwininfo())
  98. -- Only a single buffer as we're using edit and not drop like --remote does
  99. eq(1, #fn.getbufinfo())
  100. end)
  101. it('evaluate expressions', function()
  102. eq({ '0', '' }, run_remote('--remote-expr', 'setline(1, "Yo")'))
  103. eq({ 'Yo', '' }, run_remote('--remote-expr', 'getline(1)'))
  104. expect('Yo')
  105. eq({ ('k'):rep(1234), '' }, run_remote('--remote-expr', 'repeat("k", 1234)'))
  106. eq({ '1.25', '' }, run_remote('--remote-expr', '1.25'))
  107. eq({ 'no', '' }, run_remote('--remote-expr', '0z6E6F'))
  108. eq({ '\t', '' }, run_remote('--remote-expr', '"\t"'))
  109. end)
  110. end)
  111. it('creates server if not found', function()
  112. clear('--remote', fname)
  113. expect(contents)
  114. eq(1, #fn.getbufinfo())
  115. -- Since we didn't pass silent, we should get a complaint
  116. neq(nil, string.find(exec_capture('messages'), 'E247:'))
  117. end)
  118. it('creates server if not found with tabs', function()
  119. clear('--remote-tab-silent', fname, other_fname)
  120. expect(contents)
  121. eq(2, #fn.gettabinfo())
  122. eq(2, #fn.getbufinfo())
  123. -- We passed silent, so no message should be issued about the server not being found
  124. eq(nil, string.find(exec_capture('messages'), 'E247:'))
  125. end)
  126. describe('exits with error on', function()
  127. local function run_and_check_exit_code(...)
  128. local p = n.spawn_wait { args = { ... } }
  129. eq(2, p.status)
  130. end
  131. it('bogus subcommand', function()
  132. run_and_check_exit_code('--remote-bogus')
  133. end)
  134. it('send without server', function()
  135. run_and_check_exit_code('--remote-send', 'i')
  136. end)
  137. it('expr without server', function()
  138. run_and_check_exit_code('--remote-expr', 'setline(1, "Yo")')
  139. end)
  140. it('wait subcommand', function()
  141. run_and_check_exit_code('--remote-wait', fname)
  142. end)
  143. end)
  144. end)