blob: af9060a78f402ba52de15fb5a99a9acd8917eb65 [file] [log] [blame]
Bram Moolenaard7ece102016-02-02 23:23:02 +01001" Test for channel functions.
2scriptencoding utf-8
3
Bram Moolenaare2469252016-02-04 10:54:34 +01004if !has('channel')
5 finish
6endif
7
Bram Moolenaar321efdd2016-07-15 17:09:11 +02008source shared.vim
9
10let s:python = PythonProg()
11if s:python == ''
Bram Moolenaard6a8d482016-02-10 20:32:20 +010012 " Can't run this test.
Bram Moolenaard7ece102016-02-02 23:23:02 +010013 finish
14endif
15
Bram Moolenaare74e8e72016-02-16 22:01:30 +010016let s:chopt = {}
Bram Moolenaar3b05b132016-02-03 23:25:07 +010017
Bram Moolenaard6a8d482016-02-10 20:32:20 +010018" Run "testfunc" after sarting the server and stop the server afterwards.
Bram Moolenaar81661fb2016-02-18 22:23:34 +010019func s:run_server(testfunc, ...)
Bram Moolenaar321efdd2016-07-15 17:09:11 +020020 call RunServer('test_channel.py', a:testfunc, a:000)
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +010021endfunc
22
Bram Moolenaar321efdd2016-07-15 17:09:11 +020023let g:Ch_responseMsg = ''
24func Ch_requestHandler(handle, msg)
25 let g:Ch_responseHandle = a:handle
26 let g:Ch_responseMsg = a:msg
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +010027endfunc
28
Bram Moolenaar321efdd2016-07-15 17:09:11 +020029func Ch_communicate(port)
Bram Moolenaard6a8d482016-02-10 20:32:20 +010030 let handle = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar77073442016-02-13 23:23:53 +010031 if ch_status(handle) == "fail"
Bram Moolenaard6a8d482016-02-10 20:32:20 +010032 call assert_false(1, "Can't open channel")
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +010033 return
34 endif
Bram Moolenaar839fd112016-03-06 21:34:03 +010035 if has('job')
Bram Moolenaar03602ec2016-03-20 20:57:45 +010036 " check that getjob without a job is handled correctly
Bram Moolenaar839fd112016-03-06 21:34:03 +010037 call assert_equal('no process', string(ch_getjob(handle)))
38 endif
Bram Moolenaar03602ec2016-03-20 20:57:45 +010039 let dict = ch_info(handle)
40 call assert_true(dict.id != 0)
41 call assert_equal('open', dict.status)
42 call assert_equal(a:port, string(dict.port))
43 call assert_equal('open', dict.sock_status)
44 call assert_equal('socket', dict.sock_io)
45
Bram Moolenaard7ece102016-02-02 23:23:02 +010046 " Simple string request and reply.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +010047 call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
Bram Moolenaard7ece102016-02-02 23:23:02 +010048
Bram Moolenaarac74d5e2016-03-20 14:31:00 +010049 " Malformed command should be ignored.
Bram Moolenaarba61ac02016-03-20 16:40:37 +010050 call assert_equal('ok', ch_evalexpr(handle, 'malformed1'))
51 call assert_equal('ok', ch_evalexpr(handle, 'malformed2'))
52 call assert_equal('ok', ch_evalexpr(handle, 'malformed3'))
53
54 " split command should work
55 call assert_equal('ok', ch_evalexpr(handle, 'split'))
Bram Moolenaar321efdd2016-07-15 17:09:11 +020056 call WaitFor('exists("g:split")')
Bram Moolenaarba61ac02016-03-20 16:40:37 +010057 call assert_equal(123, g:split)
Bram Moolenaarac74d5e2016-03-20 14:31:00 +010058
Bram Moolenaard7ece102016-02-02 23:23:02 +010059 " Request that triggers sending two ex commands. These will usually be
60 " handled before getting the response, but it's not guaranteed, thus wait a
61 " tiny bit for the commands to get executed.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +010062 call assert_equal('ok', ch_evalexpr(handle, 'make change'))
Bram Moolenaar321efdd2016-07-15 17:09:11 +020063 call WaitFor('"added2" == getline("$")')
Bram Moolenaard7ece102016-02-02 23:23:02 +010064 call assert_equal('added1', getline(line('$') - 1))
65 call assert_equal('added2', getline('$'))
66
Bram Moolenaarc4dcd602016-03-26 22:56:46 +010067 " Request command "foo bar", which fails silently.
68 call assert_equal('ok', ch_evalexpr(handle, 'bad command'))
Bram Moolenaar321efdd2016-07-15 17:09:11 +020069 call WaitFor('v:errmsg =~ "E492"')
Bram Moolenaarea6553b2016-03-27 15:13:38 +020070 call assert_match('E492:.*foo bar', v:errmsg)
Bram Moolenaarc4dcd602016-03-26 22:56:46 +010071
Bram Moolenaarda94fdf2016-03-03 18:09:10 +010072 call assert_equal('ok', ch_evalexpr(handle, 'do normal', {'timeout': 100}))
Bram Moolenaar321efdd2016-07-15 17:09:11 +020073 call WaitFor('"added more" == getline("$")')
Bram Moolenaarf4160862016-02-05 23:09:12 +010074 call assert_equal('added more', getline('$'))
75
Bram Moolenaara07fec92016-02-05 21:04:08 +010076 " Send a request with a specific handler.
Bram Moolenaar321efdd2016-07-15 17:09:11 +020077 call ch_sendexpr(handle, 'hello!', {'callback': 'Ch_requestHandler'})
78 call WaitFor('exists("g:Ch_responseHandle")')
79 if !exists('g:Ch_responseHandle')
80 call assert_false(1, 'g:Ch_responseHandle was not set')
Bram Moolenaar77073442016-02-13 23:23:53 +010081 else
Bram Moolenaar321efdd2016-07-15 17:09:11 +020082 call assert_equal(handle, g:Ch_responseHandle)
83 unlet g:Ch_responseHandle
Bram Moolenaar77073442016-02-13 23:23:53 +010084 endif
Bram Moolenaar321efdd2016-07-15 17:09:11 +020085 call assert_equal('got it', g:Ch_responseMsg)
Bram Moolenaara07fec92016-02-05 21:04:08 +010086
Bram Moolenaar321efdd2016-07-15 17:09:11 +020087 let g:Ch_responseMsg = ''
88 call ch_sendexpr(handle, 'hello!', {'callback': function('Ch_requestHandler')})
89 call WaitFor('exists("g:Ch_responseHandle")')
90 if !exists('g:Ch_responseHandle')
91 call assert_false(1, 'g:Ch_responseHandle was not set')
Bram Moolenaar77073442016-02-13 23:23:53 +010092 else
Bram Moolenaar321efdd2016-07-15 17:09:11 +020093 call assert_equal(handle, g:Ch_responseHandle)
94 unlet g:Ch_responseHandle
Bram Moolenaar77073442016-02-13 23:23:53 +010095 endif
Bram Moolenaar321efdd2016-07-15 17:09:11 +020096 call assert_equal('got it', g:Ch_responseMsg)
Bram Moolenaarb6a4fee2016-02-11 20:48:34 +010097
Bram Moolenaar069c1e72016-07-15 21:25:08 +020098 " Using lambda.
99 let g:Ch_responseMsg = ''
100 call ch_sendexpr(handle, 'hello!', {'callback': {a, b -> Ch_requestHandler(a, b)}})
101 call WaitFor('exists("g:Ch_responseHandle")')
102 if !exists('g:Ch_responseHandle')
103 call assert_false(1, 'g:Ch_responseHandle was not set')
104 else
105 call assert_equal(handle, g:Ch_responseHandle)
106 unlet g:Ch_responseHandle
107 endif
108 call assert_equal('got it', g:Ch_responseMsg)
109
Bram Moolenaar38fd4bb2016-03-06 16:38:28 +0100110 " Collect garbage, tests that our handle isn't collected.
Bram Moolenaar574860b2016-05-24 17:33:34 +0200111 call test_garbagecollect_now()
Bram Moolenaar38fd4bb2016-03-06 16:38:28 +0100112
Bram Moolenaar40ea1da2016-02-19 22:33:35 +0100113 " check setting options (without testing the effect)
114 call ch_setoptions(handle, {'callback': 's:NotUsed'})
Bram Moolenaar1f6ef662016-02-19 22:59:44 +0100115 call ch_setoptions(handle, {'timeout': 1111})
Bram Moolenaarb6b52522016-02-20 23:30:07 +0100116 call ch_setoptions(handle, {'mode': 'json'})
Bram Moolenaar40ea1da2016-02-19 22:33:35 +0100117 call assert_fails("call ch_setoptions(handle, {'waittime': 111})", "E475")
Bram Moolenaar0ba75a92016-02-19 23:21:26 +0100118 call ch_setoptions(handle, {'callback': ''})
Bram Moolenaar40ea1da2016-02-19 22:33:35 +0100119
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100120 " Send an eval request that works.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100121 call assert_equal('ok', ch_evalexpr(handle, 'eval-works'))
Bram Moolenaara02b3212016-02-04 21:03:33 +0100122 sleep 10m
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100123 call assert_equal([-1, 'foo123'], ch_evalexpr(handle, 'eval-result'))
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100124
Bram Moolenaarfa8b2e12016-03-26 22:19:27 +0100125 " Send an eval request with special characters.
126 call assert_equal('ok', ch_evalexpr(handle, 'eval-special'))
127 sleep 10m
128 call assert_equal([-2, "foo\x7f\x10\x01bar"], ch_evalexpr(handle, 'eval-result'))
129
130 " Send an eval request to get a line with special characters.
131 call setline(3, "a\nb\<CR>c\x01d\x7fe")
132 call assert_equal('ok', ch_evalexpr(handle, 'eval-getline'))
133 sleep 10m
134 call assert_equal([-3, "a\nb\<CR>c\x01d\x7fe"], ch_evalexpr(handle, 'eval-result'))
135
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100136 " Send an eval request that fails.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100137 call assert_equal('ok', ch_evalexpr(handle, 'eval-fails'))
Bram Moolenaara02b3212016-02-04 21:03:33 +0100138 sleep 10m
Bram Moolenaarfa8b2e12016-03-26 22:19:27 +0100139 call assert_equal([-4, 'ERROR'], ch_evalexpr(handle, 'eval-result'))
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100140
Bram Moolenaar55fab432016-02-07 16:53:13 +0100141 " Send an eval request that works but can't be encoded.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100142 call assert_equal('ok', ch_evalexpr(handle, 'eval-error'))
Bram Moolenaar55fab432016-02-07 16:53:13 +0100143 sleep 10m
Bram Moolenaarfa8b2e12016-03-26 22:19:27 +0100144 call assert_equal([-5, 'ERROR'], ch_evalexpr(handle, 'eval-result'))
Bram Moolenaar55fab432016-02-07 16:53:13 +0100145
Bram Moolenaar66624ff2016-02-03 23:59:43 +0100146 " Send a bad eval request. There will be no response.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100147 call assert_equal('ok', ch_evalexpr(handle, 'eval-bad'))
Bram Moolenaara02b3212016-02-04 21:03:33 +0100148 sleep 10m
Bram Moolenaarfa8b2e12016-03-26 22:19:27 +0100149 call assert_equal([-5, 'ERROR'], ch_evalexpr(handle, 'eval-result'))
Bram Moolenaar66624ff2016-02-03 23:59:43 +0100150
Bram Moolenaarf4160862016-02-05 23:09:12 +0100151 " Send an expr request
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100152 call assert_equal('ok', ch_evalexpr(handle, 'an expr'))
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200153 call WaitFor('"three" == getline("$")')
Bram Moolenaarf4160862016-02-05 23:09:12 +0100154 call assert_equal('one', getline(line('$') - 2))
155 call assert_equal('two', getline(line('$') - 1))
156 call assert_equal('three', getline('$'))
157
158 " Request a redraw, we don't check for the effect.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100159 call assert_equal('ok', ch_evalexpr(handle, 'redraw'))
160 call assert_equal('ok', ch_evalexpr(handle, 'redraw!'))
Bram Moolenaarf4160862016-02-05 23:09:12 +0100161
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100162 call assert_equal('ok', ch_evalexpr(handle, 'empty-request'))
Bram Moolenaarf4160862016-02-05 23:09:12 +0100163
Bram Moolenaar6f3a5442016-02-20 19:56:13 +0100164 " Reading while there is nothing available.
Bram Moolenaar9186a272016-02-23 19:34:01 +0100165 call assert_equal(v:none, ch_read(handle, {'timeout': 0}))
166 let start = reltime()
167 call assert_equal(v:none, ch_read(handle, {'timeout': 333}))
168 let elapsed = reltime(start)
169 call assert_true(reltimefloat(elapsed) > 0.3)
170 call assert_true(reltimefloat(elapsed) < 0.6)
Bram Moolenaar6f3a5442016-02-20 19:56:13 +0100171
172 " Send without waiting for a response, then wait for a response.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100173 call ch_sendexpr(handle, 'wait a bit')
Bram Moolenaar6f3a5442016-02-20 19:56:13 +0100174 let resp = ch_read(handle)
175 call assert_equal(type([]), type(resp))
176 call assert_equal(type(11), type(resp[0]))
177 call assert_equal('waited', resp[1])
178
Bram Moolenaard7ece102016-02-02 23:23:02 +0100179 " make the server quit, can't check if this works, should not hang.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100180 call ch_sendexpr(handle, '!quit!')
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100181endfunc
Bram Moolenaard7ece102016-02-02 23:23:02 +0100182
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100183func Test_communicate()
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100184 call ch_log('Test_communicate()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200185 call s:run_server('Ch_communicate')
Bram Moolenaard7ece102016-02-02 23:23:02 +0100186endfunc
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100187
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100188" Test that we can open two channels.
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200189func Ch_two_channels(port)
Bram Moolenaar39b21272016-02-10 23:28:21 +0100190 let handle = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaarf562e722016-07-19 17:25:25 +0200191 call assert_equal(v:t_channel, type(handle))
Bram Moolenaar77073442016-02-13 23:23:53 +0100192 if ch_status(handle) == "fail"
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100193 call assert_false(1, "Can't open channel")
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100194 return
195 endif
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100196
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100197 call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100198
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100199 let newhandle = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar77073442016-02-13 23:23:53 +0100200 if ch_status(newhandle) == "fail"
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100201 call assert_false(1, "Can't open second channel")
202 return
203 endif
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100204 call assert_equal('got it', ch_evalexpr(newhandle, 'hello!'))
205 call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100206
207 call ch_close(handle)
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100208 call assert_equal('got it', ch_evalexpr(newhandle, 'hello!'))
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100209
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100210 call ch_close(newhandle)
211endfunc
212
213func Test_two_channels()
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100214 call ch_log('Test_two_channels()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200215 call s:run_server('Ch_two_channels')
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100216endfunc
217
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100218" Test that a server crash is handled gracefully.
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200219func Ch_server_crash(port)
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100220 let handle = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar77073442016-02-13 23:23:53 +0100221 if ch_status(handle) == "fail"
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100222 call assert_false(1, "Can't open channel")
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100223 return
224 endif
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100225
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100226 call ch_evalexpr(handle, '!crash!')
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100227
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100228 sleep 10m
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100229endfunc
230
231func Test_server_crash()
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100232 call ch_log('Test_server_crash()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200233 call s:run_server('Ch_server_crash')
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100234endfunc
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100235
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100236"""""""""
237
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200238let g:Ch_reply = ""
239func Ch_handler(chan, msg)
240 unlet g:Ch_reply
241 let g:Ch_reply = a:msg
Bram Moolenaarf6157282016-02-10 21:07:14 +0100242endfunc
243
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200244func Ch_channel_handler(port)
Bram Moolenaarb6a4fee2016-02-11 20:48:34 +0100245 let handle = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar77073442016-02-13 23:23:53 +0100246 if ch_status(handle) == "fail"
Bram Moolenaarf6157282016-02-10 21:07:14 +0100247 call assert_false(1, "Can't open channel")
248 return
249 endif
250
251 " Test that it works while waiting on a numbered message.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100252 call assert_equal('ok', ch_evalexpr(handle, 'call me'))
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200253 call WaitFor('"we called you" == g:Ch_reply')
254 call assert_equal('we called you', g:Ch_reply)
Bram Moolenaarf6157282016-02-10 21:07:14 +0100255
256 " Test that it works while not waiting on a numbered message.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100257 call ch_sendexpr(handle, 'call me again')
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200258 call WaitFor('"we did call you" == g:Ch_reply')
259 call assert_equal('we did call you', g:Ch_reply)
Bram Moolenaarf6157282016-02-10 21:07:14 +0100260endfunc
261
262func Test_channel_handler()
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100263 call ch_log('Test_channel_handler()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200264 let s:chopt.callback = 'Ch_handler'
265 call s:run_server('Ch_channel_handler')
266 let s:chopt.callback = function('Ch_handler')
267 call s:run_server('Ch_channel_handler')
Bram Moolenaarb6a4fee2016-02-11 20:48:34 +0100268 unlet s:chopt.callback
Bram Moolenaarf6157282016-02-10 21:07:14 +0100269endfunc
270
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100271"""""""""
272
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200273let g:Ch_reply = ''
274func Ch_zeroHandler(chan, msg)
275 unlet g:Ch_reply
276 let g:Ch_reply = a:msg
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100277endfunc
278
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200279let g:Ch_zero_reply = ''
280func Ch_oneHandler(chan, msg)
281 unlet g:Ch_zero_reply
282 let g:Ch_zero_reply = a:msg
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100283endfunc
284
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200285func Ch_channel_zero(port)
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100286 let handle = ch_open('localhost:' . a:port, s:chopt)
287 if ch_status(handle) == "fail"
288 call assert_false(1, "Can't open channel")
289 return
290 endif
291
292 " Check that eval works.
293 call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
294
295 " Check that eval works if a zero id message is sent back.
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200296 let g:Ch_reply = ''
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100297 call assert_equal('sent zero', ch_evalexpr(handle, 'send zero'))
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100298 if s:has_handler
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200299 call WaitFor('"zero index" == g:Ch_reply')
300 call assert_equal('zero index', g:Ch_reply)
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100301 else
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100302 sleep 20m
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200303 call assert_equal('', g:Ch_reply)
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100304 endif
305
306 " Check that handler works if a zero id message is sent back.
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200307 let g:Ch_reply = ''
308 let g:Ch_zero_reply = ''
309 call ch_sendexpr(handle, 'send zero', {'callback': 'Ch_oneHandler'})
310 call WaitFor('"sent zero" == g:Ch_zero_reply')
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100311 if s:has_handler
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200312 call assert_equal('zero index', g:Ch_reply)
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100313 else
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200314 call assert_equal('', g:Ch_reply)
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100315 endif
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200316 call assert_equal('sent zero', g:Ch_zero_reply)
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100317endfunc
318
319func Test_zero_reply()
320 call ch_log('Test_zero_reply()')
321 " Run with channel handler
322 let s:has_handler = 1
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200323 let s:chopt.callback = 'Ch_zeroHandler'
324 call s:run_server('Ch_channel_zero')
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100325 unlet s:chopt.callback
326
327 " Run without channel handler
328 let s:has_handler = 0
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200329 call s:run_server('Ch_channel_zero')
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100330endfunc
331
332"""""""""
333
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200334let g:Ch_reply1 = ""
335func Ch_handleRaw1(chan, msg)
336 unlet g:Ch_reply1
337 let g:Ch_reply1 = a:msg
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100338endfunc
339
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200340let g:Ch_reply2 = ""
341func Ch_handleRaw2(chan, msg)
342 unlet g:Ch_reply2
343 let g:Ch_reply2 = a:msg
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100344endfunc
345
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200346let g:Ch_reply3 = ""
347func Ch_handleRaw3(chan, msg)
348 unlet g:Ch_reply3
349 let g:Ch_reply3 = a:msg
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100350endfunc
351
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200352func Ch_raw_one_time_callback(port)
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100353 let handle = ch_open('localhost:' . a:port, s:chopt)
354 if ch_status(handle) == "fail"
355 call assert_false(1, "Can't open channel")
356 return
357 endif
358 call ch_setoptions(handle, {'mode': 'raw'})
359
360 " The message are sent raw, we do our own JSON strings here.
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200361 call ch_sendraw(handle, "[1, \"hello!\"]", {'callback': 'Ch_handleRaw1'})
362 call WaitFor('g:Ch_reply1 != ""')
363 call assert_equal("[1, \"got it\"]", g:Ch_reply1)
364 call ch_sendraw(handle, "[2, \"echo something\"]", {'callback': 'Ch_handleRaw2'})
365 call ch_sendraw(handle, "[3, \"wait a bit\"]", {'callback': 'Ch_handleRaw3'})
366 call WaitFor('g:Ch_reply2 != ""')
367 call assert_equal("[2, \"something\"]", g:Ch_reply2)
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100368 " wait for the 200 msec delayed reply
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200369 call WaitFor('g:Ch_reply3 != ""')
370 call assert_equal("[3, \"waited\"]", g:Ch_reply3)
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100371endfunc
372
373func Test_raw_one_time_callback()
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100374 call ch_log('Test_raw_one_time_callback()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200375 call s:run_server('Ch_raw_one_time_callback')
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100376endfunc
377
378"""""""""
379
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100380" Test that trying to connect to a non-existing port fails quickly.
381func Test_connect_waittime()
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100382 call ch_log('Test_connect_waittime()')
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100383 let start = reltime()
Bram Moolenaara4833262016-02-09 23:33:25 +0100384 let handle = ch_open('localhost:9876', s:chopt)
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100385 if ch_status(handle) != "fail"
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100386 " Oops, port does exists.
387 call ch_close(handle)
388 else
389 let elapsed = reltime(start)
Bram Moolenaar74f5e652016-02-07 21:44:49 +0100390 call assert_true(reltimefloat(elapsed) < 1.0)
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100391 endif
392
Bram Moolenaar08298fa2016-02-21 13:01:53 +0100393 " We intend to use a socket that doesn't exist and wait for half a second
394 " before giving up. If the socket does exist it can fail in various ways.
395 " Check for "Connection reset by peer" to avoid flakyness.
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100396 let start = reltime()
Bram Moolenaar08298fa2016-02-21 13:01:53 +0100397 try
398 let handle = ch_open('localhost:9867', {'waittime': 500})
399 if ch_status(handle) != "fail"
400 " Oops, port does exists.
401 call ch_close(handle)
402 else
Bram Moolenaarac42afd2016-03-12 13:48:49 +0100403 " Failed connection should wait about 500 msec. Can be longer if the
404 " computer is busy with other things.
Bram Moolenaar08298fa2016-02-21 13:01:53 +0100405 let elapsed = reltime(start)
406 call assert_true(reltimefloat(elapsed) > 0.3)
Bram Moolenaarac42afd2016-03-12 13:48:49 +0100407 call assert_true(reltimefloat(elapsed) < 1.5)
Bram Moolenaar08298fa2016-02-21 13:01:53 +0100408 endif
409 catch
410 if v:exception !~ 'Connection reset by peer'
411 call assert_false(1, "Caught exception: " . v:exception)
412 endif
413 endtry
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100414endfunc
Bram Moolenaar6463ca22016-02-13 17:04:46 +0100415
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100416"""""""""
417
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100418func Test_raw_pipe()
419 if !has('job')
420 return
421 endif
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100422 call ch_log('Test_raw_pipe()')
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100423 let job = job_start(s:python . " test_channel_pipe.py", {'mode': 'raw'})
Bram Moolenaarf562e722016-07-19 17:25:25 +0200424 call assert_equal(v:t_job, type(job))
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100425 call assert_equal("run", job_status(job))
426 try
Bram Moolenaar151f6562016-03-07 21:19:38 +0100427 " For a change use the job where a channel is expected.
428 call ch_sendraw(job, "echo something\n")
429 let msg = ch_readraw(job)
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100430 call assert_equal("something\n", substitute(msg, "\r", "", 'g'))
431
Bram Moolenaar151f6562016-03-07 21:19:38 +0100432 call ch_sendraw(job, "double this\n")
433 let msg = ch_readraw(job)
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100434 call assert_equal("this\nAND this\n", substitute(msg, "\r", "", 'g'))
435
Bram Moolenaar151f6562016-03-07 21:19:38 +0100436 let reply = ch_evalraw(job, "quit\n", {'timeout': 100})
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100437 call assert_equal("Goodbye!\n", substitute(reply, "\r", "", 'g'))
438 finally
439 call job_stop(job)
440 endtry
Bram Moolenaar8950a562016-03-12 15:22:55 +0100441
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200442 let g:Ch_job = job
443 call WaitFor('"dead" == job_status(g:Ch_job)')
Bram Moolenaar8950a562016-03-12 15:22:55 +0100444 let info = job_info(job)
445 call assert_equal("dead", info.status)
446 call assert_equal("term", info.stoponexit)
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100447endfunc
448
449func Test_nl_pipe()
Bram Moolenaard8070362016-02-15 21:56:54 +0100450 if !has('job')
Bram Moolenaar6463ca22016-02-13 17:04:46 +0100451 return
452 endif
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100453 call ch_log('Test_nl_pipe()')
Bram Moolenaar1adda342016-03-12 15:39:40 +0100454 let job = job_start([s:python, "test_channel_pipe.py"])
Bram Moolenaar6463ca22016-02-13 17:04:46 +0100455 call assert_equal("run", job_status(job))
456 try
457 let handle = job_getchannel(job)
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100458 call ch_sendraw(handle, "echo something\n")
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100459 call assert_equal("something", ch_readraw(handle))
460
Bram Moolenaarc25558b2016-03-03 21:02:23 +0100461 call ch_sendraw(handle, "echoerr wrong\n")
462 call assert_equal("wrong", ch_readraw(handle, {'part': 'err'}))
463
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100464 call ch_sendraw(handle, "double this\n")
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100465 call assert_equal("this", ch_readraw(handle))
466 call assert_equal("AND this", ch_readraw(handle))
467
Bram Moolenaarbbe8d912016-06-05 16:10:57 +0200468 call ch_sendraw(handle, "split this line\n")
469 call assert_equal("this linethis linethis line", ch_readraw(handle))
470
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100471 let reply = ch_evalraw(handle, "quit\n")
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100472 call assert_equal("Goodbye!", reply)
Bram Moolenaar6463ca22016-02-13 17:04:46 +0100473 finally
474 call job_stop(job)
475 endtry
476endfunc
Bram Moolenaar3bece9f2016-02-15 20:39:46 +0100477
Bram Moolenaarc25558b2016-03-03 21:02:23 +0100478func Test_nl_err_to_out_pipe()
479 if !has('job')
480 return
481 endif
Bram Moolenaar5a6ec522016-03-12 15:51:44 +0100482 call ch_logfile('Xlog')
Bram Moolenaarc25558b2016-03-03 21:02:23 +0100483 call ch_log('Test_nl_err_to_out_pipe()')
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100484 let job = job_start(s:python . " test_channel_pipe.py", {'err_io': 'out'})
Bram Moolenaarc25558b2016-03-03 21:02:23 +0100485 call assert_equal("run", job_status(job))
486 try
487 let handle = job_getchannel(job)
488 call ch_sendraw(handle, "echo something\n")
489 call assert_equal("something", ch_readraw(handle))
490
491 call ch_sendraw(handle, "echoerr wrong\n")
492 call assert_equal("wrong", ch_readraw(handle))
493 finally
494 call job_stop(job)
Bram Moolenaar5a6ec522016-03-12 15:51:44 +0100495 call ch_logfile('')
496 let loglines = readfile('Xlog')
497 call assert_true(len(loglines) > 10)
498 let found_test = 0
499 let found_send = 0
500 let found_recv = 0
501 let found_stop = 0
502 for l in loglines
503 if l =~ 'Test_nl_err_to_out_pipe'
504 let found_test = 1
505 endif
506 if l =~ 'SEND on.*echo something'
507 let found_send = 1
508 endif
509 if l =~ 'RECV on.*something'
510 let found_recv = 1
511 endif
512 if l =~ 'Stopping job with'
513 let found_stop = 1
514 endif
515 endfor
516 call assert_equal(1, found_test)
517 call assert_equal(1, found_send)
518 call assert_equal(1, found_recv)
519 call assert_equal(1, found_stop)
520 call delete('Xlog')
Bram Moolenaarc25558b2016-03-03 21:02:23 +0100521 endtry
522endfunc
523
Bram Moolenaarb69fccf2016-03-06 23:06:25 +0100524func Test_nl_read_file()
525 if !has('job')
526 return
527 endif
Bram Moolenaarb69fccf2016-03-06 23:06:25 +0100528 call ch_log('Test_nl_read_file()')
529 call writefile(['echo something', 'echoerr wrong', 'double this'], 'Xinput')
530 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100531 \ {'in_io': 'file', 'in_name': 'Xinput'})
Bram Moolenaarb69fccf2016-03-06 23:06:25 +0100532 call assert_equal("run", job_status(job))
533 try
534 let handle = job_getchannel(job)
535 call assert_equal("something", ch_readraw(handle))
536 call assert_equal("wrong", ch_readraw(handle, {'part': 'err'}))
537 call assert_equal("this", ch_readraw(handle))
538 call assert_equal("AND this", ch_readraw(handle))
539 finally
540 call job_stop(job)
541 call delete('Xinput')
542 endtry
543endfunc
544
Bram Moolenaare98d1212016-03-08 15:37:41 +0100545func Test_nl_write_out_file()
546 if !has('job')
547 return
548 endif
Bram Moolenaare98d1212016-03-08 15:37:41 +0100549 call ch_log('Test_nl_write_out_file()')
550 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100551 \ {'out_io': 'file', 'out_name': 'Xoutput'})
Bram Moolenaare98d1212016-03-08 15:37:41 +0100552 call assert_equal("run", job_status(job))
553 try
554 let handle = job_getchannel(job)
555 call ch_sendraw(handle, "echo line one\n")
556 call ch_sendraw(handle, "echo line two\n")
557 call ch_sendraw(handle, "double this\n")
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200558 call WaitFor('len(readfile("Xoutput")) > 2')
Bram Moolenaare98d1212016-03-08 15:37:41 +0100559 call assert_equal(['line one', 'line two', 'this', 'AND this'], readfile('Xoutput'))
560 finally
561 call job_stop(job)
562 call delete('Xoutput')
563 endtry
564endfunc
565
566func Test_nl_write_err_file()
567 if !has('job')
568 return
569 endif
Bram Moolenaare98d1212016-03-08 15:37:41 +0100570 call ch_log('Test_nl_write_err_file()')
571 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100572 \ {'err_io': 'file', 'err_name': 'Xoutput'})
Bram Moolenaare98d1212016-03-08 15:37:41 +0100573 call assert_equal("run", job_status(job))
574 try
575 let handle = job_getchannel(job)
576 call ch_sendraw(handle, "echoerr line one\n")
577 call ch_sendraw(handle, "echoerr line two\n")
578 call ch_sendraw(handle, "doubleerr this\n")
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200579 call WaitFor('len(readfile("Xoutput")) > 2')
Bram Moolenaare98d1212016-03-08 15:37:41 +0100580 call assert_equal(['line one', 'line two', 'this', 'AND this'], readfile('Xoutput'))
581 finally
582 call job_stop(job)
583 call delete('Xoutput')
584 endtry
585endfunc
586
587func Test_nl_write_both_file()
588 if !has('job')
589 return
590 endif
Bram Moolenaare98d1212016-03-08 15:37:41 +0100591 call ch_log('Test_nl_write_both_file()')
592 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100593 \ {'out_io': 'file', 'out_name': 'Xoutput', 'err_io': 'out'})
Bram Moolenaare98d1212016-03-08 15:37:41 +0100594 call assert_equal("run", job_status(job))
595 try
596 let handle = job_getchannel(job)
597 call ch_sendraw(handle, "echoerr line one\n")
598 call ch_sendraw(handle, "echo line two\n")
599 call ch_sendraw(handle, "double this\n")
600 call ch_sendraw(handle, "doubleerr that\n")
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200601 call WaitFor('len(readfile("Xoutput")) > 5')
Bram Moolenaare98d1212016-03-08 15:37:41 +0100602 call assert_equal(['line one', 'line two', 'this', 'AND this', 'that', 'AND that'], readfile('Xoutput'))
603 finally
604 call job_stop(job)
605 call delete('Xoutput')
606 endtry
607endfunc
608
Bram Moolenaar01d46e42016-06-02 19:06:25 +0200609func BufCloseCb(ch)
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200610 let g:Ch_bufClosed = 'yes'
Bram Moolenaar01d46e42016-06-02 19:06:25 +0200611endfunc
612
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200613func Run_test_pipe_to_buffer(use_name, nomod)
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100614 if !has('job')
615 return
616 endif
617 call ch_log('Test_pipe_to_buffer()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200618 let g:Ch_bufClosed = 'no'
Bram Moolenaar01d46e42016-06-02 19:06:25 +0200619 let options = {'out_io': 'buffer', 'close_cb': 'BufCloseCb'}
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100620 if a:use_name
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100621 let options['out_name'] = 'pipe-output'
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100622 let firstline = 'Reading from channel output...'
623 else
624 sp pipe-output
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100625 let options['out_buf'] = bufnr('%')
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100626 quit
627 let firstline = ''
628 endif
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200629 if a:nomod
630 let options['out_modifiable'] = 0
631 endif
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100632 let job = job_start(s:python . " test_channel_pipe.py", options)
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100633 call assert_equal("run", job_status(job))
634 try
635 let handle = job_getchannel(job)
636 call ch_sendraw(handle, "echo line one\n")
637 call ch_sendraw(handle, "echo line two\n")
638 call ch_sendraw(handle, "double this\n")
639 call ch_sendraw(handle, "quit\n")
640 sp pipe-output
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200641 call WaitFor('line("$") >= 6 && g:Ch_bufClosed == "yes"')
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100642 call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this', 'Goodbye!'], getline(1, '$'))
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200643 if a:nomod
644 call assert_equal(0, &modifiable)
645 else
646 call assert_equal(1, &modifiable)
647 endif
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200648 call assert_equal('yes', g:Ch_bufClosed)
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100649 bwipe!
650 finally
651 call job_stop(job)
652 endtry
653endfunc
654
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100655func Test_pipe_to_buffer_name()
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200656 call Run_test_pipe_to_buffer(1, 0)
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100657endfunc
658
659func Test_pipe_to_buffer_nr()
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200660 call Run_test_pipe_to_buffer(0, 0)
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100661endfunc
662
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200663func Test_pipe_to_buffer_name_nomod()
664 call Run_test_pipe_to_buffer(1, 1)
665endfunc
666
667func Run_test_pipe_err_to_buffer(use_name, nomod)
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100668 if !has('job')
669 return
670 endif
671 call ch_log('Test_pipe_err_to_buffer()')
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100672 let options = {'err_io': 'buffer'}
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100673 if a:use_name
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100674 let options['err_name'] = 'pipe-err'
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100675 let firstline = 'Reading from channel error...'
676 else
677 sp pipe-err
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100678 let options['err_buf'] = bufnr('%')
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100679 quit
680 let firstline = ''
681 endif
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200682 if a:nomod
683 let options['err_modifiable'] = 0
684 endif
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100685 let job = job_start(s:python . " test_channel_pipe.py", options)
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100686 call assert_equal("run", job_status(job))
687 try
688 let handle = job_getchannel(job)
689 call ch_sendraw(handle, "echoerr line one\n")
690 call ch_sendraw(handle, "echoerr line two\n")
691 call ch_sendraw(handle, "doubleerr this\n")
692 call ch_sendraw(handle, "quit\n")
693 sp pipe-err
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200694 call WaitFor('line("$") >= 5')
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100695 call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this'], getline(1, '$'))
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200696 if a:nomod
697 call assert_equal(0, &modifiable)
698 else
699 call assert_equal(1, &modifiable)
700 endif
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100701 bwipe!
702 finally
703 call job_stop(job)
704 endtry
705endfunc
706
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100707func Test_pipe_err_to_buffer_name()
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200708 call Run_test_pipe_err_to_buffer(1, 0)
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100709endfunc
710
711func Test_pipe_err_to_buffer_nr()
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200712 call Run_test_pipe_err_to_buffer(0, 0)
713endfunc
714
715func Test_pipe_err_to_buffer_name_nomod()
716 call Run_test_pipe_err_to_buffer(1, 1)
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100717endfunc
718
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100719func Test_pipe_both_to_buffer()
720 if !has('job')
721 return
722 endif
723 call ch_log('Test_pipe_both_to_buffer()')
724 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100725 \ {'out_io': 'buffer', 'out_name': 'pipe-err', 'err_io': 'out'})
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100726 call assert_equal("run", job_status(job))
727 try
728 let handle = job_getchannel(job)
729 call ch_sendraw(handle, "echo line one\n")
730 call ch_sendraw(handle, "echoerr line two\n")
731 call ch_sendraw(handle, "double this\n")
732 call ch_sendraw(handle, "doubleerr that\n")
733 call ch_sendraw(handle, "quit\n")
734 sp pipe-err
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200735 call WaitFor('line("$") >= 7')
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100736 call assert_equal(['Reading from channel output...', 'line one', 'line two', 'this', 'AND this', 'that', 'AND that', 'Goodbye!'], getline(1, '$'))
737 bwipe!
738 finally
739 call job_stop(job)
740 endtry
741endfunc
742
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100743func Run_test_pipe_from_buffer(use_name)
Bram Moolenaar014069a2016-03-03 22:51:40 +0100744 if !has('job')
745 return
746 endif
Bram Moolenaar014069a2016-03-03 22:51:40 +0100747 call ch_log('Test_pipe_from_buffer()')
748
749 sp pipe-input
750 call setline(1, ['echo one', 'echo two', 'echo three'])
Bram Moolenaar8b877ac2016-03-28 19:16:20 +0200751 let options = {'in_io': 'buffer', 'block_write': 1}
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100752 if a:use_name
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100753 let options['in_name'] = 'pipe-input'
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100754 else
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100755 let options['in_buf'] = bufnr('%')
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100756 endif
Bram Moolenaar014069a2016-03-03 22:51:40 +0100757
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100758 let job = job_start(s:python . " test_channel_pipe.py", options)
Bram Moolenaar014069a2016-03-03 22:51:40 +0100759 call assert_equal("run", job_status(job))
760 try
761 let handle = job_getchannel(job)
762 call assert_equal('one', ch_read(handle))
763 call assert_equal('two', ch_read(handle))
764 call assert_equal('three', ch_read(handle))
765 bwipe!
766 finally
767 call job_stop(job)
768 endtry
Bram Moolenaar014069a2016-03-03 22:51:40 +0100769endfunc
770
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100771func Test_pipe_from_buffer_name()
772 call Run_test_pipe_from_buffer(1)
773endfunc
774
775func Test_pipe_from_buffer_nr()
776 call Run_test_pipe_from_buffer(0)
777endfunc
778
Bram Moolenaarc7f0ebc2016-02-27 21:10:09 +0100779func Test_pipe_to_nameless_buffer()
780 if !has('job')
781 return
782 endif
783 call ch_log('Test_pipe_to_nameless_buffer()')
784 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100785 \ {'out_io': 'buffer'})
Bram Moolenaarc7f0ebc2016-02-27 21:10:09 +0100786 call assert_equal("run", job_status(job))
787 try
788 let handle = job_getchannel(job)
789 call ch_sendraw(handle, "echo line one\n")
790 call ch_sendraw(handle, "echo line two\n")
791 exe ch_getbufnr(handle, "out") . 'sbuf'
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200792 call WaitFor('line("$") >= 3')
Bram Moolenaarc7f0ebc2016-02-27 21:10:09 +0100793 call assert_equal(['Reading from channel output...', 'line one', 'line two'], getline(1, '$'))
794 bwipe!
795 finally
796 call job_stop(job)
797 endtry
798endfunc
799
Bram Moolenaarcc7f8be2016-02-29 22:55:56 +0100800func Test_pipe_to_buffer_json()
801 if !has('job')
802 return
803 endif
804 call ch_log('Test_pipe_to_buffer_json()')
805 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100806 \ {'out_io': 'buffer', 'out_mode': 'json'})
Bram Moolenaarcc7f8be2016-02-29 22:55:56 +0100807 call assert_equal("run", job_status(job))
808 try
809 let handle = job_getchannel(job)
810 call ch_sendraw(handle, "echo [0, \"hello\"]\n")
811 call ch_sendraw(handle, "echo [-2, 12.34]\n")
812 exe ch_getbufnr(handle, "out") . 'sbuf'
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200813 call WaitFor('line("$") >= 3')
Bram Moolenaarcc7f8be2016-02-29 22:55:56 +0100814 call assert_equal(['Reading from channel output...', '[0,"hello"]', '[-2,12.34]'], getline(1, '$'))
815 bwipe!
816 finally
817 call job_stop(job)
818 endtry
819endfunc
820
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100821" Wait a little while for the last line, minus "offset", to equal "line".
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100822func s:wait_for_last_line(line, offset)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100823 for i in range(100)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100824 if getline(line('$') - a:offset) == a:line
825 break
826 endif
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100827 sleep 10m
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100828 endfor
829endfunc
830
831func Test_pipe_io_two_buffers()
832 if !has('job')
833 return
834 endif
835 call ch_log('Test_pipe_io_two_buffers()')
836
837 " Create two buffers, one to read from and one to write to.
838 split pipe-output
839 set buftype=nofile
840 split pipe-input
841 set buftype=nofile
842
843 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100844 \ {'in_io': 'buffer', 'in_name': 'pipe-input', 'in_top': 0,
Bram Moolenaar8b877ac2016-03-28 19:16:20 +0200845 \ 'out_io': 'buffer', 'out_name': 'pipe-output',
846 \ 'block_write': 1})
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100847 call assert_equal("run", job_status(job))
848 try
849 exe "normal Gaecho hello\<CR>"
850 exe bufwinnr('pipe-output') . "wincmd w"
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100851 call s:wait_for_last_line('hello', 0)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100852 call assert_equal('hello', getline('$'))
853
854 exe bufwinnr('pipe-input') . "wincmd w"
855 exe "normal Gadouble this\<CR>"
856 exe bufwinnr('pipe-output') . "wincmd w"
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100857 call s:wait_for_last_line('AND this', 0)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100858 call assert_equal('this', getline(line('$') - 1))
859 call assert_equal('AND this', getline('$'))
860
861 bwipe!
862 exe bufwinnr('pipe-input') . "wincmd w"
863 bwipe!
864 finally
865 call job_stop(job)
866 endtry
867endfunc
868
869func Test_pipe_io_one_buffer()
870 if !has('job')
871 return
872 endif
873 call ch_log('Test_pipe_io_one_buffer()')
874
875 " Create one buffer to read from and to write to.
876 split pipe-io
877 set buftype=nofile
878
879 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100880 \ {'in_io': 'buffer', 'in_name': 'pipe-io', 'in_top': 0,
Bram Moolenaar8b877ac2016-03-28 19:16:20 +0200881 \ 'out_io': 'buffer', 'out_name': 'pipe-io',
882 \ 'block_write': 1})
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100883 call assert_equal("run", job_status(job))
884 try
885 exe "normal Goecho hello\<CR>"
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100886 call s:wait_for_last_line('hello', 1)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100887 call assert_equal('hello', getline(line('$') - 1))
888
889 exe "normal Gadouble this\<CR>"
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100890 call s:wait_for_last_line('AND this', 1)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100891 call assert_equal('this', getline(line('$') - 2))
892 call assert_equal('AND this', getline(line('$') - 1))
893
894 bwipe!
895 finally
896 call job_stop(job)
897 endtry
898endfunc
899
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100900func Test_pipe_null()
901 if !has('job')
902 return
903 endif
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100904 call ch_log('Test_pipe_null()')
905
906 " We cannot check that no I/O works, we only check that the job starts
907 " properly.
908 let job = job_start(s:python . " test_channel_pipe.py something",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100909 \ {'in_io': 'null'})
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100910 call assert_equal("run", job_status(job))
911 try
912 call assert_equal('something', ch_read(job))
913 finally
914 call job_stop(job)
915 endtry
916
917 let job = job_start(s:python . " test_channel_pipe.py err-out",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100918 \ {'out_io': 'null'})
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100919 call assert_equal("run", job_status(job))
920 try
921 call assert_equal('err-out', ch_read(job, {"part": "err"}))
922 finally
923 call job_stop(job)
924 endtry
925
926 let job = job_start(s:python . " test_channel_pipe.py something",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100927 \ {'err_io': 'null'})
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100928 call assert_equal("run", job_status(job))
929 try
930 call assert_equal('something', ch_read(job))
931 finally
932 call job_stop(job)
933 endtry
934
935 let job = job_start(s:python . " test_channel_pipe.py something",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100936 \ {'out_io': 'null', 'err_io': 'out'})
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100937 call assert_equal("run", job_status(job))
938 call job_stop(job)
939
940 let job = job_start(s:python . " test_channel_pipe.py something",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100941 \ {'in_io': 'null', 'out_io': 'null', 'err_io': 'null'})
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100942 call assert_equal("run", job_status(job))
943 call assert_equal('channel fail', string(job_getchannel(job)))
944 call assert_equal('fail', ch_status(job))
945 call job_stop(job)
946endfunc
947
Bram Moolenaaradb78a72016-06-27 21:10:31 +0200948func Test_pipe_to_buffer_raw()
949 if !has('job')
950 return
951 endif
952 call ch_log('Test_raw_pipe_to_buffer()')
953 let options = {'out_mode': 'raw', 'out_io': 'buffer', 'out_name': 'testout'}
954 split testout
955 let job = job_start([s:python, '-c',
956 \ 'import sys; [sys.stdout.write(".") and sys.stdout.flush() for _ in range(10000)]'], options)
957 call assert_equal("run", job_status(job))
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200958 call WaitFor('len(join(getline(2,line("$")),"") >= 10000')
Bram Moolenaaradb78a72016-06-27 21:10:31 +0200959 try
960 for line in getline(2, '$')
961 let line = substitute(line, '^\.*', '', '')
962 call assert_equal('', line)
963 endfor
964 finally
965 call job_stop(job)
966 bwipe!
967 endtry
968endfunc
969
Bram Moolenaarde279892016-03-11 22:19:44 +0100970func Test_reuse_channel()
971 if !has('job')
972 return
973 endif
974 call ch_log('Test_reuse_channel()')
975
976 let job = job_start(s:python . " test_channel_pipe.py")
977 call assert_equal("run", job_status(job))
978 let handle = job_getchannel(job)
979 try
980 call ch_sendraw(handle, "echo something\n")
981 call assert_equal("something", ch_readraw(handle))
982 finally
983 call job_stop(job)
984 endtry
985
986 let job = job_start(s:python . " test_channel_pipe.py", {'channel': handle})
987 call assert_equal("run", job_status(job))
988 let handle = job_getchannel(job)
989 try
990 call ch_sendraw(handle, "echo again\n")
991 call assert_equal("again", ch_readraw(handle))
992 finally
993 call job_stop(job)
994 endtry
995endfunc
996
Bram Moolenaar75f72652016-03-20 22:16:56 +0100997func Test_out_cb()
998 if !has('job')
999 return
1000 endif
1001 call ch_log('Test_out_cb()')
1002
1003 let dict = {'thisis': 'dict: '}
1004 func dict.outHandler(chan, msg) dict
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001005 let g:Ch_outmsg = self.thisis . a:msg
Bram Moolenaar75f72652016-03-20 22:16:56 +01001006 endfunc
1007 func dict.errHandler(chan, msg) dict
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001008 let g:Ch_errmsg = self.thisis . a:msg
Bram Moolenaar75f72652016-03-20 22:16:56 +01001009 endfunc
1010 let job = job_start(s:python . " test_channel_pipe.py",
1011 \ {'out_cb': dict.outHandler,
1012 \ 'out_mode': 'json',
1013 \ 'err_cb': dict.errHandler,
1014 \ 'err_mode': 'json'})
1015 call assert_equal("run", job_status(job))
1016 try
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001017 let g:Ch_outmsg = ''
1018 let g:Ch_errmsg = ''
Bram Moolenaar75f72652016-03-20 22:16:56 +01001019 call ch_sendraw(job, "echo [0, \"hello\"]\n")
1020 call ch_sendraw(job, "echoerr [0, \"there\"]\n")
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001021 call WaitFor('g:Ch_outmsg != ""')
1022 call assert_equal("dict: hello", g:Ch_outmsg)
1023 call WaitFor('g:Ch_errmsg != ""')
1024 call assert_equal("dict: there", g:Ch_errmsg)
Bram Moolenaar75f72652016-03-20 22:16:56 +01001025 finally
1026 call job_stop(job)
1027 endtry
1028endfunc
1029
Bram Moolenaarb2658a12016-04-26 17:16:24 +02001030func Test_out_close_cb()
1031 if !has('job')
1032 return
1033 endif
1034 call ch_log('Test_out_close_cb()')
1035
1036 let s:counter = 1
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001037 let g:Ch_msg1 = ''
1038 let g:Ch_closemsg = 0
Bram Moolenaarb2658a12016-04-26 17:16:24 +02001039 func! OutHandler(chan, msg)
Bram Moolenaard75263c2016-04-30 16:07:23 +02001040 if s:counter == 1
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001041 let g:Ch_msg1 = a:msg
Bram Moolenaard75263c2016-04-30 16:07:23 +02001042 endif
Bram Moolenaarb2658a12016-04-26 17:16:24 +02001043 let s:counter += 1
1044 endfunc
1045 func! CloseHandler(chan)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001046 let g:Ch_closemsg = s:counter
Bram Moolenaarb2658a12016-04-26 17:16:24 +02001047 let s:counter += 1
1048 endfunc
1049 let job = job_start(s:python . " test_channel_pipe.py quit now",
1050 \ {'out_cb': 'OutHandler',
1051 \ 'close_cb': 'CloseHandler'})
1052 call assert_equal("run", job_status(job))
1053 try
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001054 call WaitFor('g:Ch_closemsg != 0 && g:Ch_msg1 != ""')
1055 call assert_equal('quit', g:Ch_msg1)
1056 call assert_equal(2, g:Ch_closemsg)
Bram Moolenaarb2658a12016-04-26 17:16:24 +02001057 finally
1058 call job_stop(job)
1059 delfunc OutHandler
1060 delfunc CloseHandler
1061 endtry
1062endfunc
1063
Bram Moolenaar437905c2016-04-26 19:01:05 +02001064func Test_read_in_close_cb()
1065 if !has('job')
1066 return
1067 endif
1068 call ch_log('Test_read_in_close_cb()')
1069
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001070 let g:Ch_received = ''
Bram Moolenaar437905c2016-04-26 19:01:05 +02001071 func! CloseHandler(chan)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001072 let g:Ch_received = ch_read(a:chan)
Bram Moolenaar437905c2016-04-26 19:01:05 +02001073 endfunc
1074 let job = job_start(s:python . " test_channel_pipe.py quit now",
1075 \ {'close_cb': 'CloseHandler'})
1076 call assert_equal("run", job_status(job))
1077 try
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001078 call WaitFor('g:Ch_received != ""')
1079 call assert_equal('quit', g:Ch_received)
Bram Moolenaar437905c2016-04-26 19:01:05 +02001080 finally
1081 call job_stop(job)
1082 delfunc CloseHandler
1083 endtry
1084endfunc
1085
Bram Moolenaar069c1e72016-07-15 21:25:08 +02001086func Test_out_cb_lambda()
1087 if !has('job')
1088 return
1089 endif
1090 call ch_log('Test_out_cb_lambda()')
1091
1092 let job = job_start(s:python . " test_channel_pipe.py",
1093 \ {'out_cb': {ch, msg -> execute("let g:Ch_outmsg = 'lambda: ' . msg")},
1094 \ 'out_mode': 'json',
1095 \ 'err_cb': {ch, msg -> execute(":let g:Ch_errmsg = 'lambda: ' . msg")},
1096 \ 'err_mode': 'json'})
1097 call assert_equal("run", job_status(job))
1098 try
1099 let g:Ch_outmsg = ''
1100 let g:Ch_errmsg = ''
1101 call ch_sendraw(job, "echo [0, \"hello\"]\n")
1102 call ch_sendraw(job, "echoerr [0, \"there\"]\n")
1103 call WaitFor('g:Ch_outmsg != ""')
1104 call assert_equal("lambda: hello", g:Ch_outmsg)
1105 call WaitFor('g:Ch_errmsg != ""')
1106 call assert_equal("lambda: there", g:Ch_errmsg)
1107 finally
1108 call job_stop(job)
1109 endtry
1110endfunc
1111
Bram Moolenaard46ae142016-02-16 13:33:52 +01001112""""""""""
1113
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001114let g:Ch_unletResponse = ''
Bram Moolenaar3bece9f2016-02-15 20:39:46 +01001115func s:UnletHandler(handle, msg)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001116 let g:Ch_unletResponse = a:msg
Bram Moolenaar3bece9f2016-02-15 20:39:46 +01001117 unlet s:channelfd
1118endfunc
1119
1120" Test that "unlet handle" in a handler doesn't crash Vim.
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001121func Ch_unlet_handle(port)
Bram Moolenaar3bece9f2016-02-15 20:39:46 +01001122 let s:channelfd = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar910b8aa2016-02-16 21:03:07 +01001123 call ch_sendexpr(s:channelfd, "test", {'callback': function('s:UnletHandler')})
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001124 call WaitFor('"what?" == g:Ch_unletResponse')
1125 call assert_equal('what?', g:Ch_unletResponse)
Bram Moolenaar3bece9f2016-02-15 20:39:46 +01001126endfunc
1127
1128func Test_unlet_handle()
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001129 call ch_log('Test_unlet_handle()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001130 call s:run_server('Ch_unlet_handle')
Bram Moolenaar3bece9f2016-02-15 20:39:46 +01001131endfunc
Bram Moolenaar5cefd402016-02-16 12:44:26 +01001132
Bram Moolenaard46ae142016-02-16 13:33:52 +01001133""""""""""
1134
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001135let g:Ch_unletResponse = ''
1136func Ch_CloseHandler(handle, msg)
1137 let g:Ch_unletResponse = a:msg
Bram Moolenaard46ae142016-02-16 13:33:52 +01001138 call ch_close(s:channelfd)
1139endfunc
1140
1141" Test that "unlet handle" in a handler doesn't crash Vim.
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001142func Ch_close_handle(port)
Bram Moolenaard46ae142016-02-16 13:33:52 +01001143 let s:channelfd = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001144 call ch_sendexpr(s:channelfd, "test", {'callback': function('Ch_CloseHandler')})
1145 call WaitFor('"what?" == g:Ch_unletResponse')
1146 call assert_equal('what?', g:Ch_unletResponse)
Bram Moolenaard46ae142016-02-16 13:33:52 +01001147endfunc
1148
1149func Test_close_handle()
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001150 call ch_log('Test_close_handle()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001151 call s:run_server('Ch_close_handle')
Bram Moolenaard46ae142016-02-16 13:33:52 +01001152endfunc
1153
1154""""""""""
1155
Bram Moolenaar5cefd402016-02-16 12:44:26 +01001156func Test_open_fail()
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001157 call ch_log('Test_open_fail()')
Bram Moolenaar5cefd402016-02-16 12:44:26 +01001158 silent! let ch = ch_open("noserver")
1159 echo ch
1160 let d = ch
1161endfunc
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001162
1163""""""""""
1164
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001165func Ch_open_delay(port)
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001166 " Wait up to a second for the port to open.
1167 let s:chopt.waittime = 1000
1168 let channel = ch_open('localhost:' . a:port, s:chopt)
1169 unlet s:chopt.waittime
1170 if ch_status(channel) == "fail"
1171 call assert_false(1, "Can't open channel")
1172 return
1173 endif
Bram Moolenaar8b1862a2016-02-27 19:21:24 +01001174 call assert_equal('got it', ch_evalexpr(channel, 'hello!'))
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001175 call ch_close(channel)
1176endfunc
1177
1178func Test_open_delay()
1179 call ch_log('Test_open_delay()')
1180 " The server will wait half a second before creating the port.
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001181 call s:run_server('Ch_open_delay', 'delay')
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001182endfunc
Bram Moolenaarece61b02016-02-20 21:39:05 +01001183
1184"""""""""
1185
1186function MyFunction(a,b,c)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001187 let g:Ch_call_ret = [a:a, a:b, a:c]
Bram Moolenaarece61b02016-02-20 21:39:05 +01001188endfunc
1189
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001190function Ch_test_call(port)
Bram Moolenaarece61b02016-02-20 21:39:05 +01001191 let handle = ch_open('localhost:' . a:port, s:chopt)
1192 if ch_status(handle) == "fail"
1193 call assert_false(1, "Can't open channel")
1194 return
1195 endif
1196
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001197 let g:Ch_call_ret = []
Bram Moolenaar8b1862a2016-02-27 19:21:24 +01001198 call assert_equal('ok', ch_evalexpr(handle, 'call-func'))
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001199 call WaitFor('len(g:Ch_call_ret) > 0')
1200 call assert_equal([1, 2, 3], g:Ch_call_ret)
Bram Moolenaarece61b02016-02-20 21:39:05 +01001201endfunc
1202
1203func Test_call()
1204 call ch_log('Test_call()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001205 call s:run_server('Ch_test_call')
Bram Moolenaarece61b02016-02-20 21:39:05 +01001206endfunc
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001207
1208"""""""""
1209
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001210let g:Ch_job_exit_ret = 'not yet'
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001211function MyExitCb(job, status)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001212 let g:Ch_job_exit_ret = 'done'
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001213endfunc
1214
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001215function Ch_test_exit_callback(port)
1216 call job_setoptions(g:currentJob, {'exit_cb': 'MyExitCb'})
1217 let g:Ch_exit_job = g:currentJob
1218 call assert_equal('MyExitCb', job_info(g:currentJob)['exit_cb'])
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001219endfunc
1220
1221func Test_exit_callback()
1222 if has('job')
Bram Moolenaar9730f742016-02-28 19:50:51 +01001223 call ch_log('Test_exit_callback()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001224 call s:run_server('Ch_test_exit_callback')
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001225
Bram Moolenaar9730f742016-02-28 19:50:51 +01001226 " wait up to a second for the job to exit
1227 for i in range(100)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001228 if g:Ch_job_exit_ret == 'done'
Bram Moolenaar9730f742016-02-28 19:50:51 +01001229 break
1230 endif
1231 sleep 10m
1232 " calling job_status() triggers the callback
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001233 call job_status(g:Ch_exit_job)
Bram Moolenaar9730f742016-02-28 19:50:51 +01001234 endfor
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001235
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001236 call assert_equal('done', g:Ch_job_exit_ret)
1237 call assert_equal('dead', job_info(g:Ch_exit_job).status)
1238 unlet g:Ch_exit_job
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001239 endif
1240endfunc
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001241
1242"""""""""
1243
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001244let g:Ch_close_ret = 'alive'
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001245function MyCloseCb(ch)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001246 let g:Ch_close_ret = 'closed'
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001247endfunc
1248
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001249function Ch_test_close_callback(port)
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001250 let handle = ch_open('localhost:' . a:port, s:chopt)
1251 if ch_status(handle) == "fail"
1252 call assert_false(1, "Can't open channel")
1253 return
1254 endif
Bram Moolenaard6c2f052016-03-14 23:22:59 +01001255 call ch_setoptions(handle, {'close_cb': 'MyCloseCb'})
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001256
Bram Moolenaar8b1862a2016-02-27 19:21:24 +01001257 call assert_equal('', ch_evalexpr(handle, 'close me'))
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001258 call WaitFor('"closed" == g:Ch_close_ret')
1259 call assert_equal('closed', g:Ch_close_ret)
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001260endfunc
1261
1262func Test_close_callback()
1263 call ch_log('Test_close_callback()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001264 call s:run_server('Ch_test_close_callback')
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001265endfunc
1266
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001267function Ch_test_close_partial(port)
Bram Moolenaarbdf0bda2016-03-30 21:06:57 +02001268 let handle = ch_open('localhost:' . a:port, s:chopt)
1269 if ch_status(handle) == "fail"
1270 call assert_false(1, "Can't open channel")
1271 return
1272 endif
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001273 let g:Ch_d = {}
1274 func g:Ch_d.closeCb(ch) dict
Bram Moolenaarbdf0bda2016-03-30 21:06:57 +02001275 let self.close_ret = 'closed'
1276 endfunc
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001277 call ch_setoptions(handle, {'close_cb': g:Ch_d.closeCb})
Bram Moolenaarbdf0bda2016-03-30 21:06:57 +02001278
1279 call assert_equal('', ch_evalexpr(handle, 'close me'))
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001280 call WaitFor('"closed" == g:Ch_d.close_ret')
1281 call assert_equal('closed', g:Ch_d.close_ret)
1282 unlet g:Ch_d
Bram Moolenaarbdf0bda2016-03-30 21:06:57 +02001283endfunc
1284
1285func Test_close_partial()
1286 call ch_log('Test_close_partial()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001287 call s:run_server('Ch_test_close_partial')
Bram Moolenaarbdf0bda2016-03-30 21:06:57 +02001288endfunc
1289
Bram Moolenaar80385682016-03-27 19:13:35 +02001290func Test_job_start_invalid()
1291 call assert_fails('call job_start($x)', 'E474:')
1292 call assert_fails('call job_start("")', 'E474:')
1293endfunc
1294
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02001295" This was leaking memory.
Bram Moolenaar0e4c1de2016-04-07 21:40:38 +02001296func Test_partial_in_channel_cycle()
1297 let d = {}
1298 let d.a = function('string', [d])
1299 try
1300 let d.b = ch_open('nowhere:123', {'close_cb': d.a})
1301 catch
1302 call assert_exception('E901:')
1303 endtry
1304 unlet d
1305endfunc
1306
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02001307func Test_using_freed_memory()
1308 let g:a = job_start(['ls'])
1309 sleep 10m
Bram Moolenaar574860b2016-05-24 17:33:34 +02001310 call test_garbagecollect_now()
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02001311endfunc
1312
Bram Moolenaarb8aefa42016-06-10 23:02:56 +02001313func Test_collapse_buffers()
1314 if !executable('cat')
1315 return
1316 endif
1317 sp test_channel.vim
1318 let g:linecount = line('$')
1319 close
1320 split testout
1321 1,$delete
1322 call job_start('cat test_channel.vim', {'out_io': 'buffer', 'out_name': 'testout'})
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001323 call WaitFor('line("$") > g:linecount')
Bram Moolenaarb8aefa42016-06-10 23:02:56 +02001324 call assert_true(line('$') > g:linecount)
1325 bwipe!
1326endfunc
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02001327
Bram Moolenaar069c1e72016-07-15 21:25:08 +02001328function Ch_test_close_lambda(port)
1329 let handle = ch_open('localhost:' . a:port, s:chopt)
1330 if ch_status(handle) == "fail"
1331 call assert_false(1, "Can't open channel")
1332 return
1333 endif
1334 let g:Ch_close_ret = ''
1335 call ch_setoptions(handle, {'close_cb': {ch -> execute("let g:Ch_close_ret = 'closed'")}})
1336
1337 call assert_equal('', ch_evalexpr(handle, 'close me'))
1338 call WaitFor('"closed" == g:Ch_close_ret')
1339 call assert_equal('closed', g:Ch_close_ret)
1340endfunc
1341
1342func Test_close_lambda()
1343 call ch_log('Test_close_lambda()')
1344 call s:run_server('Ch_test_close_lambda')
1345endfunc
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02001346
Bram Moolenaar9730f742016-02-28 19:50:51 +01001347" Uncomment this to see what happens, output is in src/testdir/channellog.
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001348 call ch_logfile('channellog', 'w')