blob: 767510cb1d35f6befce6bba82bb411e826be5165 [file] [log] [blame]
Bram Moolenaar46acad72023-06-11 19:04:18 +01001" Runs all the syntax tests for which there is no "done/name" file.
2"
3" Current directory must be runtime/syntax.
4
Christian Brabandtde79f912024-10-24 23:03:10 +02005" needed because of line-continuation lines
6set cpo&vim
7
Bram Moolenaar46acad72023-06-11 19:04:18 +01008" Only do this with the +eval feature
9if 1
10
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +010011" Remember the directory where we started. Will change to "testdir" below.
12let syntaxDir = getcwd()
13
14let s:messagesFname = fnameescape(syntaxDir .. '/testdir/messages')
15
16let s:messages = []
17
Aliaksei Budaveif63c3462025-03-08 16:58:17 +010018" Erase the cursor line and do not advance the cursor. (Call the function
19" after each passing test report.)
20def EraseLineAndReturnCarriage(line: string)
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +010021 const full_width: number = winwidth(0)
22 const half_width: number = full_width - (full_width + 1) / 2
Aliaksei Budaveif63c3462025-03-08 16:58:17 +010023 if strlen(line) > half_width
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +010024 echon "\r" .. repeat("\x20", full_width) .. "\r"
25 else
26 echon repeat("\x20", half_width) .. "\r"
27 endif
28enddef
29
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +010030" Add one message to the list of messages
31func Message(msg)
32 echomsg a:msg
33 call add(s:messages, a:msg)
34endfunc
35
36" Report a fatal message and exit
37func Fatal(msg)
38 echoerr a:msg
39 call AppendMessages(a:msg)
40 qall!
41endfunc
42
43" Append s:messages to the messages file and make it empty.
44func AppendMessages(header)
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +010045 silent exe 'split ' .. s:messagesFname
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +010046 call append(line('$'), '')
47 call append(line('$'), a:header)
48 call append(line('$'), s:messages)
49 let s:messages = []
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +010050 silent wq
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +010051endfunc
52
53" Relevant messages are written to the "messages" file.
54" If the file already exists it is appended to.
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +010055silent exe 'split ' .. s:messagesFname
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +010056call append(line('$'), repeat('=-', 70))
57call append(line('$'), '')
Bram Moolenaar031d6322023-06-22 22:38:54 +010058let s:test_run_message = 'Test run on ' .. strftime("%Y %b %d %H:%M:%S")
59call append(line('$'), s:test_run_message)
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +010060silent wq
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +010061
62if syntaxDir !~ '[/\\]runtime[/\\]syntax\>'
63 call Fatal('Current directory must be "runtime/syntax"')
Bram Moolenaar46acad72023-06-11 19:04:18 +010064endif
65if !isdirectory('testdir')
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +010066 call Fatal('"testdir" directory not found')
Bram Moolenaar46acad72023-06-11 19:04:18 +010067endif
68
69" Use the script for source code screendump testing. It sources other scripts,
70" therefore we must "cd" there.
71cd ../../src/testdir
72source screendump.vim
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +010073exe 'cd ' .. fnameescape(syntaxDir)
Bram Moolenaar46acad72023-06-11 19:04:18 +010074
75" For these tests we need to be able to run terminal Vim with 256 colors. On
76" MS-Windows the console only has 16 colors and the GUI can't run in a
77" terminal.
78if !CanRunVimInTerminal()
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +010079 call Fatal('Cannot make screendumps, aborting')
Bram Moolenaar46acad72023-06-11 19:04:18 +010080endif
81
82cd testdir
Aliaksei Budaveif63c3462025-03-08 16:58:17 +010083
Bram Moolenaar46acad72023-06-11 19:04:18 +010084if !isdirectory('done')
85 call mkdir('done')
86endif
87
Aliaksei Budaveif63c3462025-03-08 16:58:17 +010088if !isdirectory('failed')
89 call mkdir('failed')
90endif
91
Bram Moolenaar46acad72023-06-11 19:04:18 +010092set nocp
93set nowrapscan
94set report=9999
95set modeline
96set debug=throw
97set nomore
98
99au! SwapExists * call HandleSwapExists()
100func HandleSwapExists()
101 " Ignore finding a swap file for the test input, the user might be editing
102 " it and that's OK.
103 if expand('<afile>') =~ 'input[/\\].*\..*'
104 let v:swapchoice = 'e'
105 endif
106endfunc
107
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100108" Trace ruler liveness on demand.
109if !empty($VIM_SYNTAX_TEST_LOG) && filewritable($VIM_SYNTAX_TEST_LOG)
110 def s:TraceRulerLiveness(context: string, times: number, tail: string)
111 writefile([printf('%s: %4d: %s', context, times, tail)],
112 $VIM_SYNTAX_TEST_LOG,
113 'a')
114 enddef
115else
116 def s:TraceRulerLiveness(_: string, _: number, _: string)
117 enddef
118endif
119
120" See ":help 'ruler'".
121def s:CannotSeeLastLine(ruler: list<string>): bool
122 return !(get(ruler, -1, '') ==# 'All' || get(ruler, -1, '') ==# 'Bot')
123enddef
124
125def s:CannotDumpNextPage(buf: number, prev_ruler: list<string>, ruler: list<string>): bool
126 return !(ruler !=# prev_ruler &&
127 len(ruler) == 2 &&
128 ruler[1] =~# '\%(\d%\|\<Bot\)$' &&
129 get(term_getcursor(buf), 0) != 20)
130enddef
131
132def s:CannotDumpFirstPage(buf: number, _: list<string>, ruler: list<string>): bool
133 return !(len(ruler) == 2 &&
134 ruler[1] =~# '\%(\<All\|\<Top\)$' &&
135 get(term_getcursor(buf), 0) != 20)
136enddef
137
138def s:CannotDumpShellFirstPage(buf: number, _: list<string>, ruler: list<string>): bool
139 return !(len(ruler) > 3 &&
140 get(ruler, -1, '') =~# '\%(\<All\|\<Top\)$' &&
141 get(term_getcursor(buf), 0) != 20)
142enddef
143
144" Poll for updates of the cursor position in the terminal buffer occupying the
145" first window. (ALWAYS call the function or its equivalent before calling
146" "VerifyScreenDump()" *and* after calling any number of "term_sendkeys()".)
147def s:TermPollRuler(
148 CannotDumpPage: func, # (TYPE FOR LEGACY CONTEXT CALL SITES.)
149 buf: number,
150 in_name_and_out_name: string): list<string>
151 # Expect defaults from "term_util#RunVimInTerminal()".
Aliaksei Budavei84184462024-05-21 01:10:26 +0300152 if winwidth(1) != 75 || winheight(1) != 20
153 ch_log(printf('Aborting for %s: (75 x 20) != (%d x %d)',
154 in_name_and_out_name,
155 winwidth(1),
156 winheight(1)))
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100157 return ['0,0-1', 'All']
Aliaksei Budavei84184462024-05-21 01:10:26 +0300158 endif
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100159 # A two-fold role for redrawing:
160 # (*) in case the terminal buffer cannot redraw itself just yet;
161 # (*) to avoid extra "real estate" checks.
Aliaksei Budavei84184462024-05-21 01:10:26 +0300162 redraw
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100163 # The contents of "ruler".
164 var ruler: list<string> = []
165 # Attempts at most, targeting ASan-instrumented Vim builds.
166 var times: number = 2048
167 # Check "real estate" of the terminal buffer. Read and compare its ruler
168 # line and let "Xtestscript#s:AssertCursorForwardProgress()" do the rest.
169 # Note that the cursor ought to be advanced after each successive call of
170 # this function yet its relative position need not be changed (e.g. "0%").
171 while CannotDumpPage(ruler) && times > 0
172 ruler = split(term_getline(buf, 20))
173 sleep 1m
174 times -= 1
175 if times % 8 == 0
176 redraw
177 endif
178 endwhile
179 TraceRulerLiveness('P', (2048 - times), in_name_and_out_name)
180 return ruler
181enddef
182
183" Prevent "s:TermPollRuler()" from prematurely reading the cursor position,
184" which is available at ":edit", after outracing the loading of syntax etc. in
185" the terminal buffer. (Call the function before calling "VerifyScreenDump()"
186" for the first time.)
187def s:TermWaitAndPollRuler(buf: number, in_name_and_out_name: string): list<string>
188 # Expect defaults from "term_util#RunVimInTerminal()".
189 if winwidth(1) != 75 || winheight(1) != 20
190 ch_log(printf('Aborting for %s: (75 x 20) != (%d x %d)',
191 in_name_and_out_name,
192 winwidth(1),
193 winheight(1)))
194 return ['0,0-1', 'All']
195 endif
196 # The contents of "ruler".
197 var ruler: string = ''
198 # Attempts at most, targeting ASan-instrumented Vim builds.
199 var times: number = 32768
200 # Check "real estate" of the terminal buffer. Expect a known token to be
201 # rendered in the terminal buffer; its prefix must be "is_" so that buffer
202 # variables from "sh.vim" can be matched (see "Xtestscript#ShellInfo()").
203 # Verify that the whole line is available!
204 while ruler !~# '^is_.\+\s\%(All\|Top\)$' && times > 0
205 ruler = term_getline(buf, 20)
206 sleep 1m
207 times -= 1
208 if times % 16 == 0
209 redraw
210 endif
211 endwhile
212 TraceRulerLiveness('W', (32768 - times), in_name_and_out_name)
213 if strpart(ruler, 0, 8) !=# 'is_nonce'
214 # Retain any of "b:is_(bash|dash|kornshell|posix|sh)" entries and let
215 # "CannotDumpShellFirstPage()" win the cursor race.
216 return TermPollRuler(
217 function(CannotDumpShellFirstPage, [buf, []]),
218 buf,
219 in_name_and_out_name)
220 else
221 # Clear the "is_nonce" token and let "CannotDumpFirstPage()" win any
222 # race.
223 term_sendkeys(buf, ":redraw!\<CR>")
224 endif
225 return TermPollRuler(
226 function(CannotDumpFirstPage, [buf, []]),
227 buf,
228 in_name_and_out_name)
Aliaksei Budavei84184462024-05-21 01:10:26 +0300229enddef
230
Christian Brabandt56824432024-02-28 21:24:25 +0100231func RunTest()
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100232 let XTESTSCRIPT =<< trim END
233 " Track the cursor progress through a syntax test file so that any
234 " degenerate input can be reported. Each file will have its own cursor.
235 let s:cursor = 1
236
237 " extra info for shell variables
238 func ShellInfo()
239 let msg = ''
240 for [key, val] in items(b:)
241 if key =~ '^is_'
242 let msg ..= key .. ': ' .. val .. ', '
243 endif
244 endfor
245 if msg != ''
246 echomsg msg
247 endif
248 endfunc
249
250 au! SwapExists * call HandleSwapExists()
251 func HandleSwapExists()
252 " Ignore finding a swap file for the test input, the user might be
253 " editing it and that's OK.
254 if expand('<afile>') =~ 'input[/\\].*\..*'
255 let v:swapchoice = 'e'
256 endif
257 endfunc
258
259 func LoadFiletype(type)
260 for file in glob("ftplugin/" .. a:type .. "*.vim", 1, 1)
261 exe "source " .. file
262 endfor
263 redraw!
264 endfunc
265
266 func SetUpVim()
267 call cursor(1, 1)
268 " Defend against rogue VIM_TEST_SETUP commands.
269 for _ in range(20)
270 let lnum = search('\C\<VIM_TEST_SETUP\>', 'eW', 20)
271 if lnum < 1
272 break
273 endif
274 exe substitute(getline(lnum), '\C.*\<VIM_TEST_SETUP\>', '', '')
275 endfor
276 call cursor(1, 1)
277 " BEGIN [runtime/defaults.vim]
278 " Also, disable italic highlighting to avoid issues on some terminals.
279 set display=lastline ruler scrolloff=5 t_ZH= t_ZR=
280 syntax on
281 " END [runtime/defaults.vim]
282 redraw!
283 endfunc
284
285 def s:AssertCursorForwardProgress(): bool
286 const curnum: number = line('.')
287 if curnum <= cursor
288 # Use "actions/upload-artifact@v4" of ci.yml for delivery.
289 writefile([printf('No cursor progress: %d <= %d (%s). Please file an issue.',
290 curnum,
291 cursor,
292 bufname('%'))],
293 'failed/00-FIXME',
294 'a')
295 bwipeout!
296 endif
297 cursor = curnum
298 return true
299 enddef
300
301 def ScrollToSecondPage(estate: number, op_wh: number, op_so: number): bool
302 if line('.') != 1 || line('w$') >= line('$')
303 return AssertCursorForwardProgress()
304 endif
305 try
306 set scrolloff=0
307 # Advance mark "c"[ursor] along with the cursor.
308 norm! Lmc
309 if foldclosed('.') < 0 &&
310 (strdisplaywidth(getline('.')) + &l:fdc * winheight(1)) >= estate
311 # Make for an exit for a screenful long line.
312 norm! j^
313 return AssertCursorForwardProgress()
314 else
315 # Place the cursor on the actually last visible line.
316 while winline() < op_wh
317 const lastnum: number = winline()
318 norm! gjmc
319 if lastnum > winline()
320 break
321 endif
322 endwhile
323 norm! zt
324 endif
325 finally
326 # COMPATIBILITY: Scroll up around "scrolloff" lines.
327 &scrolloff = max([1, op_so])
328 endtry
329 norm! ^
330 return AssertCursorForwardProgress()
331 enddef
332
333 def ScrollToNextPage(estate: number, op_wh: number, op_so: number): bool
334 if line('.') == 1 || line('w$') >= line('$')
335 return AssertCursorForwardProgress()
336 endif
337 try
338 set scrolloff=0
339 # Advance mark "c"[ursor] along with the cursor.
340 norm! Lmc
341 if foldclosed('.') < 0 &&
342 (strdisplaywidth(getline('.')) + &l:fdc * winheight(1)) >= estate
343 # Make for an exit for a screenful long line.
344 norm! j^
345 return AssertCursorForwardProgress()
346 else
347 # Place the cursor on the actually last visible line.
348 while winline() < op_wh
349 const lastnum: number = winline()
350 norm! gjmc
351 if lastnum > winline()
352 break
353 endif
354 endwhile
355 endif
356 finally
357 # COMPATIBILITY: Scroll up/down around "scrolloff" lines.
358 &scrolloff = max([1, op_so])
359 endtry
360 norm! zt
361 const marknum: number = line("'c")
362 # Eschew &smoothscroll since line("`c") is not supported.
363 # Remember that "w0" can point to the first line of a _closed_ fold
364 # whereas the last line of a _closed_ fold can be marked.
365 if line('w0') > marknum
366 while line('w0') > marknum
367 exe "norm! \<C-y>"
368 endwhile
369 if line('w0') != marknum
370 exe "norm! \<C-e>H"
371 endif
372 # Handle non-wrapped lines.
373 elseif line('w0') < marknum
374 while line('w0') < marknum
375 exe "norm! \<C-e>"
376 endwhile
377 if line('w0') != marknum
378 exe "norm! \<C-y>H"
379 endif
380 endif
381 norm! ^
382 return AssertCursorForwardProgress()
383 enddef
384 END
385 let MAX_FAILED_COUNT = 5
Aliaksei Budavei7ceca3e2025-03-16 20:59:28 +0100386 let DUMP_OPTS = exists("$VIM_SYNTAX_TEST_WAIT_TIME") &&
387 \ !empty($VIM_SYNTAX_TEST_WAIT_TIME)
388 \ ? {'wait': max([1, str2nr($VIM_SYNTAX_TEST_WAIT_TIME)])}
389 \ : {}
390 lockvar DUMP_OPTS MAX_FAILED_COUNT XTESTSCRIPT
Christian Brabandt56824432024-02-28 21:24:25 +0100391 let ok_count = 0
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100392 let disused_pages = []
Christian Brabandt56824432024-02-28 21:24:25 +0100393 let failed_tests = []
394 let skipped_count = 0
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100395 let last_test_status = 'invalid'
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100396 let filter = ''
Aliaksei Budaveif6069a72024-03-05 22:34:36 +0300397 " Create a map of setup configuration filenames with their basenames as keys.
398 let setup = glob('input/setup/*.vim', 1, 1)
399 \ ->reduce({d, f -> extend(d, {fnamemodify(f, ':t:r'): f})}, {})
Aliaksei Budaveiec022942024-10-06 16:57:33 +0200400 " Turn a subset of filenames etc. requested for testing into a pattern.
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100401 if filereadable('../testdir/Xfilter')
402 let filter = readfile('../testdir/Xfilter')
403 \ ->map({_, v -> '^' .. escape(substitute(v, '_$', '', ''), '.')})
Aliaksei Budaveiec022942024-10-06 16:57:33 +0200404 \ ->join('\|')
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100405 call delete('../testdir/Xfilter')
406 endif
Aliaksei Budaveif6069a72024-03-05 22:34:36 +0300407
Aliaksei Budavei7ceca3e2025-03-16 20:59:28 +0100408 " Treat "^self-testing" as a string NOT as a regexp.
409 if filter ==# '^self-testing'
Aliaksei Budaveid2f49872024-05-24 19:14:16 +0300410 let dirpath = 'input/selftestdir/'
Aliaksei Budaveid33afe12024-08-12 18:37:15 +0200411 let fnames = readdir(dirpath, {fname -> fname !~ '^README\.txt$'})
Aliaksei Budaveid2f49872024-05-24 19:14:16 +0300412 else
413 let dirpath = 'input/'
Aliaksei Budaveiec022942024-10-06 16:57:33 +0200414 let filter ..= exists("$VIM_SYNTAX_TEST_FILTER") &&
415 \ !empty($VIM_SYNTAX_TEST_FILTER)
416 \ ? (empty(filter) ? '' : '\|') .. $VIM_SYNTAX_TEST_FILTER
417 \ : ''
418 let fnames = readdir(dirpath,
419 \ {subset -> {fname -> fname !~ '\~$' && fname =~# subset}}(
420 \ empty(filter) ? '^.\+\..\+$' : filter))
Aliaksei Budaveid2f49872024-05-24 19:14:16 +0300421 endif
Bram Moolenaar7d0dbd02023-06-24 00:56:50 +0100422
Aliaksei Budaveid2f49872024-05-24 19:14:16 +0300423 for fname in fnames
424 let root = fnamemodify(fname, ':r')
425 let fname = dirpath .. fname
Bram Moolenaar46acad72023-06-11 19:04:18 +0100426
Christian Brabandt56824432024-02-28 21:24:25 +0100427 " Execute the test if the "done" file does not exist or when the input file
428 " is newer.
429 let in_time = getftime(fname)
430 let out_time = getftime('done/' .. root)
431 if out_time < 0 || in_time > out_time
432 call ch_log('running tests for: ' .. fname)
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100433 let filetype = substitute(root, '\([^_.]*\)[_.].*', '\1', '')
434 let failed_root = 'failed/' .. root
Bram Moolenaar7d0dbd02023-06-24 00:56:50 +0100435
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100436 for pagename in glob(failed_root .. '_\d*\.dump', 1, 1)
437 call delete(pagename)
Christian Brabandt56824432024-02-28 21:24:25 +0100438 endfor
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +0100439 call delete('done/' .. root)
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100440 call writefile(XTESTSCRIPT, 'Xtestscript')
Christian Brabandt56824432024-02-28 21:24:25 +0100441
442 " close all but the last window
443 while winnr('$') > 1
444 close
445 endwhile
446
447 " Redraw to make sure that messages are cleared and there is enough space
448 " for the terminal window.
449 redraw
450
Aliaksei Budavei93edd252024-03-05 22:34:36 +0300451 " Let "Xtestscript#SetUpVim()" turn the syntax on.
Aliaksei Budaveif6069a72024-03-05 22:34:36 +0300452 let prefix = '-Nu NONE -S Xtestscript'
453 let path = get(setup, root, '')
454 " Source the found setup configuration file.
455 let args = !empty(path)
456 \ ? prefix .. ' -S ' .. path
457 \ : prefix
458 let buf = RunVimInTerminal(args, {})
Christian Brabandt56824432024-02-28 21:24:25 +0100459 " edit the file only after catching the SwapExists event
460 call term_sendkeys(buf, ":edit " .. fname .. "\<CR>")
Aliaksei Budavei93edd252024-03-05 22:34:36 +0300461 " set up the testing environment
462 call term_sendkeys(buf, ":call SetUpVim()\<CR>")
Christian Brabandt56824432024-02-28 21:24:25 +0100463 " load filetype specific settings
464 call term_sendkeys(buf, ":call LoadFiletype('" .. filetype .. "')\<CR>")
465
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100466 " Make a synchronisation point between buffers by requesting to echo
467 " a known token in the terminal buffer and asserting its availability
468 " with "s:TermWaitAndPollRuler()".
Christian Brabandt56824432024-02-28 21:24:25 +0100469 if filetype == 'sh'
470 call term_sendkeys(buf, ":call ShellInfo()\<CR>")
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100471 else
472 call term_sendkeys(buf, ":echo 'is_nonce'\<CR>")
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +0100473 endif
Christian Brabandt56824432024-02-28 21:24:25 +0100474
Christian Brabandt56824432024-02-28 21:24:25 +0100475 let root_00 = root .. '_00'
Aliaksei Budavei84184462024-05-21 01:10:26 +0300476 let in_name_and_out_name = fname .. ': failed/' .. root_00 .. '.dump'
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100477 " Queue up all "term_sendkeys()"es and let them finish before returning
478 " from "s:TermWaitAndPollRuler()".
479 let ruler = s:TermWaitAndPollRuler(buf, in_name_and_out_name)
Aliaksei Budavei84184462024-05-21 01:10:26 +0300480 call ch_log('First screendump for ' .. in_name_and_out_name)
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100481 " Make a screendump at the start of the file: failed/root_00.dump
Aliaksei Budavei7ceca3e2025-03-16 20:59:28 +0100482 let fail = VerifyScreenDump(buf, root_00, DUMP_OPTS)
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100483 let nr = 0
Christian Brabandt56824432024-02-28 21:24:25 +0100484
Aliaksei Budavei71971432024-07-05 21:30:02 +0300485 " Accommodate the next code block to "buf"'s contingency for self
486 " wipe-out.
487 try
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100488 let keys_a = ":call ScrollToSecondPage((18 * 75 + 1), 19, 5) | redraw!\<CR>"
489 let keys_b = ":call ScrollToNextPage((18 * 75 + 1), 19, 5) | redraw!\<CR>"
490 while s:CannotSeeLastLine(ruler)
491 call term_sendkeys(buf, keys_a)
492 let keys_a = keys_b
Aliaksei Budavei84184462024-05-21 01:10:26 +0300493 let nr += 1
494 let root_next = printf('%s_%02d', root, nr)
495 let in_name_and_out_name = fname .. ': failed/' .. root_next .. '.dump'
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100496 let ruler = s:TermPollRuler(
497 \ function('s:CannotDumpNextPage', [buf, ruler]),
498 \ buf,
499 \ in_name_and_out_name)
500 call ch_log('Next screendump for ' .. in_name_and_out_name)
501 " Make a screendump of every 18 lines of the file: failed/root_NN.dump
Aliaksei Budavei7ceca3e2025-03-16 20:59:28 +0100502 let fail += VerifyScreenDump(buf, root_next, DUMP_OPTS)
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100503 endwhile
Aliaksei Budavei71971432024-07-05 21:30:02 +0300504 call StopVimInTerminal(buf)
505 finally
506 call delete('Xtestscript')
507 endtry
Christian Brabandt56824432024-02-28 21:24:25 +0100508
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100509 let nr += 1
510 let pagename = printf('dumps/%s_%02d.dump', root, nr)
511
512 while filereadable(pagename)
513 call add(disused_pages, pagename)
514 let nr += 1
515 let pagename = printf('dumps/%s_%02d.dump', root, nr)
516 endwhile
517
Christian Brabandt56824432024-02-28 21:24:25 +0100518 " redraw here to avoid the following messages to get mixed up with screen
519 " output.
520 redraw
521
522 " Add any assert errors to s:messages.
523 if len(v:errors) > 0
524 call extend(s:messages, v:errors)
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100525 if last_test_status == 'passed'
526 call EraseLineAndReturnCarriage('Test ' .. root .. ' OK')
527 else
528 echon "\n"
529 endif
Christian Brabandt56824432024-02-28 21:24:25 +0100530 " Echo the errors here, in case the script aborts or the "messages" file
531 " is not displayed later.
532 echomsg v:errors
533 let v:errors = []
534 let fail += 1
535 endif
536
537 if fail == 0
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100538 if last_test_status == 'skipped'
539 echon "\n"
540 endif
541 let last_test_status = 'passed'
542 let msg = "Test " .. root .. " OK"
543 call Message(msg)
544 call EraseLineAndReturnCarriage(msg)
Christian Brabandt56824432024-02-28 21:24:25 +0100545
546 call writefile(['OK'], 'done/' .. root)
547
548 let ok_count += 1
549 else
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100550 let last_test_status = 'failed'
Christian Brabandt56824432024-02-28 21:24:25 +0100551 call Message("Test " .. root .. " FAILED")
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100552 echon "\n"
Christian Brabandt56824432024-02-28 21:24:25 +0100553
554 call delete('done/' .. root)
555
556 eval failed_tests->add(root)
557 if len(failed_tests) > MAX_FAILED_COUNT
558 call Message('')
559 call Message('Too many errors, aborting')
560 endif
561 endif
562 else
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100563 if last_test_status == 'passed'
564 call EraseLineAndReturnCarriage('Test ' .. root .. ' OK')
565 endif
566 let last_test_status = 'skipped'
Christian Brabandt56824432024-02-28 21:24:25 +0100567 call Message("Test " .. root .. " skipped")
568 let skipped_count += 1
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +0100569 endif
Christian Brabandt56824432024-02-28 21:24:25 +0100570
571 " Append messages to the file "testdir/messages"
572 call AppendMessages('Input file ' .. fname .. ':')
573
574 if len(failed_tests) > MAX_FAILED_COUNT
575 break
576 endif
577 endfor
578
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100579 if last_test_status == 'passed' && exists('root')
580 call EraseLineAndReturnCarriage('Test ' .. root .. ' OK')
581 endif
582
Christian Brabandt56824432024-02-28 21:24:25 +0100583 call Message(s:test_run_message)
584 call Message('OK: ' .. ok_count)
585 call Message('FAILED: ' .. len(failed_tests) .. ': ' .. string(failed_tests))
586 call Message('skipped: ' .. skipped_count)
Aliaksei Budaveid33afe12024-08-12 18:37:15 +0200587
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100588 for pagename in disused_pages
589 call Message(printf('No input page found for "%s"', pagename))
590 endfor
591
Aliaksei Budaveid33afe12024-08-12 18:37:15 +0200592 if !empty(failed_tests)
593 call Message('')
594 call Message('View generated screendumps with "../../src/vim --clean -S testdir/viewdumps.vim"')
595 endif
596
Christian Brabandt203c7222024-10-29 20:21:42 +0100597 call AppendMessages('== SUMMARY SYNTAX TESTS ==')
Christian Brabandt56824432024-02-28 21:24:25 +0100598
599 if len(failed_tests) > 0
600 " have make report an error
601 cquit
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +0100602 endif
Christian Brabandt56824432024-02-28 21:24:25 +0100603endfunc
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +0100604
Christian Brabandt56824432024-02-28 21:24:25 +0100605call RunTest()
Christian Brabandt627c9502024-02-10 13:02:17 +0100606
607" Matching "if 1" at the start.
608endif
609
Bram Moolenaar46acad72023-06-11 19:04:18 +0100610qall!
Christian Brabandt56824432024-02-28 21:24:25 +0100611
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100612" vim:sw=2:ts=8:noet: