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