Patch 7.4.2039
Problem:    The Netbeans integration is not tested.
Solution:   Add a first Netbeans test.
Files:      src/testdir/test_netbeans.vim, src/testdir/test_netbeans.py,
            src/testdir/Make_all.mak, src/Makefile,
            src/testdir/test_channel.vim, src/testdir/shared.vim


*** ../vim-7.4.2038/src/testdir/test_netbeans.vim       2016-07-15 
17:03:26.807260745 +0200
--- src/testdir/test_netbeans.vim       2016-07-15 16:21:31.779125336 +0200
***************
*** 0 ****
--- 1,51 ----
+ " Test the netbeans interface.
+ 
+ if !has('netbeans_intg')
+   finish
+ endif
+ 
+ source shared.vim
+ 
+ let s:python = PythonProg()
+ if s:python == ''
+   " Can't run this test.
+   finish
+ endif
+ 
+ " Run "testfunc" after sarting the server and stop the server afterwards.
+ func s:run_server(testfunc, ...)
+   call RunServer('test_netbeans.py', a:testfunc, a:000)
+ endfunc
+ 
+ func Nb_basic(port)
+   call delete("Xnetbeans")
+   exe 'nbstart :localhost:' . a:port . ':bunny'
+   call assert_true(has("netbeans_enabled"))
+ 
+   call WaitFor('len(readfile("Xnetbeans")) > 2')
+   split +$ Makefile
+ 
+   " Opening Makefile will result in a setDot command
+   call WaitFor('len(readfile("Xnetbeans")) > 4')
+   let pos = getcurpos()
+   call assert_equal(2, pos[1])
+   call assert_equal(20, pos[2])
+   close
+   nbclose
+ 
+   call WaitFor('len(readfile("Xnetbeans")) > 6')
+   let lines = readfile("Xnetbeans")
+   call assert_equal('AUTH bunny', lines[0])
+   call assert_equal('0:version=0 "2.5"', lines[1])
+   call assert_equal('0:startupDone=0', lines[2])
+   call assert_equal('0:fileOpened=0 "Makefile" T F', substitute(lines[3], 
'".*/', '"', ''))
+ 
+   call assert_equal('0:disconnect=1', lines[6])
+ 
+   call delete("Xnetbeans")
+ endfunc
+ 
+ func Test_nb_basic()
+   call ch_log('Test_nb_basic')
+   call s:run_server('Nb_basic')
+ endfunc
*** ../vim-7.4.2038/src/testdir/test_netbeans.py        2016-07-15 
17:03:26.815260631 +0200
--- src/testdir/test_netbeans.py        2016-07-15 17:06:04.837005846 +0200
***************
*** 0 ****
--- 1,91 ----
+ #!/usr/bin/python
+ #
+ # Server that will communicate with Vim through the netbeans interface.
+ # Used by test_netbeans.vim.
+ #
+ # This requires Python 2.6 or later.
+ 
+ from __future__ import print_function
+ import socket
+ import sys
+ import time
+ import threading
+ 
+ try:
+     # Python 3
+     import socketserver
+ except ImportError:
+     # Python 2
+     import SocketServer as socketserver
+ 
+ class ThreadedTCPRequestHandler(socketserver.BaseRequestHandler):
+ 
+     def handle(self):
+         print("=== socket opened ===")
+         while True:
+             try:
+                 received = self.request.recv(4096).decode('utf-8')
+             except socket.error:
+                 print("=== socket error ===")
+                 break
+             except IOError:
+                 print("=== socket closed ===")
+                 break
+             if received == '':
+                 print("=== socket closed ===")
+                 break
+             print("received: {0}".format(received))
+ 
+             # Write the received line into the file, so that the test can 
check
+             # what happened.
+             with open("Xnetbeans", "a") as myfile:
+                 myfile.write(received)
+ 
+             response = ''
+             if received.find('Makefile') > 0:
+                 name = received.split('"')[1]
+                 response = '5:putBufferNumber!33 "' + name + '"\n'
+                 response += '5:setDot!1 2/19\n'
+             elif received.find('disconnect') > 0:
+                 # we're done
+                 self.server.shutdown()
+                 return
+ 
+             if len(response) > 0:
+                 self.request.sendall(response)
+                 # Write the respoinse into the file, so that the test can 
knows
+                 # the command was sent.
+                 with open("Xnetbeans", "a") as myfile:
+                     myfile.write('send: ' + response)
+ 
+ class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
+     pass
+ 
+ def writePortInFile(port):
+     # Write the port number in Xportnr, so that the test knows it.
+     f = open("Xportnr", "w")
+     f.write("{0}".format(port))
+     f.close()
+ 
+ if __name__ == "__main__":
+     HOST, PORT = "localhost", 0
+ 
+     server = ThreadedTCPServer((HOST, PORT), ThreadedTCPRequestHandler)
+     ip, port = server.server_address
+ 
+     # Start a thread with the server.  That thread will then start a new 
thread
+     # for each connection.
+     server_thread = threading.Thread(target=server.serve_forever)
+     server_thread.start()
+ 
+     writePortInFile(port)
+ 
+     print("Listening on port {0}".format(port))
+ 
+     # Main thread terminates, but the server continues running
+     # until server.shutdown() is called.
+     try:
+         while server_thread.isAlive(): 
+             server_thread.join(1)
+     except (KeyboardInterrupt, SystemExit):
+         server.shutdown()
*** ../vim-7.4.2038/src/testdir/Make_all.mak    2016-07-13 22:43:47.774233938 
+0200
--- src/testdir/Make_all.mak    2016-07-15 13:33:04.995241884 +0200
***************
*** 179,184 ****
--- 179,185 ----
            test_langmap.res \
            test_man.res \
            test_matchadd_conceal.res \
+           test_netbeans.res \
            test_packadd.res \
            test_perl.res \
            test_quickfix.res \
*** ../vim-7.4.2038/src/Makefile        2016-07-13 22:43:47.774233938 +0200
--- src/Makefile        2016-07-15 13:33:20.899013562 +0200
***************
*** 2055,2060 ****
--- 2055,2061 ----
        test_matchstrpos \
        test_menu \
        test_messages \
+       test_netbeans \
        test_packadd \
        test_partial \
        test_perl \
*** ../vim-7.4.2038/src/testdir/test_channel.vim        2016-06-27 
21:10:28.148544550 +0200
--- src/testdir/test_channel.vim        2016-07-15 16:54:54.090575546 +0200
***************
*** 5,29 ****
    finish
  endif
  
! " This test requires the Python command to run the test server.
! " This most likely only works on Unix and Windows.
! if has('unix')
!   " We also need the job feature or the pkill command to make sure the server
!   " can be stopped.
!   if !(executable('python') && (has('job') || executable('pkill')))
!     finish
!   endif
!   let s:python = 'python'
! elseif has('win32')
!   " Use Python Launcher for Windows (py.exe) if available.
!   if executable('py.exe')
!     let s:python = 'py.exe'
!   elseif executable('python.exe')
!     let s:python = 'python.exe'
!   else
!     finish
!   endif
! else
    " Can't run this test.
    finish
  endif
--- 5,14 ----
    finish
  endif
  
! source shared.vim
! 
! let s:python = PythonProg()
! if s:python == ''
    " Can't run this test.
    finish
  endif
***************
*** 32,119 ****
  
  " Run "testfunc" after sarting the server and stop the server afterwards.
  func s:run_server(testfunc, ...)
!   " The Python program writes the port number in Xportnr.
!   call delete("Xportnr")
! 
!   if a:0 == 1
!     let arg = ' ' . a:1
!   else
!     let arg = ''
!   endif
!   let cmd = s:python . " test_channel.py" . arg
! 
!   try
!     if has('job')
!       let s:job = job_start(cmd, {"stoponexit": "hup"})
!       call job_setoptions(s:job, {"stoponexit": "kill"})
!     elseif has('win32')
!       exe 'silent !start cmd /c start "test_channel" ' . cmd
!     else
!       exe 'silent !' . cmd . '&'
!     endif
! 
!     " Wait for up to 2 seconds for the port number to be there.
!     let l = []
!     for i in range(200)
!       try
!         let l = readfile("Xportnr")
!       catch
!       endtry
!       if len(l) >= 1
!         break
!       endif
!       sleep 10m
!     endfor
!     call delete("Xportnr")
! 
!     if len(l) == 0
!       " Can't make the connection, give up.
!       call assert_false(1, "Can't start test_channel.py")
!       return -1
!     endif
!     let port = l[0]
! 
!     call call(function(a:testfunc), [port])
!   catch
!     call assert_false(1, "Caught exception: " . v:exception)
!   finally
!     call s:kill_server()
!   endtry
! endfunc
! 
! func s:kill_server()
!   if has('job')
!     if exists('s:job')
!       call job_stop(s:job)
!       unlet s:job
!     endif
!   elseif has('win32')
!     call system('taskkill /IM ' . s:python . ' /T /F /FI "WINDOWTITLE eq 
test_channel"')
!   else
!     call system("pkill -f test_channel.py")
!   endif
! endfunc
! 
! let s:responseMsg = ''
! func s:RequestHandler(handle, msg)
!   let s:responseHandle = a:handle
!   let s:responseMsg = a:msg
  endfunc
  
! " Wait for up to a second for "expr" to become true.
! func s:waitFor(expr)
!   for i in range(100)
!     try
!       if eval(a:expr)
!       return
!       endif
!     catch
!     endtry
!     sleep 10m
!   endfor
  endfunc
  
! func s:communicate(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
--- 17,32 ----
  
  " Run "testfunc" after sarting the server and stop the server afterwards.
  func s:run_server(testfunc, ...)
!   call RunServer('test_channel.py', a:testfunc, a:000)
  endfunc
  
! let g:Ch_responseMsg = ''
! func Ch_requestHandler(handle, msg)
!   let g:Ch_responseHandle = a:handle
!   let g:Ch_responseMsg = a:msg
  endfunc
  
! func Ch_communicate(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
***************
*** 140,186 ****
  
    " split command should work
    call assert_equal('ok', ch_evalexpr(handle, 'split'))
!   call s:waitFor('exists("g:split")')
    call assert_equal(123, g:split)
  
    " Request that triggers sending two ex commands.  These will usually be
    " handled before getting the response, but it's not guaranteed, thus wait a
    " tiny bit for the commands to get executed.
    call assert_equal('ok', ch_evalexpr(handle, 'make change'))
!   call s:waitFor('"added2" == getline("$")')
    call assert_equal('added1', getline(line('$') - 1))
    call assert_equal('added2', getline('$'))
  
    " Request command "foo bar", which fails silently.
    call assert_equal('ok', ch_evalexpr(handle, 'bad command'))
!   call s:waitFor('v:errmsg =~ "E492"')
    call assert_match('E492:.*foo bar', v:errmsg)
  
    call assert_equal('ok', ch_evalexpr(handle, 'do normal', {'timeout': 100}))
!   call s:waitFor('"added more" == getline("$")')
    call assert_equal('added more', getline('$'))
  
    " Send a request with a specific handler.
!   call ch_sendexpr(handle, 'hello!', {'callback': 's:RequestHandler'})
!   call s:waitFor('exists("s:responseHandle")')
!   if !exists('s:responseHandle')
!     call assert_false(1, 's:responseHandle was not set')
    else
!     call assert_equal(handle, s:responseHandle)
!     unlet s:responseHandle
    endif
!   call assert_equal('got it', s:responseMsg)
  
!   let s:responseMsg = ''
!   call ch_sendexpr(handle, 'hello!', {'callback': 
function('s:RequestHandler')})
!   call s:waitFor('exists("s:responseHandle")')
!   if !exists('s:responseHandle')
!     call assert_false(1, 's:responseHandle was not set')
    else
!     call assert_equal(handle, s:responseHandle)
!     unlet s:responseHandle
    endif
!   call assert_equal('got it', s:responseMsg)
  
    " Collect garbage, tests that our handle isn't collected.
    call test_garbagecollect_now()
--- 53,99 ----
  
    " split command should work
    call assert_equal('ok', ch_evalexpr(handle, 'split'))
!   call WaitFor('exists("g:split")')
    call assert_equal(123, g:split)
  
    " Request that triggers sending two ex commands.  These will usually be
    " handled before getting the response, but it's not guaranteed, thus wait a
    " tiny bit for the commands to get executed.
    call assert_equal('ok', ch_evalexpr(handle, 'make change'))
!   call WaitFor('"added2" == getline("$")')
    call assert_equal('added1', getline(line('$') - 1))
    call assert_equal('added2', getline('$'))
  
    " Request command "foo bar", which fails silently.
    call assert_equal('ok', ch_evalexpr(handle, 'bad command'))
!   call WaitFor('v:errmsg =~ "E492"')
    call assert_match('E492:.*foo bar', v:errmsg)
  
    call assert_equal('ok', ch_evalexpr(handle, 'do normal', {'timeout': 100}))
!   call WaitFor('"added more" == getline("$")')
    call assert_equal('added more', getline('$'))
  
    " Send a request with a specific handler.
!   call ch_sendexpr(handle, 'hello!', {'callback': 'Ch_requestHandler'})
!   call WaitFor('exists("g:Ch_responseHandle")')
!   if !exists('g:Ch_responseHandle')
!     call assert_false(1, 'g:Ch_responseHandle was not set')
    else
!     call assert_equal(handle, g:Ch_responseHandle)
!     unlet g:Ch_responseHandle
    endif
!   call assert_equal('got it', g:Ch_responseMsg)
  
!   let g:Ch_responseMsg = ''
!   call ch_sendexpr(handle, 'hello!', {'callback': 
function('Ch_requestHandler')})
!   call WaitFor('exists("g:Ch_responseHandle")')
!   if !exists('g:Ch_responseHandle')
!     call assert_false(1, 'g:Ch_responseHandle was not set')
    else
!     call assert_equal(handle, g:Ch_responseHandle)
!     unlet g:Ch_responseHandle
    endif
!   call assert_equal('got it', g:Ch_responseMsg)
  
    " Collect garbage, tests that our handle isn't collected.
    call test_garbagecollect_now()
***************
*** 225,231 ****
  
    " Send an expr request
    call assert_equal('ok', ch_evalexpr(handle, 'an expr'))
!   call s:waitFor('"three" == getline("$")')
    call assert_equal('one', getline(line('$') - 2))
    call assert_equal('two', getline(line('$') - 1))
    call assert_equal('three', getline('$'))
--- 138,144 ----
  
    " Send an expr request
    call assert_equal('ok', ch_evalexpr(handle, 'an expr'))
!   call WaitFor('"three" == getline("$")')
    call assert_equal('one', getline(line('$') - 2))
    call assert_equal('two', getline(line('$') - 1))
    call assert_equal('three', getline('$'))
***************
*** 257,267 ****
  
  func Test_communicate()
    call ch_log('Test_communicate()')
!   call s:run_server('s:communicate')
  endfunc
  
  " Test that we can open two channels.
! func s:two_channels(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
--- 170,180 ----
  
  func Test_communicate()
    call ch_log('Test_communicate()')
!   call s:run_server('Ch_communicate')
  endfunc
  
  " Test that we can open two channels.
! func Ch_two_channels(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
***************
*** 286,296 ****
  
  func Test_two_channels()
    call ch_log('Test_two_channels()')
!   call s:run_server('s:two_channels')
  endfunc
  
  " Test that a server crash is handled gracefully.
! func s:server_crash(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
--- 199,209 ----
  
  func Test_two_channels()
    call ch_log('Test_two_channels()')
!   call s:run_server('Ch_two_channels')
  endfunc
  
  " Test that a server crash is handled gracefully.
! func Ch_server_crash(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
***************
*** 304,321 ****
  
  func Test_server_crash()
    call ch_log('Test_server_crash()')
!   call s:run_server('s:server_crash')
  endfunc
  
  """""""""
  
! let s:reply = ""
! func s:Handler(chan, msg)
!   unlet s:reply
!   let s:reply = a:msg
  endfunc
  
! func s:channel_handler(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
--- 217,234 ----
  
  func Test_server_crash()
    call ch_log('Test_server_crash()')
!   call s:run_server('Ch_server_crash')
  endfunc
  
  """""""""
  
! let g:Ch_reply = ""
! func Ch_handler(chan, msg)
!   unlet g:Ch_reply
!   let g:Ch_reply = a:msg
  endfunc
  
! func Ch_channel_handler(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
***************
*** 324,362 ****
  
    " Test that it works while waiting on a numbered message.
    call assert_equal('ok', ch_evalexpr(handle, 'call me'))
!   call s:waitFor('"we called you" == s:reply')
!   call assert_equal('we called you', s:reply)
  
    " Test that it works while not waiting on a numbered message.
    call ch_sendexpr(handle, 'call me again')
!   call s:waitFor('"we did call you" == s:reply')
!   call assert_equal('we did call you', s:reply)
  endfunc
  
  func Test_channel_handler()
    call ch_log('Test_channel_handler()')
!   let s:chopt.callback = 's:Handler'
!   call s:run_server('s:channel_handler')
!   let s:chopt.callback = function('s:Handler')
!   call s:run_server('s:channel_handler')
    unlet s:chopt.callback
  endfunc
  
  """""""""
  
! let s:ch_reply = ''
! func s:ChHandler(chan, msg)
!   unlet s:ch_reply
!   let s:ch_reply = a:msg
  endfunc
  
! let s:zero_reply = ''
! func s:OneHandler(chan, msg)
!   unlet s:zero_reply
!   let s:zero_reply = a:msg
  endfunc
  
! func s:channel_zero(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
--- 237,275 ----
  
    " Test that it works while waiting on a numbered message.
    call assert_equal('ok', ch_evalexpr(handle, 'call me'))
!   call WaitFor('"we called you" == g:Ch_reply')
!   call assert_equal('we called you', g:Ch_reply)
  
    " Test that it works while not waiting on a numbered message.
    call ch_sendexpr(handle, 'call me again')
!   call WaitFor('"we did call you" == g:Ch_reply')
!   call assert_equal('we did call you', g:Ch_reply)
  endfunc
  
  func Test_channel_handler()
    call ch_log('Test_channel_handler()')
!   let s:chopt.callback = 'Ch_handler'
!   call s:run_server('Ch_channel_handler')
!   let s:chopt.callback = function('Ch_handler')
!   call s:run_server('Ch_channel_handler')
    unlet s:chopt.callback
  endfunc
  
  """""""""
  
! let g:Ch_reply = ''
! func Ch_zeroHandler(chan, msg)
!   unlet g:Ch_reply
!   let g:Ch_reply = a:msg
  endfunc
  
! let g:Ch_zero_reply = ''
! func Ch_oneHandler(chan, msg)
!   unlet g:Ch_zero_reply
!   let g:Ch_zero_reply = a:msg
  endfunc
  
! func Ch_channel_zero(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
***************
*** 367,429 ****
    call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
  
    " Check that eval works if a zero id message is sent back.
!   let s:ch_reply = ''
    call assert_equal('sent zero', ch_evalexpr(handle, 'send zero'))
    if s:has_handler
!     call s:waitFor('"zero index" == s:ch_reply')
!     call assert_equal('zero index', s:ch_reply)
    else
      sleep 20m
!     call assert_equal('', s:ch_reply)
    endif
  
    " Check that handler works if a zero id message is sent back.
!   let s:ch_reply = ''
!   let s:zero_reply = ''
!   call ch_sendexpr(handle, 'send zero', {'callback': 's:OneHandler'})
!   call s:waitFor('"sent zero" == s:zero_reply')
    if s:has_handler
!     call assert_equal('zero index', s:ch_reply)
    else
!     call assert_equal('', s:ch_reply)
    endif
!   call assert_equal('sent zero', s:zero_reply)
  endfunc
  
  func Test_zero_reply()
    call ch_log('Test_zero_reply()')
    " Run with channel handler
    let s:has_handler = 1
!   let s:chopt.callback = 's:ChHandler'
!   call s:run_server('s:channel_zero')
    unlet s:chopt.callback
  
    " Run without channel handler
    let s:has_handler = 0
!   call s:run_server('s:channel_zero')
  endfunc
  
  """""""""
  
! let s:reply1 = ""
! func s:HandleRaw1(chan, msg)
!   unlet s:reply1
!   let s:reply1 = a:msg
  endfunc
  
! let s:reply2 = ""
! func s:HandleRaw2(chan, msg)
!   unlet s:reply2
!   let s:reply2 = a:msg
  endfunc
  
! let s:reply3 = ""
! func s:HandleRaw3(chan, msg)
!   unlet s:reply3
!   let s:reply3 = a:msg
  endfunc
  
! func s:raw_one_time_callback(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
--- 280,342 ----
    call assert_equal('got it', ch_evalexpr(handle, 'hello!'))
  
    " Check that eval works if a zero id message is sent back.
!   let g:Ch_reply = ''
    call assert_equal('sent zero', ch_evalexpr(handle, 'send zero'))
    if s:has_handler
!     call WaitFor('"zero index" == g:Ch_reply')
!     call assert_equal('zero index', g:Ch_reply)
    else
      sleep 20m
!     call assert_equal('', g:Ch_reply)
    endif
  
    " Check that handler works if a zero id message is sent back.
!   let g:Ch_reply = ''
!   let g:Ch_zero_reply = ''
!   call ch_sendexpr(handle, 'send zero', {'callback': 'Ch_oneHandler'})
!   call WaitFor('"sent zero" == g:Ch_zero_reply')
    if s:has_handler
!     call assert_equal('zero index', g:Ch_reply)
    else
!     call assert_equal('', g:Ch_reply)
    endif
!   call assert_equal('sent zero', g:Ch_zero_reply)
  endfunc
  
  func Test_zero_reply()
    call ch_log('Test_zero_reply()')
    " Run with channel handler
    let s:has_handler = 1
!   let s:chopt.callback = 'Ch_zeroHandler'
!   call s:run_server('Ch_channel_zero')
    unlet s:chopt.callback
  
    " Run without channel handler
    let s:has_handler = 0
!   call s:run_server('Ch_channel_zero')
  endfunc
  
  """""""""
  
! let g:Ch_reply1 = ""
! func Ch_handleRaw1(chan, msg)
!   unlet g:Ch_reply1
!   let g:Ch_reply1 = a:msg
  endfunc
  
! let g:Ch_reply2 = ""
! func Ch_handleRaw2(chan, msg)
!   unlet g:Ch_reply2
!   let g:Ch_reply2 = a:msg
  endfunc
  
! let g:Ch_reply3 = ""
! func Ch_handleRaw3(chan, msg)
!   unlet g:Ch_reply3
!   let g:Ch_reply3 = a:msg
  endfunc
  
! func Ch_raw_one_time_callback(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
***************
*** 432,452 ****
    call ch_setoptions(handle, {'mode': 'raw'})
  
    " The message are sent raw, we do our own JSON strings here.
!   call ch_sendraw(handle, "[1, \"hello!\"]", {'callback': 's:HandleRaw1'})
!   call s:waitFor('s:reply1 != ""')
!   call assert_equal("[1, \"got it\"]", s:reply1)
!   call ch_sendraw(handle, "[2, \"echo something\"]", {'callback': 
's:HandleRaw2'})
!   call ch_sendraw(handle, "[3, \"wait a bit\"]", {'callback': 's:HandleRaw3'})
!   call s:waitFor('s:reply2 != ""')
!   call assert_equal("[2, \"something\"]", s:reply2)
    " wait for the 200 msec delayed reply
!   call s:waitFor('s:reply3 != ""')
!   call assert_equal("[3, \"waited\"]", s:reply3)
  endfunc
  
  func Test_raw_one_time_callback()
    call ch_log('Test_raw_one_time_callback()')
!   call s:run_server('s:raw_one_time_callback')
  endfunc
  
  """""""""
--- 345,365 ----
    call ch_setoptions(handle, {'mode': 'raw'})
  
    " The message are sent raw, we do our own JSON strings here.
!   call ch_sendraw(handle, "[1, \"hello!\"]", {'callback': 'Ch_handleRaw1'})
!   call WaitFor('g:Ch_reply1 != ""')
!   call assert_equal("[1, \"got it\"]", g:Ch_reply1)
!   call ch_sendraw(handle, "[2, \"echo something\"]", {'callback': 
'Ch_handleRaw2'})
!   call ch_sendraw(handle, "[3, \"wait a bit\"]", {'callback': 
'Ch_handleRaw3'})
!   call WaitFor('g:Ch_reply2 != ""')
!   call assert_equal("[2, \"something\"]", g:Ch_reply2)
    " wait for the 200 msec delayed reply
!   call WaitFor('g:Ch_reply3 != ""')
!   call assert_equal("[3, \"waited\"]", g:Ch_reply3)
  endfunc
  
  func Test_raw_one_time_callback()
    call ch_log('Test_raw_one_time_callback()')
!   call s:run_server('Ch_raw_one_time_callback')
  endfunc
  
  """""""""
***************
*** 512,519 ****
      call job_stop(job)
    endtry
  
!   let s:job = job
!   call s:waitFor('"dead" == job_status(s:job)')
    let info = job_info(job)
    call assert_equal("dead", info.status)
    call assert_equal("term", info.stoponexit)
--- 425,432 ----
      call job_stop(job)
    endtry
  
!   let g:Ch_job = job
!   call WaitFor('"dead" == job_status(g:Ch_job)')
    let info = job_info(job)
    call assert_equal("dead", info.status)
    call assert_equal("term", info.stoponexit)
***************
*** 628,634 ****
      call ch_sendraw(handle, "echo line one\n")
      call ch_sendraw(handle, "echo line two\n")
      call ch_sendraw(handle, "double this\n")
!     call s:waitFor('len(readfile("Xoutput")) > 2')
      call assert_equal(['line one', 'line two', 'this', 'AND this'], 
readfile('Xoutput'))
    finally
      call job_stop(job)
--- 541,547 ----
      call ch_sendraw(handle, "echo line one\n")
      call ch_sendraw(handle, "echo line two\n")
      call ch_sendraw(handle, "double this\n")
!     call WaitFor('len(readfile("Xoutput")) > 2')
      call assert_equal(['line one', 'line two', 'this', 'AND this'], 
readfile('Xoutput'))
    finally
      call job_stop(job)
***************
*** 649,655 ****
      call ch_sendraw(handle, "echoerr line one\n")
      call ch_sendraw(handle, "echoerr line two\n")
      call ch_sendraw(handle, "doubleerr this\n")
!     call s:waitFor('len(readfile("Xoutput")) > 2')
      call assert_equal(['line one', 'line two', 'this', 'AND this'], 
readfile('Xoutput'))
    finally
      call job_stop(job)
--- 562,568 ----
      call ch_sendraw(handle, "echoerr line one\n")
      call ch_sendraw(handle, "echoerr line two\n")
      call ch_sendraw(handle, "doubleerr this\n")
!     call WaitFor('len(readfile("Xoutput")) > 2')
      call assert_equal(['line one', 'line two', 'this', 'AND this'], 
readfile('Xoutput'))
    finally
      call job_stop(job)
***************
*** 671,677 ****
      call ch_sendraw(handle, "echo line two\n")
      call ch_sendraw(handle, "double this\n")
      call ch_sendraw(handle, "doubleerr that\n")
!     call s:waitFor('len(readfile("Xoutput")) > 5')
      call assert_equal(['line one', 'line two', 'this', 'AND this', 'that', 
'AND that'], readfile('Xoutput'))
    finally
      call job_stop(job)
--- 584,590 ----
      call ch_sendraw(handle, "echo line two\n")
      call ch_sendraw(handle, "double this\n")
      call ch_sendraw(handle, "doubleerr that\n")
!     call WaitFor('len(readfile("Xoutput")) > 5')
      call assert_equal(['line one', 'line two', 'this', 'AND this', 'that', 
'AND that'], readfile('Xoutput'))
    finally
      call job_stop(job)
***************
*** 680,686 ****
  endfunc
  
  func BufCloseCb(ch)
!   let s:bufClosed = 'yes'
  endfunc
  
  func Run_test_pipe_to_buffer(use_name, nomod)
--- 593,599 ----
  endfunc
  
  func BufCloseCb(ch)
!   let g:Ch_bufClosed = 'yes'
  endfunc
  
  func Run_test_pipe_to_buffer(use_name, nomod)
***************
*** 688,694 ****
      return
    endif
    call ch_log('Test_pipe_to_buffer()')
!   let s:bufClosed = 'no'
    let options = {'out_io': 'buffer', 'close_cb': 'BufCloseCb'}
    if a:use_name
      let options['out_name'] = 'pipe-output'
--- 601,607 ----
      return
    endif
    call ch_log('Test_pipe_to_buffer()')
!   let g:Ch_bufClosed = 'no'
    let options = {'out_io': 'buffer', 'close_cb': 'BufCloseCb'}
    if a:use_name
      let options['out_name'] = 'pipe-output'
***************
*** 711,724 ****
      call ch_sendraw(handle, "double this\n")
      call ch_sendraw(handle, "quit\n")
      sp pipe-output
!     call s:waitFor('line("$") >= 6 && s:bufClosed == "yes"')
      call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this', 
'Goodbye!'], getline(1, '$'))
      if a:nomod
        call assert_equal(0, &modifiable)
      else
        call assert_equal(1, &modifiable)
      endif
!     call assert_equal('yes', s:bufClosed)
      bwipe!
    finally
      call job_stop(job)
--- 624,637 ----
      call ch_sendraw(handle, "double this\n")
      call ch_sendraw(handle, "quit\n")
      sp pipe-output
!     call WaitFor('line("$") >= 6 && g:Ch_bufClosed == "yes"')
      call assert_equal([firstline, 'line one', 'line two', 'this', 'AND this', 
'Goodbye!'], getline(1, '$'))
      if a:nomod
        call assert_equal(0, &modifiable)
      else
        call assert_equal(1, &modifiable)
      endif
!     call assert_equal('yes', g:Ch_bufClosed)
      bwipe!
    finally
      call job_stop(job)
***************
*** 764,770 ****
      call ch_sendraw(handle, "doubleerr this\n")
      call ch_sendraw(handle, "quit\n")
      sp pipe-err
!     call s:waitFor('line("$") >= 5')
      call assert_equal([firstline, 'line one', 'line two', 'this', 'AND 
this'], getline(1, '$'))
      if a:nomod
        call assert_equal(0, &modifiable)
--- 677,683 ----
      call ch_sendraw(handle, "doubleerr this\n")
      call ch_sendraw(handle, "quit\n")
      sp pipe-err
!     call WaitFor('line("$") >= 5')
      call assert_equal([firstline, 'line one', 'line two', 'this', 'AND 
this'], getline(1, '$'))
      if a:nomod
        call assert_equal(0, &modifiable)
***************
*** 805,811 ****
      call ch_sendraw(handle, "doubleerr that\n")
      call ch_sendraw(handle, "quit\n")
      sp pipe-err
!     call s:waitFor('line("$") >= 7')
      call assert_equal(['Reading from channel output...', 'line one', 'line 
two', 'this', 'AND this', 'that', 'AND that', 'Goodbye!'], getline(1, '$'))
      bwipe!
    finally
--- 718,724 ----
      call ch_sendraw(handle, "doubleerr that\n")
      call ch_sendraw(handle, "quit\n")
      sp pipe-err
!     call WaitFor('line("$") >= 7')
      call assert_equal(['Reading from channel output...', 'line one', 'line 
two', 'this', 'AND this', 'that', 'AND that', 'Goodbye!'], getline(1, '$'))
      bwipe!
    finally
***************
*** 862,868 ****
      call ch_sendraw(handle, "echo line one\n")
      call ch_sendraw(handle, "echo line two\n")
      exe ch_getbufnr(handle, "out") . 'sbuf'
!     call s:waitFor('line("$") >= 3')
      call assert_equal(['Reading from channel output...', 'line one', 'line 
two'], getline(1, '$'))
      bwipe!
    finally
--- 775,781 ----
      call ch_sendraw(handle, "echo line one\n")
      call ch_sendraw(handle, "echo line two\n")
      exe ch_getbufnr(handle, "out") . 'sbuf'
!     call WaitFor('line("$") >= 3')
      call assert_equal(['Reading from channel output...', 'line one', 'line 
two'], getline(1, '$'))
      bwipe!
    finally
***************
*** 883,889 ****
      call ch_sendraw(handle, "echo [0, \"hello\"]\n")
      call ch_sendraw(handle, "echo [-2, 12.34]\n")
      exe ch_getbufnr(handle, "out") . 'sbuf'
!     call s:waitFor('line("$") >= 3')
      call assert_equal(['Reading from channel output...', '[0,"hello"]', 
'[-2,12.34]'], getline(1, '$'))
      bwipe!
    finally
--- 796,802 ----
      call ch_sendraw(handle, "echo [0, \"hello\"]\n")
      call ch_sendraw(handle, "echo [-2, 12.34]\n")
      exe ch_getbufnr(handle, "out") . 'sbuf'
!     call WaitFor('line("$") >= 3')
      call assert_equal(['Reading from channel output...', '[0,"hello"]', 
'[-2,12.34]'], getline(1, '$'))
      bwipe!
    finally
***************
*** 1028,1034 ****
    let job = job_start([s:python, '-c', 
          \ 'import sys; [sys.stdout.write(".") and sys.stdout.flush() for _ in 
range(10000)]'], options)
    call assert_equal("run", job_status(job))
!   call s:waitFor('len(join(getline(2,line("$")),"") >= 10000')
    try
      for line in getline(2, '$')
        let line = substitute(line, '^\.*', '', '')
--- 941,947 ----
    let job = job_start([s:python, '-c', 
          \ 'import sys; [sys.stdout.write(".") and sys.stdout.flush() for _ in 
range(10000)]'], options)
    call assert_equal("run", job_status(job))
!   call WaitFor('len(join(getline(2,line("$")),"") >= 10000')
    try
      for line in getline(2, '$')
        let line = substitute(line, '^\.*', '', '')
***************
*** 1075,1084 ****
  
    let dict = {'thisis': 'dict: '}
    func dict.outHandler(chan, msg) dict
!     let s:outmsg = self.thisis . a:msg
    endfunc
    func dict.errHandler(chan, msg) dict
!     let s:errmsg = self.thisis . a:msg
    endfunc
    let job = job_start(s:python . " test_channel_pipe.py",
        \ {'out_cb': dict.outHandler,
--- 988,997 ----
  
    let dict = {'thisis': 'dict: '}
    func dict.outHandler(chan, msg) dict
!     let g:Ch_outmsg = self.thisis . a:msg
    endfunc
    func dict.errHandler(chan, msg) dict
!     let g:Ch_errmsg = self.thisis . a:msg
    endfunc
    let job = job_start(s:python . " test_channel_pipe.py",
        \ {'out_cb': dict.outHandler,
***************
*** 1087,1100 ****
        \ 'err_mode': 'json'})
    call assert_equal("run", job_status(job))
    try
!     let s:outmsg = ''
!     let s:errmsg = ''
      call ch_sendraw(job, "echo [0, \"hello\"]\n")
      call ch_sendraw(job, "echoerr [0, \"there\"]\n")
!     call s:waitFor('s:outmsg != ""')
!     call assert_equal("dict: hello", s:outmsg)
!     call s:waitFor('s:errmsg != ""')
!     call assert_equal("dict: there", s:errmsg)
    finally
      call job_stop(job)
    endtry
--- 1000,1013 ----
        \ 'err_mode': 'json'})
    call assert_equal("run", job_status(job))
    try
!     let g:Ch_outmsg = ''
!     let g:Ch_errmsg = ''
      call ch_sendraw(job, "echo [0, \"hello\"]\n")
      call ch_sendraw(job, "echoerr [0, \"there\"]\n")
!     call WaitFor('g:Ch_outmsg != ""')
!     call assert_equal("dict: hello", g:Ch_outmsg)
!     call WaitFor('g:Ch_errmsg != ""')
!     call assert_equal("dict: there", g:Ch_errmsg)
    finally
      call job_stop(job)
    endtry
***************
*** 1107,1122 ****
    call ch_log('Test_out_close_cb()')
  
    let s:counter = 1
!   let s:msg1 = ''
!   let s:closemsg = 0
    func! OutHandler(chan, msg)
      if s:counter == 1
!       let s:msg1 = a:msg
      endif
      let s:counter += 1
    endfunc
    func! CloseHandler(chan)
!     let s:closemsg = s:counter
      let s:counter += 1
    endfunc
    let job = job_start(s:python . " test_channel_pipe.py quit now",
--- 1020,1035 ----
    call ch_log('Test_out_close_cb()')
  
    let s:counter = 1
!   let g:Ch_msg1 = ''
!   let g:Ch_closemsg = 0
    func! OutHandler(chan, msg)
      if s:counter == 1
!       let g:Ch_msg1 = a:msg
      endif
      let s:counter += 1
    endfunc
    func! CloseHandler(chan)
!     let g:Ch_closemsg = s:counter
      let s:counter += 1
    endfunc
    let job = job_start(s:python . " test_channel_pipe.py quit now",
***************
*** 1124,1132 ****
        \ 'close_cb': 'CloseHandler'})
    call assert_equal("run", job_status(job))
    try
!     call s:waitFor('s:closemsg != 0 && s:msg1 != ""')
!     call assert_equal('quit', s:msg1)
!     call assert_equal(2, s:closemsg)
    finally
      call job_stop(job)
      delfunc OutHandler
--- 1037,1045 ----
        \ 'close_cb': 'CloseHandler'})
    call assert_equal("run", job_status(job))
    try
!     call WaitFor('g:Ch_closemsg != 0 && g:Ch_msg1 != ""')
!     call assert_equal('quit', g:Ch_msg1)
!     call assert_equal(2, g:Ch_closemsg)
    finally
      call job_stop(job)
      delfunc OutHandler
***************
*** 1140,1155 ****
    endif
    call ch_log('Test_read_in_close_cb()')
  
!   let s:received = ''
    func! CloseHandler(chan)
!     let s:received = ch_read(a:chan)
    endfunc
    let job = job_start(s:python . " test_channel_pipe.py quit now",
        \ {'close_cb': 'CloseHandler'})
    call assert_equal("run", job_status(job))
    try
!     call s:waitFor('s:received != ""')
!     call assert_equal('quit', s:received)
    finally
      call job_stop(job)
      delfunc CloseHandler
--- 1053,1068 ----
    endif
    call ch_log('Test_read_in_close_cb()')
  
!   let g:Ch_received = ''
    func! CloseHandler(chan)
!     let g:Ch_received = ch_read(a:chan)
    endfunc
    let job = job_start(s:python . " test_channel_pipe.py quit now",
        \ {'close_cb': 'CloseHandler'})
    call assert_equal("run", job_status(job))
    try
!     call WaitFor('g:Ch_received != ""')
!     call assert_equal('quit', g:Ch_received)
    finally
      call job_stop(job)
      delfunc CloseHandler
***************
*** 1158,1201 ****
  
  """"""""""
  
! let s:unletResponse = ''
  func s:UnletHandler(handle, msg)
!   let s:unletResponse = a:msg
    unlet s:channelfd
  endfunc
  
  " Test that "unlet handle" in a handler doesn't crash Vim.
! func s:unlet_handle(port)
    let s:channelfd = ch_open('localhost:' . a:port, s:chopt)
    call ch_sendexpr(s:channelfd, "test", {'callback': 
function('s:UnletHandler')})
!   call s:waitFor('"what?" == s:unletResponse')
!   call assert_equal('what?', s:unletResponse)
  endfunc
  
  func Test_unlet_handle()
    call ch_log('Test_unlet_handle()')
!   call s:run_server('s:unlet_handle')
  endfunc
  
  """"""""""
  
! let s:unletResponse = ''
! func s:CloseHandler(handle, msg)
!   let s:unletResponse = a:msg
    call ch_close(s:channelfd)
  endfunc
  
  " Test that "unlet handle" in a handler doesn't crash Vim.
! func s:close_handle(port)
    let s:channelfd = ch_open('localhost:' . a:port, s:chopt)
!   call ch_sendexpr(s:channelfd, "test", {'callback': 
function('s:CloseHandler')})
!   call s:waitFor('"what?" == s:unletResponse')
!   call assert_equal('what?', s:unletResponse)
  endfunc
  
  func Test_close_handle()
    call ch_log('Test_close_handle()')
!   call s:run_server('s:close_handle')
  endfunc
  
  """"""""""
--- 1071,1114 ----
  
  """"""""""
  
! let g:Ch_unletResponse = ''
  func s:UnletHandler(handle, msg)
!   let g:Ch_unletResponse = a:msg
    unlet s:channelfd
  endfunc
  
  " Test that "unlet handle" in a handler doesn't crash Vim.
! func Ch_unlet_handle(port)
    let s:channelfd = ch_open('localhost:' . a:port, s:chopt)
    call ch_sendexpr(s:channelfd, "test", {'callback': 
function('s:UnletHandler')})
!   call WaitFor('"what?" == g:Ch_unletResponse')
!   call assert_equal('what?', g:Ch_unletResponse)
  endfunc
  
  func Test_unlet_handle()
    call ch_log('Test_unlet_handle()')
!   call s:run_server('Ch_unlet_handle')
  endfunc
  
  """"""""""
  
! let g:Ch_unletResponse = ''
! func Ch_CloseHandler(handle, msg)
!   let g:Ch_unletResponse = a:msg
    call ch_close(s:channelfd)
  endfunc
  
  " Test that "unlet handle" in a handler doesn't crash Vim.
! func Ch_close_handle(port)
    let s:channelfd = ch_open('localhost:' . a:port, s:chopt)
!   call ch_sendexpr(s:channelfd, "test", {'callback': 
function('Ch_CloseHandler')})
!   call WaitFor('"what?" == g:Ch_unletResponse')
!   call assert_equal('what?', g:Ch_unletResponse)
  endfunc
  
  func Test_close_handle()
    call ch_log('Test_close_handle()')
!   call s:run_server('Ch_close_handle')
  endfunc
  
  """"""""""
***************
*** 1209,1215 ****
  
  """"""""""
  
! func s:open_delay(port)
    " Wait up to a second for the port to open.
    let s:chopt.waittime = 1000
    let channel = ch_open('localhost:' . a:port, s:chopt)
--- 1122,1128 ----
  
  """"""""""
  
! func Ch_open_delay(port)
    " Wait up to a second for the port to open.
    let s:chopt.waittime = 1000
    let channel = ch_open('localhost:' . a:port, s:chopt)
***************
*** 1225,1299 ****
  func Test_open_delay()
    call ch_log('Test_open_delay()')
    " The server will wait half a second before creating the port.
!   call s:run_server('s:open_delay', 'delay')
  endfunc
  
  """""""""
  
  function MyFunction(a,b,c)
!   let s:call_ret = [a:a, a:b, a:c]
  endfunc
  
! function s:test_call(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
      return
    endif
  
!   let s:call_ret = []
    call assert_equal('ok', ch_evalexpr(handle, 'call-func'))
!   call s:waitFor('len(s:call_ret) > 0')
!   call assert_equal([1, 2, 3], s:call_ret)
  endfunc
  
  func Test_call()
    call ch_log('Test_call()')
!   call s:run_server('s:test_call')
  endfunc
  
  """""""""
  
! let s:job_exit_ret = 'not yet'
  function MyExitCb(job, status)
!   let s:job_exit_ret = 'done'
  endfunc
  
! function s:test_exit_callback(port)
!   call job_setoptions(s:job, {'exit_cb': 'MyExitCb'})
!   let s:exit_job = s:job
!   call assert_equal('MyExitCb', job_info(s:job)['exit_cb'])
  endfunc
  
  func Test_exit_callback()
    if has('job')
      call ch_log('Test_exit_callback()')
!     call s:run_server('s:test_exit_callback')
  
      " wait up to a second for the job to exit
      for i in range(100)
!       if s:job_exit_ret == 'done'
        break
        endif
        sleep 10m
        " calling job_status() triggers the callback
!       call job_status(s:exit_job)
      endfor
  
!     call assert_equal('done', s:job_exit_ret)
!     call assert_equal('dead', job_info(s:exit_job).status)
!     unlet s:exit_job
    endif
  endfunc
  
  """""""""
  
! let s:ch_close_ret = 'alive'
  function MyCloseCb(ch)
!   let s:ch_close_ret = 'closed'
  endfunc
  
! function s:test_close_callback(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
--- 1138,1212 ----
  func Test_open_delay()
    call ch_log('Test_open_delay()')
    " The server will wait half a second before creating the port.
!   call s:run_server('Ch_open_delay', 'delay')
  endfunc
  
  """""""""
  
  function MyFunction(a,b,c)
!   let g:Ch_call_ret = [a:a, a:b, a:c]
  endfunc
  
! function Ch_test_call(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
      return
    endif
  
!   let g:Ch_call_ret = []
    call assert_equal('ok', ch_evalexpr(handle, 'call-func'))
!   call WaitFor('len(g:Ch_call_ret) > 0')
!   call assert_equal([1, 2, 3], g:Ch_call_ret)
  endfunc
  
  func Test_call()
    call ch_log('Test_call()')
!   call s:run_server('Ch_test_call')
  endfunc
  
  """""""""
  
! let g:Ch_job_exit_ret = 'not yet'
  function MyExitCb(job, status)
!   let g:Ch_job_exit_ret = 'done'
  endfunc
  
! function Ch_test_exit_callback(port)
!   call job_setoptions(g:currentJob, {'exit_cb': 'MyExitCb'})
!   let g:Ch_exit_job = g:currentJob
!   call assert_equal('MyExitCb', job_info(g:currentJob)['exit_cb'])
  endfunc
  
  func Test_exit_callback()
    if has('job')
      call ch_log('Test_exit_callback()')
!     call s:run_server('Ch_test_exit_callback')
  
      " wait up to a second for the job to exit
      for i in range(100)
!       if g:Ch_job_exit_ret == 'done'
        break
        endif
        sleep 10m
        " calling job_status() triggers the callback
!       call job_status(g:Ch_exit_job)
      endfor
  
!     call assert_equal('done', g:Ch_job_exit_ret)
!     call assert_equal('dead', job_info(g:Ch_exit_job).status)
!     unlet g:Ch_exit_job
    endif
  endfunc
  
  """""""""
  
! let g:Ch_close_ret = 'alive'
  function MyCloseCb(ch)
!   let g:Ch_close_ret = 'closed'
  endfunc
  
! function Ch_test_close_callback(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
***************
*** 1302,1337 ****
    call ch_setoptions(handle, {'close_cb': 'MyCloseCb'})
  
    call assert_equal('', ch_evalexpr(handle, 'close me'))
!   call s:waitFor('"closed" == s:ch_close_ret')
!   call assert_equal('closed', s:ch_close_ret)
  endfunc
  
  func Test_close_callback()
    call ch_log('Test_close_callback()')
!   call s:run_server('s:test_close_callback')
  endfunc
  
! function s:test_close_partial(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
      return
    endif
!   let s:d = {}
!   func s:d.closeCb(ch) dict
      let self.close_ret = 'closed'
    endfunc
!   call ch_setoptions(handle, {'close_cb': s:d.closeCb})
  
    call assert_equal('', ch_evalexpr(handle, 'close me'))
!   call s:waitFor('"closed" == s:d.close_ret')
!   call assert_equal('closed', s:d.close_ret)
!   unlet s:d
  endfunc
  
  func Test_close_partial()
    call ch_log('Test_close_partial()')
!   call s:run_server('s:test_close_partial')
  endfunc
  
  func Test_job_start_invalid()
--- 1215,1250 ----
    call ch_setoptions(handle, {'close_cb': 'MyCloseCb'})
  
    call assert_equal('', ch_evalexpr(handle, 'close me'))
!   call WaitFor('"closed" == g:Ch_close_ret')
!   call assert_equal('closed', g:Ch_close_ret)
  endfunc
  
  func Test_close_callback()
    call ch_log('Test_close_callback()')
!   call s:run_server('Ch_test_close_callback')
  endfunc
  
! function Ch_test_close_partial(port)
    let handle = ch_open('localhost:' . a:port, s:chopt)
    if ch_status(handle) == "fail"
      call assert_false(1, "Can't open channel")
      return
    endif
!   let g:Ch_d = {}
!   func g:Ch_d.closeCb(ch) dict
      let self.close_ret = 'closed'
    endfunc
!   call ch_setoptions(handle, {'close_cb': g:Ch_d.closeCb})
  
    call assert_equal('', ch_evalexpr(handle, 'close me'))
!   call WaitFor('"closed" == g:Ch_d.close_ret')
!   call assert_equal('closed', g:Ch_d.close_ret)
!   unlet g:Ch_d
  endfunc
  
  func Test_close_partial()
    call ch_log('Test_close_partial()')
!   call s:run_server('Ch_test_close_partial')
  endfunc
  
  func Test_job_start_invalid()
***************
*** 1367,1377 ****
    split testout
    1,$delete
    call job_start('cat test_channel.vim', {'out_io': 'buffer', 'out_name': 
'testout'})
!   call s:waitFor('line("$") > g:linecount')
    call assert_true(line('$') > g:linecount)
    bwipe!
  endfunc
  
  
  " Uncomment this to see what happens, output is in src/testdir/channellog.
! " call ch_logfile('channellog', 'w')
--- 1280,1290 ----
    split testout
    1,$delete
    call job_start('cat test_channel.vim', {'out_io': 'buffer', 'out_name': 
'testout'})
!   call WaitFor('line("$") > g:linecount')
    call assert_true(line('$') > g:linecount)
    bwipe!
  endfunc
  
  
  " Uncomment this to see what happens, output is in src/testdir/channellog.
!  call ch_logfile('channellog', 'w')
*** ../vim-7.4.2038/src/testdir/shared.vim      2016-07-15 17:03:53.698877032 
+0200
--- src/testdir/shared.vim      2016-07-15 16:25:11.275996150 +0200
***************
*** 0 ****
--- 1,122 ----
+ " Functions shared by several tests.
+ 
+ " Get the name of the Python executable.
+ " Also keeps it in s:python.
+ func PythonProg()
+   " This test requires the Python command to run the test server.
+   " This most likely only works on Unix and Windows.
+   if has('unix')
+     " We also need the job feature or the pkill command to make sure the 
server
+     " can be stopped.
+     if !(executable('python') && (has('job') || executable('pkill')))
+       return ''
+     endif
+     let s:python = 'python'
+   elseif has('win32')
+     " Use Python Launcher for Windows (py.exe) if available.
+     if executable('py.exe')
+       let s:python = 'py.exe'
+     elseif executable('python.exe')
+       let s:python = 'python.exe'
+     else
+       return ''
+     endif
+   else
+     return ''
+   endif
+   return s:python
+ endfunc
+ 
+ " Run "cmd".  Returns the job if using a job.
+ func RunCommand(cmd)
+   let job = 0
+   if has('job')
+     let job = job_start(a:cmd, {"stoponexit": "hup"})
+     call job_setoptions(job, {"stoponexit": "kill"})
+   elseif has('win32')
+     exe 'silent !start cmd /c start "test_channel" ' . a:cmd
+   else
+     exe 'silent !' . a:cmd . '&'
+   endif
+   return job
+ endfunc
+ 
+ " Read the port number from the Xportnr file.
+ func GetPort()
+   let l = []
+   for i in range(200)
+     try
+       let l = readfile("Xportnr")
+     catch
+     endtry
+     if len(l) >= 1
+       break
+     endif
+     sleep 10m
+   endfor
+   call delete("Xportnr")
+ 
+   if len(l) == 0
+     " Can't make the connection, give up.
+     return 0
+   endif
+   return l[0]
+ endfunc
+ 
+ " Run a Python server for "cmd" and call "testfunc".
+ " Always kills the server before returning.
+ func RunServer(cmd, testfunc, args)
+   " The Python program writes the port number in Xportnr.
+   call delete("Xportnr")
+ 
+   if len(a:args) == 1
+     let arg = ' ' . a:args[0]
+   else
+     let arg = ''
+   endif
+   let pycmd = s:python . " " . a:cmd . arg
+ 
+   try
+     let g:currentJob = RunCommand(pycmd)
+ 
+     " Wait for up to 2 seconds for the port number to be there.
+     let port = GetPort()
+     if port == 0
+       call assert_false(1, "Can't start " . a:cmd)
+       return
+     endif
+ 
+     call call(function(a:testfunc), [port])
+   catch
+     call assert_false(1, "Caught exception: " . v:exception)
+   finally
+     call s:kill_server(a:cmd)
+   endtry
+ endfunc
+ 
+ func s:kill_server(cmd)
+   if has('job')
+     if exists('g:currentJob')
+       call job_stop(g:currentJob)
+       unlet g:currentJob
+     endif
+   elseif has('win32')
+     let cmd = substitute(a:cmd, ".py", '', '')
+     call system('taskkill /IM ' . s:python . ' /T /F /FI "WINDOWTITLE eq ' . 
cmd . '"')
+   else
+     call system("pkill -f " . a:cmd)
+   endif
+ endfunc
+ 
+ " Wait for up to a second for "expr" to become true.
+ func WaitFor(expr)
+   for i in range(100)
+     try
+       if eval(a:expr)
+       return
+       endif
+     catch
+     endtry
+     sleep 10m
+   endfor
+ endfunc
*** ../vim-7.4.2038/src/version.c       2016-07-14 23:03:15.116509331 +0200
--- src/version.c       2016-07-15 16:25:39.111599311 +0200
***************
*** 760,761 ****
--- 760,763 ----
  {   /* Add new patch number below this line */
+ /**/
+     2039,
  /**/

-- 
The psychic said, "God bless you."  I said, "I didn't sneeze."  She
looked deep into my eyes and said, "You will, eventually."  And, damn
if she wasn't right.  Two days later, I sneezed.  --Ellen Degeneres

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\  an exciting new programming language -- http://www.Zimbu.org        ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui