blob: 4152702c2076855fd67d0a58a131a0d561992759 [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
392 let failed_tests = []
393 let skipped_count = 0
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100394 let last_test_status = 'invalid'
Aliaksei Budaveif6069a72024-03-05 22:34:36 +0300395 " Create a map of setup configuration filenames with their basenames as keys.
396 let setup = glob('input/setup/*.vim', 1, 1)
397 \ ->reduce({d, f -> extend(d, {fnamemodify(f, ':t:r'): f})}, {})
Aliaksei Budaveiec022942024-10-06 16:57:33 +0200398 " Turn a subset of filenames etc. requested for testing into a pattern.
399 let filter = filereadable('../testdir/Xfilter')
400 \ ? readfile('../testdir/Xfilter')
Aliaksei Budavei6852e5c2025-03-07 19:12:45 +0100401 \ ->map({_, v -> '^' .. substitute(v, '_$', '', '')})
Aliaksei Budaveiec022942024-10-06 16:57:33 +0200402 \ ->join('\|')
403 \ : ''
Aliaksei Budaveif6069a72024-03-05 22:34:36 +0300404
Aliaksei Budavei7ceca3e2025-03-16 20:59:28 +0100405 " Treat "^self-testing" as a string NOT as a regexp.
406 if filter ==# '^self-testing'
Aliaksei Budaveid2f49872024-05-24 19:14:16 +0300407 let dirpath = 'input/selftestdir/'
Aliaksei Budaveid33afe12024-08-12 18:37:15 +0200408 let fnames = readdir(dirpath, {fname -> fname !~ '^README\.txt$'})
Aliaksei Budaveid2f49872024-05-24 19:14:16 +0300409 else
410 let dirpath = 'input/'
Aliaksei Budaveiec022942024-10-06 16:57:33 +0200411 let filter ..= exists("$VIM_SYNTAX_TEST_FILTER") &&
412 \ !empty($VIM_SYNTAX_TEST_FILTER)
413 \ ? (empty(filter) ? '' : '\|') .. $VIM_SYNTAX_TEST_FILTER
414 \ : ''
415 let fnames = readdir(dirpath,
416 \ {subset -> {fname -> fname !~ '\~$' && fname =~# subset}}(
417 \ empty(filter) ? '^.\+\..\+$' : filter))
Aliaksei Budaveid2f49872024-05-24 19:14:16 +0300418 endif
Bram Moolenaar7d0dbd02023-06-24 00:56:50 +0100419
Aliaksei Budaveid2f49872024-05-24 19:14:16 +0300420 for fname in fnames
421 let root = fnamemodify(fname, ':r')
422 let fname = dirpath .. fname
Bram Moolenaar46acad72023-06-11 19:04:18 +0100423
Christian Brabandt56824432024-02-28 21:24:25 +0100424 " Execute the test if the "done" file does not exist or when the input file
425 " is newer.
426 let in_time = getftime(fname)
427 let out_time = getftime('done/' .. root)
428 if out_time < 0 || in_time > out_time
429 call ch_log('running tests for: ' .. fname)
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100430 let filetype = substitute(root, '\([^_.]*\)[_.].*', '\1', '')
431 let failed_root = 'failed/' .. root
Bram Moolenaar7d0dbd02023-06-24 00:56:50 +0100432
Christian Brabandt56824432024-02-28 21:24:25 +0100433 for dumpname in glob(failed_root .. '_\d*\.dump', 1, 1)
434 call delete(dumpname)
435 endfor
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +0100436 call delete('done/' .. root)
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100437 call writefile(XTESTSCRIPT, 'Xtestscript')
Christian Brabandt56824432024-02-28 21:24:25 +0100438
439 " close all but the last window
440 while winnr('$') > 1
441 close
442 endwhile
443
444 " Redraw to make sure that messages are cleared and there is enough space
445 " for the terminal window.
446 redraw
447
Aliaksei Budavei93edd252024-03-05 22:34:36 +0300448 " Let "Xtestscript#SetUpVim()" turn the syntax on.
Aliaksei Budaveif6069a72024-03-05 22:34:36 +0300449 let prefix = '-Nu NONE -S Xtestscript'
450 let path = get(setup, root, '')
451 " Source the found setup configuration file.
452 let args = !empty(path)
453 \ ? prefix .. ' -S ' .. path
454 \ : prefix
455 let buf = RunVimInTerminal(args, {})
Christian Brabandt56824432024-02-28 21:24:25 +0100456 " edit the file only after catching the SwapExists event
457 call term_sendkeys(buf, ":edit " .. fname .. "\<CR>")
Aliaksei Budavei93edd252024-03-05 22:34:36 +0300458 " set up the testing environment
459 call term_sendkeys(buf, ":call SetUpVim()\<CR>")
Christian Brabandt56824432024-02-28 21:24:25 +0100460 " load filetype specific settings
461 call term_sendkeys(buf, ":call LoadFiletype('" .. filetype .. "')\<CR>")
462
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100463 " Make a synchronisation point between buffers by requesting to echo
464 " a known token in the terminal buffer and asserting its availability
465 " with "s:TermWaitAndPollRuler()".
Christian Brabandt56824432024-02-28 21:24:25 +0100466 if filetype == 'sh'
467 call term_sendkeys(buf, ":call ShellInfo()\<CR>")
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100468 else
469 call term_sendkeys(buf, ":echo 'is_nonce'\<CR>")
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +0100470 endif
Christian Brabandt56824432024-02-28 21:24:25 +0100471
Christian Brabandt56824432024-02-28 21:24:25 +0100472 let root_00 = root .. '_00'
Aliaksei Budavei84184462024-05-21 01:10:26 +0300473 let in_name_and_out_name = fname .. ': failed/' .. root_00 .. '.dump'
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100474 " Queue up all "term_sendkeys()"es and let them finish before returning
475 " from "s:TermWaitAndPollRuler()".
476 let ruler = s:TermWaitAndPollRuler(buf, in_name_and_out_name)
Aliaksei Budavei84184462024-05-21 01:10:26 +0300477 call ch_log('First screendump for ' .. in_name_and_out_name)
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100478 " Make a screendump at the start of the file: failed/root_00.dump
Aliaksei Budavei7ceca3e2025-03-16 20:59:28 +0100479 let fail = VerifyScreenDump(buf, root_00, DUMP_OPTS)
Christian Brabandt56824432024-02-28 21:24:25 +0100480
Aliaksei Budavei71971432024-07-05 21:30:02 +0300481 " Accommodate the next code block to "buf"'s contingency for self
482 " wipe-out.
483 try
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100484 let nr = 0
485 let keys_a = ":call ScrollToSecondPage((18 * 75 + 1), 19, 5) | redraw!\<CR>"
486 let keys_b = ":call ScrollToNextPage((18 * 75 + 1), 19, 5) | redraw!\<CR>"
487 while s:CannotSeeLastLine(ruler)
488 call term_sendkeys(buf, keys_a)
489 let keys_a = keys_b
Aliaksei Budavei84184462024-05-21 01:10:26 +0300490 let nr += 1
491 let root_next = printf('%s_%02d', root, nr)
492 let in_name_and_out_name = fname .. ': failed/' .. root_next .. '.dump'
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100493 let ruler = s:TermPollRuler(
494 \ function('s:CannotDumpNextPage', [buf, ruler]),
495 \ buf,
496 \ in_name_and_out_name)
497 call ch_log('Next screendump for ' .. in_name_and_out_name)
498 " Make a screendump of every 18 lines of the file: failed/root_NN.dump
Aliaksei Budavei7ceca3e2025-03-16 20:59:28 +0100499 let fail += VerifyScreenDump(buf, root_next, DUMP_OPTS)
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100500 endwhile
Aliaksei Budavei71971432024-07-05 21:30:02 +0300501 call StopVimInTerminal(buf)
502 finally
503 call delete('Xtestscript')
504 endtry
Christian Brabandt56824432024-02-28 21:24:25 +0100505
506 " redraw here to avoid the following messages to get mixed up with screen
507 " output.
508 redraw
509
510 " Add any assert errors to s:messages.
511 if len(v:errors) > 0
512 call extend(s:messages, v:errors)
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100513 if last_test_status == 'passed'
514 call EraseLineAndReturnCarriage('Test ' .. root .. ' OK')
515 else
516 echon "\n"
517 endif
Christian Brabandt56824432024-02-28 21:24:25 +0100518 " Echo the errors here, in case the script aborts or the "messages" file
519 " is not displayed later.
520 echomsg v:errors
521 let v:errors = []
522 let fail += 1
523 endif
524
525 if fail == 0
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100526 if last_test_status == 'skipped'
527 echon "\n"
528 endif
529 let last_test_status = 'passed'
530 let msg = "Test " .. root .. " OK"
531 call Message(msg)
532 call EraseLineAndReturnCarriage(msg)
Christian Brabandt56824432024-02-28 21:24:25 +0100533
534 call writefile(['OK'], 'done/' .. root)
535
536 let ok_count += 1
537 else
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100538 let last_test_status = 'failed'
Christian Brabandt56824432024-02-28 21:24:25 +0100539 call Message("Test " .. root .. " FAILED")
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100540 echon "\n"
Christian Brabandt56824432024-02-28 21:24:25 +0100541
542 call delete('done/' .. root)
543
544 eval failed_tests->add(root)
545 if len(failed_tests) > MAX_FAILED_COUNT
546 call Message('')
547 call Message('Too many errors, aborting')
548 endif
549 endif
550 else
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100551 if last_test_status == 'passed'
552 call EraseLineAndReturnCarriage('Test ' .. root .. ' OK')
553 endif
554 let last_test_status = 'skipped'
Christian Brabandt56824432024-02-28 21:24:25 +0100555 call Message("Test " .. root .. " skipped")
556 let skipped_count += 1
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +0100557 endif
Christian Brabandt56824432024-02-28 21:24:25 +0100558
559 " Append messages to the file "testdir/messages"
560 call AppendMessages('Input file ' .. fname .. ':')
561
562 if len(failed_tests) > MAX_FAILED_COUNT
563 break
564 endif
565 endfor
566
Aliaksei Budaveif63c3462025-03-08 16:58:17 +0100567 if last_test_status == 'passed' && exists('root')
568 call EraseLineAndReturnCarriage('Test ' .. root .. ' OK')
569 endif
570
Christian Brabandt56824432024-02-28 21:24:25 +0100571 call Message(s:test_run_message)
572 call Message('OK: ' .. ok_count)
573 call Message('FAILED: ' .. len(failed_tests) .. ': ' .. string(failed_tests))
574 call Message('skipped: ' .. skipped_count)
Aliaksei Budaveid33afe12024-08-12 18:37:15 +0200575
576 if !empty(failed_tests)
577 call Message('')
578 call Message('View generated screendumps with "../../src/vim --clean -S testdir/viewdumps.vim"')
579 endif
580
Christian Brabandt203c7222024-10-29 20:21:42 +0100581 call AppendMessages('== SUMMARY SYNTAX TESTS ==')
Christian Brabandt56824432024-02-28 21:24:25 +0100582
583 if len(failed_tests) > 0
584 " have make report an error
585 cquit
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +0100586 endif
Christian Brabandt56824432024-02-28 21:24:25 +0100587endfunc
Bram Moolenaar1aa5f1c2023-06-22 21:57:51 +0100588
Christian Brabandt56824432024-02-28 21:24:25 +0100589call RunTest()
Christian Brabandt627c9502024-02-10 13:02:17 +0100590
591" Matching "if 1" at the start.
592endif
593
Bram Moolenaar46acad72023-06-11 19:04:18 +0100594qall!
Christian Brabandt56824432024-02-28 21:24:25 +0100595
Aliaksei Budavei7003a5d2025-03-01 16:28:20 +0100596" vim:sw=2:ts=8:noet: