1" Functions shared by several tests. 2 3" Get the name of the Python executable. 4" Also keeps it in s:python. 5func PythonProg() 6 " This test requires the Python command to run the test server. 7 " This most likely only works on Unix and Windows. 8 if has('unix') 9 " We also need the job feature or the pkill command to make sure the server 10 " can be stopped. 11 if !(executable('python') && (has('job') || executable('pkill'))) 12 return '' 13 endif 14 let s:python = 'python' 15 elseif has('win32') 16 " Use Python Launcher for Windows (py.exe) if available. 17 if executable('py.exe') 18 let s:python = 'py.exe' 19 elseif executable('python.exe') 20 let s:python = 'python.exe' 21 else 22 return '' 23 endif 24 else 25 return '' 26 endif 27 return s:python 28endfunc 29 30" Run "cmd". Returns the job if using a job. 31func RunCommand(cmd) 32 let job = 0 33 if has('job') 34 let job = job_start(a:cmd, {"stoponexit": "hup"}) 35 call job_setoptions(job, {"stoponexit": "kill"}) 36 elseif has('win32') 37 exe 'silent !start cmd /c start "test_channel" ' . a:cmd 38 else 39 exe 'silent !' . a:cmd . '&' 40 endif 41 return job 42endfunc 43 44" Read the port number from the Xportnr file. 45func GetPort() 46 let l = [] 47 for i in range(200) 48 try 49 let l = readfile("Xportnr") 50 catch 51 endtry 52 if len(l) >= 1 53 break 54 endif 55 sleep 10m 56 endfor 57 call delete("Xportnr") 58 59 if len(l) == 0 60 " Can't make the connection, give up. 61 return 0 62 endif 63 return l[0] 64endfunc 65 66" Run a Python server for "cmd" and call "testfunc". 67" Always kills the server before returning. 68func RunServer(cmd, testfunc, args) 69 " The Python program writes the port number in Xportnr. 70 call delete("Xportnr") 71 72 if len(a:args) == 1 73 let arg = ' ' . a:args[0] 74 else 75 let arg = '' 76 endif 77 let pycmd = s:python . " " . a:cmd . arg 78 79 try 80 let g:currentJob = RunCommand(pycmd) 81 82 " Wait for up to 2 seconds for the port number to be there. 83 let port = GetPort() 84 if port == 0 85 call assert_false(1, "Can't start " . a:cmd) 86 return 87 endif 88 89 call call(function(a:testfunc), [port]) 90 catch 91 call assert_false(1, "Caught exception: " . v:exception) 92 finally 93 call s:kill_server(a:cmd) 94 endtry 95endfunc 96 97func s:kill_server(cmd) 98 if has('job') 99 if exists('g:currentJob') 100 call job_stop(g:currentJob) 101 unlet g:currentJob 102 endif 103 elseif has('win32') 104 let cmd = substitute(a:cmd, ".py", '', '') 105 call system('taskkill /IM ' . s:python . ' /T /F /FI "WINDOWTITLE eq ' . cmd . '"') 106 else 107 call system("pkill -f " . a:cmd) 108 endif 109endfunc 110 111" Wait for up to a second for "expr" to become true. 112" Return time slept in milliseconds. 113func WaitFor(expr) 114 let slept = 0 115 for i in range(100) 116 try 117 if eval(a:expr) 118 return slept 119 endif 120 catch 121 endtry 122 let slept += 10 123 sleep 10m 124 endfor 125endfunc 126 127" Run Vim, using the "vimcmd" file and "-u NORC". 128" "before" is a list of Vim commands to be executed before loading plugins. 129" "after" is a list of Vim commands to be executed after loading plugins. 130" Plugins are not loaded, unless 'loadplugins' is set in "before". 131" Return 1 if Vim could be executed. 132func RunVim(before, after, arguments) 133 return RunVimPiped(a:before, a:after, a:arguments, '') 134endfunc 135 136func RunVimPiped(before, after, arguments, pipecmd) 137 if !filereadable('vimcmd') 138 return 0 139 endif 140 let args = '' 141 if len(a:before) > 0 142 call writefile(a:before, 'Xbefore.vim') 143 let args .= ' --cmd "so Xbefore.vim"' 144 endif 145 if len(a:after) > 0 146 call writefile(a:after, 'Xafter.vim') 147 let args .= ' -S Xafter.vim' 148 endif 149 150 let cmd = readfile('vimcmd')[0] 151 let cmd = substitute(cmd, '-u \f\+', '-u NONE', '') 152 if cmd !~ '-u NONE' 153 let cmd = cmd . ' -u NONE' 154 endif 155 156 " With pipecmd we can't set VIMRUNTIME. 157 if a:pipecmd != '' 158 let cmd = substitute(cmd, 'VIMRUNTIME=.*VIMRUNTIME;', '', '') 159 endif 160 161 exe "silent !" . a:pipecmd . cmd . args . ' ' . a:arguments 162 163 if len(a:before) > 0 164 call delete('Xbefore.vim') 165 endif 166 if len(a:after) > 0 167 call delete('Xafter.vim') 168 endif 169 return 1 170endfunc 171