blob: be6af861aaba796326bd9a4eaf3e45ada476a5fb [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 Moolenaar7a39dd72019-06-23 00:50:15 +02004if exists('*VerifyScreenDump')
Bram Moolenaarda650582018-02-20 15:51:40 +01005 finish
6endif
7
Bram Moolenaarf2732452018-06-03 14:47:35 +02008" Skip the rest if there is no terminal feature at all.
9if !has('terminal')
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +010010 finish
11endif
12
Bram Moolenaar11901392022-09-26 19:50:44 +010013" Read a dump file "fname" and if "filter" exists apply it to the text.
14def ReadAndFilter(fname: string, filter: string): list<string>
15 var contents = readfile(fname)
16
17 if filereadable(filter)
18 # do this in the bottom window so that the terminal window is unaffected
19 wincmd j
20 enew
21 setline(1, contents)
22 exe "source " .. filter
23 contents = getline(1, '$')
24 enew!
25 wincmd k
26 redraw
27 endif
28
29 return contents
30enddef
31
32
Bram Moolenaarda650582018-02-20 15:51:40 +010033" Verify that Vim running in terminal buffer "buf" matches the screen dump.
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +010034" "options" is passed to term_dumpwrite().
Bram Moolenaar3e794272022-05-06 11:21:19 +010035" Additionally, the "wait" entry can specify the maximum time to wait for the
36" screen dump to match in msec (default 1000 msec).
Bram Moolenaarda650582018-02-20 15:51:40 +010037" The file name used is "dumps/{filename}.dump".
Bram Moolenaar11901392022-09-26 19:50:44 +010038"
39" To ignore part of the dump, provide a "dumps/{filename}.vim" file with
40" Vim commands to be applied to both the reference and the current dump, so
41" that parts that are irrelevant are not used for the comparison. The result
42" is NOT written, thus "term_dumpdiff()" shows the difference anyway.
43"
Bram Moolenaar6f8bdab2018-09-09 22:02:24 +020044" Optionally an extra argument can be passed which is prepended to the error
45" message. Use this when using the same dump file with different options.
Bram Moolenaar6f8bdab2018-09-09 22:02:24 +020046" Returns non-zero when verification fails.
47func VerifyScreenDump(buf, filename, options, ...)
Drew Vogelea67ba72025-05-07 22:05:17 +020048 if has('gui_running') && exists("g:check_screendump_called") && g:check_screendump_called == v:false
49 echoerr "VerifyScreenDump() called from a test that lacks a CheckScreendump guard."
50 return 1
51 endif
Bram Moolenaarda650582018-02-20 15:51:40 +010052 let reference = 'dumps/' . a:filename . '.dump'
Bram Moolenaar11901392022-09-26 19:50:44 +010053 let filter = 'dumps/' . a:filename . '.vim'
Bram Moolenaaref7f0e32019-03-30 15:59:51 +010054 let testfile = 'failed/' . a:filename . '.dump'
55
Yee Cheng Chine70587d2025-02-13 20:55:45 +010056 let max_loops = get(a:options, 'wait', 1000) / 1
Bram Moolenaar3e794272022-05-06 11:21:19 +010057
Bram Moolenaar3cdcb092020-03-18 19:18:10 +010058 " Starting a terminal to make a screendump is always considered flaky.
Bram Moolenaar30d53e22020-03-18 21:10:44 +010059 let g:test_is_flaky = 1
Millybaab7c02024-10-28 21:56:14 +010060 let g:giveup_same_error = 0
Bram Moolenaar3cdcb092020-03-18 19:18:10 +010061
Yegappan Lakshmanan560dff42022-02-10 19:52:10 +000062 " wait for the pending updates to be handled.
Yee Cheng Chine70587d2025-02-13 20:55:45 +010063 call TermWait(a:buf, 0)
Yegappan Lakshmanan560dff42022-02-10 19:52:10 +000064
Bram Moolenaar1bc353b2019-09-01 14:45:28 +020065 " Redraw to execute the code that updates the screen. Otherwise we get the
Bram Moolenaar87dcfd72019-04-13 22:35:29 +020066 " text and attributes only from the internal buffer.
67 redraw
68
Bram Moolenaar11901392022-09-26 19:50:44 +010069 if filereadable(reference)
70 let refdump = ReadAndFilter(reference, filter)
71 else
72 " Must be a new screendump, always fail
73 let refdump = []
74 endif
75
Bram Moolenaaref7f0e32019-03-30 15:59:51 +010076 let did_mkdir = 0
77 if !isdirectory('failed')
78 let did_mkdir = 1
79 call mkdir('failed')
80 endif
Bram Moolenaarda650582018-02-20 15:51:40 +010081
82 let i = 0
83 while 1
Yee Cheng Chine70587d2025-02-13 20:55:45 +010084 " leave a bit of time for updating the original window while we spin wait.
85 sleep 1m
Bram Moolenaarda650582018-02-20 15:51:40 +010086 call delete(testfile)
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +010087 call term_dumpwrite(a:buf, testfile, a:options)
Millybaab7c02024-10-28 21:56:14 +010088
89 if refdump->empty()
90 let msg = 'See new dump file: call term_dumpload("testdir/' .. testfile .. '")'
91 call assert_report(msg)
92 " no point in retrying
93 let g:run_nr = 10
94 return 1
95 endif
96
Bram Moolenaar11901392022-09-26 19:50:44 +010097 let testdump = ReadAndFilter(testfile, filter)
Bram Moolenaar353aca12019-02-21 17:05:59 +010098 if refdump == testdump
Bram Moolenaarda650582018-02-20 15:51:40 +010099 call delete(testfile)
Bram Moolenaaref7f0e32019-03-30 15:59:51 +0100100 if did_mkdir
101 call delete('failed', 'd')
102 endif
Millybaab7c02024-10-28 21:56:14 +0100103 if i > 0
104 call remove(v:errors, -1)
105 endif
Bram Moolenaarda650582018-02-20 15:51:40 +0100106 break
107 endif
Millybaab7c02024-10-28 21:56:14 +0100108
109 " Leave the failed dump around for inspection.
110 let msg = 'See dump file difference: call term_dumpdiff("testdir/' .. testfile .. '", "testdir/' .. reference .. '")'
111 if a:0 == 1
112 let msg = a:1 . ': ' . msg
113 endif
114 if len(testdump) != len(refdump)
115 let msg = msg . '; line count is ' . len(testdump) . ' instead of ' . len(refdump)
116 endif
117 for j in range(len(refdump))
118 if j >= len(testdump)
119 break
Bram Moolenaar353aca12019-02-21 17:05:59 +0100120 endif
Millybaab7c02024-10-28 21:56:14 +0100121 if testdump[j] != refdump[j]
122 let msg = msg . '; difference in line ' . (j + 1) . ': "' . testdump[j] . '"'
123 endif
124 endfor
125
126 " Always add the last error so that it is displayed on timeout.
127 " See TestTimeout() in runtest.vim.
128 if i > 0
129 call remove(v:errors, -1)
130 endif
131 call assert_report(msg)
132
133 let i += 1
134 if i >= max_loops
Bram Moolenaar6f8bdab2018-09-09 22:02:24 +0200135 return 1
Bram Moolenaarda650582018-02-20 15:51:40 +0100136 endif
Bram Moolenaarda650582018-02-20 15:51:40 +0100137 endwhile
Bram Moolenaar6f8bdab2018-09-09 22:02:24 +0200138 return 0
Bram Moolenaarda650582018-02-20 15:51:40 +0100139endfunc