1" Tests for the terminal window.
2
3if !exists('*term_start')
4  finish
5endif
6
7source shared.vim
8
9let s:python = PythonProg()
10
11" Open a terminal with a shell, assign the job to g:job and return the buffer
12" number.
13func Run_shell_in_terminal(options)
14  let buf = term_start(&shell, a:options)
15
16  let termlist = term_list()
17  call assert_equal(1, len(termlist))
18  call assert_equal(buf, termlist[0])
19
20  let g:job = term_getjob(buf)
21  call assert_equal(v:t_job, type(g:job))
22
23  let string = string({'job': term_getjob(buf)})
24  call assert_match("{'job': 'process \\d\\+ run'}", string)
25
26  return buf
27endfunc
28
29" Stops the shell started by Run_shell_in_terminal().
30func Stop_shell_in_terminal(buf)
31  call term_sendkeys(a:buf, "exit\r")
32  call WaitFor('job_status(g:job) == "dead"')
33  call assert_equal('dead', job_status(g:job))
34endfunc
35
36func Test_terminal_basic()
37  let buf = Run_shell_in_terminal({})
38  if has("unix")
39    call assert_match("^/dev/", job_info(g:job).tty)
40    call assert_match("^/dev/", term_gettty(''))
41  else
42    call assert_match("^winpty://", job_info(g:job).tty)
43    call assert_match("^winpty://", term_gettty(''))
44  endif
45  call Stop_shell_in_terminal(buf)
46  call term_wait(buf)
47
48  " closing window wipes out the terminal buffer a with finished job
49  close
50  call assert_equal("", bufname(buf))
51
52  unlet g:job
53endfunc
54
55func Test_terminal_make_change()
56  let buf = Run_shell_in_terminal({})
57  call Stop_shell_in_terminal(buf)
58  call term_wait(buf)
59
60  setlocal modifiable
61  exe "normal Axxx\<Esc>"
62  call assert_fails(buf . 'bwipe', 'E517')
63  undo
64
65  exe buf . 'bwipe'
66  unlet g:job
67endfunc
68
69func Test_terminal_wipe_buffer()
70  let buf = Run_shell_in_terminal({})
71  call assert_fails(buf . 'bwipe', 'E517')
72  exe buf . 'bwipe!'
73  call WaitFor('job_status(g:job) == "dead"')
74  call assert_equal('dead', job_status(g:job))
75  call assert_equal("", bufname(buf))
76
77  unlet g:job
78endfunc
79
80func Test_terminal_hide_buffer()
81  let buf = Run_shell_in_terminal({})
82  quit
83  for nr in range(1, winnr('$'))
84    call assert_notequal(winbufnr(nr), buf)
85  endfor
86  call assert_true(bufloaded(buf))
87  call assert_true(buflisted(buf))
88
89  exe 'split ' . buf . 'buf'
90  call Stop_shell_in_terminal(buf)
91  exe buf . 'bwipe'
92
93  unlet g:job
94endfunc
95
96func! s:Nasty_exit_cb(job, st)
97  exe g:buf . 'bwipe!'
98  let g:buf = 0
99endfunc
100
101func Test_terminal_nasty_cb()
102  let cmd = Get_cat_123_cmd()
103  let g:buf = term_start(cmd, {'exit_cb': function('s:Nasty_exit_cb')})
104  let g:job = term_getjob(g:buf)
105
106  call WaitFor('job_status(g:job) == "dead"')
107  call WaitFor('g:buf == 0')
108  unlet g:buf
109  unlet g:job
110  call delete('Xtext')
111endfunc
112
113func Check_123(buf)
114  let l = term_scrape(a:buf, 0)
115  call assert_true(len(l) == 0)
116  let l = term_scrape(a:buf, 999)
117  call assert_true(len(l) == 0)
118  let l = term_scrape(a:buf, 1)
119  call assert_true(len(l) > 0)
120  call assert_equal('1', l[0].chars)
121  call assert_equal('2', l[1].chars)
122  call assert_equal('3', l[2].chars)
123  call assert_equal('#00e000', l[0].fg)
124  if &background == 'light'
125    call assert_equal('#ffffff', l[0].bg)
126  else
127    call assert_equal('#000000', l[0].bg)
128  endif
129
130  let l = term_getline(a:buf, -1)
131  call assert_equal('', l)
132  let l = term_getline(a:buf, 0)
133  call assert_equal('', l)
134  let l = term_getline(a:buf, 999)
135  call assert_equal('', l)
136  let l = term_getline(a:buf, 1)
137  call assert_equal('123', l)
138endfunc
139
140func Get_cat_123_cmd()
141  if has('win32')
142    return 'cmd /c "cls && color 2 && echo 123"'
143  else
144    call writefile(["\<Esc>[32m123"], 'Xtext')
145    return "cat Xtext"
146  endif
147endfunc
148
149func Test_terminal_scrape_123()
150  let cmd = Get_cat_123_cmd()
151  let buf = term_start(cmd)
152
153  let termlist = term_list()
154  call assert_equal(1, len(termlist))
155  call assert_equal(buf, termlist[0])
156
157  " Nothing happens with invalid buffer number
158  call term_wait(1234)
159
160  call term_wait(buf)
161  if has('win32')
162    " TODO: this should not be needed
163    sleep 100m
164  endif
165  call Check_123(buf)
166
167  " Must still work after the job ended.
168  let g:job = term_getjob(buf)
169  call WaitFor('job_status(g:job) == "dead"')
170  call term_wait(buf)
171  call Check_123(buf)
172
173  exe buf . 'bwipe'
174  call delete('Xtext')
175endfunc
176
177func Test_terminal_scrape_multibyte()
178  if !has('multi_byte')
179    return
180  endif
181  call writefile(["léttまrs"], 'Xtext')
182  if has('win32')
183    let cmd = 'cmd /c "type Xtext"'
184  else
185    let cmd = "cat Xtext"
186  endif
187  let buf = term_start(cmd)
188
189  call term_wait(buf)
190  if has('win32')
191    " TODO: this should not be needed
192    sleep 100m
193  endif
194
195  let l = term_scrape(buf, 1)
196  call assert_true(len(l) >= 7)
197  call assert_equal('l', l[0].chars)
198  call assert_equal('é', l[1].chars)
199  call assert_equal(1, l[1].width)
200  call assert_equal('t', l[2].chars)
201  call assert_equal('t', l[3].chars)
202  call assert_equal('ま', l[4].chars)
203  call assert_equal(2, l[4].width)
204  call assert_equal('r', l[5].chars)
205  call assert_equal('s', l[6].chars)
206
207  let g:job = term_getjob(buf)
208  call WaitFor('job_status(g:job) == "dead"')
209  call term_wait(buf)
210
211  exe buf . 'bwipe'
212  call delete('Xtext')
213endfunc
214
215func Test_terminal_scroll()
216  call writefile(range(1, 200), 'Xtext')
217  if has('win32')
218    let cmd = 'cmd /c "type Xtext"'
219  else
220    let cmd = "cat Xtext"
221  endif
222  let buf = term_start(cmd)
223
224  let g:job = term_getjob(buf)
225  call WaitFor('job_status(g:job) == "dead"')
226  call term_wait(buf)
227  if has('win32')
228    " TODO: this should not be needed
229    sleep 100m
230  endif
231
232  let scrolled = term_getscrolled(buf)
233  call assert_equal('1', getline(1))
234  call assert_equal('1', term_getline(buf, 1 - scrolled))
235  call assert_equal('49', getline(49))
236  call assert_equal('49', term_getline(buf, 49 - scrolled))
237  call assert_equal('200', getline(200))
238  call assert_equal('200', term_getline(buf, 200 - scrolled))
239
240  exe buf . 'bwipe'
241  call delete('Xtext')
242endfunc
243
244func Test_terminal_size()
245  let cmd = Get_cat_123_cmd()
246
247  exe '5terminal ' . cmd
248  let size = term_getsize('')
249  bwipe!
250  call assert_equal(5, size[0])
251
252  call term_start(cmd, {'term_rows': 6})
253  let size = term_getsize('')
254  bwipe!
255  call assert_equal(6, size[0])
256
257  vsplit
258  exe '5,33terminal ' . cmd
259  let size = term_getsize('')
260  bwipe!
261  call assert_equal([5, 33], size)
262
263  call term_start(cmd, {'term_rows': 6, 'term_cols': 36})
264  let size = term_getsize('')
265  bwipe!
266  call assert_equal([6, 36], size)
267
268  exe 'vertical 20terminal ' . cmd
269  let size = term_getsize('')
270  bwipe!
271  call assert_equal(20, size[1])
272
273  call term_start(cmd, {'vertical': 1, 'term_cols': 26})
274  let size = term_getsize('')
275  bwipe!
276  call assert_equal(26, size[1])
277
278  split
279  exe 'vertical 6,20terminal ' . cmd
280  let size = term_getsize('')
281  bwipe!
282  call assert_equal([6, 20], size)
283
284  call term_start(cmd, {'vertical': 1, 'term_rows': 7, 'term_cols': 27})
285  let size = term_getsize('')
286  bwipe!
287  call assert_equal([7, 27], size)
288endfunc
289
290func Test_terminal_curwin()
291  let cmd = Get_cat_123_cmd()
292  call assert_equal(1, winnr('$'))
293
294  split dummy
295  exe 'terminal ++curwin ' . cmd
296  call assert_equal(2, winnr('$'))
297  bwipe!
298
299  split dummy
300  call term_start(cmd, {'curwin': 1})
301  call assert_equal(2, winnr('$'))
302  bwipe!
303
304  split dummy
305  call setline(1, 'change')
306  call assert_fails('terminal ++curwin ' . cmd, 'E37:')
307  call assert_equal(2, winnr('$'))
308  exe 'terminal! ++curwin ' . cmd
309  call assert_equal(2, winnr('$'))
310  bwipe!
311
312  split dummy
313  call setline(1, 'change')
314  call assert_fails("call term_start(cmd, {'curwin': 1})", 'E37:')
315  call assert_equal(2, winnr('$'))
316  bwipe!
317
318  split dummy
319  bwipe!
320
321endfunc
322
323func Test_finish_open_close()
324  call assert_equal(1, winnr('$'))
325
326  if s:python != ''
327    let cmd = s:python . " test_short_sleep.py"
328    let waittime = 500
329  else
330    echo 'This will take five seconds...'
331    let waittime = 2000
332    if has('win32')
333      let cmd = $windir . '\system32\timeout.exe 1'
334    else
335      let cmd = 'sleep 1'
336    endif
337  endif
338
339  exe 'terminal ++close ' . cmd
340  call assert_equal(2, winnr('$'))
341  wincmd p
342  call WaitFor("winnr('$') == 1", waittime)
343  call assert_equal(1, winnr('$'))
344
345  call term_start(cmd, {'term_finish': 'close'})
346  call assert_equal(2, winnr('$'))
347  wincmd p
348  call WaitFor("winnr('$') == 1", waittime)
349  call assert_equal(1, winnr('$'))
350
351  exe 'terminal ++open ' . cmd
352  close
353  call WaitFor("winnr('$') == 2", waittime)
354  call assert_equal(2, winnr('$'))
355  bwipe
356
357  call term_start(cmd, {'term_finish': 'open'})
358  close
359  call WaitFor("winnr('$') == 2", waittime)
360  call assert_equal(2, winnr('$'))
361  bwipe
362
363  exe 'terminal ++hidden ++open ' . cmd
364  call assert_equal(1, winnr('$'))
365  call WaitFor("winnr('$') == 2", waittime)
366  call assert_equal(2, winnr('$'))
367  bwipe
368
369  call term_start(cmd, {'term_finish': 'open', 'hidden': 1})
370  call assert_equal(1, winnr('$'))
371  call WaitFor("winnr('$') == 2", waittime)
372  call assert_equal(2, winnr('$'))
373  bwipe
374
375  call assert_fails("call term_start(cmd, {'term_opencmd': 'open'})", 'E475:')
376  call assert_fails("call term_start(cmd, {'term_opencmd': 'split %x'})", 'E475:')
377  call assert_fails("call term_start(cmd, {'term_opencmd': 'split %d and %s'})", 'E475:')
378  call assert_fails("call term_start(cmd, {'term_opencmd': 'split % and %d'})", 'E475:')
379
380  call term_start(cmd, {'term_finish': 'open', 'term_opencmd': '4split | buffer %d'})
381  close
382  call WaitFor("winnr('$') == 2", waittime)
383  call assert_equal(2, winnr('$'))
384  call assert_equal(4, winheight(0))
385  bwipe
386
387endfunc
388
389func Test_terminal_cwd()
390  if !has('unix')
391    return
392  endif
393  call mkdir('Xdir')
394  let buf = term_start('pwd', {'cwd': 'Xdir'})
395  sleep 100m
396  call term_wait(buf)
397  call assert_equal(getcwd() . '/Xdir', getline(1))
398
399  exe buf . 'bwipe'
400  call delete('Xdir', 'rf')
401endfunc
402
403func Test_terminal_env()
404  if !has('unix')
405    return
406  endif
407  let buf = Run_shell_in_terminal({'env': {'TESTENV': 'correct'}})
408  call term_wait(buf)
409  call term_sendkeys(buf, "echo $TESTENV\r")
410  call term_wait(buf)
411  call Stop_shell_in_terminal(buf)
412  call term_wait(buf)
413  call assert_equal('correct', getline(2))
414
415  exe buf . 'bwipe'
416endfunc
417