0
0
mirror of https://github.com/vim/vim.git synced 2025-07-26 11:04:33 -04:00

patch 8.0.1526: no test using a screen dump yet

Problem:    No test using a screen dump yet.
Solution:   Add a test for C syntax highlighting.  Add helper functions.
This commit is contained in:
Bram Moolenaar 2018-02-20 15:51:40 +01:00
parent 7a76092a51
commit da65058a9c
8 changed files with 266 additions and 30 deletions

View File

@ -1,4 +1,4 @@
*terminal.txt* For Vim version 8.0. Last change: 2018 Jan 28
*terminal.txt* For Vim version 8.0. Last change: 2018 Feb 20
VIM REFERENCE MANUAL by Bram Moolenaar
@ -25,7 +25,11 @@ If the result is "1" you have it.
Unix |terminal-unix|
MS-Windows |terminal-ms-windows|
2. Remote testing |terminal-testing|
3. Debugging |terminal-debug|
3. Diffing screen dumps |terminal-diff|
Writing a screen dump test for Vim |terminal-dumptest|
Creating a screen dump |terminal-screendump|
Comparing screen dumps |terminal-diffscreendump|
4. Debugging |terminal-debug|
Starting |termdebug-starting|
Example session |termdebug-example|
Stepping through code |termdebug-stepping|
@ -360,7 +364,97 @@ term_scrape() inspect terminal screen
==============================================================================
3. Debugging *terminal-debug*
3. Diffing screen dumps *terminal-diff*
In some cases it can be bothersome to test that Vim displays the right
characters on the screen. E.g. with syntax highlighting. To make this
simpler it is possible to take a screen dump of a terminal and compare it to
an expected screen dump.
Vim uses the window size, text, color and other attributes as displayed. The
Vim screen size, font and other properties do not matter. Therefore this
mechanism is portable across systems. A convential screenshot would reflect
all differences, including font size and family.
Writing a screen dump test for Vim ~
*terminal-dumptest*
For an example see the Test_syntax_c() function in
src/testdir/test_syntax.vim. The main parts are:
- Write a file you want to test with. This is useful for testing syntax
highlighting. You can also start Vim with en empty buffer.
- Run Vim in a terminal with a specific size. The default is 20 lines of 75
characters. This makes sure the dump is always this size. The function
RunVimInTerminal() takes care of this. Pass it the arguments for the Vim
command.
- Send any commands to Vim using term_sendkeys(). For example: >
call term_sendkeys(buf, ":echo &lines &columns\<CR>")
- Check that the screen is now in the expected state, using
VerifyScreenDump(). This expects the reference screen dump to be in the
src/testdir/dumps/ directory. Pass the name without ".dump". It is
recommended to use the name of the test function and a sequence number, so
that we know what test is using the file.
- Repeat sending commands and checking the state.
- Finally stop Vim by calling StopVimInTerminal().
The first time you do this you won't have a screen dump yet. Create an empty
file for now, e.g.: >
touch src/testdir/dumps/Test_function_name_01.dump
The test will then fail, giving you the command to compare the reference dump
and the failed dump, e.g.: >
call term_dumpdiff("Test_func.dump.failed", "dumps/Test_func.dump")
Use this command in Vim, with the current directory set to src/testdir.
Once you are satisfied with the test, move the failed dump in place of the
reference: >
:!mv Test_func.dump.failed dumps/Test_func.dump
Creating a screen dump ~
*terminal-screendump*
To create the screen dump, run Vim (or any other program) in a terminal and
make it show the desired state. Then use the term_dumpwrite() function to
create a screen dump file. For example: >
:call term_dumpwrite(77, "mysyntax.dump")
Here "77" is the buffer number of the terminal. Use `:ls!` to see it.
You can view the screen dump with term_dumpload(): >
:call term_dumpload("mysyntax.dump")
To verify that Vim still shows exactly the same screen, run Vim again with
exactly the same way to show the desired state. Then create a screen dump
again, using a different file name: >
:call term_dumpwrite(88, "test.dump")
To assert that the files are exactly the same use assert_equalfile(): >
call assert_equalfile("mysyntax.dump", "test.dump")
If there are differences then v:errors will contain the error message.
Comparing screen dumps ~
*terminal-diffscreendump*
assert_equalfile() does not make it easy to see what is different.
To spot the problem use term_dumpdiff(): >
call term_dumpdiff("mysyntax.dump", "test.dump")
This will open a window consisting of three parts:
1. The contents of the first dump
2. The difference between the first and second dump
3. The contents of the second dump
You can usually see what differs in the second part. Use the 'ruler' to
relate it to the postion in the first or second dump.
Alternatively, press "s" to swap the first and second dump. Do this everal
times so that you can spot the difference in the context of the text.
==============================================================================
4. Debugging *terminal-debug*
The Terminal debugging plugin can be used to debug a program with gdb and view
the source code in a Vim window. Since this is completely contained inside

View File

@ -410,10 +410,13 @@ term_start(typval_T *argvar, jobopt_T *opt, int without_job, int forceit)
if (!opt->jo_hidden)
{
/* only one size was taken care of with :new, do the other one */
if (opt->jo_term_rows > 0 && (cmdmod.split & WSP_VERT))
/* Only one size was taken care of with :new, do the other one. With
* "curwin" both need to be done. */
if (opt->jo_term_rows > 0 && (opt->jo_curwin
|| (cmdmod.split & WSP_VERT)))
win_setheight(opt->jo_term_rows);
if (opt->jo_term_cols > 0 && !(cmdmod.split & WSP_VERT))
if (opt->jo_term_cols > 0 && (opt->jo_curwin
|| !(cmdmod.split & WSP_VERT)))
win_setwidth(opt->jo_term_cols);
}

View File

@ -35,6 +35,12 @@ What you can use (see test_assert.vim for an example):
- See the start of runtest.vim for more help.
TO ADD A SCREEN DUMP TEST:
Mostly the same as writing a new style test. Additonally, see help on
"terminal-dumptest". Put the reference dump in "dumps/Test_func_name.dump".
TO ADD AN OLD STYLE TEST:
1) Create test_<subject>.in and test_<subject>.ok files.

View File

@ -0,0 +1,20 @@
|/+0#0000e05#ffffff16|*| |c|o|m@1|e|n|t| |l|i|n|e| |a|t| |t|h|e| |t|o|p| |*|/| +0#0000001&@45
| @1|i+0#00e0003&|n|t| +0#0000001&@69
|m|a|i|n|(|i+0#00e0003&|n|t| +0#0000001&|a|r|g|c|,| |c+0#00e0003&|h|a|r| +0#0000001&|*@1|a|r|g|v|)|/+0#0000e05&@1| |a|n|o|t|h|e|r| |c|o|m@1|e|n|t| +0#0000001&@29
|{| @73
|#+0#e000e06&|i|f| |0| +0#0000001&@69
| +0#0000e05&@2|i|n|t| @2|n|o|t|_|u|s|e|d|;| +0#0000001&@56
|#+0#e000e06&|e|l|s|e| +0#0000001&@69
| @2|i+0#00e0003&|n|t| +0#0000001&@2|u|s|e|d|;| @60
|#+0#e000e06&|e|n|d|i|f| +0#0000001&@68
| @2|p|r|i|n|t|f|(|"+0#e000002&|J|u|s|t| |a|n| |e|x|a|m|p|l|e| |p|i|e|c|e| |o|f| |C| |c|o|d|e|\+0#e000e06&|n|"+0#e000002&|)+0#0000001&|;| @27
| @2|r+0#af5f00255&|e|t|u|r|n| +0#0000001&|0+0#e000002&|x|0|f@1|;+0#0000001&| @58
|}| @73
| @2|s+0#00e0003&|t|a|t|i|c| +0#0000001&|v+0#00e0003&|o|i|d| +0#0000001&@60
|m|y|F|u|n|c|t|i|o|n|(|c+0#00e0003&|o|n|s|t| +0#0000001&|d+0#00e0003&|o|u|b|l|e| +0#0000001&|c|o|u|n|t|,| |s+0#00e0003&|t|r|u|c|t| +0#0000001&|n|o|t|h|i|n|g|,| |l+0#00e0003&|o|n|g| +0#0000001&|t|h|e|r|e|)| |{| @14
| @1|/+0#0000e05&@1| |1+0#e000002&|2|3|:+0#0000e05&| |n|o|t|h|i|n|g| |t|o| |r|e|a|d| |h|e|r|e| +0#0000001&@44
| @1|f+0#af5f00255&|o|r| +0#0000001&|(|i+0#00e0003&|n|t| +0#0000001&|i| |=| |0+0#e000002&|;+0#0000001&| |i| |<| |c|o|u|n|t|;| |+@1|i|)| |{| @39
| @3|b+0#af5f00255&|r|e|a|k|;+0#0000001&| @64
| @1|}| @71
|}| @73
|"|X|t|e|s|t|.|c|"| |1|9|L|,| |3|6|4|C| @37|1|,|1| @10|A|l@1|

View File

@ -0,0 +1,65 @@
" Functions shared by tests making screen dumps.
" Only load this script once.
if exists('*RunVimInTerminal')
finish
endif
source shared.vim
" Run Vim with "arguments" in a new terminal window.
" By default uses a size of 20 lines and 75 columns.
" Returns the buffer number of the terminal.
"
" Options is a dictionary (not used yet).
func RunVimInTerminal(arguments, options)
" Make a horizontal and vertical split, so that we can get exactly the right
" size terminal window. Works only when we currently have one window.
call assert_equal(1, winnr('$'))
split
vsplit
" Always doo this with 256 colors and a light background.
set t_Co=256
hi Normal ctermfg=0 ctermbg=15
let cmd = GetVimCommandClean()
let cmd .= ' ' . a:arguments
let buf = term_start(cmd, {'curwin': 1, 'term_rows': 20, 'term_cols': 75})
call assert_equal([20, 75], term_getsize(buf))
return buf
endfunc
" Stop a Vim running in terminal buffer "buf".
func StopVimInTerminal(buf)
call assert_equal("running", term_getstatus(a:buf))
call term_sendkeys(a:buf, ":qa!\<cr>")
call WaitFor('term_getstatus(' . a:buf . ') == "finished"')
only!
endfunc
" Verify that Vim running in terminal buffer "buf" matches the screen dump.
" The file name used is "dumps/{filename}.dump".
" Will wait for up to a second for the screen dump to match.
func VerifyScreenDump(buf, filename)
let reference = 'dumps/' . a:filename . '.dump'
let testfile = a:filename . '.dump.failed'
let i = 0
while 1
call delete(testfile)
call term_dumpwrite(a:buf, testfile)
if readfile(reference) == readfile(testfile)
call delete(testfile)
break
endif
if i == 100
" Leave the test file around for inspection.
call assert_report('See dump file difference: call term_dumpdiff("' . testfile . '", "' . reference . '")')
break
endif
sleep 10m
let i += 1
endwhile
endfunc

View File

@ -178,17 +178,20 @@ endfunc
" The Makefile writes it as the first line in the "vimcmd" file.
func GetVimProg()
if !filereadable('vimcmd')
return ''
" Assume the script was sourced instead of running "make".
return '../vim'
endif
return readfile('vimcmd')[0]
endfunc
" Get the command to run Vim, with -u NONE and --not-a-term arguments.
" If there is an argument use it instead of "NONE".
" Returns an empty string on error.
func GetVimCommand(...)
if !filereadable('vimcmd')
return ''
echo 'Cannot read the "vimcmd" file, falling back to ../vim.'
let lines = ['../vim']
else
let lines = readfile('vimcmd')
endif
if a:0 == 0
let name = 'NONE'
@ -199,7 +202,6 @@ func GetVimCommand(...)
" "vimcmd" file, including environment options.
" Other Makefiles just write the executable in the first line, so fall back
" to that if there is no second line.
let lines = readfile('vimcmd')
let cmd = get(lines, 1, lines[0])
let cmd = substitute(cmd, '-u \f\+', '-u ' . name, '')
if cmd !~ '-u '. name
@ -210,6 +212,14 @@ func GetVimCommand(...)
return cmd
endfunc
" Get the command to run Vim, with --clean.
func GetVimCommandClean()
let cmd = GetVimCommand()
let cmd = substitute(cmd, '-u NONE', '--clean', '')
let cmd = substitute(cmd, '--not-a-term', '', '')
return cmd
endfunc
" Run Vim, using the "vimcmd" file and "-u NORC".
" "before" is a list of Vim commands to be executed before loading plugins.
" "after" is a list of Vim commands to be executed after loading plugins.

View File

@ -5,6 +5,9 @@ if !has("syntax")
endif
source view_util.vim
if has('terminal')
source screendump.vim
endif
func GetSyntaxItem(pat)
let c = ''
@ -497,7 +500,7 @@ func Test_conceal()
bw!
endfunc
fun Test_synstack_synIDtrans()
func Test_synstack_synIDtrans()
new
setfiletype c
syntax on
@ -520,3 +523,36 @@ fun Test_synstack_synIDtrans()
syn clear
bw!
endfunc
" Check highlighting for a small piece of C code with a screen dump.
func Test_syntax_c()
if !has('terminal')
return
endif
call writefile([
\ '/* comment line at the top */',
\ ' int',
\ 'main(int argc, char **argv)// another comment',
\ '{',
\ '#if 0',
\ ' int not_used;',
\ '#else',
\ ' int used;',
\ '#endif',
\ ' printf("Just an example piece of C code\n");',
\ ' return 0x0ff;',
\ '}',
\ ' static void',
\ 'myFunction(const double count, struct nothing, long there) {',
\ ' // 123: nothing to read here',
\ ' for (int i = 0; i < count; ++i) {',
\ ' break;',
\ ' }',
\ '}',
\ ], 'Xtest.c')
let buf = RunVimInTerminal('Xtest.c', {})
call VerifyScreenDump(buf, 'Test_syntax_c_01')
call StopVimInTerminal(buf)
call delete('Xtest.c')
endfun

View File

@ -771,6 +771,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1526,
/**/
1525,
/**/