blob: a2a54f4ec3737e3478ed23223737a946bb9a0544 [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 Moolenaar7a39dd72019-06-23 00:50:15 +02008source shared.vim
9source term_util.vim
Bram Moolenaarf2732452018-06-03 14:47:35 +020010
11" Skip the rest if there is no terminal feature at all.
12if !has('terminal')
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +010013 finish
14endif
15
Bram Moolenaar11901392022-09-26 19:50:44 +010016" Read a dump file "fname" and if "filter" exists apply it to the text.
17def ReadAndFilter(fname: string, filter: string): list<string>
18 var contents = readfile(fname)
19
20 if filereadable(filter)
21 # do this in the bottom window so that the terminal window is unaffected
22 wincmd j
23 enew
24 setline(1, contents)
25 exe "source " .. filter
26 contents = getline(1, '$')
27 enew!
28 wincmd k
29 redraw
30 endif
31
32 return contents
33enddef
34
35
Bram Moolenaarda650582018-02-20 15:51:40 +010036" Verify that Vim running in terminal buffer "buf" matches the screen dump.
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +010037" "options" is passed to term_dumpwrite().
Bram Moolenaar3e794272022-05-06 11:21:19 +010038" Additionally, the "wait" entry can specify the maximum time to wait for the
39" screen dump to match in msec (default 1000 msec).
Bram Moolenaarda650582018-02-20 15:51:40 +010040" The file name used is "dumps/{filename}.dump".
Bram Moolenaar11901392022-09-26 19:50:44 +010041"
42" To ignore part of the dump, provide a "dumps/{filename}.vim" file with
43" Vim commands to be applied to both the reference and the current dump, so
44" that parts that are irrelevant are not used for the comparison. The result
45" is NOT written, thus "term_dumpdiff()" shows the difference anyway.
46"
Bram Moolenaar6f8bdab2018-09-09 22:02:24 +020047" Optionally an extra argument can be passed which is prepended to the error
48" message. Use this when using the same dump file with different options.
Bram Moolenaar6f8bdab2018-09-09 22:02:24 +020049" Returns non-zero when verification fails.
50func VerifyScreenDump(buf, filename, options, ...)
Bram Moolenaarda650582018-02-20 15:51:40 +010051 let reference = 'dumps/' . a:filename . '.dump'
Bram Moolenaar11901392022-09-26 19:50:44 +010052 let filter = 'dumps/' . a:filename . '.vim'
Bram Moolenaaref7f0e32019-03-30 15:59:51 +010053 let testfile = 'failed/' . a:filename . '.dump'
54
Bram Moolenaar3e794272022-05-06 11:21:19 +010055 let max_loops = get(a:options, 'wait', 1000) / 10
56
Bram Moolenaar3cdcb092020-03-18 19:18:10 +010057 " Starting a terminal to make a screendump is always considered flaky.
Bram Moolenaar30d53e22020-03-18 21:10:44 +010058 let g:test_is_flaky = 1
Bram Moolenaar3cdcb092020-03-18 19:18:10 +010059
Yegappan Lakshmanan560dff42022-02-10 19:52:10 +000060 " wait for the pending updates to be handled.
61 call TermWait(a:buf)
62
Bram Moolenaar1bc353b2019-09-01 14:45:28 +020063 " Redraw to execute the code that updates the screen. Otherwise we get the
Bram Moolenaar87dcfd72019-04-13 22:35:29 +020064 " text and attributes only from the internal buffer.
65 redraw
66
Bram Moolenaar11901392022-09-26 19:50:44 +010067 if filereadable(reference)
68 let refdump = ReadAndFilter(reference, filter)
69 else
70 " Must be a new screendump, always fail
71 let refdump = []
72 endif
73
Bram Moolenaaref7f0e32019-03-30 15:59:51 +010074 let did_mkdir = 0
75 if !isdirectory('failed')
76 let did_mkdir = 1
77 call mkdir('failed')
78 endif
Bram Moolenaarda650582018-02-20 15:51:40 +010079
80 let i = 0
81 while 1
Bram Moolenaarb6fc7282018-12-04 22:24:16 +010082 " leave some time for updating the original window
83 sleep 10m
Bram Moolenaarda650582018-02-20 15:51:40 +010084 call delete(testfile)
Bram Moolenaar6bb2cdf2018-02-24 19:53:53 +010085 call term_dumpwrite(a:buf, testfile, a:options)
Bram Moolenaar11901392022-09-26 19:50:44 +010086 let testdump = ReadAndFilter(testfile, filter)
Bram Moolenaar353aca12019-02-21 17:05:59 +010087 if refdump == testdump
Bram Moolenaarda650582018-02-20 15:51:40 +010088 call delete(testfile)
Bram Moolenaaref7f0e32019-03-30 15:59:51 +010089 if did_mkdir
90 call delete('failed', 'd')
91 endif
Bram Moolenaarda650582018-02-20 15:51:40 +010092 break
93 endif
Bram Moolenaar3e794272022-05-06 11:21:19 +010094 if i == max_loops
Bram Moolenaar2d7260d2019-04-06 20:51:52 +020095 " Leave the failed dump around for inspection.
96 if filereadable(reference)
Bram Moolenaar8a5c7ef2019-06-16 16:14:20 +020097 let msg = 'See dump file difference: call term_dumpdiff("testdir/' .. testfile .. '", "testdir/' .. reference .. '")'
Bram Moolenaar2d7260d2019-04-06 20:51:52 +020098 if a:0 == 1
99 let msg = a:1 . ': ' . msg
100 endif
101 if len(testdump) != len(refdump)
102 let msg = msg . '; line count is ' . len(testdump) . ' instead of ' . len(refdump)
103 endif
104 else
Bram Moolenaar8a5c7ef2019-06-16 16:14:20 +0200105 let msg = 'See new dump file: call term_dumpload("testdir/' .. testfile .. '")'
Bram Moolenaar96ba25a2022-07-04 17:34:33 +0100106 " no point in retrying
107 let g:run_nr = 10
Bram Moolenaar353aca12019-02-21 17:05:59 +0100108 endif
109 for i in range(len(refdump))
110 if i >= len(testdump)
111 break
112 endif
113 if testdump[i] != refdump[i]
114 let msg = msg . '; difference in line ' . (i + 1) . ': "' . testdump[i] . '"'
115 endif
116 endfor
Bram Moolenaar6f8bdab2018-09-09 22:02:24 +0200117 call assert_report(msg)
118 return 1
Bram Moolenaarda650582018-02-20 15:51:40 +0100119 endif
Bram Moolenaarda650582018-02-20 15:51:40 +0100120 let i += 1
121 endwhile
Bram Moolenaar6f8bdab2018-09-09 22:02:24 +0200122 return 0
Bram Moolenaarda650582018-02-20 15:51:40 +0100123endfunc