@@ -15,6 +15,17 @@ let s:messagesFname = fnameescape(syntaxDir .. '/testdir/messages')
1515
1616let s: messages = []
1717
18+ " Erase the cursor line and do not advance the cursor.
19+ def EraseLineAndReturnCarriage (rname: string )
20+ const full_width: number = winwidth (0 )
21+ const half_width: number = full_width - (full_width + 1 ) / 2
22+ if (strlen (rname) + strlen (' Test' .. " \x20\x20 " .. ' FAILED' )) > half_width
23+ echon " \r " .. repeat (" \x20 " , full_width) .. " \r "
24+ else
25+ echon repeat (" \x20 " , half_width) .. " \r "
26+ endif
27+ enddef
28+
1829" Add one message to the list of messages
1930func Message (msg)
2031 echomsg a: msg
@@ -30,22 +41,23 @@ endfunc
3041
3142" Append s:messages to the messages file and make it empty.
3243func AppendMessages (header)
33- exe ' split ' .. s: messagesFname
44+ silent exe ' split ' .. s: messagesFname
3445 call append (line (' $' ), ' ' )
3546 call append (line (' $' ), a: header )
3647 call append (line (' $' ), s: messages )
3748 let s: messages = []
38- wq
49+ silent wq
3950endfunc
4051
4152" Relevant messages are written to the "messages" file.
4253" If the file already exists it is appended to.
43- exe ' split ' .. s: messagesFname
54+ silent exe ' split ' .. s: messagesFname
4455call append (line (' $' ), repeat (' =-' , 70 ))
4556call append (line (' $' ), ' ' )
4657let s: test_run_message = ' Test run on ' .. strftime (" %Y %b %d %H:%M:%S" )
4758call append (line (' $' ), s: test_run_message )
48- wq
59+ silent wq
60+ echo " \n "
4961
5062if syntaxDir !~ ' [/\\]runtime[/\\]syntax\>'
5163 call Fatal (' Current directory must be "runtime/syntax"' )
@@ -88,26 +100,127 @@ func HandleSwapExists()
88100 endif
89101endfunc
90102
91- def IsWinNumOneAtEOF (in_name_and_out_name: string ): bool
92- # Expect defaults from term_util#RunVimInTerminal ().
103+ " Trace ruler liveness on demand.
104+ if ! empty ($VIM_SYNTAX_TEST_LOG ) && filewritable ($VIM_SYNTAX_TEST_LOG )
105+ def s: TraceRulerLiveness (context: string , times: number , tail: string )
106+ writefile ([printf (' %s: %4d: %s' , context, times, tail)],
107+ $VIM_SYNTAX_TEST_LOG ,
108+ ' a' )
109+ enddef
110+ else
111+ def s: TraceRulerLiveness (_: string , _: number , _: string )
112+ enddef
113+ endif
114+
115+ " See ":help 'ruler'".
116+ def s: CannotSeeLastLine (ruler : list <string> ): bool
117+ return ! (get (ruler , -1 , ' ' ) == # ' All' || get (ruler , -1 , ' ' ) == # ' Bot' )
118+ enddef
119+
120+ def s: CannotDumpNextPage (buf : number , prev_ruler: list <string> , ruler : list <string> ): bool
121+ return ! (ruler !=# prev_ruler &&
122+ len (ruler ) == 2 &&
123+ ruler [1 ] = ~# ' \%(\d%\|\<Bot\)$' &&
124+ get (term_getcursor (buf ), 0 ) != 20 )
125+ enddef
126+
127+ def s: CannotDumpFirstPage (buf : number , _: list <string> , ruler : list <string> ): bool
128+ return ! (len (ruler ) == 2 &&
129+ ruler [1 ] = ~# ' \%(\<All\|\<Top\)$' &&
130+ get (term_getcursor (buf ), 0 ) != 20 )
131+ enddef
132+
133+ def s: CannotDumpShellFirstPage (buf : number , _: list <string> , ruler : list <string> ): bool
134+ return ! (len (ruler ) > 3 &&
135+ get (ruler , -1 , ' ' ) = ~# ' \%(\<All\|\<Top\)$' &&
136+ get (term_getcursor (buf ), 0 ) != 20 )
137+ enddef
138+
139+ " Poll for updates of the cursor position in the terminal buffer occupying the
140+ " first window. (ALWAYS call the function or its equivalent before calling
141+ " "VerifyScreenDump()" *and* after calling any number of "term_sendkeys()".)
142+ def s: TermPollRuler (
143+ CannotDumpPage: func , # (TYPE FOR LEGACY CONTEXT CALL SITES.)
144+ buf : number ,
145+ in_name_and_out_name: string ): list <string>
146+ # Expect defaults from " term_util#RunVimInTerminal()" .
93147 if winwidth (1 ) != 75 || winheight (1 ) != 20
94148 ch_log (printf (' Aborting for %s: (75 x 20) != (%d x %d)' ,
95149 in_name_and_out_name,
96150 winwidth (1 ),
97151 winheight (1 )))
98- return true
152+ return [ ' 0,0-1 ' , ' All ' ]
99153 endif
100- # A two- fold role: ( 1 ) redraw whenever the first test file is of 19 lines or
101- # less long (not applicable to c . c ); ( 2 ) redraw in case the terminal buffer
102- # cannot redraw itself just yet ( else expect extra files generated) .
154+ # A two- fold role for redrawin g:
155+ # ( * ) in case the terminal buffer cannot redraw itself just yet;
156+ # ( * ) to avoid extra " real estate " checks .
103157 redraw
104- const pos: string = join ([
105- screenstring (20 , 71 ),
106- screenstring (20 , 72 ),
107- screenstring (20 , 73 ),
108- screenstring (20 , 74 ),
109- screenstring (20 , 75 )], ' ' )
110- return (pos == ' All ' || pos == ' Bot ' )
158+ # The contents of " ruler" .
159+ var ruler : list <string> = []
160+ # Attempts at most, targeting ASan- instrumented Vim builds.
161+ var times: number = 2048
162+ # Check " real estate" of the terminal buffer . Read and compare its ruler
163+ # line and let " Xtestscript#s:AssertCursorForwardProgress()" do the rest.
164+ # Note that the cursor ought to be advanced after each successive call of
165+ # this function yet its relative position need not be changed (e .g . " 0%" ).
166+ while CannotDumpPage (ruler ) && times > 0
167+ ruler = split (term_getline (buf , 20 ))
168+ sleep 1 m
169+ times -= 1
170+ if times % 8 == 0
171+ redraw
172+ endif
173+ endwhile
174+ TraceRulerLiveness (' P' , (2048 - times), in_name_and_out_name)
175+ return ruler
176+ enddef
177+
178+ " Prevent "s:TermPollRuler()" from prematurely reading the cursor position,
179+ " which is available at ":edit", after outracing the loading of syntax etc. in
180+ " the terminal buffer. (Call the function before calling "VerifyScreenDump()"
181+ " for the first time.)
182+ def s: TermWaitAndPollRuler (buf : number , in_name_and_out_name: string ): list <string>
183+ # Expect defaults from " term_util#RunVimInTerminal()" .
184+ if winwidth (1 ) != 75 || winheight (1 ) != 20
185+ ch_log (printf (' Aborting for %s: (75 x 20) != (%d x %d)' ,
186+ in_name_and_out_name,
187+ winwidth (1 ),
188+ winheight (1 )))
189+ return [' 0,0-1' , ' All' ]
190+ endif
191+ # The contents of " ruler" .
192+ var ruler : string = ' '
193+ # Attempts at most, targeting ASan- instrumented Vim builds.
194+ var times: number = 32768
195+ # Check " real estate" of the terminal buffer . Expect a known token to be
196+ # rendered in the terminal buffer ; its prefix must be " is_" so that buffer
197+ # variables from " sh.vim" can be matched (see " Xtestscript#ShellInfo()" ).
198+ # Verify that the whole line is available!
199+ while ruler !~# ' ^is_.\+\s\%(All\|Top\)$' && times > 0
200+ ruler = term_getline (buf , 20 )
201+ sleep 1 m
202+ times -= 1
203+ if times % 16 == 0
204+ redraw
205+ endif
206+ endwhile
207+ TraceRulerLiveness (' W' , (32768 - times), in_name_and_out_name)
208+ if strpart (ruler , 0 , 8 ) !=# ' is_nonce'
209+ # Retain any of " b:is_(bash|dash|kornshell|posix|sh)" entries and let
210+ # " CannotDumpShellFirstPage()" win the cursor race.
211+ return TermPollRuler (
212+ function (CannotDumpShellFirstPage, [buf , []]),
213+ buf ,
214+ in_name_and_out_name)
215+ else
216+ # Clear the " is_nonce" token and let " CannotDumpFirstPage()" win any
217+ # race.
218+ term_sendkeys (buf , " :redraw!\<CR> " )
219+ endif
220+ return TermPollRuler (
221+ function (CannotDumpFirstPage, [buf , []]),
222+ buf ,
223+ in_name_and_out_name)
111224enddef
112225
113226func RunTest ()
@@ -337,41 +450,44 @@ func RunTest()
337450 " load filetype specific settings
338451 call term_sendkeys (buf , " :call LoadFiletype('" .. filetype .. " ')\<CR> " )
339452
453+ " Make a synchronisation point between buffers by requesting to echo
454+ " a known token in the terminal buffer and asserting its availability
455+ " with "s:TermWaitAndPollRuler()".
340456 if filetype == ' sh'
341457 call term_sendkeys (buf , " :call ShellInfo()\<CR> " )
458+ else
459+ call term_sendkeys (buf , " :echo 'is_nonce'\<CR> " )
342460 endif
343461
344- " Screendump at the start of the file: failed/root_00.dump
345462 let root_00 = root .. ' _00'
346463 let in_name_and_out_name = fname .. ' : failed/' .. root_00 .. ' .dump'
464+ " Queue up all "term_sendkeys()"es and let them finish before returning
465+ " from "s:TermWaitAndPollRuler()".
466+ let ruler = s: TermWaitAndPollRuler (buf , in_name_and_out_name)
347467 call ch_log (' First screendump for ' .. in_name_and_out_name)
468+ " Make a screendump at the start of the file: failed/root_00.dump
348469 let fail = VerifyScreenDump (buf , root_00, {})
349470
350- " Make a Screendump every 18 lines of the file: failed/root_NN.dump
351- let nr = 1
352- let root_next = printf (' %s_%02d' , root, nr)
353- let in_name_and_out_name = fname .. ' : failed/' .. root_next .. ' .dump'
354-
355471 " Accommodate the next code block to "buf"'s contingency for self
356472 " wipe-out.
357473 try
358- if ! IsWinNumOneAtEOF (in_name_and_out_name)
359- call term_sendkeys (buf , " :call ScrollToSecondPage((18 * 75 + 1), 19, 5) | redraw!\<CR> " )
360- call ch_log (' Next screendump for ' .. in_name_and_out_name)
361- let fail += VerifyScreenDump (buf , root_next, {})
474+ let nr = 0
475+ let keys_a = " :call ScrollToSecondPage((18 * 75 + 1), 19, 5) | redraw!\<CR> "
476+ let keys_b = " :call ScrollToNextPage((18 * 75 + 1), 19, 5) | redraw!\<CR> "
477+ while s: CannotSeeLastLine (ruler )
478+ call term_sendkeys (buf , keys_a)
479+ let keys_a = keys_b
362480 let nr += 1
363481 let root_next = printf (' %s_%02d' , root, nr)
364482 let in_name_and_out_name = fname .. ' : failed/' .. root_next .. ' .dump'
365-
366- while ! IsWinNumOneAtEOF (in_name_and_out_name)
367- call term_sendkeys (buf , " :call ScrollToNextPage((18 * 75 + 1), 19, 5) | redraw!\<CR> " )
368- call ch_log (' Next screendump for ' .. in_name_and_out_name)
369- let fail += VerifyScreenDump (buf , root_next, {})
370- let nr += 1
371- let root_next = printf (' %s_%02d' , root, nr)
372- let in_name_and_out_name = fname .. ' : failed/' .. root_next .. ' .dump'
373- endwhile
374- endif
483+ let ruler = s: TermPollRuler (
484+ \ function (' s:CannotDumpNextPage' , [buf , ruler ]),
485+ \ buf ,
486+ \ in_name_and_out_name)
487+ call ch_log (' Next screendump for ' .. in_name_and_out_name)
488+ " Make a screendump of every 18 lines of the file: failed/root_NN.dump
489+ let fail += VerifyScreenDump (buf , root_next, {})
490+ endwhile
375491 call StopVimInTerminal (buf )
376492 finally
377493 call delete (' Xtestscript' )
@@ -413,6 +529,8 @@ func RunTest()
413529 let skipped_count += 1
414530 endif
415531
532+ call EraseLineAndReturnCarriage (root)
533+
416534 " Append messages to the file "testdir/messages"
417535 call AppendMessages (' Input file ' .. fname .. ' :' )
418536
@@ -421,6 +539,7 @@ func RunTest()
421539 endif
422540 endfor
423541
542+ call EraseLineAndReturnCarriage (' ' )
424543 call Message (s: test_run_message )
425544 call Message (' OK: ' .. ok_count)
426545 call Message (' FAILED: ' .. len (failed_tests) .. ' : ' .. string (failed_tests))
@@ -446,4 +565,4 @@ endif
446565
447566qall !
448567
449- " vim:ts = 8
568+ " vim:sw = 2 : ts = 8 : noet :
0 commit comments