blob: c0852e090f0cd6da00e5f14e20c829833baf705f [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
Dominique Pelle5a6cfb32021-05-29 17:29:33 +0200586 " can't write the .spl file as its directory does not exist
587 call writefile([], 'Xtest.aff')
588 call writefile([], 'Xtest.dic')
589 call assert_fails('mkspell DOES_NOT_EXIT/Xtest.spl Xtest.dic', 'E484:')
590 call delete('Xtest.aff')
591 call delete('Xtest.dic')
592
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200593 call assert_fails('mkspell en en_US abc_xyz', 'E755:')
594endfunc
595
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200596" Tests for :mkspell with a .dic and .aff file
597func Test_aff_file_format_error()
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200598 " FIXME: For some reason, the :mkspell command below doesn't fail on the
599 " MS-Windows CI build. Disable this test on MS-Windows for now.
600 CheckNotMSWindows
601
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200602 " No word count in .dic file
603 call writefile([], 'Xtest.dic')
604 call writefile([], 'Xtest.aff')
605 call assert_fails('mkspell! Xtest.spl Xtest', 'E760:')
606
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200607 " create a .dic file for the tests below
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200608 call writefile(['1', 'work'], 'Xtest.dic')
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200609
610 " Invalid encoding in .aff file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200611 call writefile(['# comment', 'SET Xinvalidencoding'], 'Xtest.aff')
612 let output = execute('mkspell! Xtest.spl Xtest')
613 call assert_match('Conversion in Xtest.aff not supported: from xinvalidencoding', output)
614
615 " Invalid flag in .aff file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200616 call writefile(['FLAG xxx'], 'Xtest.aff')
617 let output = execute('mkspell! Xtest.spl Xtest')
618 call assert_match('Invalid value for FLAG in Xtest.aff line 1: xxx', output)
619
620 " set FLAGS after using flag for an affix
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200621 call writefile(['SFX L Y 1', 'SFX L 0 re [^x]', 'FLAG long'], 'Xtest.aff')
622 let output = execute('mkspell! Xtest.spl Xtest')
623 call assert_match('FLAG after using flags in Xtest.aff line 3: long', output)
624
625 " INFO in affix file
626 let save_encoding = &encoding
627 call mkdir('Xrtp/spell', 'p')
628 call writefile(['1', 'work'], 'Xrtp/spell/Xtest.dic')
629 call writefile(['NAME klingon', 'VERSION 1.4', 'AUTHOR Spock'],
630 \ 'Xrtp/spell/Xtest.aff')
631 silent mkspell! Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest
632 let save_rtp = &rtp
633 set runtimepath=./Xrtp
634 set spelllang=Xtest
635 set spell
636 let output = split(execute('spellinfo'), "\n")
637 call assert_equal("NAME klingon", output[1])
638 call assert_equal("VERSION 1.4", output[2])
639 call assert_equal("AUTHOR Spock", output[3])
640 let &rtp = save_rtp
641 call delete('Xrtp', 'rf')
642 set spell& spelllang& spellfile&
643 %bw!
644 " 'encoding' must be set again to clear the spell file in memory
645 let &encoding = save_encoding
646
647 " COMPOUNDFORBIDFLAG flag after PFX in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200648 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDFLAG c', 'COMPOUNDFORBIDFLAG x'],
649 \ 'Xtest.aff')
650 let output = execute('mkspell! Xtest.spl Xtest')
651 call assert_match('Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in Xtest.aff line 4', output)
652
653 " COMPOUNDPERMITFLAG flag after PFX in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200654 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDPERMITFLAG c'],
655 \ 'Xtest.aff')
656 let output = execute('mkspell! Xtest.spl Xtest')
657 call assert_match('Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in Xtest.aff line 3', output)
658
659 " Wrong COMPOUNDRULES flag value in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200660 call writefile(['COMPOUNDRULES a'], 'Xtest.aff')
661 let output = execute('mkspell! Xtest.spl Xtest')
662 call assert_match('Wrong COMPOUNDRULES value in Xtest.aff line 1: a', output)
663
664 " Wrong COMPOUNDWORDMAX flag value in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200665 call writefile(['COMPOUNDWORDMAX 0'], 'Xtest.aff')
666 let output = execute('mkspell! Xtest.spl Xtest')
667 call assert_match('Wrong COMPOUNDWORDMAX value in Xtest.aff line 1: 0', output)
668
669 " Wrong COMPOUNDMIN flag value in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200670 call writefile(['COMPOUNDMIN 0'], 'Xtest.aff')
671 let output = execute('mkspell! Xtest.spl Xtest')
672 call assert_match('Wrong COMPOUNDMIN value in Xtest.aff line 1: 0', output)
673
674 " Wrong COMPOUNDSYLMAX flag value in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200675 call writefile(['COMPOUNDSYLMAX 0'], 'Xtest.aff')
676 let output = execute('mkspell! Xtest.spl Xtest')
677 call assert_match('Wrong COMPOUNDSYLMAX value in Xtest.aff line 1: 0', output)
678
679 " Wrong CHECKCOMPOUNDPATTERN flag value in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200680 call writefile(['CHECKCOMPOUNDPATTERN 0'], 'Xtest.aff')
681 let output = execute('mkspell! Xtest.spl Xtest')
682 call assert_match('Wrong CHECKCOMPOUNDPATTERN value in Xtest.aff line 1: 0', output)
683
Dominique Pellebb162362021-05-31 20:04:07 +0200684 " Both compounding and NOBREAK specified
685 call writefile(['COMPOUNDFLAG c', 'NOBREAK'], 'Xtest.aff')
686 let output = execute('mkspell! Xtest.spl Xtest')
687 call assert_match('Warning: both compounding and NOBREAK specified', output)
688
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200689 " Duplicate affix entry in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200690 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L Y 1', 'PFX L 0 re x'],
691 \ 'Xtest.aff')
692 let output = execute('mkspell! Xtest.spl Xtest')
693 call assert_match('Duplicate affix in Xtest.aff line 3: L', output)
694
695 " Duplicate affix entry in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200696 call writefile(['PFX L Y 1', 'PFX L Y 1'], 'Xtest.aff')
697 let output = execute('mkspell! Xtest.spl Xtest')
698 call assert_match('Unrecognized or duplicate item in Xtest.aff line 2: PFX', output)
699
700 " Different combining flags in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200701 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L N 1'], 'Xtest.aff')
702 let output = execute('mkspell! Xtest.spl Xtest')
703 call assert_match('Different combining flag in continued affix block in Xtest.aff line 3', output)
704
705 " Try to reuse a affix used for BAD flag
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200706 call writefile(['BAD x', 'PFX x Y 1', 'PFX x 0 re x'], 'Xtest.aff')
707 let output = execute('mkspell! Xtest.spl Xtest')
708 call assert_match('Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in Xtest.aff line 2: x', output)
709
710 " Trailing characters in an affix entry
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200711 call writefile(['PFX L Y 1 Test', 'PFX L 0 re x'], 'Xtest.aff')
712 let output = execute('mkspell! Xtest.spl Xtest')
713 call assert_match('Trailing text in Xtest.aff line 1: Test', output)
714
715 " Trailing characters in an affix entry
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200716 call writefile(['PFX L Y 1', 'PFX L 0 re x Test'], 'Xtest.aff')
717 let output = execute('mkspell! Xtest.spl Xtest')
718 call assert_match('Trailing text in Xtest.aff line 2: Test', output)
719
720 " Incorrect combine flag in an affix entry
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200721 call writefile(['PFX L X 1', 'PFX L 0 re x'], 'Xtest.aff')
722 let output = execute('mkspell! Xtest.spl Xtest')
723 call assert_match('Expected Y or N in Xtest.aff line 1: X', output)
724
725 " Invalid count for REP item
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200726 call writefile(['REP a'], 'Xtest.aff')
727 let output = execute('mkspell! Xtest.spl Xtest')
728 call assert_match('Expected REP(SAL) count in Xtest.aff line 1', output)
729
730 " Trailing characters in REP item
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200731 call writefile(['REP 1', 'REP f ph test'], 'Xtest.aff')
732 let output = execute('mkspell! Xtest.spl Xtest')
733 call assert_match('Trailing text in Xtest.aff line 2: test', output)
734
735 " Invalid count for MAP item
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200736 call writefile(['MAP a'], 'Xtest.aff')
737 let output = execute('mkspell! Xtest.spl Xtest')
738 call assert_match('Expected MAP count in Xtest.aff line 1', output)
739
740 " Duplicate character in a MAP item
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200741 call writefile(['MAP 2', 'MAP xx', 'MAP yy'], 'Xtest.aff')
742 let output = execute('mkspell! Xtest.spl Xtest')
743 call assert_match('Duplicate character in MAP in Xtest.aff line 2', output)
744
745 " Use COMPOUNDSYLMAX without SYLLABLE
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200746 call writefile(['COMPOUNDSYLMAX 2'], 'Xtest.aff')
747 let output = execute('mkspell! Xtest.spl Xtest')
748 call assert_match('COMPOUNDSYLMAX used without SYLLABLE', output)
749
750 " Missing SOFOTO
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200751 call writefile(['SOFOFROM abcdef'], 'Xtest.aff')
752 let output = execute('mkspell! Xtest.spl Xtest')
753 call assert_match('Missing SOFOTO line in Xtest.aff', output)
754
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200755 " Length of SOFOFROM and SOFOTO differ
756 call writefile(['SOFOFROM abcde', 'SOFOTO ABCD'], 'Xtest.aff')
757 call assert_fails('mkspell! Xtest.spl Xtest', 'E759:')
758
759 " Both SAL and SOFOFROM/SOFOTO items
760 call writefile(['SOFOFROM abcd', 'SOFOTO ABCD', 'SAL CIA X'], 'Xtest.aff')
761 let output = execute('mkspell! Xtest.spl Xtest')
762 call assert_match('Both SAL and SOFO lines in Xtest.aff', output)
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200763
764 " use an alphabet flag when FLAG is num
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200765 call writefile(['FLAG num', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff')
766 let output = execute('mkspell! Xtest.spl Xtest')
767 call assert_match('Flag is not a number in Xtest.aff line 2: L', output)
768
769 " use number and alphabet flag when FLAG is num
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200770 call writefile(['FLAG num', 'SFX 4f Y 1', 'SFX 4f 0 re [^x]'], 'Xtest.aff')
771 let output = execute('mkspell! Xtest.spl Xtest')
772 call assert_match('Affix name too long in Xtest.aff line 2: 4f', output)
773
774 " use a single character flag when FLAG is long
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200775 call writefile(['FLAG long', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff')
776 let output = execute('mkspell! Xtest.spl Xtest')
777 call assert_match('Illegal flag in Xtest.aff line 2: L', output)
778
Bram Moolenaar64e2db62020-09-09 22:43:19 +0200779 " missing character in UPP entry. The character table is used only in a
780 " non-utf8 encoding
781 call writefile(['FOL abc', 'LOW abc', 'UPP A'], 'Xtest.aff')
782 let save_encoding = &encoding
783 set encoding=cp949
784 call assert_fails('mkspell! Xtest.spl Xtest', 'E761:')
785 let &encoding = save_encoding
786
787 " character range doesn't match between FOL and LOW entries
788 call writefile(["FOL \u0102bc", 'LOW abc', 'UPP ABC'], 'Xtest.aff')
789 let save_encoding = &encoding
790 set encoding=cp949
791 call assert_fails('mkspell! Xtest.spl Xtest', 'E762:')
792 let &encoding = save_encoding
793
794 " character range doesn't match between FOL and UPP entries
795 call writefile(["FOL \u0102bc", "LOW \u0102bc", 'UPP ABC'], 'Xtest.aff')
796 let save_encoding = &encoding
797 set encoding=cp949
798 call assert_fails('mkspell! Xtest.spl Xtest', 'E762:')
799 let &encoding = save_encoding
800
801 " additional characters in LOW and UPP entries
802 call writefile(["FOL ab", "LOW abc", 'UPP ABC'], 'Xtest.aff')
803 let save_encoding = &encoding
804 set encoding=cp949
805 call assert_fails('mkspell! Xtest.spl Xtest', 'E761:')
806 let &encoding = save_encoding
807
Bram Moolenaar96fdf432020-09-11 18:11:50 +0200808 " missing UPP entry
809 call writefile(["FOL abc", "LOW abc"], 'Xtest.aff')
810 let save_encoding = &encoding
811 set encoding=cp949
812 let output = execute('mkspell! Xtest.spl Xtest')
813 call assert_match('Missing FOL/LOW/UPP line in Xtest.aff', output)
814 let &encoding = save_encoding
815
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200816 " duplicate word in the .dic file
817 call writefile(['2', 'good', 'good', 'good'], 'Xtest.dic')
818 call writefile(['NAME vim'], 'Xtest.aff')
819 let output = execute('mkspell! Xtest.spl Xtest')
820 call assert_match('First duplicate word in Xtest.dic line 3: good', output)
821 call assert_match('2 duplicate word(s) in Xtest.dic', output)
822
Bram Moolenaar96fdf432020-09-11 18:11:50 +0200823 " use multiple .aff files with different values for COMPOUNDWORDMAX and
824 " MIDWORD (number and string)
825 call writefile(['1', 'world'], 'Xtest_US.dic')
826 call writefile(['1', 'world'], 'Xtest_CA.dic')
827 call writefile(["COMPOUNDWORDMAX 3", "MIDWORD '-"], 'Xtest_US.aff')
828 call writefile(["COMPOUNDWORDMAX 4", "MIDWORD '="], 'Xtest_CA.aff')
829 let output = execute('mkspell! Xtest.spl Xtest_US Xtest_CA')
830 call assert_match('COMPOUNDWORDMAX value differs from what is used in another .aff file', output)
831 call assert_match('MIDWORD value differs from what is used in another .aff file', output)
832 call delete('Xtest_US.dic')
833 call delete('Xtest_CA.dic')
834 call delete('Xtest_US.aff')
835 call delete('Xtest_CA.aff')
836
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200837 call delete('Xtest.dic')
838 call delete('Xtest.aff')
839 call delete('Xtest.spl')
840 call delete('Xtest.sug')
841endfunc
842
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200843func Test_spell_add_word()
844 set spellfile=
845 call assert_fails('spellgood abc', 'E764:')
846
847 set spellfile=Xtest.utf-8.add
848 call assert_fails('2spellgood abc', 'E765:')
849
850 edit Xtest.utf-8.add
851 call setline(1, 'sample')
852 call assert_fails('spellgood abc', 'E139:')
853 set spellfile&
854 %bw!
855endfunc
856
Dominique Pelle5a6cfb32021-05-29 17:29:33 +0200857func Test_spellfile_verbose()
858 call writefile(['1', 'one'], 'XtestVerbose.dic')
859 call writefile([], 'XtestVerbose.aff')
860 mkspell! XtestVerbose-utf8.spl XtestVerbose
861 set spell
862
863 " First time: the spl file should be read.
864 let a = execute('3verbose set spelllang=XtestVerbose-utf8.spl')
865 call assert_match('Reading spell file "XtestVerbose-utf8.spl"', a)
866
867 " Second time time: the spl file should not be read (already read).
868 let a = execute('3verbose set spelllang=XtestVerbose-utf8.spl')
869 call assert_notmatch('Reading spell file "XtestVerbose-utf8.spl"', a)
870
871 set spell& spelllang&
872 call delete('XtestVerbose.dic')
873 call delete('XtestVerbose.aff')
874 call delete('XtestVerbose-utf8.spl')
875endfunc
876
877" Test NOBREAK (see :help spell-NOBREAK)
878func Test_NOBREAK()
879 call writefile(['3', 'one', 'two', 'three' ], 'XtestNOBREAK.dic')
880 call writefile(['NOBREAK' ], 'XtestNOBREAK.aff')
881
882 mkspell! XtestNOBREAK-utf8.spl XtestNOBREAK
883 set spell spelllang=XtestNOBREAK-utf8.spl
884
885 call assert_equal(['', ''], spellbadword('One two three onetwo onetwothree threetwoone'))
886
887 call assert_equal(['x', 'bad'], spellbadword('x'))
888 call assert_equal(['y', 'bad'], spellbadword('yone'))
889 call assert_equal(['z', 'bad'], spellbadword('onez'))
890 call assert_equal(['zero', 'bad'], spellbadword('Onetwozerothree'))
891
Dominique Pellebb162362021-05-31 20:04:07 +0200892 new
893 call setline(1, 'Onetwwothree')
894 norm! fw1z=
895 call assert_equal('Onetwothree', getline(1))
896 call setline(1, 'Onetwothre')
897 norm! fh1z=
898 call assert_equal('Onetwothree', getline(1))
899
900 bw!
Dominique Pelle5a6cfb32021-05-29 17:29:33 +0200901 set spell& spelllang&
902 call delete('XtestNOBREAK.dic')
903 call delete('XtestNOBREAK.aff')
904 call delete('XtestNOBREAK-utf8.spl')
905endfunc
906
Dominique Pelledc3275a2021-05-28 18:32:12 +0200907" Test CHECKCOMPOUNDPATTERN (see :help spell-CHECKCOMPOUNDPATTERN)
908func Test_spellfile_CHECKCOMPOUNDPATTERN()
909 call writefile(['4',
910 \ 'one/c',
911 \ 'two/c',
912 \ 'three/c',
913 \ 'four'], 'XtestCHECKCOMPOUNDPATTERN.dic')
914 " Forbid compound words where first word ends with 'wo' and second starts with 'on'.
915 call writefile(['CHECKCOMPOUNDPATTERN 1',
916 \ 'CHECKCOMPOUNDPATTERN wo on',
917 \ 'COMPOUNDFLAG c'], 'XtestCHECKCOMPOUNDPATTERN.aff')
918
Dominique Pelle5a6cfb32021-05-29 17:29:33 +0200919 mkspell! XtestCHECKCOMPOUNDPATTERN-utf8.spl XtestCHECKCOMPOUNDPATTERN
Dominique Pelledc3275a2021-05-28 18:32:12 +0200920 set spell spelllang=XtestCHECKCOMPOUNDPATTERN-utf8.spl
921
922 " Check valid words with and without valid compounds.
923 for goodword in ['one', 'two', 'three', 'four',
924 \ 'oneone', 'onetwo', 'onethree',
925 \ 'twotwo', 'twothree',
926 \ 'threeone', 'threetwo', 'threethree',
927 \ 'onetwothree', 'onethreetwo', 'twothreeone', 'oneoneone']
928 call assert_equal(['', ''], spellbadword(goodword), goodword)
929 endfor
930
931 " Compounds 'twoone' or 'threetwoone' should be forbidden by CHECKCOMPOUNPATTERN.
932 " 'four' does not have the 'c' flag in *.aff file so no compound.
933 " 'five' is not in the *.dic file.
934 for badword in ['five', 'onetwox',
935 \ 'twoone', 'threetwoone',
936 \ 'fourone', 'onefour']
937 call assert_equal([badword, 'bad'], spellbadword(badword))
938 endfor
939
940 set spell& spelllang&
941 call delete('XtestCHECKCOMPOUNDPATTERN.dic')
942 call delete('XtestCHECKCOMPOUNDPATTERN.aff')
943 call delete('XtestCHECKCOMPOUNDPATTERN-utf8.spl')
944endfunc
945
Dominique Pelle9c9472f2021-07-24 20:51:13 +0200946" Test NOCOMPOUNDSUGS (see :help spell-NOCOMPOUNDSUGS)
947func Test_spellfile_NOCOMPOUNDSUGS()
948 call writefile(['3',
949 \ 'one/c',
950 \ 'two/c',
951 \ 'three/c'], 'XtestNOCOMPOUNDSUGS.dic')
952
953 " pass 0 tests without NOCOMPOUNDSUGS, pass 1 tests with NOCOMPOUNDSUGS
954 for pass in [0, 1]
955 if pass == 0
956 call writefile(['COMPOUNDFLAG c'], 'XtestNOCOMPOUNDSUGS.aff')
957 else
958 call writefile(['NOCOMPOUNDSUGS',
959 \ 'COMPOUNDFLAG c'], 'XtestNOCOMPOUNDSUGS.aff')
960 endif
961
962 mkspell! XtestNOCOMPOUNDSUGS-utf8.spl XtestNOCOMPOUNDSUGS
963 set spell spelllang=XtestNOCOMPOUNDSUGS-utf8.spl
964
965 for goodword in ['one', 'two', 'three',
966 \ 'oneone', 'onetwo', 'onethree',
967 \ 'twoone', 'twotwo', 'twothree',
968 \ 'threeone', 'threetwo', 'threethree',
969 \ 'onetwothree', 'onethreetwo', 'twothreeone', 'oneoneone']
970 call assert_equal(['', ''], spellbadword(goodword), goodword)
971 endfor
972
973 for badword in ['four', 'onetwox', 'onexone']
974 call assert_equal([badword, 'bad'], spellbadword(badword))
975 endfor
976
977 if pass == 0
978 call assert_equal(['one', 'oneone'], spellsuggest('onne', 2))
979 call assert_equal(['onethree', 'one three'], spellsuggest('onethre', 2))
980 else
981 call assert_equal(['one', 'one one'], spellsuggest('onne', 2))
982 call assert_equal(['one three'], spellsuggest('onethre', 2))
983 endif
984 endfor
985
986 set spell& spelllang&
987 call delete('XtestNOCOMPOUNDSUGS.dic')
988 call delete('XtestNOCOMPOUNDSUGS.aff')
989 call delete('XtestNOCOMPOUNDSUGS-utf8.spl')
990endfunc
991
Dominique Pelledc3275a2021-05-28 18:32:12 +0200992" Test COMMON (better suggestions with common words, see :help spell-COMMON)
993func Test_spellfile_COMMON()
994 call writefile(['7',
995 \ 'and',
996 \ 'ant',
997 \ 'end',
998 \ 'any',
999 \ 'tee',
1000 \ 'the',
1001 \ 'ted'], 'XtestCOMMON.dic')
1002 call writefile(['COMMON the and'], 'XtestCOMMON.aff')
1003
Dominique Pelle5a6cfb32021-05-29 17:29:33 +02001004 mkspell! XtestCOMMON-utf8.spl XtestCOMMON
Dominique Pelledc3275a2021-05-28 18:32:12 +02001005 set spell spelllang=XtestCOMMON-utf8.spl
1006
1007 " COMMON words 'and' and 'the' should be the top suggestions.
1008 call assert_equal(['and', 'ant'], spellsuggest('anr', 2))
1009 call assert_equal(['and', 'end'], spellsuggest('ond', 2))
1010 call assert_equal(['the', 'ted'], spellsuggest('tha', 2))
1011 call assert_equal(['the', 'tee'], spellsuggest('dhe', 2))
1012
1013 set spell& spelllang&
1014 call delete('XtestCOMMON.dic')
1015 call delete('XtestCOMMON.aff')
1016 call delete('XtestCOMMON-utf8.spl')
1017endfunc
1018
Dominique Pelle5a6cfb32021-05-29 17:29:33 +02001019" Test CIRCUMFIX (see: :help spell-CIRCUMFIX)
1020func Test_spellfile_CIRCUMFIX()
1021 " Example taken verbatim from https://github.com/hunspell/hunspell/tree/master/tests
1022 call writefile(['1',
1023 \ 'nagy/C po:adj'], 'XtestCIRCUMFIX.dic')
1024 call writefile(['# circumfixes: ~ obligate prefix/suffix combinations',
1025 \ '# superlative in Hungarian: leg- (prefix) AND -bb (suffix)',
1026 \ '',
1027 \ 'CIRCUMFIX X',
1028 \ '',
1029 \ 'PFX A Y 1',
1030 \ 'PFX A 0 leg/X .',
1031 \ '',
1032 \ 'PFX B Y 1',
1033 \ 'PFX B 0 legesleg/X .',
1034 \ '',
1035 \ 'SFX C Y 3',
1036 \ 'SFX C 0 obb . is:COMPARATIVE',
1037 \ 'SFX C 0 obb/AX . is:SUPERLATIVE',
1038 \ 'SFX C 0 obb/BX . is:SUPERSUPERLATIVE'], 'XtestCIRCUMFIX.aff')
1039
1040 mkspell! XtestCIRCUMFIX-utf8.spl XtestCIRCUMFIX
1041 set spell spelllang=XtestCIRCUMFIX-utf8.spl
1042
1043 " From https://catalog.ldc.upenn.edu/docs/LDC2008T01/acta04.pdf:
1044 " Hungarian English
1045 " --------- -------
1046 " nagy great
1047 " nagyobb greater
1048 " legnagyobb greatest
1049 " legeslegnagyob most greatest
1050 call assert_equal(['', ''], spellbadword('nagy nagyobb legnagyobb legeslegnagyobb'))
1051
1052 for badword in ['legnagy', 'legeslegnagy', 'legobb', 'legeslegobb']
1053 call assert_equal([badword, 'bad'], spellbadword(badword))
1054 endfor
1055
1056 set spell& spelllang&
1057 call delete('XtestCIRCUMFIX.dic')
1058 call delete('XtestCIRCUMFIX.aff')
1059 call delete('XtestCIRCUMFIX-utf8.spl')
1060endfunc
1061
Dominique Pellebb162362021-05-31 20:04:07 +02001062" Test SFX that strips/chops characters
1063func Test_spellfile_SFX_strip()
1064 " Simplified conjugation of Italian verbs ending in -are (first conjugation).
1065 call writefile(['SFX A Y 4',
1066 \ 'SFX A are iamo [^icg]are',
1067 \ 'SFX A are hiamo [cg]are',
1068 \ 'SFX A re mo iare',
1069 \ 'SFX A re vamo are'],
1070 \ 'XtestSFX.aff')
1071 " Examples of Italian verbs:
1072 " - cantare = to sing
1073 " - cercare = to search
1074 " - odiare = to hate
1075 call writefile(['3', 'cantare/A', 'cercare/A', 'odiare/A'], 'XtestSFX.dic')
1076
1077 mkspell! XtestSFX-utf8.spl XtestSFX
1078 set spell spelllang=XtestSFX-utf8.spl
1079
1080 " To sing, we're singing, we were singing.
1081 call assert_equal(['', ''], spellbadword('cantare cantiamo cantavamo'))
1082
1083 " To search, we're searching, we were searching.
1084 call assert_equal(['', ''], spellbadword('cercare cerchiamo cercavamo'))
1085
1086 " To hate, we hate, we were hating.
1087 call assert_equal(['', ''], spellbadword('odiare odiamo odiavamo'))
1088
1089 for badword in ['canthiamo', 'cerciamo', 'cantarevamo', 'odiiamo']
1090 call assert_equal([badword, 'bad'], spellbadword(badword))
1091 endfor
1092
1093 call assert_equal(['cantiamo'], spellsuggest('canthiamo', 1))
1094 call assert_equal(['cerchiamo'], spellsuggest('cerciamo', 1))
1095 call assert_equal(['cantavamo'], spellsuggest('cantarevamo', 1))
1096 call assert_equal(['odiamo'], spellsuggest('odiiamo', 1))
1097
1098 set spell& spelllang&
1099 call delete('XtestSFX.dic')
1100 call delete('XtestSFX.aff')
1101 call delete('XtestSFX-utf8.spl')
1102endfunc
1103
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +02001104" When 'spellfile' is not set, adding a new good word will automatically set
1105" the 'spellfile'
1106func Test_init_spellfile()
1107 let save_rtp = &rtp
1108 let save_encoding = &encoding
1109 call mkdir('Xrtp/spell', 'p')
1110 call writefile(['vim'], 'Xrtp/spell/Xtest.dic')
1111 silent mkspell Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest.dic
1112 set runtimepath=./Xrtp
1113 set spelllang=Xtest
1114 set spell
1115 silent spellgood abc
1116 call assert_equal('./Xrtp/spell/Xtest.utf-8.add', &spellfile)
1117 call assert_equal(['abc'], readfile('Xrtp/spell/Xtest.utf-8.add'))
1118 call assert_true(filereadable('Xrtp/spell/Xtest.utf-8.spl'))
1119 set spell& spelllang& spellfile&
1120 call delete('Xrtp', 'rf')
1121 let &encoding = save_encoding
1122 let &rtp = save_rtp
1123 %bw!
1124endfunc
1125
Bram Moolenaarb9fc1922020-08-25 21:19:36 +02001126" Test for the 'mkspellmem' option
1127func Test_mkspellmem_opt()
1128 call assert_fails('set mkspellmem=1000', 'E474:')
1129 call assert_fails('set mkspellmem=1000,', 'E474:')
1130 call assert_fails('set mkspellmem=1000,50', 'E474:')
1131 call assert_fails('set mkspellmem=1000,50,', 'E474:')
1132 call assert_fails('set mkspellmem=1000,50,10,', 'E474:')
1133 call assert_fails('set mkspellmem=1000,50,0', 'E474:')
1134endfunc
1135
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001136" vim: shiftwidth=2 sts=2 expandtab