blob: d6033d581187a85f2b7a7b2955646976e3acb464 [file] [log] [blame]
Bram Moolenaar321efdd2016-07-15 17:09:11 +02001" Functions shared by several tests.
2
Bram Moolenaara5e66212017-09-29 22:42:33 +02003" Only load this script once.
4if exists('*WaitFor')
5 finish
6endif
7
Bram Moolenaar321efdd2016-07-15 17:09:11 +02008" Get the name of the Python executable.
9" Also keeps it in s:python.
10func PythonProg()
11 " This test requires the Python command to run the test server.
12 " This most likely only works on Unix and Windows.
13 if has('unix')
14 " We also need the job feature or the pkill command to make sure the server
15 " can be stopped.
16 if !(executable('python') && (has('job') || executable('pkill')))
17 return ''
18 endif
19 let s:python = 'python'
20 elseif has('win32')
21 " Use Python Launcher for Windows (py.exe) if available.
22 if executable('py.exe')
23 let s:python = 'py.exe'
24 elseif executable('python.exe')
25 let s:python = 'python.exe'
26 else
27 return ''
28 endif
29 else
30 return ''
31 endif
32 return s:python
33endfunc
34
35" Run "cmd". Returns the job if using a job.
36func RunCommand(cmd)
37 let job = 0
38 if has('job')
39 let job = job_start(a:cmd, {"stoponexit": "hup"})
40 call job_setoptions(job, {"stoponexit": "kill"})
41 elseif has('win32')
42 exe 'silent !start cmd /c start "test_channel" ' . a:cmd
43 else
44 exe 'silent !' . a:cmd . '&'
45 endif
46 return job
47endfunc
48
49" Read the port number from the Xportnr file.
50func GetPort()
51 let l = []
52 for i in range(200)
53 try
54 let l = readfile("Xportnr")
55 catch
56 endtry
57 if len(l) >= 1
58 break
59 endif
60 sleep 10m
61 endfor
62 call delete("Xportnr")
63
64 if len(l) == 0
65 " Can't make the connection, give up.
66 return 0
67 endif
68 return l[0]
69endfunc
70
71" Run a Python server for "cmd" and call "testfunc".
72" Always kills the server before returning.
73func RunServer(cmd, testfunc, args)
74 " The Python program writes the port number in Xportnr.
75 call delete("Xportnr")
76
77 if len(a:args) == 1
78 let arg = ' ' . a:args[0]
79 else
80 let arg = ''
81 endif
82 let pycmd = s:python . " " . a:cmd . arg
83
84 try
85 let g:currentJob = RunCommand(pycmd)
86
87 " Wait for up to 2 seconds for the port number to be there.
88 let port = GetPort()
89 if port == 0
90 call assert_false(1, "Can't start " . a:cmd)
91 return
92 endif
93
94 call call(function(a:testfunc), [port])
95 catch
Bram Moolenaar4b785f62016-11-29 21:54:44 +010096 call assert_false(1, 'Caught exception: "' . v:exception . '" in ' . v:throwpoint)
Bram Moolenaar321efdd2016-07-15 17:09:11 +020097 finally
98 call s:kill_server(a:cmd)
99 endtry
100endfunc
101
102func s:kill_server(cmd)
103 if has('job')
104 if exists('g:currentJob')
105 call job_stop(g:currentJob)
106 unlet g:currentJob
107 endif
108 elseif has('win32')
109 let cmd = substitute(a:cmd, ".py", '', '')
110 call system('taskkill /IM ' . s:python . ' /T /F /FI "WINDOWTITLE eq ' . cmd . '"')
111 else
112 call system("pkill -f " . a:cmd)
113 endif
114endfunc
115
116" Wait for up to a second for "expr" to become true.
Bram Moolenaarf267f8b2016-08-22 21:40:29 +0200117" Return time slept in milliseconds. With the +reltime feature this can be
118" more than the actual waiting time. Without +reltime it can also be less.
Bram Moolenaarcdb7e1b2017-07-19 19:55:58 +0200119func WaitFor(expr, ...)
120 let timeout = get(a:000, 0, 1000)
Bram Moolenaarf267f8b2016-08-22 21:40:29 +0200121 " using reltime() is more accurate, but not always available
122 if has('reltime')
123 let start = reltime()
124 else
125 let slept = 0
126 endif
Bram Moolenaarcdb7e1b2017-07-19 19:55:58 +0200127 for i in range(timeout / 10)
Bram Moolenaarc20e0d52017-11-02 18:19:19 +0100128 if eval(a:expr)
129 if has('reltime')
130 return float2nr(reltimefloat(reltime(start)) * 1000)
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200131 endif
Bram Moolenaarc20e0d52017-11-02 18:19:19 +0100132 return slept
133 endif
Bram Moolenaarf267f8b2016-08-22 21:40:29 +0200134 if !has('reltime')
135 let slept += 10
136 endif
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200137 sleep 10m
138 endfor
Bram Moolenaar3e1c6172017-11-02 16:58:00 +0100139 throw 'WaitFor() timed out after ' . timeout . ' msec'
Bram Moolenaar321efdd2016-07-15 17:09:11 +0200140endfunc
Bram Moolenaar66459b72016-08-06 19:01:55 +0200141
Bram Moolenaar01688ad2016-10-27 20:00:07 +0200142" Wait for up to a given milliseconds.
143" With the +timers feature this waits for key-input by getchar(), Resume()
144" feeds key-input and resumes process. Return time waited in milliseconds.
145" Without +timers it uses simply :sleep.
146func Standby(msec)
147 if has('timers')
148 let start = reltime()
149 let g:_standby_timer = timer_start(a:msec, function('s:feedkeys'))
150 call getchar()
151 return float2nr(reltimefloat(reltime(start)) * 1000)
152 else
153 execute 'sleep ' a:msec . 'm'
154 return a:msec
155 endif
156endfunc
157
158func Resume()
159 if exists('g:_standby_timer')
160 call timer_stop(g:_standby_timer)
161 call s:feedkeys(0)
162 unlet g:_standby_timer
163 endif
164endfunc
165
166func s:feedkeys(timer)
167 call feedkeys('x', 'nt')
168endfunc
169
Bram Moolenaar63182052017-10-07 20:03:23 +0200170" Get $VIMPROG to run Vim executable.
171" The Makefile writes it as the first line in the "vimcmd" file.
172func GetVimProg()
173 if !filereadable('vimcmd')
174 return ''
175 endif
176 return readfile('vimcmd')[0]
177endfunc
178
Bram Moolenaar15bf76d2017-03-18 16:18:37 +0100179" Get the command to run Vim, with -u NONE and --not-a-term arguments.
Bram Moolenaar9d954202017-09-04 20:34:19 +0200180" If there is an argument use it instead of "NONE".
Bram Moolenaar15bf76d2017-03-18 16:18:37 +0100181" Returns an empty string on error.
Bram Moolenaar9d954202017-09-04 20:34:19 +0200182func GetVimCommand(...)
Bram Moolenaar15bf76d2017-03-18 16:18:37 +0100183 if !filereadable('vimcmd')
184 return ''
185 endif
Bram Moolenaar9d954202017-09-04 20:34:19 +0200186 if a:0 == 0
187 let name = 'NONE'
188 else
189 let name = a:1
190 endif
Bram Moolenaar63182052017-10-07 20:03:23 +0200191 " For Unix Makefile writes the command to use in the second line of the
192 " "vimcmd" file, including environment options.
193 " Other Makefiles just write the executable in the first line, so fall back
194 " to that if there is no second line.
195 let lines = readfile('vimcmd')
196 let cmd = get(lines, 1, lines[0])
Bram Moolenaar9d954202017-09-04 20:34:19 +0200197 let cmd = substitute(cmd, '-u \f\+', '-u ' . name, '')
198 if cmd !~ '-u '. name
199 let cmd = cmd . ' -u ' . name
Bram Moolenaar15bf76d2017-03-18 16:18:37 +0100200 endif
201 let cmd .= ' --not-a-term'
202 let cmd = substitute(cmd, 'VIMRUNTIME=.*VIMRUNTIME;', '', '')
203 return cmd
204endfunc
205
Bram Moolenaar66459b72016-08-06 19:01:55 +0200206" Run Vim, using the "vimcmd" file and "-u NORC".
Bram Moolenaar3a938382016-08-07 16:36:40 +0200207" "before" is a list of Vim commands to be executed before loading plugins.
208" "after" is a list of Vim commands to be executed after loading plugins.
Bram Moolenaar66459b72016-08-06 19:01:55 +0200209" Plugins are not loaded, unless 'loadplugins' is set in "before".
210" Return 1 if Vim could be executed.
Bram Moolenaar472a0a82016-08-06 22:31:42 +0200211func RunVim(before, after, arguments)
Bram Moolenaar7a9a5f42016-08-08 22:34:14 +0200212 return RunVimPiped(a:before, a:after, a:arguments, '')
Bram Moolenaar3a938382016-08-07 16:36:40 +0200213endfunc
214
215func RunVimPiped(before, after, arguments, pipecmd)
Bram Moolenaar15bf76d2017-03-18 16:18:37 +0100216 let cmd = GetVimCommand()
217 if cmd == ''
Bram Moolenaar66459b72016-08-06 19:01:55 +0200218 return 0
219 endif
Bram Moolenaarba98bef2016-08-07 15:51:39 +0200220 let args = ''
Bram Moolenaar472a0a82016-08-06 22:31:42 +0200221 if len(a:before) > 0
222 call writefile(a:before, 'Xbefore.vim')
223 let args .= ' --cmd "so Xbefore.vim"'
224 endif
225 if len(a:after) > 0
226 call writefile(a:after, 'Xafter.vim')
227 let args .= ' -S Xafter.vim'
228 endif
Bram Moolenaar66459b72016-08-06 19:01:55 +0200229
Bram Moolenaar3a938382016-08-07 16:36:40 +0200230 exe "silent !" . a:pipecmd . cmd . args . ' ' . a:arguments
Bram Moolenaar66459b72016-08-06 19:01:55 +0200231
Bram Moolenaar472a0a82016-08-06 22:31:42 +0200232 if len(a:before) > 0
233 call delete('Xbefore.vim')
234 endif
235 if len(a:after) > 0
236 call delete('Xafter.vim')
237 endif
Bram Moolenaar66459b72016-08-06 19:01:55 +0200238 return 1
239endfunc
Bram Moolenaar9f0139a2017-08-13 20:26:20 +0200240
241func CanRunGui()
242 return has('gui') && ($DISPLAY != "" || has('gui_running'))
243endfunc