blob: 410553daf4fc199c622268e60541b49d463abb5d [file] [log] [blame]
Bram Moolenaar08cc3742019-08-11 22:51:14 +02001" Test for commands that operate on the spellfile.
2
3source shared.vim
4source check.vim
5
6CheckFeature spell
7CheckFeature syntax
8
9func Test_spell_normal()
10 new
11 call append(0, ['1 good', '2 goood', '3 goood'])
12 set spell spellfile=./Xspellfile.add spelllang=en
13 let oldlang=v:lang
14 lang C
15
16 " Test for zg
17 1
18 norm! ]s
19 call assert_equal('2 goood', getline('.'))
20 norm! zg
21 1
22 let a=execute('unsilent :norm! ]s')
23 call assert_equal('1 good', getline('.'))
24 call assert_equal('search hit BOTTOM, continuing at TOP', a[1:])
25 let cnt=readfile('./Xspellfile.add')
26 call assert_equal('goood', cnt[0])
27
Bram Moolenaar8a9bc952020-10-02 18:48:07 +020028 " zg should fail in operator-pending mode
29 call assert_beeps('norm! czg')
30
31 " zg fails in visual mode when not able to get the visual text
32 call assert_beeps('norm! ggVjzg')
33 norm! V
34
35 " zg fails for a non-identifier word
36 call append(line('$'), '###')
37 call assert_fails('norm! Gzg', 'E349:')
38 $d
39
Bram Moolenaar08cc3742019-08-11 22:51:14 +020040 " Test for zw
41 2
42 norm! $zw
43 1
44 norm! ]s
45 call assert_equal('2 goood', getline('.'))
46 let cnt=readfile('./Xspellfile.add')
47 call assert_equal('#oood', cnt[0])
48 call assert_equal('goood/!', cnt[1])
49
50 " Test for :spellrare
51 spellrare rare
52 let cnt=readfile('./Xspellfile.add')
53 call assert_equal(['#oood', 'goood/!', 'rare/?'], cnt)
54
55 " Make sure :spellundo works for rare words.
56 spellundo rare
57 let cnt=readfile('./Xspellfile.add')
58 call assert_equal(['#oood', 'goood/!', '#are/?'], cnt)
59
60 " Test for zg in visual mode
61 let a=execute('unsilent :norm! V$zg')
62 call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:])
63 1
64 norm! ]s
65 call assert_equal('3 goood', getline('.'))
66 let cnt=readfile('./Xspellfile.add')
67 call assert_equal('2 goood', cnt[3])
68 " Remove "2 good" from spellfile
69 2
70 let a=execute('unsilent norm! V$zw')
71 call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:])
72 let cnt=readfile('./Xspellfile.add')
73 call assert_equal('2 goood/!', cnt[4])
74
75 " Test for zG
76 let a=execute('unsilent norm! V$zG')
77 call assert_match("Word '2 goood' added to .*", a)
78 let fname=matchstr(a, 'to\s\+\zs\f\+$')
79 let cnt=readfile(fname)
80 call assert_equal('2 goood', cnt[0])
81
82 " Test for zW
83 let a=execute('unsilent norm! V$zW')
84 call assert_match("Word '2 goood' added to .*", a)
85 let cnt=readfile(fname)
86 call assert_equal('# goood', cnt[0])
87 call assert_equal('2 goood/!', cnt[1])
88
89 " Test for zuW
90 let a=execute('unsilent norm! V$zuW')
91 call assert_match("Word '2 goood' removed from .*", a)
92 let cnt=readfile(fname)
93 call assert_equal('# goood', cnt[0])
94 call assert_equal('# goood/!', cnt[1])
95
96 " Test for zuG
97 let a=execute('unsilent norm! $zG')
98 call assert_match("Word 'goood' added to .*", a)
99 let cnt=readfile(fname)
100 call assert_equal('# goood', cnt[0])
101 call assert_equal('# goood/!', cnt[1])
102 call assert_equal('goood', cnt[2])
103 let a=execute('unsilent norm! $zuG')
104 let cnt=readfile(fname)
105 call assert_match("Word 'goood' removed from .*", a)
106 call assert_equal('# goood', cnt[0])
107 call assert_equal('# goood/!', cnt[1])
108 call assert_equal('#oood', cnt[2])
109 " word not found in wordlist
110 let a=execute('unsilent norm! V$zuG')
111 let cnt=readfile(fname)
112 call assert_match("", a)
113 call assert_equal('# goood', cnt[0])
114 call assert_equal('# goood/!', cnt[1])
115 call assert_equal('#oood', cnt[2])
116
117 " Test for zug
118 call delete('./Xspellfile.add')
119 2
120 let a=execute('unsilent norm! $zg')
121 let cnt=readfile('./Xspellfile.add')
122 call assert_equal('goood', cnt[0])
123 let a=execute('unsilent norm! $zug')
124 call assert_match("Word 'goood' removed from \./Xspellfile.add", a)
125 let cnt=readfile('./Xspellfile.add')
126 call assert_equal('#oood', cnt[0])
127 " word not in wordlist
128 let a=execute('unsilent norm! V$zug')
129 call assert_match('', a)
130 let cnt=readfile('./Xspellfile.add')
131 call assert_equal('#oood', cnt[0])
132
133 " Test for zuw
134 call delete('./Xspellfile.add')
135 2
136 let a=execute('unsilent norm! Vzw')
137 let cnt=readfile('./Xspellfile.add')
138 call assert_equal('2 goood/!', cnt[0])
139 let a=execute('unsilent norm! Vzuw')
140 call assert_match("Word '2 goood' removed from \./Xspellfile.add", a)
141 let cnt=readfile('./Xspellfile.add')
142 call assert_equal('# goood/!', cnt[0])
143 " word not in wordlist
144 let a=execute('unsilent norm! $zug')
145 call assert_match('', a)
146 let cnt=readfile('./Xspellfile.add')
147 call assert_equal('# goood/!', cnt[0])
148
149 " add second entry to spellfile setting
150 set spellfile=./Xspellfile.add,./Xspellfile2.add
151 call delete('./Xspellfile.add')
152 2
153 let a=execute('unsilent norm! $2zg')
154 let cnt=readfile('./Xspellfile2.add')
155 call assert_match("Word 'goood' added to ./Xspellfile2.add", a)
156 call assert_equal('goood', cnt[0])
157
158 " Test for :spellgood!
159 let temp = execute(':spe!0/0')
160 call assert_match('Invalid region', temp)
161 let spellfile = matchstr(temp, 'Invalid region nr in \zs.*\ze line \d: 0')
162 call assert_equal(['# goood', '# goood/!', '#oood', '0/0'], readfile(spellfile))
163
164 " Test for :spellrare!
165 :spellrare! raare
166 call assert_equal(['# goood', '# goood/!', '#oood', '0/0', 'raare/?'], readfile(spellfile))
167 call delete(spellfile)
168
169 " clean up
170 exe "lang" oldlang
171 call delete("./Xspellfile.add")
172 call delete("./Xspellfile2.add")
173 call delete("./Xspellfile.add.spl")
174 call delete("./Xspellfile2.add.spl")
175
176 " zux -> no-op
177 2
178 norm! $zux
179 call assert_equal([], glob('Xspellfile.add',0,1))
180 call assert_equal([], glob('Xspellfile2.add',0,1))
181
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200182 set spellfile= spell& spelllang&
Bram Moolenaar08cc3742019-08-11 22:51:14 +0200183 bw!
184endfunc
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200185
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200186" Spell file content test. Write 'content' to the spell file prefixed by the
187" spell file header and then enable spell checking. If 'emsg' is not empty,
188" then check for error.
189func Spellfile_Test(content, emsg)
190 let splfile = './Xtest/spell/Xtest.utf-8.spl'
191 " Add the spell file header and version (VIMspell2)
192 let v = 0z56494D7370656C6C32 + a:content
193 call writefile(v, splfile, 'b')
Bram Moolenaar64e2db62020-09-09 22:43:19 +0200194
195 " 'encoding' is set before each test to clear the previously loaded suggest
196 " file from memory.
197 set encoding=utf-8
198
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200199 set runtimepath=./Xtest
200 set spelllang=Xtest
201 if a:emsg != ''
202 call assert_fails('set spell', a:emsg)
203 else
204 " FIXME: With some invalid spellfile contents, there are no error
205 " messages. So don't know how to check for the test result.
206 set spell
207 endif
208 set nospell spelllang& rtp&
209endfunc
210
211" Test for spell file format errors.
212" The spell file format is described in spellfile.c
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200213func Test_spellfile_format_error()
214 let save_rtp = &rtp
215 call mkdir('Xtest/spell', 'p')
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200216 let splfile = './Xtest/spell/Xtest.utf-8.spl'
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200217
218 " empty spell file
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200219 call writefile([], splfile)
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200220 set runtimepath=./Xtest
221 set spelllang=Xtest
222 call assert_fails('set spell', 'E757:')
223 set nospell spelllang&
224
225 " invalid file ID
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200226 call writefile(0z56494D, splfile, 'b')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200227 set runtimepath=./Xtest
228 set spelllang=Xtest
229 call assert_fails('set spell', 'E757:')
230 set nospell spelllang&
231
232 " missing version number
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200233 call writefile(0z56494D7370656C6C, splfile, 'b')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200234 set runtimepath=./Xtest
235 set spelllang=Xtest
236 call assert_fails('set spell', 'E771:')
237 set nospell spelllang&
238
239 " invalid version number
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200240 call writefile(0z56494D7370656C6C7A, splfile, 'b')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200241 set runtimepath=./Xtest
242 set spelllang=Xtest
243 call assert_fails('set spell', 'E772:')
244 set nospell spelllang&
245
246 " no sections
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200247 call Spellfile_Test(0z, 'E758:')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200248
249 " missing section length
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200250 call Spellfile_Test(0z00, 'E758:')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200251
252 " unsupported required section
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200253 call Spellfile_Test(0z7A0100000004, 'E770:')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200254
255 " unsupported not-required section
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200256 call Spellfile_Test(0z7A0000000004, 'E758:')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200257
258 " SN_REGION: invalid number of region names
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200259 call Spellfile_Test(0z0000000000FF, 'E759:')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200260
261 " SN_CHARFLAGS: missing <charflagslen> length
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200262 call Spellfile_Test(0z010000000004, 'E758:')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200263
264 " SN_CHARFLAGS: invalid <charflagslen> length
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200265 call Spellfile_Test(0z0100000000010201, '')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200266
267 " SN_CHARFLAGS: charflagslen == 0 and folcharslen != 0
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200268 call Spellfile_Test(0z01000000000400000101, 'E759:')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200269
270 " SN_CHARFLAGS: missing <folcharslen> length
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200271 call Spellfile_Test(0z01000000000100, 'E758:')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200272
273 " SN_PREFCOND: invalid prefcondcnt
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200274 call Spellfile_Test(0z03000000000100, 'E759:')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200275
276 " SN_PREFCOND: invalid condlen
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200277 call Spellfile_Test(0z0300000000020001, 'E759:')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200278
279 " SN_REP: invalid repcount
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200280 call Spellfile_Test(0z04000000000100, 'E758:')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200281
282 " SN_REP: missing rep
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200283 call Spellfile_Test(0z0400000000020004, 'E758:')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200284
285 " SN_REP: zero repfromlen
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200286 call Spellfile_Test(0z040000000003000100, 'E759:')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200287
288 " SN_REP: invalid reptolen
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200289 call Spellfile_Test(0z0400000000050001014101, '')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200290
291 " SN_REP: zero reptolen
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200292 call Spellfile_Test(0z0400000000050001014100, 'E759:')
293
294 " SN_SAL: missing salcount
295 call Spellfile_Test(0z05000000000102, 'E758:')
296
297 " SN_SAL: missing salfromlen
298 call Spellfile_Test(0z050000000003080001, 'E758:')
299
300 " SN_SAL: missing saltolen
301 call Spellfile_Test(0z0500000000050400010161, 'E758:')
302
303 " SN_WORDS: non-NUL terminated word
304 call Spellfile_Test(0z0D000000000376696D, 'E758:')
305
306 " SN_WORDS: very long word
307 let v = eval('0z0D000000012C' .. repeat('41', 300))
308 call Spellfile_Test(v, 'E759:')
309
310 " SN_SOFO: missing sofofromlen
311 call Spellfile_Test(0z06000000000100, 'E758:')
312
313 " SN_SOFO: missing sofotolen
314 call Spellfile_Test(0z06000000000400016100, 'E758:')
315
316 " SN_SOFO: missing sofoto
317 call Spellfile_Test(0z0600000000050001610000, 'E759:')
318
Bram Moolenaar64e2db62020-09-09 22:43:19 +0200319 " SN_SOFO: empty sofofrom and sofoto
320 call Spellfile_Test(0z06000000000400000000FF000000000000000000000000, '')
321
Bram Moolenaar96fdf432020-09-11 18:11:50 +0200322 " SN_SOFO: multi-byte characters in sofofrom and sofoto
323 call Spellfile_Test(0z0600000000080002CF810002CF82FF000000000000000000000000, '')
324
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200325 " SN_COMPOUND: compmax is less than 2
326 call Spellfile_Test(0z08000000000101, 'E759:')
327
328 " SN_COMPOUND: missing compsylmax and other options
329 call Spellfile_Test(0z0800000000020401, 'E759:')
330
331 " SN_COMPOUND: missing compoptions
332 call Spellfile_Test(0z080000000005040101, 'E758:')
333
Bram Moolenaar64e2db62020-09-09 22:43:19 +0200334 " SN_COMPOUND: missing comppattern
335 call Spellfile_Test(0z08000000000704010100000001, 'E758:')
336
337 " SN_COMPOUND: incorrect comppatlen
338 call Spellfile_Test(0z080000000007040101000000020165, 'E758:')
339
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200340 " SN_INFO: missing info
341 call Spellfile_Test(0z0F0000000005040101, '')
342
343 " SN_MIDWORD: missing midword
344 call Spellfile_Test(0z0200000000040102, '')
345
346 " SN_MAP: missing midword
347 call Spellfile_Test(0z0700000000040102, '')
348
Bram Moolenaar64e2db62020-09-09 22:43:19 +0200349 " SN_MAP: empty map string
350 call Spellfile_Test(0z070000000000FF000000000000000000000000, '')
351
352 " SN_MAP: duplicate multibyte character
353 call Spellfile_Test(0z070000000004DC81DC81, 'E783:')
354
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200355 " SN_SYLLABLE: missing SYLLABLE item
356 call Spellfile_Test(0z0900000000040102, '')
357
358 " SN_SYLLABLE: More than SY_MAXLEN size
359 let v = eval('0z090000000022612F' .. repeat('62', 32))
360 call Spellfile_Test(v, '')
361
362 " LWORDTREE: missing
363 call Spellfile_Test(0zFF, 'E758:')
364
365 " LWORDTREE: missing tree node
366 call Spellfile_Test(0zFF00000004, 'E758:')
367
368 " LWORDTREE: missing tree node value
369 call Spellfile_Test(0zFF0000000402, 'E758:')
370
Bram Moolenaar64e2db62020-09-09 22:43:19 +0200371 " LWORDTREE: incorrect sibling node count
372 call Spellfile_Test(0zFF00000001040000000000000000, 'E759:')
373
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200374 " KWORDTREE: missing tree node
375 call Spellfile_Test(0zFF0000000000000004, 'E758:')
376
377 " PREFIXTREE: missing tree node
378 call Spellfile_Test(0zFF000000000000000000000004, 'E758:')
379
Bram Moolenaar64e2db62020-09-09 22:43:19 +0200380 " PREFIXTREE: incorrect prefcondnr
381 call Spellfile_Test(0zFF000000000000000000000002010200000020, 'E759:')
382
383 " PREFIXTREE: invalid nodeidx
384 call Spellfile_Test(0zFF00000000000000000000000201010000, 'E759:')
385
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200386 let &rtp = save_rtp
387 call delete('Xtest', 'rf')
388endfunc
389
390" Test for format errors in suggest file
391func Test_sugfile_format_error()
392 let save_rtp = &rtp
393 call mkdir('Xtest/spell', 'p')
394 let splfile = './Xtest/spell/Xtest.utf-8.spl'
395 let sugfile = './Xtest/spell/Xtest.utf-8.sug'
396
397 " create an empty spell file with a suggest timestamp
398 call writefile(0z56494D7370656C6C320B00000000080000000000000044FF000000000000000000000000, splfile, 'b')
399
400 " 'encoding' is set before each test to clear the previously loaded suggest
401 " file from memory.
402
403 " empty suggest file
404 set encoding=utf-8
405 call writefile([], sugfile)
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200406 set runtimepath=./Xtest
407 set spelllang=Xtest
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200408 set spell
409 call assert_fails("let s = spellsuggest('abc')", 'E778:')
410 set nospell spelllang&
411
412 " zero suggest version
413 set encoding=utf-8
414 call writefile(0z56494D73756700, sugfile)
415 set runtimepath=./Xtest
416 set spelllang=Xtest
417 set spell
418 call assert_fails("let s = spellsuggest('abc')", 'E779:')
419 set nospell spelllang&
420
421 " unsupported suggest version
422 set encoding=utf-8
423 call writefile(0z56494D7375671F, sugfile)
424 set runtimepath=./Xtest
425 set spelllang=Xtest
426 set spell
427 call assert_fails("let s = spellsuggest('abc')", 'E780:')
428 set nospell spelllang&
429
430 " missing suggest timestamp
431 set encoding=utf-8
432 call writefile(0z56494D73756701, sugfile)
433 set runtimepath=./Xtest
434 set spelllang=Xtest
435 set spell
436 call assert_fails("let s = spellsuggest('abc')", 'E781:')
437 set nospell spelllang&
438
439 " incorrect suggest timestamp
440 set encoding=utf-8
441 call writefile(0z56494D7375670100000000000000FF, sugfile)
442 set runtimepath=./Xtest
443 set spelllang=Xtest
444 set spell
445 call assert_fails("let s = spellsuggest('abc')", 'E781:')
446 set nospell spelllang&
447
448 " missing suggest wordtree
449 set encoding=utf-8
450 call writefile(0z56494D737567010000000000000044, sugfile)
451 set runtimepath=./Xtest
452 set spelllang=Xtest
453 set spell
454 call assert_fails("let s = spellsuggest('abc')", 'E782:')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200455 set nospell spelllang&
456
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200457 " invalid suggest word count in SUGTABLE
458 set encoding=utf-8
459 call writefile(0z56494D7375670100000000000000440000000022, sugfile)
460 set runtimepath=./Xtest
461 set spelllang=Xtest
462 set spell
463 call assert_fails("let s = spellsuggest('abc')", 'E782:')
464 set nospell spelllang&
465
466 " missing sugline in SUGTABLE
467 set encoding=utf-8
468 call writefile(0z56494D7375670100000000000000440000000000000005, sugfile)
469 set runtimepath=./Xtest
470 set spelllang=Xtest
471 set spell
472 call assert_fails("let s = spellsuggest('abc')", 'E782:')
473 set nospell spelllang&
474
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200475 let &rtp = save_rtp
476 call delete('Xtest', 'rf')
477endfunc
478
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200479" Test for using :mkspell to create a spell file from a list of words
480func Test_wordlist_dic()
481 " duplicate encoding
482 let lines =<< trim [END]
483 # This is an example word list
484
485 /encoding=latin1
486 /encoding=latin1
487 example
488 [END]
489 call writefile(lines, 'Xwordlist.dic')
490 let output = execute('mkspell Xwordlist.spl Xwordlist.dic')
491 call assert_match('Duplicate /encoding= line ignored in Xwordlist.dic line 4: /encoding=latin1', output)
492
493 " multiple encoding for a word
494 let lines =<< trim [END]
495 example
496 /encoding=latin1
497 example
498 [END]
499 call writefile(lines, 'Xwordlist.dic')
500 let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
501 call assert_match('/encoding= line after word ignored in Xwordlist.dic line 2: /encoding=latin1', output)
502
503 " unsupported encoding for a word
504 let lines =<< trim [END]
505 /encoding=Xtest
506 example
507 [END]
508 call writefile(lines, 'Xwordlist.dic')
509 let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
510 call assert_match('Conversion in Xwordlist.dic not supported: from Xtest to utf-8', output)
511
512 " duplicate region
513 let lines =<< trim [END]
514 /regions=usca
515 /regions=usca
516 example
517 [END]
518 call writefile(lines, 'Xwordlist.dic')
519 let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
520 call assert_match('Duplicate /regions= line ignored in Xwordlist.dic line 2: regions=usca', output)
521
522 " maximum regions
523 let lines =<< trim [END]
524 /regions=uscauscauscauscausca
525 example
526 [END]
527 call writefile(lines, 'Xwordlist.dic')
528 let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
529 call assert_match('Too many regions in Xwordlist.dic line 1: uscauscauscauscausca', output)
530
531 " unsupported '/' value
532 let lines =<< trim [END]
533 /test=abc
534 example
535 [END]
536 call writefile(lines, 'Xwordlist.dic')
537 let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
538 call assert_match('/ line ignored in Xwordlist.dic line 1: /test=abc', output)
539
540 " unsupported flag
541 let lines =<< trim [END]
542 example/+
543 [END]
544 call writefile(lines, 'Xwordlist.dic')
545 let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
546 call assert_match('Unrecognized flags in Xwordlist.dic line 1: +', output)
547
548 " non-ascii word
549 call writefile(["ʀʀ"], 'Xwordlist.dic')
550 let output = execute('mkspell! -ascii Xwordlist.spl Xwordlist.dic')
551 call assert_match('Ignored 1 words with non-ASCII characters', output)
552
Bram Moolenaar64e2db62020-09-09 22:43:19 +0200553 " keep case of a word
554 let lines =<< trim [END]
555 example/=
556 [END]
557 call writefile(lines, 'Xwordlist.dic')
558 let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
559 call assert_match('Compressed keep-case:', output)
560
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200561 call delete('Xwordlist.spl')
562 call delete('Xwordlist.dic')
563endfunc
564
565" Test for the :mkspell command
566func Test_mkspell()
567 call assert_fails('mkspell Xtest_us.spl', 'E751:')
Bram Moolenaar96fdf432020-09-11 18:11:50 +0200568 call assert_fails('mkspell Xtest.spl abc', 'E484:')
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200569 call assert_fails('mkspell a b c d e f g h i j k', 'E754:')
570
Bram Moolenaar96fdf432020-09-11 18:11:50 +0200571 " create a .aff file but not the .dic file
572 call writefile([], 'Xtest.aff')
573 call assert_fails('mkspell Xtest.spl Xtest', 'E484:')
574 call delete('Xtest.aff')
575
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200576 call writefile([], 'Xtest.spl')
577 call writefile([], 'Xtest.dic')
578 call assert_fails('mkspell Xtest.spl Xtest.dic', 'E13:')
579 call delete('Xtest.spl')
580 call delete('Xtest.dic')
581
582 call mkdir('Xtest.spl')
583 call assert_fails('mkspell! Xtest.spl Xtest.dic', 'E17:')
584 call delete('Xtest.spl', 'rf')
585
586 call assert_fails('mkspell en en_US abc_xyz', 'E755:')
587endfunc
588
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200589" Tests for :mkspell with a .dic and .aff file
590func Test_aff_file_format_error()
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200591 " FIXME: For some reason, the :mkspell command below doesn't fail on the
592 " MS-Windows CI build. Disable this test on MS-Windows for now.
593 CheckNotMSWindows
594
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200595 " No word count in .dic file
596 call writefile([], 'Xtest.dic')
597 call writefile([], 'Xtest.aff')
598 call assert_fails('mkspell! Xtest.spl Xtest', 'E760:')
599
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200600 " create a .dic file for the tests below
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200601 call writefile(['1', 'work'], 'Xtest.dic')
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200602
603 " Invalid encoding in .aff file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200604 call writefile(['# comment', 'SET Xinvalidencoding'], 'Xtest.aff')
605 let output = execute('mkspell! Xtest.spl Xtest')
606 call assert_match('Conversion in Xtest.aff not supported: from xinvalidencoding', output)
607
608 " Invalid flag in .aff file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200609 call writefile(['FLAG xxx'], 'Xtest.aff')
610 let output = execute('mkspell! Xtest.spl Xtest')
611 call assert_match('Invalid value for FLAG in Xtest.aff line 1: xxx', output)
612
613 " set FLAGS after using flag for an affix
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200614 call writefile(['SFX L Y 1', 'SFX L 0 re [^x]', 'FLAG long'], 'Xtest.aff')
615 let output = execute('mkspell! Xtest.spl Xtest')
616 call assert_match('FLAG after using flags in Xtest.aff line 3: long', output)
617
618 " INFO in affix file
619 let save_encoding = &encoding
620 call mkdir('Xrtp/spell', 'p')
621 call writefile(['1', 'work'], 'Xrtp/spell/Xtest.dic')
622 call writefile(['NAME klingon', 'VERSION 1.4', 'AUTHOR Spock'],
623 \ 'Xrtp/spell/Xtest.aff')
624 silent mkspell! Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest
625 let save_rtp = &rtp
626 set runtimepath=./Xrtp
627 set spelllang=Xtest
628 set spell
629 let output = split(execute('spellinfo'), "\n")
630 call assert_equal("NAME klingon", output[1])
631 call assert_equal("VERSION 1.4", output[2])
632 call assert_equal("AUTHOR Spock", output[3])
633 let &rtp = save_rtp
634 call delete('Xrtp', 'rf')
635 set spell& spelllang& spellfile&
636 %bw!
637 " 'encoding' must be set again to clear the spell file in memory
638 let &encoding = save_encoding
639
640 " COMPOUNDFORBIDFLAG flag after PFX in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200641 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDFLAG c', 'COMPOUNDFORBIDFLAG x'],
642 \ 'Xtest.aff')
643 let output = execute('mkspell! Xtest.spl Xtest')
644 call assert_match('Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in Xtest.aff line 4', output)
645
646 " COMPOUNDPERMITFLAG flag after PFX in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200647 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDPERMITFLAG c'],
648 \ 'Xtest.aff')
649 let output = execute('mkspell! Xtest.spl Xtest')
650 call assert_match('Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in Xtest.aff line 3', output)
651
652 " Wrong COMPOUNDRULES flag value in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200653 call writefile(['COMPOUNDRULES a'], 'Xtest.aff')
654 let output = execute('mkspell! Xtest.spl Xtest')
655 call assert_match('Wrong COMPOUNDRULES value in Xtest.aff line 1: a', output)
656
657 " Wrong COMPOUNDWORDMAX flag value in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200658 call writefile(['COMPOUNDWORDMAX 0'], 'Xtest.aff')
659 let output = execute('mkspell! Xtest.spl Xtest')
660 call assert_match('Wrong COMPOUNDWORDMAX value in Xtest.aff line 1: 0', output)
661
662 " Wrong COMPOUNDMIN flag value in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200663 call writefile(['COMPOUNDMIN 0'], 'Xtest.aff')
664 let output = execute('mkspell! Xtest.spl Xtest')
665 call assert_match('Wrong COMPOUNDMIN value in Xtest.aff line 1: 0', output)
666
667 " Wrong COMPOUNDSYLMAX flag value in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200668 call writefile(['COMPOUNDSYLMAX 0'], 'Xtest.aff')
669 let output = execute('mkspell! Xtest.spl Xtest')
670 call assert_match('Wrong COMPOUNDSYLMAX value in Xtest.aff line 1: 0', output)
671
672 " Wrong CHECKCOMPOUNDPATTERN flag value in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200673 call writefile(['CHECKCOMPOUNDPATTERN 0'], 'Xtest.aff')
674 let output = execute('mkspell! Xtest.spl Xtest')
675 call assert_match('Wrong CHECKCOMPOUNDPATTERN value in Xtest.aff line 1: 0', output)
676
677 " Duplicate affix entry in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200678 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L Y 1', 'PFX L 0 re x'],
679 \ 'Xtest.aff')
680 let output = execute('mkspell! Xtest.spl Xtest')
681 call assert_match('Duplicate affix in Xtest.aff line 3: L', output)
682
683 " Duplicate affix entry in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200684 call writefile(['PFX L Y 1', 'PFX L Y 1'], 'Xtest.aff')
685 let output = execute('mkspell! Xtest.spl Xtest')
686 call assert_match('Unrecognized or duplicate item in Xtest.aff line 2: PFX', output)
687
688 " Different combining flags in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200689 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L N 1'], 'Xtest.aff')
690 let output = execute('mkspell! Xtest.spl Xtest')
691 call assert_match('Different combining flag in continued affix block in Xtest.aff line 3', output)
692
693 " Try to reuse a affix used for BAD flag
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200694 call writefile(['BAD x', 'PFX x Y 1', 'PFX x 0 re x'], 'Xtest.aff')
695 let output = execute('mkspell! Xtest.spl Xtest')
696 call assert_match('Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in Xtest.aff line 2: x', output)
697
698 " Trailing characters in an affix entry
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200699 call writefile(['PFX L Y 1 Test', 'PFX L 0 re x'], 'Xtest.aff')
700 let output = execute('mkspell! Xtest.spl Xtest')
701 call assert_match('Trailing text in Xtest.aff line 1: Test', output)
702
703 " Trailing characters in an affix entry
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200704 call writefile(['PFX L Y 1', 'PFX L 0 re x Test'], 'Xtest.aff')
705 let output = execute('mkspell! Xtest.spl Xtest')
706 call assert_match('Trailing text in Xtest.aff line 2: Test', output)
707
708 " Incorrect combine flag in an affix entry
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200709 call writefile(['PFX L X 1', 'PFX L 0 re x'], 'Xtest.aff')
710 let output = execute('mkspell! Xtest.spl Xtest')
711 call assert_match('Expected Y or N in Xtest.aff line 1: X', output)
712
713 " Invalid count for REP item
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200714 call writefile(['REP a'], 'Xtest.aff')
715 let output = execute('mkspell! Xtest.spl Xtest')
716 call assert_match('Expected REP(SAL) count in Xtest.aff line 1', output)
717
718 " Trailing characters in REP item
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200719 call writefile(['REP 1', 'REP f ph test'], 'Xtest.aff')
720 let output = execute('mkspell! Xtest.spl Xtest')
721 call assert_match('Trailing text in Xtest.aff line 2: test', output)
722
723 " Invalid count for MAP item
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200724 call writefile(['MAP a'], 'Xtest.aff')
725 let output = execute('mkspell! Xtest.spl Xtest')
726 call assert_match('Expected MAP count in Xtest.aff line 1', output)
727
728 " Duplicate character in a MAP item
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200729 call writefile(['MAP 2', 'MAP xx', 'MAP yy'], 'Xtest.aff')
730 let output = execute('mkspell! Xtest.spl Xtest')
731 call assert_match('Duplicate character in MAP in Xtest.aff line 2', output)
732
733 " Use COMPOUNDSYLMAX without SYLLABLE
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200734 call writefile(['COMPOUNDSYLMAX 2'], 'Xtest.aff')
735 let output = execute('mkspell! Xtest.spl Xtest')
736 call assert_match('COMPOUNDSYLMAX used without SYLLABLE', output)
737
738 " Missing SOFOTO
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200739 call writefile(['SOFOFROM abcdef'], 'Xtest.aff')
740 let output = execute('mkspell! Xtest.spl Xtest')
741 call assert_match('Missing SOFOTO line in Xtest.aff', output)
742
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200743 " Length of SOFOFROM and SOFOTO differ
744 call writefile(['SOFOFROM abcde', 'SOFOTO ABCD'], 'Xtest.aff')
745 call assert_fails('mkspell! Xtest.spl Xtest', 'E759:')
746
747 " Both SAL and SOFOFROM/SOFOTO items
748 call writefile(['SOFOFROM abcd', 'SOFOTO ABCD', 'SAL CIA X'], 'Xtest.aff')
749 let output = execute('mkspell! Xtest.spl Xtest')
750 call assert_match('Both SAL and SOFO lines in Xtest.aff', output)
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200751
752 " use an alphabet flag when FLAG is num
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200753 call writefile(['FLAG num', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff')
754 let output = execute('mkspell! Xtest.spl Xtest')
755 call assert_match('Flag is not a number in Xtest.aff line 2: L', output)
756
757 " use number and alphabet flag when FLAG is num
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200758 call writefile(['FLAG num', 'SFX 4f Y 1', 'SFX 4f 0 re [^x]'], 'Xtest.aff')
759 let output = execute('mkspell! Xtest.spl Xtest')
760 call assert_match('Affix name too long in Xtest.aff line 2: 4f', output)
761
762 " use a single character flag when FLAG is long
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200763 call writefile(['FLAG long', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff')
764 let output = execute('mkspell! Xtest.spl Xtest')
765 call assert_match('Illegal flag in Xtest.aff line 2: L', output)
766
Bram Moolenaar64e2db62020-09-09 22:43:19 +0200767 " missing character in UPP entry. The character table is used only in a
768 " non-utf8 encoding
769 call writefile(['FOL abc', 'LOW abc', 'UPP A'], 'Xtest.aff')
770 let save_encoding = &encoding
771 set encoding=cp949
772 call assert_fails('mkspell! Xtest.spl Xtest', 'E761:')
773 let &encoding = save_encoding
774
775 " character range doesn't match between FOL and LOW entries
776 call writefile(["FOL \u0102bc", 'LOW abc', 'UPP ABC'], 'Xtest.aff')
777 let save_encoding = &encoding
778 set encoding=cp949
779 call assert_fails('mkspell! Xtest.spl Xtest', 'E762:')
780 let &encoding = save_encoding
781
782 " character range doesn't match between FOL and UPP entries
783 call writefile(["FOL \u0102bc", "LOW \u0102bc", 'UPP ABC'], 'Xtest.aff')
784 let save_encoding = &encoding
785 set encoding=cp949
786 call assert_fails('mkspell! Xtest.spl Xtest', 'E762:')
787 let &encoding = save_encoding
788
789 " additional characters in LOW and UPP entries
790 call writefile(["FOL ab", "LOW abc", 'UPP ABC'], 'Xtest.aff')
791 let save_encoding = &encoding
792 set encoding=cp949
793 call assert_fails('mkspell! Xtest.spl Xtest', 'E761:')
794 let &encoding = save_encoding
795
Bram Moolenaar96fdf432020-09-11 18:11:50 +0200796 " missing UPP entry
797 call writefile(["FOL abc", "LOW abc"], 'Xtest.aff')
798 let save_encoding = &encoding
799 set encoding=cp949
800 let output = execute('mkspell! Xtest.spl Xtest')
801 call assert_match('Missing FOL/LOW/UPP line in Xtest.aff', output)
802 let &encoding = save_encoding
803
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200804 " duplicate word in the .dic file
805 call writefile(['2', 'good', 'good', 'good'], 'Xtest.dic')
806 call writefile(['NAME vim'], 'Xtest.aff')
807 let output = execute('mkspell! Xtest.spl Xtest')
808 call assert_match('First duplicate word in Xtest.dic line 3: good', output)
809 call assert_match('2 duplicate word(s) in Xtest.dic', output)
810
Bram Moolenaar96fdf432020-09-11 18:11:50 +0200811 " use multiple .aff files with different values for COMPOUNDWORDMAX and
812 " MIDWORD (number and string)
813 call writefile(['1', 'world'], 'Xtest_US.dic')
814 call writefile(['1', 'world'], 'Xtest_CA.dic')
815 call writefile(["COMPOUNDWORDMAX 3", "MIDWORD '-"], 'Xtest_US.aff')
816 call writefile(["COMPOUNDWORDMAX 4", "MIDWORD '="], 'Xtest_CA.aff')
817 let output = execute('mkspell! Xtest.spl Xtest_US Xtest_CA')
818 call assert_match('COMPOUNDWORDMAX value differs from what is used in another .aff file', output)
819 call assert_match('MIDWORD value differs from what is used in another .aff file', output)
820 call delete('Xtest_US.dic')
821 call delete('Xtest_CA.dic')
822 call delete('Xtest_US.aff')
823 call delete('Xtest_CA.aff')
824
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200825 call delete('Xtest.dic')
826 call delete('Xtest.aff')
827 call delete('Xtest.spl')
828 call delete('Xtest.sug')
829endfunc
830
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200831func Test_spell_add_word()
832 set spellfile=
833 call assert_fails('spellgood abc', 'E764:')
834
835 set spellfile=Xtest.utf-8.add
836 call assert_fails('2spellgood abc', 'E765:')
837
838 edit Xtest.utf-8.add
839 call setline(1, 'sample')
840 call assert_fails('spellgood abc', 'E139:')
841 set spellfile&
842 %bw!
843endfunc
844
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200845" When 'spellfile' is not set, adding a new good word will automatically set
846" the 'spellfile'
847func Test_init_spellfile()
848 let save_rtp = &rtp
849 let save_encoding = &encoding
850 call mkdir('Xrtp/spell', 'p')
851 call writefile(['vim'], 'Xrtp/spell/Xtest.dic')
852 silent mkspell Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest.dic
853 set runtimepath=./Xrtp
854 set spelllang=Xtest
855 set spell
856 silent spellgood abc
857 call assert_equal('./Xrtp/spell/Xtest.utf-8.add', &spellfile)
858 call assert_equal(['abc'], readfile('Xrtp/spell/Xtest.utf-8.add'))
859 call assert_true(filereadable('Xrtp/spell/Xtest.utf-8.spl'))
860 set spell& spelllang& spellfile&
861 call delete('Xrtp', 'rf')
862 let &encoding = save_encoding
863 let &rtp = save_rtp
864 %bw!
865endfunc
866
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200867" Test for the 'mkspellmem' option
868func Test_mkspellmem_opt()
869 call assert_fails('set mkspellmem=1000', 'E474:')
870 call assert_fails('set mkspellmem=1000,', 'E474:')
871 call assert_fails('set mkspellmem=1000,50', 'E474:')
872 call assert_fails('set mkspellmem=1000,50,', 'E474:')
873 call assert_fails('set mkspellmem=1000,50,10,', 'E474:')
874 call assert_fails('set mkspellmem=1000,50,0', 'E474:')
875endfunc
876
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +0200877" vim: shiftwidth=2 sts=2 expandtab