1" Tests for the terminal window.
2
3if !exists('*term_start')
4  finish
5endif
6
7source shared.vim
8
9" Open a terminal with a shell, assign the job to g:job and return the buffer
10" number.
11func Run_shell_in_terminal()
12  let buf = term_start(&shell)
13
14  let termlist = term_list()
15  call assert_equal(1, len(termlist))
16  call assert_equal(buf, termlist[0])
17
18  let g:job = term_getjob(buf)
19  call assert_equal(v:t_job, type(g:job))
20
21  let string = string({'job': term_getjob(buf)})
22  call assert_match("{'job': 'process \\d\\+ run'}", string)
23
24  return buf
25endfunc
26
27" Stops the shell started by Run_shell_in_terminal().
28func Stop_shell_in_terminal(buf)
29  call term_sendkeys(a:buf, "exit\r")
30  call WaitFor('job_status(g:job) == "dead"')
31  call assert_equal('dead', job_status(g:job))
32endfunc
33
34func Test_terminal_basic()
35  let buf = Run_shell_in_terminal()
36  if has("unix")
37    call assert_match("^/dev/", job_info(g:job).tty)
38    call assert_match("^/dev/", term_gettty(''))
39  else
40    call assert_match("^winpty://", job_info(g:job).tty)
41    call assert_match("^winpty://", term_gettty(''))
42  endif
43  call Stop_shell_in_terminal(buf)
44  call term_wait(buf)
45
46  " closing window wipes out the terminal buffer a with finished job
47  close
48  call assert_equal("", bufname(buf))
49
50  unlet g:job
51endfunc
52
53func Test_terminal_make_change()
54  let buf = Run_shell_in_terminal()
55  call Stop_shell_in_terminal(buf)
56  call term_wait(buf)
57
58  setlocal modifiable
59  exe "normal Axxx\<Esc>"
60  call assert_fails(buf . 'bwipe', 'E517')
61  undo
62
63  exe buf . 'bwipe'
64  unlet g:job
65endfunc
66
67func Test_terminal_wipe_buffer()
68  let buf = Run_shell_in_terminal()
69  call assert_fails(buf . 'bwipe', 'E517')
70  exe buf . 'bwipe!'
71  call WaitFor('job_status(g:job) == "dead"')
72  call assert_equal('dead', job_status(g:job))
73  call assert_equal("", bufname(buf))
74
75  unlet g:job
76endfunc
77
78func Test_terminal_hide_buffer()
79  let buf = Run_shell_in_terminal()
80  quit
81  for nr in range(1, winnr('$'))
82    call assert_notequal(winbufnr(nr), buf)
83  endfor
84  call assert_true(bufloaded(buf))
85  call assert_true(buflisted(buf))
86
87  exe 'split ' . buf . 'buf'
88  call Stop_shell_in_terminal(buf)
89  exe buf . 'bwipe'
90
91  unlet g:job
92endfunc
93
94func! s:Nasty_exit_cb(job, st)
95  exe g:buf . 'bwipe!'
96  let g:buf = 0
97endfunc
98
99func Test_terminal_nasty_cb()
100  let cmd = Get_cat_cmd()
101  let g:buf = term_start(cmd, {'exit_cb': function('s:Nasty_exit_cb')})
102  let g:job = term_getjob(g:buf)
103
104  call WaitFor('job_status(g:job) == "dead"')
105  call WaitFor('g:buf == 0')
106  unlet g:buf
107  unlet g:job
108  call delete('Xtext')
109endfunc
110
111func Check_123(buf)
112  let l = term_scrape(a:buf, 0)
113  call assert_true(len(l) == 0)
114  let l = term_scrape(a:buf, 999)
115  call assert_true(len(l) == 0)
116  let l = term_scrape(a:buf, 1)
117  call assert_true(len(l) > 0)
118  call assert_equal('1', l[0].chars)
119  call assert_equal('2', l[1].chars)
120  call assert_equal('3', l[2].chars)
121  call assert_equal('#00e000', l[0].fg)
122  if &background == 'light'
123    call assert_equal('#ffffff', l[0].bg)
124  else
125    call assert_equal('#000000', l[0].bg)
126  endif
127
128  let l = term_getline(a:buf, -1)
129  call assert_equal('', l)
130  let l = term_getline(a:buf, 0)
131  call assert_equal('', l)
132  let l = term_getline(a:buf, 999)
133  call assert_equal('', l)
134  let l = term_getline(a:buf, 1)
135  call assert_equal('123', l)
136endfunc
137
138func Get_cat_cmd()
139  if has('win32')
140    return 'cmd /c "cls && color 2 && echo 123"'
141  else
142    call writefile(["\<Esc>[32m123"], 'Xtext')
143    return "cat Xtext"
144  endif
145endfunc
146
147func Test_terminal_scrape()
148  let cmd = Get_cat_cmd()
149  let buf = term_start(cmd)
150
151  let termlist = term_list()
152  call assert_equal(1, len(termlist))
153  call assert_equal(buf, termlist[0])
154
155  " Nothing happens with invalid buffer number
156  call term_wait(1234)
157
158  call term_wait(buf)
159  if has('win32')
160    " TODO: this should not be needed
161    sleep 100m
162  endif
163  call Check_123(buf)
164
165  " Must still work after the job ended.
166  let g:job = term_getjob(buf)
167  call WaitFor('job_status(g:job) == "dead"')
168  call term_wait(buf)
169  call Check_123(buf)
170
171  exe buf . 'bwipe'
172  call delete('Xtext')
173endfunc
174
175func Test_terminal_size()
176  let cmd = Get_cat_cmd()
177
178  exe '5terminal ' . cmd
179  let size = term_getsize('')
180  bwipe!
181  call assert_equal(5, size[0])
182
183  vsplit
184  exe '5,33terminal ' . cmd
185  let size = term_getsize('')
186  bwipe!
187  call assert_equal([5, 33], size)
188
189  exe 'vertical 20terminal ' . cmd
190  let size = term_getsize('')
191  bwipe!
192  call assert_equal(20, size[1])
193
194  split
195  exe 'vertical 6,20terminal ' . cmd
196  let size = term_getsize('')
197  bwipe!
198  call assert_equal([6, 20], size)
199endfunc
200