115bf76d4SBram Moolenaar" Tests for the +clientserver feature.
215bf76d4SBram Moolenaar
38c5a278fSBram Moolenaarsource check.vim
48c5a278fSBram MoolenaarCheckFeature job
5ee4e0c1eSBram Moolenaar
6ee4e0c1eSBram Moolenaarif !has('clientserver')
7ee4e0c1eSBram Moolenaar  call assert_fails('call remote_startserver("local")', 'E942:')
8ee4e0c1eSBram Moolenaarendif
9ee4e0c1eSBram Moolenaar
108c5a278fSBram MoolenaarCheckFeature clientserver
1115bf76d4SBram Moolenaar
1215bf76d4SBram Moolenaarsource shared.vim
1315bf76d4SBram Moolenaar
14cde0ff39SBram Moolenaarfunc Check_X11_Connection()
15a683ec44SBram Moolenaar  if has('x11')
16d6fa7bd5SBram Moolenaar    CheckEnv DISPLAY
17a2845b8fSBram Moolenaar    try
18a2845b8fSBram Moolenaar      call remote_send('xxx', '')
19a2845b8fSBram Moolenaar    catch
20a2845b8fSBram Moolenaar      if v:exception =~ 'E240:'
21a683ec44SBram Moolenaar        throw 'Skipped: no connection to the X server'
22a2845b8fSBram Moolenaar      endif
23a2845b8fSBram Moolenaar      " ignore other errors
24a2845b8fSBram Moolenaar    endtry
25a2845b8fSBram Moolenaar  endif
26cde0ff39SBram Moolenaarendfunc
27cde0ff39SBram Moolenaar
28cde0ff39SBram Moolenaarfunc Test_client_server()
29*f08b0eb8SBram Moolenaar  let g:test_is_flaky = 1
30cde0ff39SBram Moolenaar  let cmd = GetVimCommand()
31cde0ff39SBram Moolenaar  if cmd == ''
326d91bcb4SBram Moolenaar    throw 'GetVimCommand() failed'
33cde0ff39SBram Moolenaar  endif
34cde0ff39SBram Moolenaar  call Check_X11_Connection()
3542205551SBram Moolenaar
3642205551SBram Moolenaar  let name = 'XVIMTEST'
3715bf76d4SBram Moolenaar  let cmd .= ' --servername ' . name
38ab8b1c14SBram Moolenaar  let job = job_start(cmd, {'stoponexit': 'kill', 'out_io': 'null'})
3950182fa8SBram Moolenaar  call WaitForAssert({-> assert_equal("run", job_status(job))})
4015bf76d4SBram Moolenaar
4115bf76d4SBram Moolenaar  " Takes a short while for the server to be active.
429d189613SBram Moolenaar  " When using valgrind it takes much longer.
4350182fa8SBram Moolenaar  call WaitForAssert({-> assert_match(name, serverlist())})
4415bf76d4SBram Moolenaar
45c5cf369eSBram Moolenaar  if !has('win32')
46c5cf369eSBram Moolenaar    if RunVim([], [], '--serverlist >Xtest_serverlist')
47c5cf369eSBram Moolenaar      let lines = readfile('Xtest_serverlist')
48c5cf369eSBram Moolenaar      call assert_true(index(lines, 'XVIMTEST') >= 0)
49c5cf369eSBram Moolenaar    endif
50c5cf369eSBram Moolenaar    call delete('Xtest_serverlist')
51c5cf369eSBram Moolenaar  endif
52c5cf369eSBram Moolenaar
53a0d1fef4SBram Moolenaar  eval name->remote_foreground()
5415bf76d4SBram Moolenaar
5515bf76d4SBram Moolenaar  call remote_send(name, ":let testvar = 'yes'\<CR>")
56d97fbf17SBram Moolenaar  call WaitFor('remote_expr("' . name . '", "exists(\"testvar\") ? testvar : \"\"", "", 1) == "yes"')
5781b9d0bdSBram Moolenaar  call assert_equal('yes', remote_expr(name, "testvar", "", 2))
58ca68ae13SBram Moolenaar  call assert_fails("let x=remote_expr(name, '2+x')", 'E449:')
59ca68ae13SBram Moolenaar  call assert_fails("let x=remote_expr('[], '2+2')", 'E116:')
6015bf76d4SBram Moolenaar
617416f3e7SBram Moolenaar  if has('unix') && has('gui') && !has('gui_running')
6260964f68SBram Moolenaar    " Running in a terminal and the GUI is available: Tell the server to open
637416f3e7SBram Moolenaar    " the GUI and check that the remote command still works.
647416f3e7SBram Moolenaar    " Need to wait for the GUI to start up, otherwise the send hangs in trying
657416f3e7SBram Moolenaar    " to send to the terminal window.
6681b9d0bdSBram Moolenaar    if has('gui_athena') || has('gui_motif')
6781b9d0bdSBram Moolenaar      " For those GUIs, ignore the 'failed to create input context' error.
6881b9d0bdSBram Moolenaar      call remote_send(name, ":call test_ignore_error('E285') | gui -f\<CR>")
6981b9d0bdSBram Moolenaar    else
707416f3e7SBram Moolenaar      call remote_send(name, ":gui -f\<CR>")
7181b9d0bdSBram Moolenaar    endif
7281b9d0bdSBram Moolenaar    " Wait for the server to be up and answering requests.
7318dc3553SBram Moolenaar    " When using valgrind this can be very, very slow.
7418dc3553SBram Moolenaar    sleep 1
7518dc3553SBram Moolenaar    call WaitForAssert({-> assert_match('\d', name->remote_expr("v:version", "", 1))}, 10000)
7681b9d0bdSBram Moolenaar
777416f3e7SBram Moolenaar    call remote_send(name, ":let testvar = 'maybe'\<CR>")
7850182fa8SBram Moolenaar    call WaitForAssert({-> assert_equal('maybe', remote_expr(name, "testvar", "", 2))})
797416f3e7SBram Moolenaar  endif
807416f3e7SBram Moolenaar
81e2e4075fSBram Moolenaar  call assert_fails('call remote_send("XXX", ":let testvar = ''yes''\<CR>")', 'E241:')
827416f3e7SBram Moolenaar
83e4862a0fSBram Moolenaar  call writefile(['one'], 'Xclientfile')
84e4862a0fSBram Moolenaar  let cmd = GetVimProg() .. ' --servername ' .. name .. ' --remote Xclientfile'
85e4862a0fSBram Moolenaar  call system(cmd)
86e4862a0fSBram Moolenaar  call WaitForAssert({-> assert_equal('Xclientfile', remote_expr(name, "bufname()", "", 2))})
87e4862a0fSBram Moolenaar  call WaitForAssert({-> assert_equal('one', remote_expr(name, "getline(1)", "", 2))})
88e4862a0fSBram Moolenaar  call writefile(['one', 'two'], 'Xclientfile')
89e4862a0fSBram Moolenaar  call system(cmd)
90e4862a0fSBram Moolenaar  call WaitForAssert({-> assert_equal('two', remote_expr(name, "getline(2)", "", 2))})
9148e11c10SBram Moolenaar  call delete('Xclientfile')
92e4862a0fSBram Moolenaar
937416f3e7SBram Moolenaar  " Expression evaluated locally.
947416f3e7SBram Moolenaar  if v:servername == ''
95a0d1fef4SBram Moolenaar    eval 'MYSELF'->remote_startserver()
9681b9d0bdSBram Moolenaar    " May get MYSELF1 when running the test again.
9781b9d0bdSBram Moolenaar    call assert_match('MYSELF', v:servername)
98ca68ae13SBram Moolenaar    call assert_fails("call remote_startserver('MYSELF')", 'E941:')
997416f3e7SBram Moolenaar  endif
1007416f3e7SBram Moolenaar  let g:testvar = 'myself'
1017416f3e7SBram Moolenaar  call assert_equal('myself', remote_expr(v:servername, 'testvar'))
102cde0ff39SBram Moolenaar  call remote_send(v:servername, ":let g:testvar2 = 75\<CR>")
103cde0ff39SBram Moolenaar  call feedkeys('', 'x')
104cde0ff39SBram Moolenaar  call assert_equal(75, g:testvar2)
1059b7bf9e9SBram Moolenaar  call assert_fails('let v = remote_expr(v:servername, "/2")', ['E15:.*/2'])
1067416f3e7SBram Moolenaar
1077416f3e7SBram Moolenaar  call remote_send(name, ":call server2client(expand('<client>'), 'got it')\<CR>", 'g:myserverid')
108a0d1fef4SBram Moolenaar  call assert_equal('got it', g:myserverid->remote_read(2))
1097416f3e7SBram Moolenaar
110196b4664SBram Moolenaar  call remote_send(name, ":eval expand('<client>')->server2client('another')\<CR>", 'g:myserverid')
1116caf606bSBram Moolenaar  let peek_result = 'nothing'
112a0d1fef4SBram Moolenaar  let r = g:myserverid->remote_peek('peek_result')
113ab8b1c14SBram Moolenaar  " unpredictable whether the result is already available.
1146caf606bSBram Moolenaar  if r > 0
1156caf606bSBram Moolenaar    call assert_equal('another', peek_result)
1166caf606bSBram Moolenaar  elseif r == 0
1176caf606bSBram Moolenaar    call assert_equal('nothing', peek_result)
1186caf606bSBram Moolenaar  else
1196caf606bSBram Moolenaar    call assert_report('remote_peek() failed')
1206caf606bSBram Moolenaar  endif
1216caf606bSBram Moolenaar  let g:peek_result = 'empty'
1226caf606bSBram Moolenaar  call WaitFor('remote_peek(g:myserverid, "g:peek_result") > 0')
1236caf606bSBram Moolenaar  call assert_equal('another', g:peek_result)
12481b9d0bdSBram Moolenaar  call assert_equal('another', remote_read(g:myserverid, 2))
1256caf606bSBram Moolenaar
126cde0ff39SBram Moolenaar  if !has('gui_running')
127cde0ff39SBram Moolenaar    " In GUI vim, the following tests display a dialog box
128cde0ff39SBram Moolenaar
129cde0ff39SBram Moolenaar    let cmd = GetVimProg() .. ' --servername ' .. name
130cde0ff39SBram Moolenaar
131cde0ff39SBram Moolenaar    " Run a separate instance to send a command to the server
132cde0ff39SBram Moolenaar    call remote_expr(name, 'execute("only")')
133cde0ff39SBram Moolenaar    call system(cmd .. ' --remote-send ":new Xfile<CR>"')
134cde0ff39SBram Moolenaar    call assert_equal('2', remote_expr(name, 'winnr("$")'))
135cde0ff39SBram Moolenaar    call assert_equal('Xfile', remote_expr(name, 'winbufnr(1)->bufname()'))
136cde0ff39SBram Moolenaar    call remote_expr(name, 'execute("only")')
137cde0ff39SBram Moolenaar
138cde0ff39SBram Moolenaar    " Invoke a remote-expr. On MS-Windows, the returned value has a carriage
139cde0ff39SBram Moolenaar    " return.
140cde0ff39SBram Moolenaar    let l = system(cmd .. ' --remote-expr "2 + 2"')
141cde0ff39SBram Moolenaar    call assert_equal(['4'], split(l, "\n"))
142cde0ff39SBram Moolenaar
143cde0ff39SBram Moolenaar    " Edit multiple files using --remote
144cde0ff39SBram Moolenaar    call system(cmd .. ' --remote Xfile1 Xfile2 Xfile3')
14541a834d1SBram Moolenaar    call assert_match(".*Xfile1\n.*Xfile2\n.*Xfile3\n", remote_expr(name, 'argv()'))
146cde0ff39SBram Moolenaar    eval name->remote_send(":%bw!\<CR>")
147cde0ff39SBram Moolenaar
148cde0ff39SBram Moolenaar    " Edit files in separate tab pages
149cde0ff39SBram Moolenaar    call system(cmd .. ' --remote-tab Xfile1 Xfile2 Xfile3')
15025d57009SBram Moolenaar    call WaitForAssert({-> assert_equal('3', remote_expr(name, 'tabpagenr("$")'))})
15141a834d1SBram Moolenaar    call assert_match('.*\<Xfile2', remote_expr(name, 'bufname(tabpagebuflist(2)[0])'))
152cde0ff39SBram Moolenaar    eval name->remote_send(":%bw!\<CR>")
153cde0ff39SBram Moolenaar
154cde0ff39SBram Moolenaar    " Edit a file using --remote-wait
155cde0ff39SBram Moolenaar    eval name->remote_send(":source $VIMRUNTIME/plugin/rrhelper.vim\<CR>")
156cde0ff39SBram Moolenaar    call system(cmd .. ' --remote-wait +enew Xfile1')
15741a834d1SBram Moolenaar    call assert_match('.*\<Xfile1', remote_expr(name, 'bufname("#")'))
158cde0ff39SBram Moolenaar    eval name->remote_send(":%bw!\<CR>")
159cde0ff39SBram Moolenaar
160cde0ff39SBram Moolenaar    " Edit files using --remote-tab-wait
161cde0ff39SBram Moolenaar    call system(cmd .. ' --remote-tabwait +tabonly\|enew Xfile1 Xfile2')
162cde0ff39SBram Moolenaar    call assert_equal('1', remote_expr(name, 'tabpagenr("$")'))
163cde0ff39SBram Moolenaar    eval name->remote_send(":%bw!\<CR>")
164cde0ff39SBram Moolenaar
165cde0ff39SBram Moolenaar    " Error cases
166cde0ff39SBram Moolenaar    if v:lang == "C" || v:lang =~ '^[Ee]n'
167cde0ff39SBram Moolenaar      let l = split(system(cmd .. ' --remote +pwd'), "\n")
168cde0ff39SBram Moolenaar      call assert_equal("Argument missing after: \"+pwd\"", l[1])
169cde0ff39SBram Moolenaar    endif
170cde0ff39SBram Moolenaar    let l = system(cmd .. ' --remote-expr "abcd"')
171cde0ff39SBram Moolenaar    call assert_match('^E449: ', l)
172cde0ff39SBram Moolenaar  endif
173cde0ff39SBram Moolenaar
174cde0ff39SBram Moolenaar  eval name->remote_send(":%bw!\<CR>")
175a0d1fef4SBram Moolenaar  eval name->remote_send(":qa!\<CR>")
176ab8b1c14SBram Moolenaar  try
17750182fa8SBram Moolenaar    call WaitForAssert({-> assert_equal("dead", job_status(job))})
178ab8b1c14SBram Moolenaar  finally
179ab8b1c14SBram Moolenaar    if job_status(job) != 'dead'
18042205551SBram Moolenaar      call assert_report('Server did not exit')
181ab8b1c14SBram Moolenaar      call job_stop(job, 'kill')
18215bf76d4SBram Moolenaar    endif
183ab8b1c14SBram Moolenaar  endtry
1840e05de46SBram Moolenaar
18599fa7219SBram Moolenaar  call assert_fails('call remote_startserver([])', 'E730:')
1860e05de46SBram Moolenaar  call assert_fails("let x = remote_peek([])", 'E730:')
1874d57ba02SBram Moolenaar  call assert_fails("let x = remote_read('vim10')",
188c212dd0aSBram Moolenaar        \ has('unix') ? ['E573:.*vim10'] : 'E277:')
1894d57ba02SBram Moolenaar  call assert_fails("call server2client('abc', 'xyz')",
190c212dd0aSBram Moolenaar        \ has('unix') ? ['E573:.*abc'] : 'E258:')
19115bf76d4SBram Moolenaarendfunc
19215bf76d4SBram Moolenaar
19315bf76d4SBram Moolenaar" Uncomment this line to get a debugging log
19415bf76d4SBram Moolenaar" call ch_logfile('channellog', 'w')
1950e05de46SBram Moolenaar
1960e05de46SBram Moolenaar" vim: shiftwidth=2 sts=2 expandtab
197