blob: 3d4b350d0243d1941e29022bcad1f74db0322a59 [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
Christian Brabandteb380b92025-07-07 20:53:55 +020072source util/screendump.vim
73source util/term_util.vim
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +010074exe 'cd ' .. fnameescape(syntaxDir)
Bram Moolenaar46acad72023-06-11 19:04:18 +010075
76" For these tests we need to be able to run terminal Vim with 256 colors. On
77" MS-Windows the console only has 16 colors and the GUI can't run in a
78" terminal.
79if !CanRunVimInTerminal()
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +010080 call Fatal('Cannot make screendumps, aborting')
Bram Moolenaar46acad72023-06-11 19:04:18 +010081endif
82
83cd testdir
Aliaksei Budaveif63c3462025-03-08 16:58:17 +010084
Bram Moolenaar46acad72023-06-11 19:04:18 +010085if !isdirectory('done')
86 call mkdir('done')
87endif
88
Aliaksei Budaveif63c3462025-03-08 16:58:17 +010089if !isdirectory('failed')
90 call mkdir('failed')
91endif
92
Bram Moolenaar46acad72023-06-11 19:04:18 +010093set nocp
94set nowrapscan
95set report=9999
96set modeline
97set debug=throw
98set nomore
99
100au! SwapExists * call HandleSwapExists()
101func HandleSwapExists()
102 " Ignore finding a swap file for the test input, the user might be editing
103 " it and that's OK.
104 if expand('<afile>') =~ 'input[/\\].*\..*'
105 let v:swapchoice = 'e'
106 endif
107endfunc
108
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100109" Trace ruler liveness on demand.
110if !empty($VIM_SYNTAX_TEST_LOG) && filewritable($VIM_SYNTAX_TEST_LOG)
111 def s:TraceRulerLiveness(context: string, times: number, tail: string)
112 writefile([printf('%s: %4d: %s', context, times, tail)],
113 $VIM_SYNTAX_TEST_LOG,
114 'a')
115 enddef
116else
117 def s:TraceRulerLiveness(_: string, _: number, _: string)
118 enddef
119endif
120
121" See ":help 'ruler'".
122def s:CannotSeeLastLine(ruler: list<string>): bool
123 return !(get(ruler, -1, '') ==# 'All' || get(ruler, -1, '') ==# 'Bot')
124enddef
125
126def s:CannotDumpNextPage(buf: number, prev_ruler: list<string>, ruler: list<string>): bool
127 return !(ruler !=# prev_ruler &&
128 len(ruler) == 2 &&
129 ruler[1] =~# '\%(\d%\|\<Bot\)$' &&
130 get(term_getcursor(buf), 0) != 20)
131enddef
132
133def s:CannotDumpFirstPage(buf: number, _: list<string>, ruler: list<string>): bool
134 return !(len(ruler) == 2 &&
135 ruler[1] =~# '\%(\<All\|\<Top\)$' &&
136 get(term_getcursor(buf), 0) != 20)
137enddef
138
139def s:CannotDumpShellFirstPage(buf: number, _: list<string>, ruler: list<string>): bool
140 return !(len(ruler) > 3 &&
141 get(ruler, -1, '') =~# '\%(\<All\|\<Top\)$' &&
142 get(term_getcursor(buf), 0) != 20)
143enddef
144
145" Poll for updates of the cursor position in the terminal buffer occupying the
146" first window. (ALWAYS call the function or its equivalent before calling
147" "VerifyScreenDump()" *and* after calling any number of "term_sendkeys()".)
148def s:TermPollRuler(
149 CannotDumpPage: func, # (TYPE FOR LEGACY CONTEXT CALL SITES.)
150 buf: number,
151 in_name_and_out_name: string): list<string>
152 # Expect defaults from "term_util#RunVimInTerminal()".
Aliaksei Budavei84184462024-05-21 01:10:26 +0300153 if winwidth(1) != 75 || winheight(1) != 20
154 ch_log(printf('Aborting for %s: (75 x 20) != (%d x %d)',
155 in_name_and_out_name,
156 winwidth(1),
157 winheight(1)))
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100158 return ['0,0-1', 'All']
Aliaksei Budavei84184462024-05-21 01:10:26 +0300159 endif
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100160 # A two-fold role for redrawing:
161 # (*) in case the terminal buffer cannot redraw itself just yet;
162 # (*) to avoid extra "real estate" checks.
Aliaksei Budavei84184462024-05-21 01:10:26 +0300163 redraw
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100164 # The contents of "ruler".
165 var ruler: list<string> = []
166 # Attempts at most, targeting ASan-instrumented Vim builds.
167 var times: number = 2048
168 # Check "real estate" of the terminal buffer. Read and compare its ruler
169 # line and let "Xtestscript#s:AssertCursorForwardProgress()" do the rest.
170 # Note that the cursor ought to be advanced after each successive call of
171 # this function yet its relative position need not be changed (e.g. "0%").
172 while CannotDumpPage(ruler) && times > 0
173 ruler = split(term_getline(buf, 20))
174 sleep 1m
175 times -= 1
176 if times % 8 == 0
177 redraw
178 endif
179 endwhile
180 TraceRulerLiveness('P', (2048 - times), in_name_and_out_name)
181 return ruler
182enddef
183
184" Prevent "s:TermPollRuler()" from prematurely reading the cursor position,
185" which is available at ":edit", after outracing the loading of syntax etc. in
186" the terminal buffer. (Call the function before calling "VerifyScreenDump()"
187" for the first time.)
188def s:TermWaitAndPollRuler(buf: number, in_name_and_out_name: string): list<string>
189 # Expect defaults from "term_util#RunVimInTerminal()".
190 if winwidth(1) != 75 || winheight(1) != 20
191 ch_log(printf('Aborting for %s: (75 x 20) != (%d x %d)',
192 in_name_and_out_name,
193 winwidth(1),
194 winheight(1)))
195 return ['0,0-1', 'All']
196 endif
197 # The contents of "ruler".
198 var ruler: string = ''
199 # Attempts at most, targeting ASan-instrumented Vim builds.
200 var times: number = 32768
201 # Check "real estate" of the terminal buffer. Expect a known token to be
202 # rendered in the terminal buffer; its prefix must be "is_" so that buffer
203 # variables from "sh.vim" can be matched (see "Xtestscript#ShellInfo()").
204 # Verify that the whole line is available!
205 while ruler !~# '^is_.\+\s\%(All\|Top\)$' && times > 0
206 ruler = term_getline(buf, 20)
207 sleep 1m
208 times -= 1
209 if times % 16 == 0
210 redraw
211 endif
212 endwhile
213 TraceRulerLiveness('W', (32768 - times), in_name_and_out_name)
214 if strpart(ruler, 0, 8) !=# 'is_nonce'
215 # Retain any of "b:is_(bash|dash|kornshell|posix|sh)" entries and let
216 # "CannotDumpShellFirstPage()" win the cursor race.
217 return TermPollRuler(
218 function(CannotDumpShellFirstPage, [buf, []]),
219 buf,
220 in_name_and_out_name)
221 else
222 # Clear the "is_nonce" token and let "CannotDumpFirstPage()" win any
223 # race.
224 term_sendkeys(buf, ":redraw!\<CR>")
225 endif
226 return TermPollRuler(
227 function(CannotDumpFirstPage, [buf, []]),
228 buf,
229 in_name_and_out_name)
Aliaksei Budavei84184462024-05-21 01:10:26 +0300230enddef
231
Christian Brabandt56824432024-02-28 21:24:25 +0100232func RunTest()
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100233 let XTESTSCRIPT =<< trim END
234 " Track the cursor progress through a syntax test file so that any
235 " degenerate input can be reported. Each file will have its own cursor.
236 let s:cursor = 1
237
238 " extra info for shell variables
239 func ShellInfo()
240 let msg = ''
241 for [key, val] in items(b:)
242 if key =~ '^is_'
243 let msg ..= key .. ': ' .. val .. ', '
244 endif
245 endfor
246 if msg != ''
247 echomsg msg
248 endif
249 endfunc
250
251 au! SwapExists * call HandleSwapExists()
252 func HandleSwapExists()
253 " Ignore finding a swap file for the test input, the user might be
254 " editing it and that's OK.
255 if expand('<afile>') =~ 'input[/\\].*\..*'
256 let v:swapchoice = 'e'
257 endif
258 endfunc
259
260 func LoadFiletype(type)
261 for file in glob("ftplugin/" .. a:type .. "*.vim", 1, 1)
262 exe "source " .. file
263 endfor
264 redraw!
265 endfunc
266
267 func SetUpVim()
268 call cursor(1, 1)
269 " Defend against rogue VIM_TEST_SETUP commands.
270 for _ in range(20)
271 let lnum = search('\C\<VIM_TEST_SETUP\>', 'eW', 20)
272 if lnum < 1
273 break
274 endif
275 exe substitute(getline(lnum), '\C.*\<VIM_TEST_SETUP\>', '', '')
276 endfor
277 call cursor(1, 1)
278 " BEGIN [runtime/defaults.vim]
279 " Also, disable italic highlighting to avoid issues on some terminals.
280 set display=lastline ruler scrolloff=5 t_ZH= t_ZR=
281 syntax on
282 " END [runtime/defaults.vim]
283 redraw!
284 endfunc
285
286 def s:AssertCursorForwardProgress(): bool
287 const curnum: number = line('.')
288 if curnum <= cursor
289 # Use "actions/upload-artifact@v4" of ci.yml for delivery.
290 writefile([printf('No cursor progress: %d <= %d (%s). Please file an issue.',
291 curnum,
292 cursor,
293 bufname('%'))],
294 'failed/00-FIXME',
295 'a')
296 bwipeout!
297 endif
298 cursor = curnum
299 return true
300 enddef
301
302 def ScrollToSecondPage(estate: number, op_wh: number, op_so: number): bool
303 if line('.') != 1 || line('w$') >= line('$')
304 return AssertCursorForwardProgress()
305 endif
306 try
307 set scrolloff=0
308 # Advance mark "c"[ursor] along with the cursor.
309 norm! Lmc
310 if foldclosed('.') < 0 &&
311 (strdisplaywidth(getline('.')) + &l:fdc * winheight(1)) >= estate
312 # Make for an exit for a screenful long line.
313 norm! j^
314 return AssertCursorForwardProgress()
315 else
316 # Place the cursor on the actually last visible line.
317 while winline() < op_wh
318 const lastnum: number = winline()
319 norm! gjmc
320 if lastnum > winline()
321 break
322 endif
323 endwhile
324 norm! zt
325 endif
326 finally
327 # COMPATIBILITY: Scroll up around "scrolloff" lines.
328 &scrolloff = max([1, op_so])
329 endtry
330 norm! ^
331 return AssertCursorForwardProgress()
332 enddef
333
334 def ScrollToNextPage(estate: number, op_wh: number, op_so: number): bool
335 if line('.') == 1 || line('w$') >= line('$')
336 return AssertCursorForwardProgress()
337 endif
338 try
339 set scrolloff=0
340 # Advance mark "c"[ursor] along with the cursor.
341 norm! Lmc
342 if foldclosed('.') < 0 &&
343 (strdisplaywidth(getline('.')) + &l:fdc * winheight(1)) >= estate
344 # Make for an exit for a screenful long line.
345 norm! j^
346 return AssertCursorForwardProgress()
347 else
348 # Place the cursor on the actually last visible line.
349 while winline() < op_wh
350 const lastnum: number = winline()
351 norm! gjmc
352 if lastnum > winline()
353 break
354 endif
355 endwhile
356 endif
357 finally
358 # COMPATIBILITY: Scroll up/down around "scrolloff" lines.
359 &scrolloff = max([1, op_so])
360 endtry
361 norm! zt
362 const marknum: number = line("'c")
363 # Eschew &smoothscroll since line("`c") is not supported.
364 # Remember that "w0" can point to the first line of a _closed_ fold
365 # whereas the last line of a _closed_ fold can be marked.
366 if line('w0') > marknum
367 while line('w0') > marknum
368 exe "norm! \<C-y>"
369 endwhile
370 if line('w0') != marknum
371 exe "norm! \<C-e>H"
372 endif
373 # Handle non-wrapped lines.
374 elseif line('w0') < marknum
375 while line('w0') < marknum
376 exe "norm! \<C-e>"
377 endwhile
378 if line('w0') != marknum
379 exe "norm! \<C-y>H"
380 endif
381 endif
382 norm! ^
383 return AssertCursorForwardProgress()
384 enddef
385 END
386 let MAX_FAILED_COUNT = 5
Aliaksei Budavei7ceca3e2025-03-16 20:59:28 +0100387 let DUMP_OPTS = exists("$VIM_SYNTAX_TEST_WAIT_TIME") &&
388 \ !empty($VIM_SYNTAX_TEST_WAIT_TIME)
389 \ ? {'wait': max([1, str2nr($VIM_SYNTAX_TEST_WAIT_TIME)])}
390 \ : {}
391 lockvar DUMP_OPTS MAX_FAILED_COUNT XTESTSCRIPT
Christian Brabandt56824432024-02-28 21:24:25 +0100392 let ok_count = 0
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100393 let disused_pages = []
Christian Brabandt56824432024-02-28 21:24:25 +0100394 let failed_tests = []
395 let skipped_count = 0
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100396 let last_test_status = 'invalid'
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100397 let filter = ''
Aliaksei Budaveif6069a72024-03-05 22:34:36 +0300398 " Create a map of setup configuration filenames with their basenames as keys.
399 let setup = glob('input/setup/*.vim', 1, 1)
400 \ ->reduce({d, f -> extend(d, {fnamemodify(f, ':t:r'): f})}, {})
Aliaksei Budaveiec022942024-10-06 16:57:33 +0200401 " Turn a subset of filenames etc. requested for testing into a pattern.
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100402 if filereadable('../testdir/Xfilter')
403 let filter = readfile('../testdir/Xfilter')
404 \ ->map({_, v -> '^' .. escape(substitute(v, '_$', '', ''), '.')})
Aliaksei Budaveiec022942024-10-06 16:57:33 +0200405 \ ->join('\|')
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100406 call delete('../testdir/Xfilter')
407 endif
Aliaksei Budaveif6069a72024-03-05 22:34:36 +0300408
Aliaksei Budavei7ceca3e2025-03-16 20:59:28 +0100409 " Treat "^self-testing" as a string NOT as a regexp.
410 if filter ==# '^self-testing'
Aliaksei Budaveid2f49872024-05-24 19:14:16 +0300411 let dirpath = 'input/selftestdir/'
Aliaksei Budaveid33afe12024-08-12 18:37:15 +0200412 let fnames = readdir(dirpath, {fname -> fname !~ '^README\.txt$'})
Aliaksei Budaveid2f49872024-05-24 19:14:16 +0300413 else
414 let dirpath = 'input/'
Aliaksei Budaveiec022942024-10-06 16:57:33 +0200415 let filter ..= exists("$VIM_SYNTAX_TEST_FILTER") &&
416 \ !empty($VIM_SYNTAX_TEST_FILTER)
417 \ ? (empty(filter) ? '' : '\|') .. $VIM_SYNTAX_TEST_FILTER
418 \ : ''
419 let fnames = readdir(dirpath,
420 \ {subset -> {fname -> fname !~ '\~$' && fname =~# subset}}(
421 \ empty(filter) ? '^.\+\..\+$' : filter))
Aliaksei Budaveid2f49872024-05-24 19:14:16 +0300422 endif
Bram Moolenaar7d0dbd02023-06-24 00:56:50 +0100423
Aliaksei Budaveid2f49872024-05-24 19:14:16 +0300424 for fname in fnames
425 let root = fnamemodify(fname, ':r')
426 let fname = dirpath .. fname
Bram Moolenaar46acad72023-06-11 19:04:18 +0100427
Christian Brabandt56824432024-02-28 21:24:25 +0100428 " Execute the test if the "done" file does not exist or when the input file
429 " is newer.
430 let in_time = getftime(fname)
431 let out_time = getftime('done/' .. root)
432 if out_time < 0 || in_time > out_time
433 call ch_log('running tests for: ' .. fname)
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100434 let filetype = substitute(root, '\([^_.]*\)[_.].*', '\1', '')
435 let failed_root = 'failed/' .. root
Bram Moolenaar7d0dbd02023-06-24 00:56:50 +0100436
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100437 for pagename in glob(failed_root .. '_\d*\.dump', 1, 1)
438 call delete(pagename)
Christian Brabandt56824432024-02-28 21:24:25 +0100439 endfor
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +0100440 call delete('done/' .. root)
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100441 call writefile(XTESTSCRIPT, 'Xtestscript')
Christian Brabandt56824432024-02-28 21:24:25 +0100442
443 " close all but the last window
444 while winnr('$') > 1
445 close
446 endwhile
447
448 " Redraw to make sure that messages are cleared and there is enough space
449 " for the terminal window.
450 redraw
451
Aliaksei Budavei93edd252024-03-05 22:34:36 +0300452 " Let "Xtestscript#SetUpVim()" turn the syntax on.
Aliaksei Budaveif6069a72024-03-05 22:34:36 +0300453 let prefix = '-Nu NONE -S Xtestscript'
454 let path = get(setup, root, '')
455 " Source the found setup configuration file.
456 let args = !empty(path)
457 \ ? prefix .. ' -S ' .. path
458 \ : prefix
459 let buf = RunVimInTerminal(args, {})
Christian Brabandt56824432024-02-28 21:24:25 +0100460 " edit the file only after catching the SwapExists event
461 call term_sendkeys(buf, ":edit " .. fname .. "\<CR>")
Aliaksei Budavei93edd252024-03-05 22:34:36 +0300462 " set up the testing environment
463 call term_sendkeys(buf, ":call SetUpVim()\<CR>")
Christian Brabandt56824432024-02-28 21:24:25 +0100464 " load filetype specific settings
465 call term_sendkeys(buf, ":call LoadFiletype('" .. filetype .. "')\<CR>")
466
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100467 " Make a synchronisation point between buffers by requesting to echo
468 " a known token in the terminal buffer and asserting its availability
469 " with "s:TermWaitAndPollRuler()".
Christian Brabandt56824432024-02-28 21:24:25 +0100470 if filetype == 'sh'
471 call term_sendkeys(buf, ":call ShellInfo()\<CR>")
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100472 else
473 call term_sendkeys(buf, ":echo 'is_nonce'\<CR>")
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +0100474 endif
Christian Brabandt56824432024-02-28 21:24:25 +0100475
Christian Brabandt56824432024-02-28 21:24:25 +0100476 let root_00 = root .. '_00'
Aliaksei Budavei84184462024-05-21 01:10:26 +0300477 let in_name_and_out_name = fname .. ': failed/' .. root_00 .. '.dump'
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100478 " Queue up all "term_sendkeys()"es and let them finish before returning
479 " from "s:TermWaitAndPollRuler()".
480 let ruler = s:TermWaitAndPollRuler(buf, in_name_and_out_name)
Aliaksei Budavei84184462024-05-21 01:10:26 +0300481 call ch_log('First screendump for ' .. in_name_and_out_name)
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100482 " Make a screendump at the start of the file: failed/root_00.dump
Aliaksei Budavei7ceca3e2025-03-16 20:59:28 +0100483 let fail = VerifyScreenDump(buf, root_00, DUMP_OPTS)
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100484 let nr = 0
Christian Brabandt56824432024-02-28 21:24:25 +0100485
Aliaksei Budavei71971432024-07-05 21:30:02 +0300486 " Accommodate the next code block to "buf"'s contingency for self
487 " wipe-out.
488 try
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100489 let keys_a = ":call ScrollToSecondPage((18 * 75 + 1), 19, 5) | redraw!\<CR>"
490 let keys_b = ":call ScrollToNextPage((18 * 75 + 1), 19, 5) | redraw!\<CR>"
491 while s:CannotSeeLastLine(ruler)
492 call term_sendkeys(buf, keys_a)
493 let keys_a = keys_b
Aliaksei Budavei84184462024-05-21 01:10:26 +0300494 let nr += 1
495 let root_next = printf('%s_%02d', root, nr)
496 let in_name_and_out_name = fname .. ': failed/' .. root_next .. '.dump'
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100497 let ruler = s:TermPollRuler(
498 \ function('s:CannotDumpNextPage', [buf, ruler]),
499 \ buf,
500 \ in_name_and_out_name)
501 call ch_log('Next screendump for ' .. in_name_and_out_name)
502 " Make a screendump of every 18 lines of the file: failed/root_NN.dump
Aliaksei Budavei7ceca3e2025-03-16 20:59:28 +0100503 let fail += VerifyScreenDump(buf, root_next, DUMP_OPTS)
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100504 endwhile
Aliaksei Budavei71971432024-07-05 21:30:02 +0300505 call StopVimInTerminal(buf)
506 finally
507 call delete('Xtestscript')
508 endtry
Christian Brabandt56824432024-02-28 21:24:25 +0100509
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100510 let nr += 1
511 let pagename = printf('dumps/%s_%02d.dump', root, nr)
512
513 while filereadable(pagename)
514 call add(disused_pages, pagename)
515 let nr += 1
516 let pagename = printf('dumps/%s_%02d.dump', root, nr)
517 endwhile
518
Christian Brabandt56824432024-02-28 21:24:25 +0100519 " redraw here to avoid the following messages to get mixed up with screen
520 " output.
521 redraw
522
523 " Add any assert errors to s:messages.
524 if len(v:errors) > 0
525 call extend(s:messages, v:errors)
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100526 if last_test_status == 'passed'
527 call EraseLineAndReturnCarriage('Test ' .. root .. ' OK')
528 else
529 echon "\n"
530 endif
Christian Brabandt56824432024-02-28 21:24:25 +0100531 " Echo the errors here, in case the script aborts or the "messages" file
532 " is not displayed later.
533 echomsg v:errors
534 let v:errors = []
535 let fail += 1
536 endif
537
538 if fail == 0
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100539 if last_test_status == 'skipped'
540 echon "\n"
541 endif
542 let last_test_status = 'passed'
543 let msg = "Test " .. root .. " OK"
544 call Message(msg)
545 call EraseLineAndReturnCarriage(msg)
Christian Brabandt56824432024-02-28 21:24:25 +0100546
547 call writefile(['OK'], 'done/' .. root)
548
549 let ok_count += 1
550 else
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100551 let last_test_status = 'failed'
Christian Brabandt56824432024-02-28 21:24:25 +0100552 call Message("Test " .. root .. " FAILED")
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100553 echon "\n"
Christian Brabandt56824432024-02-28 21:24:25 +0100554
555 call delete('done/' .. root)
556
557 eval failed_tests->add(root)
558 if len(failed_tests) > MAX_FAILED_COUNT
559 call Message('')
560 call Message('Too many errors, aborting')
561 endif
562 endif
563 else
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100564 if last_test_status == 'passed'
565 call EraseLineAndReturnCarriage('Test ' .. root .. ' OK')
566 endif
567 let last_test_status = 'skipped'
Christian Brabandt56824432024-02-28 21:24:25 +0100568 call Message("Test " .. root .. " skipped")
569 let skipped_count += 1
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +0100570 endif
Christian Brabandt56824432024-02-28 21:24:25 +0100571
572 " Append messages to the file "testdir/messages"
573 call AppendMessages('Input file ' .. fname .. ':')
574
575 if len(failed_tests) > MAX_FAILED_COUNT
576 break
577 endif
578 endfor
579
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100580 if last_test_status == 'passed' && exists('root')
581 call EraseLineAndReturnCarriage('Test ' .. root .. ' OK')
582 endif
583
Christian Brabandt56824432024-02-28 21:24:25 +0100584 call Message(s:test_run_message)
585 call Message('OK: ' .. ok_count)
586 call Message('FAILED: ' .. len(failed_tests) .. ': ' .. string(failed_tests))
587 call Message('skipped: ' .. skipped_count)
Aliaksei Budaveid33afe12024-08-12 18:37:15 +0200588
Aliaksei Budaveib5459ee2025-03-23 10:42:23 +0100589 for pagename in disused_pages
590 call Message(printf('No input page found for "%s"', pagename))
591 endfor
592
Aliaksei Budaveid33afe12024-08-12 18:37:15 +0200593 if !empty(failed_tests)
594 call Message('')
595 call Message('View generated screendumps with "../../src/vim --clean -S testdir/viewdumps.vim"')
596 endif
597
Christian Brabandt203c7222024-10-29 20:21:42 +0100598 call AppendMessages('== SUMMARY SYNTAX TESTS ==')
Christian Brabandt56824432024-02-28 21:24:25 +0100599
600 if len(failed_tests) > 0
601 " have make report an error
602 cquit
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +0100603 endif
Christian Brabandt56824432024-02-28 21:24:25 +0100604endfunc
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +0100605
Christian Brabandt56824432024-02-28 21:24:25 +0100606call RunTest()
Christian Brabandt627c9502024-02-10 13:02:17 +0100607
608" Matching "if 1" at the start.
609endif
610
Bram Moolenaar46acad72023-06-11 19:04:18 +0100611qall!
Christian Brabandt56824432024-02-28 21:24:25 +0100612
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100613" vim:sw=2:ts=8:noet: