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. With the +reltime feature this can be 113" more than the actual waiting time. Without +reltime it can also be less. 114func WaitFor(expr) 115 " using reltime() is more accurate, but not always available 116 if has('reltime') 117 let start = reltime() 118 else 119 let slept = 0 120 endif 121 for i in range(100) 122 try 123 if eval(a:expr) 124 if has('reltime') 125 return float2nr(reltimefloat(reltime(start)) * 1000) 126 endif 127 return slept 128 endif 129 catch 130 endtry 131 if !has('reltime') 132 let slept += 10 133 endif 134 sleep 10m 135 endfor 136 return 1000 137endfunc 138 139" Run Vim, using the "vimcmd" file and "-u NORC". 140" "before" is a list of Vim commands to be executed before loading plugins. 141" "after" is a list of Vim commands to be executed after loading plugins. 142" Plugins are not loaded, unless 'loadplugins' is set in "before". 143" Return 1 if Vim could be executed. 144func RunVim(before, after, arguments) 145 return RunVimPiped(a:before, a:after, a:arguments, '') 146endfunc 147 148func RunVimPiped(before, after, arguments, pipecmd) 149 if !filereadable('vimcmd') 150 return 0 151 endif 152 let args = '' 153 if len(a:before) > 0 154 call writefile(a:before, 'Xbefore.vim') 155 let args .= ' --cmd "so Xbefore.vim"' 156 endif 157 if len(a:after) > 0 158 call writefile(a:after, 'Xafter.vim') 159 let args .= ' -S Xafter.vim' 160 endif 161 162 let cmd = readfile('vimcmd')[0] 163 let cmd = substitute(cmd, '-u \f\+', '-u NONE', '') 164 if cmd !~ '-u NONE' 165 let cmd = cmd . ' -u NONE' 166 endif 167 168 " With pipecmd we can't set VIMRUNTIME. 169 if a:pipecmd != '' 170 let cmd = substitute(cmd, 'VIMRUNTIME=.*VIMRUNTIME;', '', '') 171 endif 172 173 exe "silent !" . a:pipecmd . cmd . args . ' ' . a:arguments 174 175 if len(a:before) > 0 176 call delete('Xbefore.vim') 177 endif 178 if len(a:after) > 0 179 call delete('Xafter.vim') 180 endif 181 return 1 182endfunc 183