blob: ea7abd4b38ecfb3b3f2c1472698c7a43cf28f84a [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 Moolenaar77073442016-02-13 23:23:53 +0100191 if ch_status(handle) == "fail"
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100192 call assert_false(1, "Can't open channel")
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100193 return
194 endif
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100195
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100196 call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100197
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100198 let newhandle = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar77073442016-02-13 23:23:53 +0100199 if ch_status(newhandle) == "fail"
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100200 call assert_false(1, "Can't open second channel")
201 return
202 endif
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100203 call assert_equal('got it', ch_evalexpr(newhandle, 'hello!'))
204 call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100205
206 call ch_close(handle)
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100207 call assert_equal('got it', ch_evalexpr(newhandle, 'hello!'))
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100208
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100209 call ch_close(newhandle)
210endfunc
211
212func Test_two_channels()
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100213 call ch_log('Test_two_channels()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200214 call s:run_server('Ch_two_channels')
Bram Moolenaar3b05b132016-02-03 23:25:07 +0100215endfunc
216
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100217" Test that a server crash is handled gracefully.
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200218func Ch_server_crash(port)
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100219 let handle = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar77073442016-02-13 23:23:53 +0100220 if ch_status(handle) == "fail"
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100221 call assert_false(1, "Can't open channel")
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100222 return
223 endif
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100224
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100225 call ch_evalexpr(handle, '!crash!')
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100226
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100227 sleep 10m
Bram Moolenaard6a8d482016-02-10 20:32:20 +0100228endfunc
229
230func Test_server_crash()
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100231 call ch_log('Test_server_crash()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200232 call s:run_server('Ch_server_crash')
Bram Moolenaarfcb1e3d2016-02-03 21:32:46 +0100233endfunc
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100234
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100235"""""""""
236
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200237let g:Ch_reply = ""
238func Ch_handler(chan, msg)
239 unlet g:Ch_reply
240 let g:Ch_reply = a:msg
Bram Moolenaarf6157282016-02-10 21:07:14 +0100241endfunc
242
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200243func Ch_channel_handler(port)
Bram Moolenaarb6a4fee2016-02-11 20:48:34 +0100244 let handle = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar77073442016-02-13 23:23:53 +0100245 if ch_status(handle) == "fail"
Bram Moolenaarf6157282016-02-10 21:07:14 +0100246 call assert_false(1, "Can't open channel")
247 return
248 endif
249
250 " Test that it works while waiting on a numbered message.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100251 call assert_equal('ok', ch_evalexpr(handle, 'call me'))
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200252 call WaitFor('"we called you" == g:Ch_reply')
253 call assert_equal('we called you', g:Ch_reply)
Bram Moolenaarf6157282016-02-10 21:07:14 +0100254
255 " Test that it works while not waiting on a numbered message.
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100256 call ch_sendexpr(handle, 'call me again')
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200257 call WaitFor('"we did call you" == g:Ch_reply')
258 call assert_equal('we did call you', g:Ch_reply)
Bram Moolenaarf6157282016-02-10 21:07:14 +0100259endfunc
260
261func Test_channel_handler()
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100262 call ch_log('Test_channel_handler()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200263 let s:chopt.callback = 'Ch_handler'
264 call s:run_server('Ch_channel_handler')
265 let s:chopt.callback = function('Ch_handler')
266 call s:run_server('Ch_channel_handler')
Bram Moolenaarb6a4fee2016-02-11 20:48:34 +0100267 unlet s:chopt.callback
Bram Moolenaarf6157282016-02-10 21:07:14 +0100268endfunc
269
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100270"""""""""
271
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200272let g:Ch_reply = ''
273func Ch_zeroHandler(chan, msg)
274 unlet g:Ch_reply
275 let g:Ch_reply = a:msg
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100276endfunc
277
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200278let g:Ch_zero_reply = ''
279func Ch_oneHandler(chan, msg)
280 unlet g:Ch_zero_reply
281 let g:Ch_zero_reply = a:msg
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100282endfunc
283
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200284func Ch_channel_zero(port)
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100285 let handle = ch_open('localhost:' . a:port, s:chopt)
286 if ch_status(handle) == "fail"
287 call assert_false(1, "Can't open channel")
288 return
289 endif
290
291 " Check that eval works.
292 call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
293
294 " Check that eval works if a zero id message is sent back.
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200295 let g:Ch_reply = ''
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100296 call assert_equal('sent zero', ch_evalexpr(handle, 'send zero'))
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100297 if s:has_handler
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200298 call WaitFor('"zero index" == g:Ch_reply')
299 call assert_equal('zero index', g:Ch_reply)
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100300 else
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100301 sleep 20m
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200302 call assert_equal('', g:Ch_reply)
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100303 endif
304
305 " Check that handler works if a zero id message is sent back.
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200306 let g:Ch_reply = ''
307 let g:Ch_zero_reply = ''
308 call ch_sendexpr(handle, 'send zero', {'callback': 'Ch_oneHandler'})
309 call WaitFor('"sent zero" == g:Ch_zero_reply')
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100310 if s:has_handler
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200311 call assert_equal('zero index', g:Ch_reply)
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100312 else
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200313 call assert_equal('', g:Ch_reply)
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100314 endif
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200315 call assert_equal('sent zero', g:Ch_zero_reply)
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100316endfunc
317
318func Test_zero_reply()
319 call ch_log('Test_zero_reply()')
320 " Run with channel handler
321 let s:has_handler = 1
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200322 let s:chopt.callback = 'Ch_zeroHandler'
323 call s:run_server('Ch_channel_zero')
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100324 unlet s:chopt.callback
325
326 " Run without channel handler
327 let s:has_handler = 0
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200328 call s:run_server('Ch_channel_zero')
Bram Moolenaar5983ad02016-03-05 20:54:36 +0100329endfunc
330
331"""""""""
332
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200333let g:Ch_reply1 = ""
334func Ch_handleRaw1(chan, msg)
335 unlet g:Ch_reply1
336 let g:Ch_reply1 = a:msg
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100337endfunc
338
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200339let g:Ch_reply2 = ""
340func Ch_handleRaw2(chan, msg)
341 unlet g:Ch_reply2
342 let g:Ch_reply2 = a:msg
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100343endfunc
344
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200345let g:Ch_reply3 = ""
346func Ch_handleRaw3(chan, msg)
347 unlet g:Ch_reply3
348 let g:Ch_reply3 = a:msg
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100349endfunc
350
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200351func Ch_raw_one_time_callback(port)
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100352 let handle = ch_open('localhost:' . a:port, s:chopt)
353 if ch_status(handle) == "fail"
354 call assert_false(1, "Can't open channel")
355 return
356 endif
357 call ch_setoptions(handle, {'mode': 'raw'})
358
359 " The message are sent raw, we do our own JSON strings here.
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200360 call ch_sendraw(handle, "[1, \"hello!\"]", {'callback': 'Ch_handleRaw1'})
361 call WaitFor('g:Ch_reply1 != ""')
362 call assert_equal("[1, \"got it\"]", g:Ch_reply1)
363 call ch_sendraw(handle, "[2, \"echo something\"]", {'callback': 'Ch_handleRaw2'})
364 call ch_sendraw(handle, "[3, \"wait a bit\"]", {'callback': 'Ch_handleRaw3'})
365 call WaitFor('g:Ch_reply2 != ""')
366 call assert_equal("[2, \"something\"]", g:Ch_reply2)
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100367 " wait for the 200 msec delayed reply
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200368 call WaitFor('g:Ch_reply3 != ""')
369 call assert_equal("[3, \"waited\"]", g:Ch_reply3)
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100370endfunc
371
372func Test_raw_one_time_callback()
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100373 call ch_log('Test_raw_one_time_callback()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200374 call s:run_server('Ch_raw_one_time_callback')
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100375endfunc
376
377"""""""""
378
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100379" Test that trying to connect to a non-existing port fails quickly.
380func Test_connect_waittime()
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100381 call ch_log('Test_connect_waittime()')
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100382 let start = reltime()
Bram Moolenaara4833262016-02-09 23:33:25 +0100383 let handle = ch_open('localhost:9876', s:chopt)
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100384 if ch_status(handle) != "fail"
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100385 " Oops, port does exists.
386 call ch_close(handle)
387 else
388 let elapsed = reltime(start)
Bram Moolenaar74f5e652016-02-07 21:44:49 +0100389 call assert_true(reltimefloat(elapsed) < 1.0)
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100390 endif
391
Bram Moolenaar08298fa2016-02-21 13:01:53 +0100392 " We intend to use a socket that doesn't exist and wait for half a second
393 " before giving up. If the socket does exist it can fail in various ways.
394 " Check for "Connection reset by peer" to avoid flakyness.
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100395 let start = reltime()
Bram Moolenaar08298fa2016-02-21 13:01:53 +0100396 try
397 let handle = ch_open('localhost:9867', {'waittime': 500})
398 if ch_status(handle) != "fail"
399 " Oops, port does exists.
400 call ch_close(handle)
401 else
Bram Moolenaarac42afd2016-03-12 13:48:49 +0100402 " Failed connection should wait about 500 msec. Can be longer if the
403 " computer is busy with other things.
Bram Moolenaar08298fa2016-02-21 13:01:53 +0100404 let elapsed = reltime(start)
405 call assert_true(reltimefloat(elapsed) > 0.3)
Bram Moolenaarac42afd2016-03-12 13:48:49 +0100406 call assert_true(reltimefloat(elapsed) < 1.5)
Bram Moolenaar08298fa2016-02-21 13:01:53 +0100407 endif
408 catch
409 if v:exception !~ 'Connection reset by peer'
410 call assert_false(1, "Caught exception: " . v:exception)
411 endif
412 endtry
Bram Moolenaar7a84dbe2016-02-07 21:29:00 +0100413endfunc
Bram Moolenaar6463ca22016-02-13 17:04:46 +0100414
Bram Moolenaard6547fc2016-03-03 19:35:02 +0100415"""""""""
416
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100417func Test_raw_pipe()
418 if !has('job')
419 return
420 endif
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100421 call ch_log('Test_raw_pipe()')
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100422 let job = job_start(s:python . " test_channel_pipe.py", {'mode': 'raw'})
423 call assert_equal("run", job_status(job))
424 try
Bram Moolenaar151f6562016-03-07 21:19:38 +0100425 " For a change use the job where a channel is expected.
426 call ch_sendraw(job, "echo something\n")
427 let msg = ch_readraw(job)
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100428 call assert_equal("something\n", substitute(msg, "\r", "", 'g'))
429
Bram Moolenaar151f6562016-03-07 21:19:38 +0100430 call ch_sendraw(job, "double this\n")
431 let msg = ch_readraw(job)
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100432 call assert_equal("this\nAND this\n", substitute(msg, "\r", "", 'g'))
433
Bram Moolenaar151f6562016-03-07 21:19:38 +0100434 let reply = ch_evalraw(job, "quit\n", {'timeout': 100})
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100435 call assert_equal("Goodbye!\n", substitute(reply, "\r", "", 'g'))
436 finally
437 call job_stop(job)
438 endtry
Bram Moolenaar8950a562016-03-12 15:22:55 +0100439
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200440 let g:Ch_job = job
441 call WaitFor('"dead" == job_status(g:Ch_job)')
Bram Moolenaar8950a562016-03-12 15:22:55 +0100442 let info = job_info(job)
443 call assert_equal("dead", info.status)
444 call assert_equal("term", info.stoponexit)
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100445endfunc
446
447func Test_nl_pipe()
Bram Moolenaard8070362016-02-15 21:56:54 +0100448 if !has('job')
Bram Moolenaar6463ca22016-02-13 17:04:46 +0100449 return
450 endif
Bram Moolenaar81661fb2016-02-18 22:23:34 +0100451 call ch_log('Test_nl_pipe()')
Bram Moolenaar1adda342016-03-12 15:39:40 +0100452 let job = job_start([s:python, "test_channel_pipe.py"])
Bram Moolenaar6463ca22016-02-13 17:04:46 +0100453 call assert_equal("run", job_status(job))
454 try
455 let handle = job_getchannel(job)
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100456 call ch_sendraw(handle, "echo something\n")
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100457 call assert_equal("something", ch_readraw(handle))
458
Bram Moolenaarc25558b2016-03-03 21:02:23 +0100459 call ch_sendraw(handle, "echoerr wrong\n")
460 call assert_equal("wrong", ch_readraw(handle, {'part': 'err'}))
461
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100462 call ch_sendraw(handle, "double this\n")
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100463 call assert_equal("this", ch_readraw(handle))
464 call assert_equal("AND this", ch_readraw(handle))
465
Bram Moolenaarbbe8d912016-06-05 16:10:57 +0200466 call ch_sendraw(handle, "split this line\n")
467 call assert_equal("this linethis linethis line", ch_readraw(handle))
468
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100469 let reply = ch_evalraw(handle, "quit\n")
Bram Moolenaar9a6e33a2016-02-16 19:25:12 +0100470 call assert_equal("Goodbye!", reply)
Bram Moolenaar6463ca22016-02-13 17:04:46 +0100471 finally
472 call job_stop(job)
473 endtry
474endfunc
Bram Moolenaar3bece9f2016-02-15 20:39:46 +0100475
Bram Moolenaarc25558b2016-03-03 21:02:23 +0100476func Test_nl_err_to_out_pipe()
477 if !has('job')
478 return
479 endif
Bram Moolenaar5a6ec522016-03-12 15:51:44 +0100480 call ch_logfile('Xlog')
Bram Moolenaarc25558b2016-03-03 21:02:23 +0100481 call ch_log('Test_nl_err_to_out_pipe()')
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100482 let job = job_start(s:python . " test_channel_pipe.py", {'err_io': 'out'})
Bram Moolenaarc25558b2016-03-03 21:02:23 +0100483 call assert_equal("run", job_status(job))
484 try
485 let handle = job_getchannel(job)
486 call ch_sendraw(handle, "echo something\n")
487 call assert_equal("something", ch_readraw(handle))
488
489 call ch_sendraw(handle, "echoerr wrong\n")
490 call assert_equal("wrong", ch_readraw(handle))
491 finally
492 call job_stop(job)
Bram Moolenaar5a6ec522016-03-12 15:51:44 +0100493 call ch_logfile('')
494 let loglines = readfile('Xlog')
495 call assert_true(len(loglines) > 10)
496 let found_test = 0
497 let found_send = 0
498 let found_recv = 0
499 let found_stop = 0
500 for l in loglines
501 if l =~ 'Test_nl_err_to_out_pipe'
502 let found_test = 1
503 endif
504 if l =~ 'SEND on.*echo something'
505 let found_send = 1
506 endif
507 if l =~ 'RECV on.*something'
508 let found_recv = 1
509 endif
510 if l =~ 'Stopping job with'
511 let found_stop = 1
512 endif
513 endfor
514 call assert_equal(1, found_test)
515 call assert_equal(1, found_send)
516 call assert_equal(1, found_recv)
517 call assert_equal(1, found_stop)
518 call delete('Xlog')
Bram Moolenaarc25558b2016-03-03 21:02:23 +0100519 endtry
520endfunc
521
Bram Moolenaarb69fccf2016-03-06 23:06:25 +0100522func Test_nl_read_file()
523 if !has('job')
524 return
525 endif
Bram Moolenaarb69fccf2016-03-06 23:06:25 +0100526 call ch_log('Test_nl_read_file()')
527 call writefile(['echo something', 'echoerr wrong', 'double this'], 'Xinput')
528 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100529 \ {'in_io': 'file', 'in_name': 'Xinput'})
Bram Moolenaarb69fccf2016-03-06 23:06:25 +0100530 call assert_equal("run", job_status(job))
531 try
532 let handle = job_getchannel(job)
533 call assert_equal("something", ch_readraw(handle))
534 call assert_equal("wrong", ch_readraw(handle, {'part': 'err'}))
535 call assert_equal("this", ch_readraw(handle))
536 call assert_equal("AND this", ch_readraw(handle))
537 finally
538 call job_stop(job)
539 call delete('Xinput')
540 endtry
541endfunc
542
Bram Moolenaare98d1212016-03-08 15:37:41 +0100543func Test_nl_write_out_file()
544 if !has('job')
545 return
546 endif
Bram Moolenaare98d1212016-03-08 15:37:41 +0100547 call ch_log('Test_nl_write_out_file()')
548 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100549 \ {'out_io': 'file', 'out_name': 'Xoutput'})
Bram Moolenaare98d1212016-03-08 15:37:41 +0100550 call assert_equal("run", job_status(job))
551 try
552 let handle = job_getchannel(job)
553 call ch_sendraw(handle, "echo line one\n")
554 call ch_sendraw(handle, "echo line two\n")
555 call ch_sendraw(handle, "double this\n")
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200556 call WaitFor('len(readfile("Xoutput")) > 2')
Bram Moolenaare98d1212016-03-08 15:37:41 +0100557 call assert_equal(['line one', 'line two', 'this', 'AND this'], readfile('Xoutput'))
558 finally
559 call job_stop(job)
560 call delete('Xoutput')
561 endtry
562endfunc
563
564func Test_nl_write_err_file()
565 if !has('job')
566 return
567 endif
Bram Moolenaare98d1212016-03-08 15:37:41 +0100568 call ch_log('Test_nl_write_err_file()')
569 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100570 \ {'err_io': 'file', 'err_name': 'Xoutput'})
Bram Moolenaare98d1212016-03-08 15:37:41 +0100571 call assert_equal("run", job_status(job))
572 try
573 let handle = job_getchannel(job)
574 call ch_sendraw(handle, "echoerr line one\n")
575 call ch_sendraw(handle, "echoerr line two\n")
576 call ch_sendraw(handle, "doubleerr this\n")
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200577 call WaitFor('len(readfile("Xoutput")) > 2')
Bram Moolenaare98d1212016-03-08 15:37:41 +0100578 call assert_equal(['line one', 'line two', 'this', 'AND this'], readfile('Xoutput'))
579 finally
580 call job_stop(job)
581 call delete('Xoutput')
582 endtry
583endfunc
584
585func Test_nl_write_both_file()
586 if !has('job')
587 return
588 endif
Bram Moolenaare98d1212016-03-08 15:37:41 +0100589 call ch_log('Test_nl_write_both_file()')
590 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100591 \ {'out_io': 'file', 'out_name': 'Xoutput', 'err_io': 'out'})
Bram Moolenaare98d1212016-03-08 15:37:41 +0100592 call assert_equal("run", job_status(job))
593 try
594 let handle = job_getchannel(job)
595 call ch_sendraw(handle, "echoerr line one\n")
596 call ch_sendraw(handle, "echo line two\n")
597 call ch_sendraw(handle, "double this\n")
598 call ch_sendraw(handle, "doubleerr that\n")
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200599 call WaitFor('len(readfile("Xoutput")) > 5')
Bram Moolenaare98d1212016-03-08 15:37:41 +0100600 call assert_equal(['line one', 'line two', 'this', 'AND this', 'that', 'AND that'], readfile('Xoutput'))
601 finally
602 call job_stop(job)
603 call delete('Xoutput')
604 endtry
605endfunc
606
Bram Moolenaar01d46e42016-06-02 19:06:25 +0200607func BufCloseCb(ch)
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200608 let g:Ch_bufClosed = 'yes'
Bram Moolenaar01d46e42016-06-02 19:06:25 +0200609endfunc
610
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200611func Run_test_pipe_to_buffer(use_name, nomod)
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100612 if !has('job')
613 return
614 endif
615 call ch_log('Test_pipe_to_buffer()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200616 let g:Ch_bufClosed = 'no'
Bram Moolenaar01d46e42016-06-02 19:06:25 +0200617 let options = {'out_io': 'buffer', 'close_cb': 'BufCloseCb'}
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100618 if a:use_name
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100619 let options['out_name'] = 'pipe-output'
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100620 let firstline = 'Reading from channel output...'
621 else
622 sp pipe-output
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100623 let options['out_buf'] = bufnr('%')
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100624 quit
625 let firstline = ''
626 endif
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200627 if a:nomod
628 let options['out_modifiable'] = 0
629 endif
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100630 let job = job_start(s:python . " test_channel_pipe.py", options)
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100631 call assert_equal("run", job_status(job))
632 try
633 let handle = job_getchannel(job)
634 call ch_sendraw(handle, "echo line one\n")
635 call ch_sendraw(handle, "echo line two\n")
636 call ch_sendraw(handle, "double this\n")
637 call ch_sendraw(handle, "quit\n")
638 sp pipe-output
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200639 call WaitFor('line("$") >= 6 && g:Ch_bufClosed == "yes"')
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100640 call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this', 'Goodbye!'], getline(1, '$'))
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200641 if a:nomod
642 call assert_equal(0, &modifiable)
643 else
644 call assert_equal(1, &modifiable)
645 endif
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200646 call assert_equal('yes', g:Ch_bufClosed)
Bram Moolenaar8b1862a2016-02-27 19:21:24 +0100647 bwipe!
648 finally
649 call job_stop(job)
650 endtry
651endfunc
652
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100653func Test_pipe_to_buffer_name()
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200654 call Run_test_pipe_to_buffer(1, 0)
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100655endfunc
656
657func Test_pipe_to_buffer_nr()
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200658 call Run_test_pipe_to_buffer(0, 0)
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100659endfunc
660
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200661func Test_pipe_to_buffer_name_nomod()
662 call Run_test_pipe_to_buffer(1, 1)
663endfunc
664
665func Run_test_pipe_err_to_buffer(use_name, nomod)
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100666 if !has('job')
667 return
668 endif
669 call ch_log('Test_pipe_err_to_buffer()')
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100670 let options = {'err_io': 'buffer'}
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100671 if a:use_name
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100672 let options['err_name'] = 'pipe-err'
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100673 let firstline = 'Reading from channel error...'
674 else
675 sp pipe-err
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100676 let options['err_buf'] = bufnr('%')
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100677 quit
678 let firstline = ''
679 endif
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200680 if a:nomod
681 let options['err_modifiable'] = 0
682 endif
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100683 let job = job_start(s:python . " test_channel_pipe.py", options)
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100684 call assert_equal("run", job_status(job))
685 try
686 let handle = job_getchannel(job)
687 call ch_sendraw(handle, "echoerr line one\n")
688 call ch_sendraw(handle, "echoerr line two\n")
689 call ch_sendraw(handle, "doubleerr this\n")
690 call ch_sendraw(handle, "quit\n")
691 sp pipe-err
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200692 call WaitFor('line("$") >= 5')
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100693 call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this'], getline(1, '$'))
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200694 if a:nomod
695 call assert_equal(0, &modifiable)
696 else
697 call assert_equal(1, &modifiable)
698 endif
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100699 bwipe!
700 finally
701 call job_stop(job)
702 endtry
703endfunc
704
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100705func Test_pipe_err_to_buffer_name()
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200706 call Run_test_pipe_err_to_buffer(1, 0)
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100707endfunc
708
709func Test_pipe_err_to_buffer_nr()
Bram Moolenaar9f5842e2016-05-29 16:17:08 +0200710 call Run_test_pipe_err_to_buffer(0, 0)
711endfunc
712
713func Test_pipe_err_to_buffer_name_nomod()
714 call Run_test_pipe_err_to_buffer(1, 1)
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100715endfunc
716
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100717func Test_pipe_both_to_buffer()
718 if !has('job')
719 return
720 endif
721 call ch_log('Test_pipe_both_to_buffer()')
722 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100723 \ {'out_io': 'buffer', 'out_name': 'pipe-err', 'err_io': 'out'})
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100724 call assert_equal("run", job_status(job))
725 try
726 let handle = job_getchannel(job)
727 call ch_sendraw(handle, "echo line one\n")
728 call ch_sendraw(handle, "echoerr line two\n")
729 call ch_sendraw(handle, "double this\n")
730 call ch_sendraw(handle, "doubleerr that\n")
731 call ch_sendraw(handle, "quit\n")
732 sp pipe-err
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200733 call WaitFor('line("$") >= 7')
Bram Moolenaar6ff02c92016-03-08 20:12:44 +0100734 call assert_equal(['Reading from channel output...', 'line one', 'line two', 'this', 'AND this', 'that', 'AND that', 'Goodbye!'], getline(1, '$'))
735 bwipe!
736 finally
737 call job_stop(job)
738 endtry
739endfunc
740
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100741func Run_test_pipe_from_buffer(use_name)
Bram Moolenaar014069a2016-03-03 22:51:40 +0100742 if !has('job')
743 return
744 endif
Bram Moolenaar014069a2016-03-03 22:51:40 +0100745 call ch_log('Test_pipe_from_buffer()')
746
747 sp pipe-input
748 call setline(1, ['echo one', 'echo two', 'echo three'])
Bram Moolenaar8b877ac2016-03-28 19:16:20 +0200749 let options = {'in_io': 'buffer', 'block_write': 1}
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100750 if a:use_name
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100751 let options['in_name'] = 'pipe-input'
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100752 else
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100753 let options['in_buf'] = bufnr('%')
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100754 endif
Bram Moolenaar014069a2016-03-03 22:51:40 +0100755
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100756 let job = job_start(s:python . " test_channel_pipe.py", options)
Bram Moolenaar014069a2016-03-03 22:51:40 +0100757 call assert_equal("run", job_status(job))
758 try
759 let handle = job_getchannel(job)
760 call assert_equal('one', ch_read(handle))
761 call assert_equal('two', ch_read(handle))
762 call assert_equal('three', ch_read(handle))
763 bwipe!
764 finally
765 call job_stop(job)
766 endtry
Bram Moolenaar014069a2016-03-03 22:51:40 +0100767endfunc
768
Bram Moolenaar29fd0382016-03-09 23:14:07 +0100769func Test_pipe_from_buffer_name()
770 call Run_test_pipe_from_buffer(1)
771endfunc
772
773func Test_pipe_from_buffer_nr()
774 call Run_test_pipe_from_buffer(0)
775endfunc
776
Bram Moolenaarc7f0ebc2016-02-27 21:10:09 +0100777func Test_pipe_to_nameless_buffer()
778 if !has('job')
779 return
780 endif
781 call ch_log('Test_pipe_to_nameless_buffer()')
782 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100783 \ {'out_io': 'buffer'})
Bram Moolenaarc7f0ebc2016-02-27 21:10:09 +0100784 call assert_equal("run", job_status(job))
785 try
786 let handle = job_getchannel(job)
787 call ch_sendraw(handle, "echo line one\n")
788 call ch_sendraw(handle, "echo line two\n")
789 exe ch_getbufnr(handle, "out") . 'sbuf'
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200790 call WaitFor('line("$") >= 3')
Bram Moolenaarc7f0ebc2016-02-27 21:10:09 +0100791 call assert_equal(['Reading from channel output...', 'line one', 'line two'], getline(1, '$'))
792 bwipe!
793 finally
794 call job_stop(job)
795 endtry
796endfunc
797
Bram Moolenaarcc7f8be2016-02-29 22:55:56 +0100798func Test_pipe_to_buffer_json()
799 if !has('job')
800 return
801 endif
802 call ch_log('Test_pipe_to_buffer_json()')
803 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100804 \ {'out_io': 'buffer', 'out_mode': 'json'})
Bram Moolenaarcc7f8be2016-02-29 22:55:56 +0100805 call assert_equal("run", job_status(job))
806 try
807 let handle = job_getchannel(job)
808 call ch_sendraw(handle, "echo [0, \"hello\"]\n")
809 call ch_sendraw(handle, "echo [-2, 12.34]\n")
810 exe ch_getbufnr(handle, "out") . 'sbuf'
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200811 call WaitFor('line("$") >= 3')
Bram Moolenaarcc7f8be2016-02-29 22:55:56 +0100812 call assert_equal(['Reading from channel output...', '[0,"hello"]', '[-2,12.34]'], getline(1, '$'))
813 bwipe!
814 finally
815 call job_stop(job)
816 endtry
817endfunc
818
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100819" Wait a little while for the last line, minus "offset", to equal "line".
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100820func s:wait_for_last_line(line, offset)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100821 for i in range(100)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100822 if getline(line('$') - a:offset) == a:line
823 break
824 endif
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100825 sleep 10m
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100826 endfor
827endfunc
828
829func Test_pipe_io_two_buffers()
830 if !has('job')
831 return
832 endif
833 call ch_log('Test_pipe_io_two_buffers()')
834
835 " Create two buffers, one to read from and one to write to.
836 split pipe-output
837 set buftype=nofile
838 split pipe-input
839 set buftype=nofile
840
841 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100842 \ {'in_io': 'buffer', 'in_name': 'pipe-input', 'in_top': 0,
Bram Moolenaar8b877ac2016-03-28 19:16:20 +0200843 \ 'out_io': 'buffer', 'out_name': 'pipe-output',
844 \ 'block_write': 1})
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100845 call assert_equal("run", job_status(job))
846 try
847 exe "normal Gaecho hello\<CR>"
848 exe bufwinnr('pipe-output') . "wincmd w"
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100849 call s:wait_for_last_line('hello', 0)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100850 call assert_equal('hello', getline('$'))
851
852 exe bufwinnr('pipe-input') . "wincmd w"
853 exe "normal Gadouble this\<CR>"
854 exe bufwinnr('pipe-output') . "wincmd w"
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100855 call s:wait_for_last_line('AND this', 0)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100856 call assert_equal('this', getline(line('$') - 1))
857 call assert_equal('AND this', getline('$'))
858
859 bwipe!
860 exe bufwinnr('pipe-input') . "wincmd w"
861 bwipe!
862 finally
863 call job_stop(job)
864 endtry
865endfunc
866
867func Test_pipe_io_one_buffer()
868 if !has('job')
869 return
870 endif
871 call ch_log('Test_pipe_io_one_buffer()')
872
873 " Create one buffer to read from and to write to.
874 split pipe-io
875 set buftype=nofile
876
877 let job = job_start(s:python . " test_channel_pipe.py",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100878 \ {'in_io': 'buffer', 'in_name': 'pipe-io', 'in_top': 0,
Bram Moolenaar8b877ac2016-03-28 19:16:20 +0200879 \ 'out_io': 'buffer', 'out_name': 'pipe-io',
880 \ 'block_write': 1})
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100881 call assert_equal("run", job_status(job))
882 try
883 exe "normal Goecho hello\<CR>"
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100884 call s:wait_for_last_line('hello', 1)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100885 call assert_equal('hello', getline(line('$') - 1))
886
887 exe "normal Gadouble this\<CR>"
Bram Moolenaar9fe885e2016-03-08 16:06:55 +0100888 call s:wait_for_last_line('AND this', 1)
Bram Moolenaar3f39f642016-03-06 21:35:57 +0100889 call assert_equal('this', getline(line('$') - 2))
890 call assert_equal('AND this', getline(line('$') - 1))
891
892 bwipe!
893 finally
894 call job_stop(job)
895 endtry
896endfunc
897
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100898func Test_pipe_null()
899 if !has('job')
900 return
901 endif
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100902 call ch_log('Test_pipe_null()')
903
904 " We cannot check that no I/O works, we only check that the job starts
905 " properly.
906 let job = job_start(s:python . " test_channel_pipe.py something",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100907 \ {'in_io': 'null'})
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100908 call assert_equal("run", job_status(job))
909 try
910 call assert_equal('something', ch_read(job))
911 finally
912 call job_stop(job)
913 endtry
914
915 let job = job_start(s:python . " test_channel_pipe.py err-out",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100916 \ {'out_io': 'null'})
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100917 call assert_equal("run", job_status(job))
918 try
919 call assert_equal('err-out', ch_read(job, {"part": "err"}))
920 finally
921 call job_stop(job)
922 endtry
923
924 let job = job_start(s:python . " test_channel_pipe.py something",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100925 \ {'err_io': 'null'})
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100926 call assert_equal("run", job_status(job))
927 try
928 call assert_equal('something', ch_read(job))
929 finally
930 call job_stop(job)
931 endtry
932
933 let job = job_start(s:python . " test_channel_pipe.py something",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100934 \ {'out_io': 'null', 'err_io': 'out'})
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100935 call assert_equal("run", job_status(job))
936 call job_stop(job)
937
938 let job = job_start(s:python . " test_channel_pipe.py something",
Bram Moolenaard6c2f052016-03-14 23:22:59 +0100939 \ {'in_io': 'null', 'out_io': 'null', 'err_io': 'null'})
Bram Moolenaarf65333c2016-03-08 18:27:21 +0100940 call assert_equal("run", job_status(job))
941 call assert_equal('channel fail', string(job_getchannel(job)))
942 call assert_equal('fail', ch_status(job))
943 call job_stop(job)
944endfunc
945
Bram Moolenaaradb78a72016-06-27 21:10:31 +0200946func Test_pipe_to_buffer_raw()
947 if !has('job')
948 return
949 endif
950 call ch_log('Test_raw_pipe_to_buffer()')
951 let options = {'out_mode': 'raw', 'out_io': 'buffer', 'out_name': 'testout'}
952 split testout
953 let job = job_start([s:python, '-c',
954 \ 'import sys; [sys.stdout.write(".") and sys.stdout.flush() for _ in range(10000)]'], options)
955 call assert_equal("run", job_status(job))
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200956 call WaitFor('len(join(getline(2,line("$")),"") >= 10000')
Bram Moolenaaradb78a72016-06-27 21:10:31 +0200957 try
958 for line in getline(2, '$')
959 let line = substitute(line, '^\.*', '', '')
960 call assert_equal('', line)
961 endfor
962 finally
963 call job_stop(job)
964 bwipe!
965 endtry
966endfunc
967
Bram Moolenaarde279892016-03-11 22:19:44 +0100968func Test_reuse_channel()
969 if !has('job')
970 return
971 endif
972 call ch_log('Test_reuse_channel()')
973
974 let job = job_start(s:python . " test_channel_pipe.py")
975 call assert_equal("run", job_status(job))
976 let handle = job_getchannel(job)
977 try
978 call ch_sendraw(handle, "echo something\n")
979 call assert_equal("something", ch_readraw(handle))
980 finally
981 call job_stop(job)
982 endtry
983
984 let job = job_start(s:python . " test_channel_pipe.py", {'channel': handle})
985 call assert_equal("run", job_status(job))
986 let handle = job_getchannel(job)
987 try
988 call ch_sendraw(handle, "echo again\n")
989 call assert_equal("again", ch_readraw(handle))
990 finally
991 call job_stop(job)
992 endtry
993endfunc
994
Bram Moolenaar75f72652016-03-20 22:16:56 +0100995func Test_out_cb()
996 if !has('job')
997 return
998 endif
999 call ch_log('Test_out_cb()')
1000
1001 let dict = {'thisis': 'dict: '}
1002 func dict.outHandler(chan, msg) dict
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001003 let g:Ch_outmsg = self.thisis . a:msg
Bram Moolenaar75f72652016-03-20 22:16:56 +01001004 endfunc
1005 func dict.errHandler(chan, msg) dict
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001006 let g:Ch_errmsg = self.thisis . a:msg
Bram Moolenaar75f72652016-03-20 22:16:56 +01001007 endfunc
1008 let job = job_start(s:python . " test_channel_pipe.py",
1009 \ {'out_cb': dict.outHandler,
1010 \ 'out_mode': 'json',
1011 \ 'err_cb': dict.errHandler,
1012 \ 'err_mode': 'json'})
1013 call assert_equal("run", job_status(job))
1014 try
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001015 let g:Ch_outmsg = ''
1016 let g:Ch_errmsg = ''
Bram Moolenaar75f72652016-03-20 22:16:56 +01001017 call ch_sendraw(job, "echo [0, \"hello\"]\n")
1018 call ch_sendraw(job, "echoerr [0, \"there\"]\n")
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001019 call WaitFor('g:Ch_outmsg != ""')
1020 call assert_equal("dict: hello", g:Ch_outmsg)
1021 call WaitFor('g:Ch_errmsg != ""')
1022 call assert_equal("dict: there", g:Ch_errmsg)
Bram Moolenaar75f72652016-03-20 22:16:56 +01001023 finally
1024 call job_stop(job)
1025 endtry
1026endfunc
1027
Bram Moolenaarb2658a12016-04-26 17:16:24 +02001028func Test_out_close_cb()
1029 if !has('job')
1030 return
1031 endif
1032 call ch_log('Test_out_close_cb()')
1033
1034 let s:counter = 1
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001035 let g:Ch_msg1 = ''
1036 let g:Ch_closemsg = 0
Bram Moolenaarb2658a12016-04-26 17:16:24 +02001037 func! OutHandler(chan, msg)
Bram Moolenaard75263c2016-04-30 16:07:23 +02001038 if s:counter == 1
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001039 let g:Ch_msg1 = a:msg
Bram Moolenaard75263c2016-04-30 16:07:23 +02001040 endif
Bram Moolenaarb2658a12016-04-26 17:16:24 +02001041 let s:counter += 1
1042 endfunc
1043 func! CloseHandler(chan)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001044 let g:Ch_closemsg = s:counter
Bram Moolenaarb2658a12016-04-26 17:16:24 +02001045 let s:counter += 1
1046 endfunc
1047 let job = job_start(s:python . " test_channel_pipe.py quit now",
1048 \ {'out_cb': 'OutHandler',
1049 \ 'close_cb': 'CloseHandler'})
1050 call assert_equal("run", job_status(job))
1051 try
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001052 call WaitFor('g:Ch_closemsg != 0 && g:Ch_msg1 != ""')
1053 call assert_equal('quit', g:Ch_msg1)
1054 call assert_equal(2, g:Ch_closemsg)
Bram Moolenaarb2658a12016-04-26 17:16:24 +02001055 finally
1056 call job_stop(job)
1057 delfunc OutHandler
1058 delfunc CloseHandler
1059 endtry
1060endfunc
1061
Bram Moolenaar437905c2016-04-26 19:01:05 +02001062func Test_read_in_close_cb()
1063 if !has('job')
1064 return
1065 endif
1066 call ch_log('Test_read_in_close_cb()')
1067
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001068 let g:Ch_received = ''
Bram Moolenaar437905c2016-04-26 19:01:05 +02001069 func! CloseHandler(chan)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001070 let g:Ch_received = ch_read(a:chan)
Bram Moolenaar437905c2016-04-26 19:01:05 +02001071 endfunc
1072 let job = job_start(s:python . " test_channel_pipe.py quit now",
1073 \ {'close_cb': 'CloseHandler'})
1074 call assert_equal("run", job_status(job))
1075 try
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001076 call WaitFor('g:Ch_received != ""')
1077 call assert_equal('quit', g:Ch_received)
Bram Moolenaar437905c2016-04-26 19:01:05 +02001078 finally
1079 call job_stop(job)
1080 delfunc CloseHandler
1081 endtry
1082endfunc
1083
Bram Moolenaar069c1e72016-07-15 21:25:08 +02001084func Test_out_cb_lambda()
1085 if !has('job')
1086 return
1087 endif
1088 call ch_log('Test_out_cb_lambda()')
1089
1090 let job = job_start(s:python . " test_channel_pipe.py",
1091 \ {'out_cb': {ch, msg -> execute("let g:Ch_outmsg = 'lambda: ' . msg")},
1092 \ 'out_mode': 'json',
1093 \ 'err_cb': {ch, msg -> execute(":let g:Ch_errmsg = 'lambda: ' . msg")},
1094 \ 'err_mode': 'json'})
1095 call assert_equal("run", job_status(job))
1096 try
1097 let g:Ch_outmsg = ''
1098 let g:Ch_errmsg = ''
1099 call ch_sendraw(job, "echo [0, \"hello\"]\n")
1100 call ch_sendraw(job, "echoerr [0, \"there\"]\n")
1101 call WaitFor('g:Ch_outmsg != ""')
1102 call assert_equal("lambda: hello", g:Ch_outmsg)
1103 call WaitFor('g:Ch_errmsg != ""')
1104 call assert_equal("lambda: there", g:Ch_errmsg)
1105 finally
1106 call job_stop(job)
1107 endtry
1108endfunc
1109
Bram Moolenaard46ae142016-02-16 13:33:52 +01001110""""""""""
1111
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001112let g:Ch_unletResponse = ''
Bram Moolenaar3bece9f2016-02-15 20:39:46 +01001113func s:UnletHandler(handle, msg)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001114 let g:Ch_unletResponse = a:msg
Bram Moolenaar3bece9f2016-02-15 20:39:46 +01001115 unlet s:channelfd
1116endfunc
1117
1118" Test that "unlet handle" in a handler doesn't crash Vim.
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001119func Ch_unlet_handle(port)
Bram Moolenaar3bece9f2016-02-15 20:39:46 +01001120 let s:channelfd = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar910b8aa2016-02-16 21:03:07 +01001121 call ch_sendexpr(s:channelfd, "test", {'callback': function('s:UnletHandler')})
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001122 call WaitFor('"what?" == g:Ch_unletResponse')
1123 call assert_equal('what?', g:Ch_unletResponse)
Bram Moolenaar3bece9f2016-02-15 20:39:46 +01001124endfunc
1125
1126func Test_unlet_handle()
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001127 call ch_log('Test_unlet_handle()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001128 call s:run_server('Ch_unlet_handle')
Bram Moolenaar3bece9f2016-02-15 20:39:46 +01001129endfunc
Bram Moolenaar5cefd402016-02-16 12:44:26 +01001130
Bram Moolenaard46ae142016-02-16 13:33:52 +01001131""""""""""
1132
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001133let g:Ch_unletResponse = ''
1134func Ch_CloseHandler(handle, msg)
1135 let g:Ch_unletResponse = a:msg
Bram Moolenaard46ae142016-02-16 13:33:52 +01001136 call ch_close(s:channelfd)
1137endfunc
1138
1139" Test that "unlet handle" in a handler doesn't crash Vim.
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001140func Ch_close_handle(port)
Bram Moolenaard46ae142016-02-16 13:33:52 +01001141 let s:channelfd = ch_open('localhost:' . a:port, s:chopt)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001142 call ch_sendexpr(s:channelfd, "test", {'callback': function('Ch_CloseHandler')})
1143 call WaitFor('"what?" == g:Ch_unletResponse')
1144 call assert_equal('what?', g:Ch_unletResponse)
Bram Moolenaard46ae142016-02-16 13:33:52 +01001145endfunc
1146
1147func Test_close_handle()
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001148 call ch_log('Test_close_handle()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001149 call s:run_server('Ch_close_handle')
Bram Moolenaard46ae142016-02-16 13:33:52 +01001150endfunc
1151
1152""""""""""
1153
Bram Moolenaar5cefd402016-02-16 12:44:26 +01001154func Test_open_fail()
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001155 call ch_log('Test_open_fail()')
Bram Moolenaar5cefd402016-02-16 12:44:26 +01001156 silent! let ch = ch_open("noserver")
1157 echo ch
1158 let d = ch
1159endfunc
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001160
1161""""""""""
1162
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001163func Ch_open_delay(port)
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001164 " Wait up to a second for the port to open.
1165 let s:chopt.waittime = 1000
1166 let channel = ch_open('localhost:' . a:port, s:chopt)
1167 unlet s:chopt.waittime
1168 if ch_status(channel) == "fail"
1169 call assert_false(1, "Can't open channel")
1170 return
1171 endif
Bram Moolenaar8b1862a2016-02-27 19:21:24 +01001172 call assert_equal('got it', ch_evalexpr(channel, 'hello!'))
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001173 call ch_close(channel)
1174endfunc
1175
1176func Test_open_delay()
1177 call ch_log('Test_open_delay()')
1178 " The server will wait half a second before creating the port.
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001179 call s:run_server('Ch_open_delay', 'delay')
Bram Moolenaar81661fb2016-02-18 22:23:34 +01001180endfunc
Bram Moolenaarece61b02016-02-20 21:39:05 +01001181
1182"""""""""
1183
1184function MyFunction(a,b,c)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001185 let g:Ch_call_ret = [a:a, a:b, a:c]
Bram Moolenaarece61b02016-02-20 21:39:05 +01001186endfunc
1187
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001188function Ch_test_call(port)
Bram Moolenaarece61b02016-02-20 21:39:05 +01001189 let handle = ch_open('localhost:' . a:port, s:chopt)
1190 if ch_status(handle) == "fail"
1191 call assert_false(1, "Can't open channel")
1192 return
1193 endif
1194
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001195 let g:Ch_call_ret = []
Bram Moolenaar8b1862a2016-02-27 19:21:24 +01001196 call assert_equal('ok', ch_evalexpr(handle, 'call-func'))
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001197 call WaitFor('len(g:Ch_call_ret) > 0')
1198 call assert_equal([1, 2, 3], g:Ch_call_ret)
Bram Moolenaarece61b02016-02-20 21:39:05 +01001199endfunc
1200
1201func Test_call()
1202 call ch_log('Test_call()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001203 call s:run_server('Ch_test_call')
Bram Moolenaarece61b02016-02-20 21:39:05 +01001204endfunc
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001205
1206"""""""""
1207
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001208let g:Ch_job_exit_ret = 'not yet'
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001209function MyExitCb(job, status)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001210 let g:Ch_job_exit_ret = 'done'
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001211endfunc
1212
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001213function Ch_test_exit_callback(port)
1214 call job_setoptions(g:currentJob, {'exit_cb': 'MyExitCb'})
1215 let g:Ch_exit_job = g:currentJob
1216 call assert_equal('MyExitCb', job_info(g:currentJob)['exit_cb'])
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001217endfunc
1218
1219func Test_exit_callback()
1220 if has('job')
Bram Moolenaar9730f742016-02-28 19:50:51 +01001221 call ch_log('Test_exit_callback()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001222 call s:run_server('Ch_test_exit_callback')
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001223
Bram Moolenaar9730f742016-02-28 19:50:51 +01001224 " wait up to a second for the job to exit
1225 for i in range(100)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001226 if g:Ch_job_exit_ret == 'done'
Bram Moolenaar9730f742016-02-28 19:50:51 +01001227 break
1228 endif
1229 sleep 10m
1230 " calling job_status() triggers the callback
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001231 call job_status(g:Ch_exit_job)
Bram Moolenaar9730f742016-02-28 19:50:51 +01001232 endfor
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001233
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001234 call assert_equal('done', g:Ch_job_exit_ret)
1235 call assert_equal('dead', job_info(g:Ch_exit_job).status)
1236 unlet g:Ch_exit_job
Bram Moolenaaree1cffc2016-02-21 19:14:41 +01001237 endif
1238endfunc
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001239
1240"""""""""
1241
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001242let g:Ch_close_ret = 'alive'
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001243function MyCloseCb(ch)
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001244 let g:Ch_close_ret = 'closed'
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001245endfunc
1246
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001247function Ch_test_close_callback(port)
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001248 let handle = ch_open('localhost:' . a:port, s:chopt)
1249 if ch_status(handle) == "fail"
1250 call assert_false(1, "Can't open channel")
1251 return
1252 endif
Bram Moolenaard6c2f052016-03-14 23:22:59 +01001253 call ch_setoptions(handle, {'close_cb': 'MyCloseCb'})
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001254
Bram Moolenaar8b1862a2016-02-27 19:21:24 +01001255 call assert_equal('', ch_evalexpr(handle, 'close me'))
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001256 call WaitFor('"closed" == g:Ch_close_ret')
1257 call assert_equal('closed', g:Ch_close_ret)
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001258endfunc
1259
1260func Test_close_callback()
1261 call ch_log('Test_close_callback()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001262 call s:run_server('Ch_test_close_callback')
Bram Moolenaar4e221c92016-02-23 13:20:22 +01001263endfunc
1264
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001265function Ch_test_close_partial(port)
Bram Moolenaarbdf0bda2016-03-30 21:06:57 +02001266 let handle = ch_open('localhost:' . a:port, s:chopt)
1267 if ch_status(handle) == "fail"
1268 call assert_false(1, "Can't open channel")
1269 return
1270 endif
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001271 let g:Ch_d = {}
1272 func g:Ch_d.closeCb(ch) dict
Bram Moolenaarbdf0bda2016-03-30 21:06:57 +02001273 let self.close_ret = 'closed'
1274 endfunc
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001275 call ch_setoptions(handle, {'close_cb': g:Ch_d.closeCb})
Bram Moolenaarbdf0bda2016-03-30 21:06:57 +02001276
1277 call assert_equal('', ch_evalexpr(handle, 'close me'))
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001278 call WaitFor('"closed" == g:Ch_d.close_ret')
1279 call assert_equal('closed', g:Ch_d.close_ret)
1280 unlet g:Ch_d
Bram Moolenaarbdf0bda2016-03-30 21:06:57 +02001281endfunc
1282
1283func Test_close_partial()
1284 call ch_log('Test_close_partial()')
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001285 call s:run_server('Ch_test_close_partial')
Bram Moolenaarbdf0bda2016-03-30 21:06:57 +02001286endfunc
1287
Bram Moolenaar80385682016-03-27 19:13:35 +02001288func Test_job_start_invalid()
1289 call assert_fails('call job_start($x)', 'E474:')
1290 call assert_fails('call job_start("")', 'E474:')
1291endfunc
1292
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02001293" This was leaking memory.
Bram Moolenaar0e4c1de2016-04-07 21:40:38 +02001294func Test_partial_in_channel_cycle()
1295 let d = {}
1296 let d.a = function('string', [d])
1297 try
1298 let d.b = ch_open('nowhere:123', {'close_cb': d.a})
1299 catch
1300 call assert_exception('E901:')
1301 endtry
1302 unlet d
1303endfunc
1304
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02001305func Test_using_freed_memory()
1306 let g:a = job_start(['ls'])
1307 sleep 10m
Bram Moolenaar574860b2016-05-24 17:33:34 +02001308 call test_garbagecollect_now()
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02001309endfunc
1310
Bram Moolenaarb8aefa42016-06-10 23:02:56 +02001311func Test_collapse_buffers()
1312 if !executable('cat')
1313 return
1314 endif
1315 sp test_channel.vim
1316 let g:linecount = line('$')
1317 close
1318 split testout
1319 1,$delete
1320 call job_start('cat test_channel.vim', {'out_io': 'buffer', 'out_name': 'testout'})
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001321 call WaitFor('line("$") > g:linecount')
Bram Moolenaarb8aefa42016-06-10 23:02:56 +02001322 call assert_true(line('$') > g:linecount)
1323 bwipe!
1324endfunc
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02001325
Bram Moolenaar069c1e72016-07-15 21:25:08 +02001326function Ch_test_close_lambda(port)
1327 let handle = ch_open('localhost:' . a:port, s:chopt)
1328 if ch_status(handle) == "fail"
1329 call assert_false(1, "Can't open channel")
1330 return
1331 endif
1332 let g:Ch_close_ret = ''
1333 call ch_setoptions(handle, {'close_cb': {ch -> execute("let g:Ch_close_ret = 'closed'")}})
1334
1335 call assert_equal('', ch_evalexpr(handle, 'close me'))
1336 call WaitFor('"closed" == g:Ch_close_ret')
1337 call assert_equal('closed', g:Ch_close_ret)
1338endfunc
1339
1340func Test_close_lambda()
1341 call ch_log('Test_close_lambda()')
1342 call s:run_server('Ch_test_close_lambda')
1343endfunc
Bram Moolenaarebf7dfa2016-04-14 12:46:51 +02001344
Bram Moolenaar9730f742016-02-28 19:50:51 +01001345" Uncomment this to see what happens, output is in src/testdir/channellog.
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001346 call ch_logfile('channellog', 'w')