blob: e4f3945c8f8f6c0184241bba0ea307b6d358a843 [file] [log] [blame]
Bram Moolenaar46acad72023-06-11 19:04:18 +01001Tests for syntax highlighting plugins
2=====================================
3
4Summary: Files in the "input" directory are edited by Vim with syntax
5highlighting enabled. Screendumps are generated and compared with the
6expected screendumps in the "dumps" directory. This will uncover any
7character attributes that differ.
8
Aliaksei Budaveib5a92d72024-07-07 20:51:14 +02009The dumps are normally 20 screen lines tall. Without any further setup
10a screendump is made at the top of the file (using _00.dump) and another
11screendump is made if there are more lines (using _01.dump), and so on.
Bram Moolenaar46acad72023-06-11 19:04:18 +010012
13When the screendumps are OK an empty "done/{name}" file is created. This
14avoids running the test again until "make clean" is used. Thus you can run
15"make test", see one test fail, try to fix the problem, then run "make test"
16again to only repeat the failing test.
17
18When a screendump differs it is stored in the "failed" directory. This allows
19for comparing it with the expected screendump, using a command like:
20
Aliaksei Budaveib5a92d72024-07-07 20:51:14 +020021 let fname = '{name}_00.dump'
Bram Moolenaar46acad72023-06-11 19:04:18 +010022 call term_dumpdiff('failed/' .. fname, 'dumps/' .. fname)
23
24
25Creating a syntax plugin test
26-----------------------------
27
28Create a source file in the language you want to test in the "input"
Aliaksei Budavei93edd252024-03-05 22:34:36 +030029directory. Use the filetype name as the base and a file name extension
Aliaksei Budavei84184462024-05-21 01:10:26 +030030matching the filetype. Let's use Java as an example. The file would then be
Bram Moolenaar46acad72023-06-11 19:04:18 +010031"input/java.java".
32
Aliaksei Budavei93edd252024-03-05 22:34:36 +030033Make sure to include some interesting constructs with plenty of complicated
34highlighting. Optionally, pre-configure the testing environment by including
Aliaksei Budavei84184462024-05-21 01:10:26 +030035setup commands at the top of the input file. The format for these lines is:
Aliaksei Budavei93edd252024-03-05 22:34:36 +030036
Aliaksei Budaveia2addeb2024-03-18 20:39:32 +010037 VIM_TEST_SETUP {command}
Aliaksei Budavei93edd252024-03-05 22:34:36 +030038
39where {command} is any valid Ex command, which extends to the end of the line.
40The first 20 lines of the input file are ALWAYS scanned for setup commands and
41these will be executed before the syntax highlighting is enabled. Typically,
42these lines would be included as comments so as not to introduce any syntax
43errors in the input file but this is not required.
44
45Continuing the Java example:
46
Aliaksei Budaveia2addeb2024-03-18 20:39:32 +010047 // VIM_TEST_SETUP let g:java_space_errors = 1
48 // VIM_TEST_SETUP let g:java_minlines = 5
Aliaksei Budavei93edd252024-03-05 22:34:36 +030049 class Test { }
50
Aliaksei Budaveif6069a72024-03-05 22:34:36 +030051As an alternative, setup commands can be included in an external Vim script
52file in the "input/setup" directory. This script file must have the same base
53name as the input file.
54
55So, the equivalent example configuration using this method would be to create
56an "input/setup/java.vim" script file with the following lines:
57
58 let g:java_space_errors = 1
59 let g:java_minlines = 5
60
61Both inline setup commands and setup scripts may be used at the same time, the
Aliaksei Budaveia2addeb2024-03-18 20:39:32 +010062script file will be sourced before any VIM_TEST_SETUP commands are executed.
Aliaksei Budaveif6069a72024-03-05 22:34:36 +030063
Aliaksei Budavei84184462024-05-21 01:10:26 +030064Every line of a source file must not be longer than 1425 (19 x 75) characters.
65
Aliaksei Budaveiec022942024-10-06 16:57:33 +020066If there is no further setup required, you can now run all tests:
Aliaksei Budavei93edd252024-03-05 22:34:36 +030067
Bram Moolenaar46acad72023-06-11 19:04:18 +010068 make test
69
Eisuke Kawashima2e18fac2025-03-05 21:15:45 +010070Or you can run the tests for a filetype only by passing its name as another
71target, e.g. "java", before "test":
Aliaksei Budaveiec022942024-10-06 16:57:33 +020072
73 make java test
74
75Or you can run a test or two by passing their filenames as extra targets, e.g.
76"java_string.java" and "java_numbers.java", before "test", after listing all
77available syntax tests for Java:
78
79 ls testdir/input/java*
80 make java_string.java java_numbers.java test
81
82(Some interactive shells may attempt to perform word completion on arbitrary
83command arguments when you press certain keys, e.g. Tab or Ctrl-i.)
84
85As an alternative, you can specify a subset of test filenames for running as
86a regular expression and assign it to a VIM_SYNTAX_TEST_FILTER environment
87variable; e.g. to run all tests whose base names contain "fold", use any of:
88
89 make test -e 'VIM_SYNTAX_TEST_FILTER = fold.*\..\+'
90 make test VIM_SYNTAX_TEST_FILTER='fold.*\..\+'
91 VIM_SYNTAX_TEST_FILTER='fold.*\..\+' make test
92
93Consider quoting the variable value to avoid any interpretation by the shell.
94
95Both Make targets and the variable may be used at the same time, the target
96names will be tried for matching before the variable value.
97
98The first time testing "input/java.java" will fail with an error for a missing
99screendump. The newly created screendumps will be "failed/java_00.dump",
Bram Moolenaar46acad72023-06-11 19:04:18 +0100100"failed/java_01.dump", etc. You can inspect each with:
101
102 call term_dumpload('failed/java_00.dump')
103 call term_dumpload('failed/java_01.dump')
104 ...
Bram Moolenaar46acad72023-06-11 19:04:18 +0100105
106If they look OK, move them to the "dumps" directory:
107
108 :!mv failed/java_00.dump dumps
109 :!mv failed/java_01.dump dumps
110 ...
Bram Moolenaar46acad72023-06-11 19:04:18 +0100111
112If you now run the test again, it will succeed.
113
114
115Adjusting a syntax plugin test
116------------------------------
117
118If you make changes to the syntax plugin, you should add code to the input
119file to see the effect of these changes. So that the effect of the changes
Aliaksei Budavei7ceca3e2025-03-16 20:59:28 +0100120is covered by the test. You can follow these steps:
Bram Moolenaar46acad72023-06-11 19:04:18 +0100121
1221. Edit the syntax plugin somewhere in your personal setup. Use a file
123 somewhere to try out the changes.
1242. Go to the directory where you have the Vim code checked out and replace the
125 syntax plugin. Run the tests: "make test". Usually the tests will still
126 pass, but if you fixed syntax highlighting that was already visible in the
127 input file, carefully check that the changes in the screendump are
128 intentional:
Aliaksei Budavei93edd252024-03-05 22:34:36 +0300129
Aliaksei Budaveib5a92d72024-07-07 20:51:14 +0200130 let fname = '{name}_00.dump'
Bram Moolenaar46acad72023-06-11 19:04:18 +0100131 call term_dumpdiff('failed/' .. fname, 'dumps/' .. fname)
Aliaksei Budavei93edd252024-03-05 22:34:36 +0300132
Bram Moolenaar46acad72023-06-11 19:04:18 +0100133 Fix the syntax plugin until the result is good.
1342. Edit the input file for your language to add the items you have improved.
135 (TODO: how to add another screendump?).
Aliaksei Budavei7ceca3e2025-03-16 20:59:28 +0100136 Run the tests and you should get failures. (You may opt for faster failure
137 by assigning a small number, e.g. "1", to a VIM_SYNTAX_TEST_WAIT_TIME
138 environment variable and gambling away an "uncertain" possibility of
139 success.) Like with the previous step, carefully check that the new
140 screendumps in the "failed" directory are good. Update the syntax plugin
141 and the input file until the highlighting is good and you can see the
142 effect of the syntax plugin improvements. Then move the screendumps from
143 the "failed" to the "dumps" directory. Now "make test" should succeed.
Bram Moolenaar46acad72023-06-11 19:04:18 +01001443. Prepare a pull request with the modified files:
145 - syntax plugin: syntax/{name}.vim
Aliaksei Budaveif6069a72024-03-05 22:34:36 +0300146 - Vim setup file: syntax/testdir/input/setup/{name}.vim (if any)
Bram Moolenaar46acad72023-06-11 19:04:18 +0100147 - test input file: syntax/testdir/input/{name}.{ext}
Aliaksei Budavei7ceca3e2025-03-16 20:59:28 +0100148 - test dump files: syntax/testdir/dumps/{name}_*.dump
Bram Moolenaar46acad72023-06-11 19:04:18 +0100149
150As an extra check you can temporarily put back the old syntax plugin and
151verify that the tests fail. Then you know your changes are covered by the
152test.
153
154
Aliaksei Budavei6bff6a22024-08-19 21:33:26 +0200155Viewing generated screendumps (local)
156-------------------------------------
Aliaksei Budaveid33afe12024-08-12 18:37:15 +0200157
158You may also wish to look at the whole batch of failed screendumps after
159running "make test". Source the "viewdumps.vim" script for this task:
160
161 [VIMRUNTIME=../..] \
162 ../../src/vim --clean -S testdir/viewdumps.vim \
163 [testdir/dumps/java_*.dump ...]
164
165By default, all screendumps found in the "failed" directory will be added to
166the argument list and then the first one will be loaded. Loaded screendumps
167that bear filenames of screendumps found in the "dumps" directory will be
168rendering the contents of any such pair of files and the difference between
169them (:help term_dumpdiff()); otherwise, they will be rendering own contents
170(:help term_dumpload()). Remember to execute :edit when occasionally you see
171raw file contents instead of rendered.
172
173At any time, you can add, list, and abandon other screendumps:
174
175 :$argedit testdir/dumps/java_*.dump
176 :args
177 :qall
178
179The listing of argument commands can be found under :help buffer-list.
Bram Moolenaar46acad72023-06-11 19:04:18 +0100180
Bram Moolenaar46acad72023-06-11 19:04:18 +0100181
Aliaksei Budavei6bff6a22024-08-19 21:33:26 +0200182Viewing generated screendumps (from a CI-uploaded artifact)
183-----------------------------------------------------------
184
185After you have downloaded an artifact archive containing failed screendumps
186and extracted its files in a temporary directory, you need to set up a "dumps"
187directory by creating a symlink:
188
189 cd /path/to/fork
190 ln -s $(pwd)/runtime/syntax/testdir/dumps \
191 /tmp/runtime/syntax/testdir/dumps
192
193You can now examine the extracted screendumps:
194
195 ./src/vim --clean -S runtime/syntax/testdir/viewdumps.vim \
196 /tmp/runtime/syntax/testdir/failed/*.dump
197
198
199Viewing generated screendumps (submitted for a pull request)
200------------------------------------------------------------
201
Aliaksei Budavei5eaacef2025-01-11 17:10:06 +0100202Note: There is also a "git difftool" extension described in
203 src/testdir/commondumps.vim
204
Aliaksei Budavei6bff6a22024-08-19 21:33:26 +0200205First, you need to check out the topic branch with the proposed changes and
206write down a difference list between the HEAD commit (index) and its parent
207commit with respect to the changed "dumps" filenames:
208
209 cd /path/to/fork
210 git switch prs/1234
211 git diff-index --relative=runtime/syntax/testdir/dumps/ \
212 --name-only prs/1234~1 > /tmp/filelist
213
214Then, you need to check out the master branch, change the current working
215directory to reconcile relative filepaths written in the filenames list, copy
216in the "failed" directory the old "dumps" files, whose names are on the same
217list, and follow it by checking out the topic branch:
218
219 git switch master
220 cd runtime/syntax/testdir/dumps
221 cp -t ../failed $(cat /tmp/filelist)
222 git switch prs/1234
223
224Make note of any missing new screendumps. Please remember about the
225introduced INVERTED relation between "dumps" and "failed", i.e. the files to
226be committed are in "dumps" already and their old versions are in "failed".
227Therefore, you need to copy the missing new screendumps from "dumps" to
228"failed":
229
230 cp -t ../failed foo_10.dump foo_11.dump foo_12.dump
231
232After you have changed the current working directory to its parent directory,
233you can now examine the screendumps from the "failed" directory (note that new
234screendumps will be shown with no difference between their versions):
235
236 cd ..
237 ../../../src/vim --clean -S viewdumps.vim
238
239
Bram Moolenaar46acad72023-06-11 19:04:18 +0100240TODO: test syncing by jumping around