blob: 50e3384c3c37c146243307e60c9821bcf0ec7cbb [file] [log] [blame]
Bram Moolenaarda650582018-02-20 15:51:40 +01001" Functions shared by tests making screen dumps.
2
3" Only load this script once.
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +01004if exists('*CanRunVimInTerminal')
Bram Moolenaarda650582018-02-20 15:51:40 +01005 finish
6endif
7
Bram Moolenaarf2732452018-06-03 14:47:35 +02008" For most tests we need to be able to run terminal Vim with 256 colors. On
9" MS-Windows the console only has 16 colors and the GUI can't run in a
10" terminal.
11func CanRunVimInTerminal()
12 return has('terminal') && !has('win32')
13endfunc
14
15" Skip the rest if there is no terminal feature at all.
16if !has('terminal')
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +010017 finish
18endif
19
Bram Moolenaarda650582018-02-20 15:51:40 +010020source shared.vim
21
22" Run Vim with "arguments" in a new terminal window.
23" By default uses a size of 20 lines and 75 columns.
24" Returns the buffer number of the terminal.
25"
Bram Moolenaarcf67a502018-03-25 20:31:32 +020026" Options is a dictionary, these items are recognized:
27" "rows" - height of the terminal window (max. 20)
28" "cols" - width of the terminal window (max. 78)
Bram Moolenaar0fef0ae2019-05-01 20:30:40 +020029" "statusoff" - number of lines the status is offset from default
Bram Moolenaarda650582018-02-20 15:51:40 +010030func RunVimInTerminal(arguments, options)
Bram Moolenaar948a7962018-03-23 20:37:45 +010031 " If Vim doesn't exit a swap file remains, causing other tests to fail.
32 " Remove it here.
33 call delete(".swp")
34
Bram Moolenaare7499dd2018-03-24 17:56:13 +010035 if exists('$COLORFGBG')
36 " Clear $COLORFGBG to avoid 'background' being set to "dark", which will
37 " only be corrected if the response to t_RB is received, which may be too
38 " late.
39 let $COLORFGBG = ''
40 endif
41
Bram Moolenaarda650582018-02-20 15:51:40 +010042 " Make a horizontal and vertical split, so that we can get exactly the right
Bram Moolenaar8fbaeb12018-03-25 18:20:17 +020043 " size terminal window. Works only when the current window is full width.
44 call assert_equal(&columns, winwidth(0))
Bram Moolenaarda650582018-02-20 15:51:40 +010045 split
46 vsplit
47
Bram Moolenaar6acadda2018-02-24 16:51:32 +010048 " Always do this with 256 colors and a light background.
49 set t_Co=256 background=light
50 hi Normal ctermfg=NONE ctermbg=NONE
Bram Moolenaarda650582018-02-20 15:51:40 +010051
Bram Moolenaarcf67a502018-03-25 20:31:32 +020052 " Make the window 20 lines high and 75 columns, unless told otherwise.
53 let rows = get(a:options, 'rows', 20)
54 let cols = get(a:options, 'cols', 75)
Bram Moolenaar0fef0ae2019-05-01 20:30:40 +020055 let statusoff = get(a:options, 'statusoff', 1)
Bram Moolenaar15a1c3f2018-03-25 18:56:25 +020056
Bram Moolenaarda650582018-02-20 15:51:40 +010057 let cmd = GetVimCommandClean()
Bram Moolenaarf2732452018-06-03 14:47:35 +020058
Bram Moolenaarb7ea7cb2018-02-24 14:38:51 +010059 " Add -v to have gvim run in the terminal (if possible)
60 let cmd .= ' -v ' . a:arguments
Bram Moolenaarf587ef32019-04-13 13:13:54 +020061 let buf = term_start(cmd, {
62 \ 'curwin': 1,
63 \ 'term_rows': rows,
64 \ 'term_cols': cols,
Bram Moolenaarf587ef32019-04-13 13:13:54 +020065 \ })
Bram Moolenaarb833c1e2018-05-05 16:36:06 +020066 if &termwinsize == ''
Bram Moolenaare40b9d42019-01-27 16:55:47 +010067 " in the GUI we may end up with a different size, try to set it.
68 if term_getsize(buf) != [rows, cols]
69 call term_setsize(buf, rows, cols)
70 endif
Bram Moolenaara7eef3d2018-04-15 22:25:54 +020071 call assert_equal([rows, cols], term_getsize(buf))
72 else
73 let rows = term_getsize(buf)[0]
74 let cols = term_getsize(buf)[1]
75 endif
Bram Moolenaarda650582018-02-20 15:51:40 +010076
Bram Moolenaarf2732452018-06-03 14:47:35 +020077 " Wait for "All" or "Top" of the ruler to be shown in the last line or in
78 " the status line of the last window. This can be quite slow (e.g. when
79 " using valgrind).
Bram Moolenaar50182fa2018-04-28 21:34:40 +020080 " If it fails then show the terminal contents for debugging.
81 try
Bram Moolenaar0fef0ae2019-05-01 20:30:40 +020082 call WaitFor({-> len(term_getline(buf, rows)) >= cols - 1 || len(term_getline(buf, rows - statusoff)) >= cols - 1})
Bram Moolenaar50182fa2018-04-28 21:34:40 +020083 catch /timed out after/
84 let lines = map(range(1, rows), {key, val -> term_getline(buf, val)})
85 call assert_report('RunVimInTerminal() failed, screen contents: ' . join(lines, "<NL>"))
86 endtry
Bram Moolenaar1834d372018-03-29 17:40:46 +020087
Bram Moolenaarda650582018-02-20 15:51:40 +010088 return buf
89endfunc
90
91" Stop a Vim running in terminal buffer "buf".
92func StopVimInTerminal(buf)
93 call assert_equal("running", term_getstatus(a:buf))
Bram Moolenaar3339d3d2018-06-03 17:10:40 +020094
95 " CTRL-O : works both in Normal mode and Insert mode to start a command line.
96 " In Command-line it's inserted, the CTRL-U removes it again.
Bram Moolenaaracb9eff2018-06-04 19:11:11 +020097 call term_sendkeys(a:buf, "\<C-O>:\<C-U>qa!\<cr>")
Bram Moolenaar3339d3d2018-06-03 17:10:40 +020098
Bram Moolenaar50182fa2018-04-28 21:34:40 +020099 call WaitForAssert({-> assert_equal("finished", term_getstatus(a:buf))})
Bram Moolenaarda650582018-02-20 15:51:40 +0100100 only!
101endfunc
102
103" Verify that Vim running in terminal buffer "buf" matches the screen dump.
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +0100104" "options" is passed to term_dumpwrite().
Bram Moolenaarda650582018-02-20 15:51:40 +0100105" The file name used is "dumps/{filename}.dump".
Bram Moolenaar6f8bdab2018-09-09 22:02:24 +0200106" Optionally an extra argument can be passed which is prepended to the error
107" message. Use this when using the same dump file with different options.
Bram Moolenaarda650582018-02-20 15:51:40 +0100108" Will wait for up to a second for the screen dump to match.
Bram Moolenaar6f8bdab2018-09-09 22:02:24 +0200109" Returns non-zero when verification fails.
110func VerifyScreenDump(buf, filename, options, ...)
Bram Moolenaarda650582018-02-20 15:51:40 +0100111 let reference = 'dumps/' . a:filename . '.dump'
Bram Moolenaaref7f0e32019-03-30 15:59:51 +0100112 let testfile = 'failed/' . a:filename . '.dump'
113
Bram Moolenaar87dcfd72019-04-13 22:35:29 +0200114 " Redraw to execut the code that updates the screen. Otherwise we get the
115 " text and attributes only from the internal buffer.
116 redraw
117
Bram Moolenaaref7f0e32019-03-30 15:59:51 +0100118 let did_mkdir = 0
119 if !isdirectory('failed')
120 let did_mkdir = 1
121 call mkdir('failed')
122 endif
Bram Moolenaarda650582018-02-20 15:51:40 +0100123
124 let i = 0
125 while 1
Bram Moolenaarb6fc7282018-12-04 22:24:16 +0100126 " leave some time for updating the original window
127 sleep 10m
Bram Moolenaarda650582018-02-20 15:51:40 +0100128 call delete(testfile)
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +0100129 call term_dumpwrite(a:buf, testfile, a:options)
Bram Moolenaar353aca12019-02-21 17:05:59 +0100130 let testdump = readfile(testfile)
Bram Moolenaar2d7260d2019-04-06 20:51:52 +0200131 if filereadable(reference)
132 let refdump = readfile(reference)
133 else
134 " Must be a new screendump, always fail
135 let refdump = []
136 endif
Bram Moolenaar353aca12019-02-21 17:05:59 +0100137 if refdump == testdump
Bram Moolenaarda650582018-02-20 15:51:40 +0100138 call delete(testfile)
Bram Moolenaaref7f0e32019-03-30 15:59:51 +0100139 if did_mkdir
140 call delete('failed', 'd')
141 endif
Bram Moolenaarda650582018-02-20 15:51:40 +0100142 break
143 endif
144 if i == 100
Bram Moolenaar2d7260d2019-04-06 20:51:52 +0200145 " Leave the failed dump around for inspection.
146 if filereadable(reference)
147 let msg = 'See dump file difference: call term_dumpdiff("' . testfile . '", "' . reference . '")'
148 if a:0 == 1
149 let msg = a:1 . ': ' . msg
150 endif
151 if len(testdump) != len(refdump)
152 let msg = msg . '; line count is ' . len(testdump) . ' instead of ' . len(refdump)
153 endif
154 else
155 let msg = 'See new dump file: call term_dumpload("' . testfile . '")'
Bram Moolenaar353aca12019-02-21 17:05:59 +0100156 endif
157 for i in range(len(refdump))
158 if i >= len(testdump)
159 break
160 endif
161 if testdump[i] != refdump[i]
162 let msg = msg . '; difference in line ' . (i + 1) . ': "' . testdump[i] . '"'
163 endif
164 endfor
Bram Moolenaar6f8bdab2018-09-09 22:02:24 +0200165 call assert_report(msg)
166 return 1
Bram Moolenaarda650582018-02-20 15:51:40 +0100167 endif
Bram Moolenaarda650582018-02-20 15:51:40 +0100168 let i += 1
169 endwhile
Bram Moolenaar6f8bdab2018-09-09 22:02:24 +0200170 return 0
Bram Moolenaarda650582018-02-20 15:51:40 +0100171endfunc