blob: d8d954b3bf053017c1b7bc04b521ad15fc120a3d [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
Bram Moolenaar56564962022-10-10 22:39:42 +0100215 call mkdir('Xtest/spell', 'pR')
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
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200387endfunc
388
389" Test for format errors in suggest file
390func Test_sugfile_format_error()
391 let save_rtp = &rtp
Bram Moolenaar56564962022-10-10 22:39:42 +0100392 call mkdir('Xtest/spell', 'pR')
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200393 let splfile = './Xtest/spell/Xtest.utf-8.spl'
394 let sugfile = './Xtest/spell/Xtest.utf-8.sug'
395
396 " create an empty spell file with a suggest timestamp
397 call writefile(0z56494D7370656C6C320B00000000080000000000000044FF000000000000000000000000, splfile, 'b')
398
399 " 'encoding' is set before each test to clear the previously loaded suggest
400 " file from memory.
401
402 " empty suggest file
403 set encoding=utf-8
404 call writefile([], sugfile)
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200405 set runtimepath=./Xtest
406 set spelllang=Xtest
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200407 set spell
408 call assert_fails("let s = spellsuggest('abc')", 'E778:')
409 set nospell spelllang&
410
411 " zero suggest version
412 set encoding=utf-8
413 call writefile(0z56494D73756700, sugfile)
414 set runtimepath=./Xtest
415 set spelllang=Xtest
416 set spell
417 call assert_fails("let s = spellsuggest('abc')", 'E779:')
418 set nospell spelllang&
419
420 " unsupported suggest version
421 set encoding=utf-8
422 call writefile(0z56494D7375671F, sugfile)
423 set runtimepath=./Xtest
424 set spelllang=Xtest
425 set spell
426 call assert_fails("let s = spellsuggest('abc')", 'E780:')
427 set nospell spelllang&
428
429 " missing suggest timestamp
430 set encoding=utf-8
431 call writefile(0z56494D73756701, sugfile)
432 set runtimepath=./Xtest
433 set spelllang=Xtest
434 set spell
435 call assert_fails("let s = spellsuggest('abc')", 'E781:')
436 set nospell spelllang&
437
438 " incorrect suggest timestamp
439 set encoding=utf-8
440 call writefile(0z56494D7375670100000000000000FF, sugfile)
441 set runtimepath=./Xtest
442 set spelllang=Xtest
443 set spell
444 call assert_fails("let s = spellsuggest('abc')", 'E781:')
445 set nospell spelllang&
446
447 " missing suggest wordtree
448 set encoding=utf-8
449 call writefile(0z56494D737567010000000000000044, sugfile)
450 set runtimepath=./Xtest
451 set spelllang=Xtest
452 set spell
453 call assert_fails("let s = spellsuggest('abc')", 'E782:')
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200454 set nospell spelllang&
455
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200456 " invalid suggest word count in SUGTABLE
457 set encoding=utf-8
458 call writefile(0z56494D7375670100000000000000440000000022, sugfile)
459 set runtimepath=./Xtest
460 set spelllang=Xtest
461 set spell
462 call assert_fails("let s = spellsuggest('abc')", 'E782:')
463 set nospell spelllang&
464
465 " missing sugline in SUGTABLE
466 set encoding=utf-8
467 call writefile(0z56494D7375670100000000000000440000000000000005, sugfile)
468 set runtimepath=./Xtest
469 set spelllang=Xtest
470 set spell
471 call assert_fails("let s = spellsuggest('abc')", 'E782:')
472 set nospell spelllang&
473
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200474 let &rtp = save_rtp
Bram Moolenaarc0f88232020-08-16 21:51:49 +0200475endfunc
476
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200477" Test for using :mkspell to create a spell file from a list of words
478func Test_wordlist_dic()
479 " duplicate encoding
480 let lines =<< trim [END]
481 # This is an example word list
482
483 /encoding=latin1
484 /encoding=latin1
485 example
486 [END]
Bram Moolenaar56564962022-10-10 22:39:42 +0100487 call writefile(lines, 'Xwordlist.dic', 'D')
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200488 let output = execute('mkspell Xwordlist.spl Xwordlist.dic')
489 call assert_match('Duplicate /encoding= line ignored in Xwordlist.dic line 4: /encoding=latin1', output)
490
491 " multiple encoding for a word
492 let lines =<< trim [END]
493 example
494 /encoding=latin1
495 example
496 [END]
497 call writefile(lines, 'Xwordlist.dic')
498 let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
499 call assert_match('/encoding= line after word ignored in Xwordlist.dic line 2: /encoding=latin1', output)
500
501 " unsupported encoding for a word
502 let lines =<< trim [END]
503 /encoding=Xtest
504 example
505 [END]
506 call writefile(lines, 'Xwordlist.dic')
507 let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
508 call assert_match('Conversion in Xwordlist.dic not supported: from Xtest to utf-8', output)
509
510 " duplicate region
511 let lines =<< trim [END]
512 /regions=usca
513 /regions=usca
514 example
515 [END]
516 call writefile(lines, 'Xwordlist.dic')
517 let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
518 call assert_match('Duplicate /regions= line ignored in Xwordlist.dic line 2: regions=usca', output)
519
520 " maximum regions
521 let lines =<< trim [END]
522 /regions=uscauscauscauscausca
523 example
524 [END]
525 call writefile(lines, 'Xwordlist.dic')
526 let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
527 call assert_match('Too many regions in Xwordlist.dic line 1: uscauscauscauscausca', output)
528
529 " unsupported '/' value
530 let lines =<< trim [END]
531 /test=abc
532 example
533 [END]
534 call writefile(lines, 'Xwordlist.dic')
535 let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
536 call assert_match('/ line ignored in Xwordlist.dic line 1: /test=abc', output)
537
538 " unsupported flag
539 let lines =<< trim [END]
540 example/+
541 [END]
542 call writefile(lines, 'Xwordlist.dic')
543 let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
544 call assert_match('Unrecognized flags in Xwordlist.dic line 1: +', output)
545
546 " non-ascii word
547 call writefile(["ʀʀ"], 'Xwordlist.dic')
548 let output = execute('mkspell! -ascii Xwordlist.spl Xwordlist.dic')
549 call assert_match('Ignored 1 words with non-ASCII characters', output)
550
Bram Moolenaar64e2db62020-09-09 22:43:19 +0200551 " keep case of a word
552 let lines =<< trim [END]
553 example/=
554 [END]
555 call writefile(lines, 'Xwordlist.dic')
556 let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
557 call assert_match('Compressed keep-case:', output)
558
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200559 call delete('Xwordlist.spl')
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200560endfunc
561
562" Test for the :mkspell command
563func Test_mkspell()
564 call assert_fails('mkspell Xtest_us.spl', 'E751:')
Bram Moolenaar96fdf432020-09-11 18:11:50 +0200565 call assert_fails('mkspell Xtest.spl abc', 'E484:')
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200566 call assert_fails('mkspell a b c d e f g h i j k', 'E754:')
567
Bram Moolenaar96fdf432020-09-11 18:11:50 +0200568 " create a .aff file but not the .dic file
569 call writefile([], 'Xtest.aff')
570 call assert_fails('mkspell Xtest.spl Xtest', 'E484:')
571 call delete('Xtest.aff')
572
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200573 call writefile([], 'Xtest.spl')
574 call writefile([], 'Xtest.dic')
575 call assert_fails('mkspell Xtest.spl Xtest.dic', 'E13:')
576 call delete('Xtest.spl')
577 call delete('Xtest.dic')
578
579 call mkdir('Xtest.spl')
580 call assert_fails('mkspell! Xtest.spl Xtest.dic', 'E17:')
581 call delete('Xtest.spl', 'rf')
582
Dominique Pelle5a6cfb32021-05-29 17:29:33 +0200583 " can't write the .spl file as its directory does not exist
584 call writefile([], 'Xtest.aff')
585 call writefile([], 'Xtest.dic')
586 call assert_fails('mkspell DOES_NOT_EXIT/Xtest.spl Xtest.dic', 'E484:')
587 call delete('Xtest.aff')
588 call delete('Xtest.dic')
589
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200590 call assert_fails('mkspell en en_US abc_xyz', 'E755:')
591endfunc
592
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200593" Tests for :mkspell with a .dic and .aff file
594func Test_aff_file_format_error()
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200595 " FIXME: For some reason, the :mkspell command below doesn't fail on the
596 " MS-Windows CI build. Disable this test on MS-Windows for now.
597 CheckNotMSWindows
598
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200599 " No word count in .dic file
Bram Moolenaar56564962022-10-10 22:39:42 +0100600 call writefile([], 'Xtest.dic', 'D')
601 call writefile([], 'Xtest.aff', 'D')
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200602 call assert_fails('mkspell! Xtest.spl Xtest', 'E760:')
603
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200604 " create a .dic file for the tests below
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200605 call writefile(['1', 'work'], 'Xtest.dic')
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200606
607 " Invalid encoding in .aff file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200608 call writefile(['# comment', 'SET Xinvalidencoding'], 'Xtest.aff')
609 let output = execute('mkspell! Xtest.spl Xtest')
610 call assert_match('Conversion in Xtest.aff not supported: from xinvalidencoding', output)
611
612 " Invalid flag in .aff file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200613 call writefile(['FLAG xxx'], 'Xtest.aff')
614 let output = execute('mkspell! Xtest.spl Xtest')
615 call assert_match('Invalid value for FLAG in Xtest.aff line 1: xxx', output)
616
617 " set FLAGS after using flag for an affix
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200618 call writefile(['SFX L Y 1', 'SFX L 0 re [^x]', 'FLAG long'], 'Xtest.aff')
619 let output = execute('mkspell! Xtest.spl Xtest')
620 call assert_match('FLAG after using flags in Xtest.aff line 3: long', output)
621
622 " INFO in affix file
623 let save_encoding = &encoding
624 call mkdir('Xrtp/spell', 'p')
625 call writefile(['1', 'work'], 'Xrtp/spell/Xtest.dic')
626 call writefile(['NAME klingon', 'VERSION 1.4', 'AUTHOR Spock'],
627 \ 'Xrtp/spell/Xtest.aff')
628 silent mkspell! Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest
629 let save_rtp = &rtp
630 set runtimepath=./Xrtp
631 set spelllang=Xtest
632 set spell
633 let output = split(execute('spellinfo'), "\n")
634 call assert_equal("NAME klingon", output[1])
635 call assert_equal("VERSION 1.4", output[2])
636 call assert_equal("AUTHOR Spock", output[3])
637 let &rtp = save_rtp
638 call delete('Xrtp', 'rf')
639 set spell& spelllang& spellfile&
640 %bw!
641 " 'encoding' must be set again to clear the spell file in memory
642 let &encoding = save_encoding
643
644 " COMPOUNDFORBIDFLAG flag after PFX in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200645 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDFLAG c', 'COMPOUNDFORBIDFLAG x'],
646 \ 'Xtest.aff')
647 let output = execute('mkspell! Xtest.spl Xtest')
648 call assert_match('Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in Xtest.aff line 4', output)
649
650 " COMPOUNDPERMITFLAG flag after PFX in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200651 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDPERMITFLAG c'],
652 \ 'Xtest.aff')
653 let output = execute('mkspell! Xtest.spl Xtest')
654 call assert_match('Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in Xtest.aff line 3', output)
655
656 " Wrong COMPOUNDRULES flag value in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200657 call writefile(['COMPOUNDRULES a'], 'Xtest.aff')
658 let output = execute('mkspell! Xtest.spl Xtest')
659 call assert_match('Wrong COMPOUNDRULES value in Xtest.aff line 1: a', output)
660
661 " Wrong COMPOUNDWORDMAX flag value in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200662 call writefile(['COMPOUNDWORDMAX 0'], 'Xtest.aff')
663 let output = execute('mkspell! Xtest.spl Xtest')
664 call assert_match('Wrong COMPOUNDWORDMAX value in Xtest.aff line 1: 0', output)
665
666 " Wrong COMPOUNDMIN flag value in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200667 call writefile(['COMPOUNDMIN 0'], 'Xtest.aff')
668 let output = execute('mkspell! Xtest.spl Xtest')
669 call assert_match('Wrong COMPOUNDMIN value in Xtest.aff line 1: 0', output)
670
671 " Wrong COMPOUNDSYLMAX flag value in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200672 call writefile(['COMPOUNDSYLMAX 0'], 'Xtest.aff')
673 let output = execute('mkspell! Xtest.spl Xtest')
674 call assert_match('Wrong COMPOUNDSYLMAX value in Xtest.aff line 1: 0', output)
675
676 " Wrong CHECKCOMPOUNDPATTERN flag value in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200677 call writefile(['CHECKCOMPOUNDPATTERN 0'], 'Xtest.aff')
678 let output = execute('mkspell! Xtest.spl Xtest')
679 call assert_match('Wrong CHECKCOMPOUNDPATTERN value in Xtest.aff line 1: 0', output)
680
Dominique Pellebb162362021-05-31 20:04:07 +0200681 " Both compounding and NOBREAK specified
682 call writefile(['COMPOUNDFLAG c', 'NOBREAK'], 'Xtest.aff')
683 let output = execute('mkspell! Xtest.spl Xtest')
684 call assert_match('Warning: both compounding and NOBREAK specified', output)
685
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200686 " Duplicate affix entry in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200687 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L Y 1', 'PFX L 0 re x'],
688 \ 'Xtest.aff')
689 let output = execute('mkspell! Xtest.spl Xtest')
690 call assert_match('Duplicate affix in Xtest.aff line 3: L', output)
691
692 " Duplicate affix entry in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200693 call writefile(['PFX L Y 1', 'PFX L Y 1'], 'Xtest.aff')
694 let output = execute('mkspell! Xtest.spl Xtest')
695 call assert_match('Unrecognized or duplicate item in Xtest.aff line 2: PFX', output)
696
697 " Different combining flags in an affix file
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200698 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L N 1'], 'Xtest.aff')
699 let output = execute('mkspell! Xtest.spl Xtest')
700 call assert_match('Different combining flag in continued affix block in Xtest.aff line 3', output)
701
Dominique Pelle923dce22021-11-21 11:36:04 +0000702 " Try to reuse an affix used for BAD flag
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200703 call writefile(['BAD x', 'PFX x Y 1', 'PFX x 0 re x'], 'Xtest.aff')
704 let output = execute('mkspell! Xtest.spl Xtest')
705 call assert_match('Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in Xtest.aff line 2: x', output)
706
707 " Trailing characters in an affix entry
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200708 call writefile(['PFX L Y 1 Test', 'PFX L 0 re x'], 'Xtest.aff')
709 let output = execute('mkspell! Xtest.spl Xtest')
710 call assert_match('Trailing text in Xtest.aff line 1: Test', output)
711
712 " Trailing characters in an affix entry
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200713 call writefile(['PFX L Y 1', 'PFX L 0 re x Test'], 'Xtest.aff')
714 let output = execute('mkspell! Xtest.spl Xtest')
715 call assert_match('Trailing text in Xtest.aff line 2: Test', output)
716
717 " Incorrect combine flag in an affix entry
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200718 call writefile(['PFX L X 1', 'PFX L 0 re x'], 'Xtest.aff')
719 let output = execute('mkspell! Xtest.spl Xtest')
720 call assert_match('Expected Y or N in Xtest.aff line 1: X', output)
721
722 " Invalid count for REP item
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200723 call writefile(['REP a'], 'Xtest.aff')
724 let output = execute('mkspell! Xtest.spl Xtest')
725 call assert_match('Expected REP(SAL) count in Xtest.aff line 1', output)
726
727 " Trailing characters in REP item
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200728 call writefile(['REP 1', 'REP f ph test'], 'Xtest.aff')
729 let output = execute('mkspell! Xtest.spl Xtest')
730 call assert_match('Trailing text in Xtest.aff line 2: test', output)
731
732 " Invalid count for MAP item
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200733 call writefile(['MAP a'], 'Xtest.aff')
734 let output = execute('mkspell! Xtest.spl Xtest')
735 call assert_match('Expected MAP count in Xtest.aff line 1', output)
736
737 " Duplicate character in a MAP item
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200738 call writefile(['MAP 2', 'MAP xx', 'MAP yy'], 'Xtest.aff')
739 let output = execute('mkspell! Xtest.spl Xtest')
740 call assert_match('Duplicate character in MAP in Xtest.aff line 2', output)
741
742 " Use COMPOUNDSYLMAX without SYLLABLE
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200743 call writefile(['COMPOUNDSYLMAX 2'], 'Xtest.aff')
744 let output = execute('mkspell! Xtest.spl Xtest')
745 call assert_match('COMPOUNDSYLMAX used without SYLLABLE', output)
746
747 " Missing SOFOTO
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200748 call writefile(['SOFOFROM abcdef'], 'Xtest.aff')
749 let output = execute('mkspell! Xtest.spl Xtest')
750 call assert_match('Missing SOFOTO line in Xtest.aff', output)
751
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200752 " Length of SOFOFROM and SOFOTO differ
753 call writefile(['SOFOFROM abcde', 'SOFOTO ABCD'], 'Xtest.aff')
754 call assert_fails('mkspell! Xtest.spl Xtest', 'E759:')
755
756 " Both SAL and SOFOFROM/SOFOTO items
757 call writefile(['SOFOFROM abcd', 'SOFOTO ABCD', 'SAL CIA X'], 'Xtest.aff')
758 let output = execute('mkspell! Xtest.spl Xtest')
759 call assert_match('Both SAL and SOFO lines in Xtest.aff', output)
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200760
761 " use an alphabet flag when FLAG is num
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200762 call writefile(['FLAG num', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff')
763 let output = execute('mkspell! Xtest.spl Xtest')
764 call assert_match('Flag is not a number in Xtest.aff line 2: L', output)
765
766 " use number and alphabet flag when FLAG is num
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200767 call writefile(['FLAG num', 'SFX 4f Y 1', 'SFX 4f 0 re [^x]'], 'Xtest.aff')
768 let output = execute('mkspell! Xtest.spl Xtest')
769 call assert_match('Affix name too long in Xtest.aff line 2: 4f', output)
770
771 " use a single character flag when FLAG is long
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200772 call writefile(['FLAG long', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff')
773 let output = execute('mkspell! Xtest.spl Xtest')
774 call assert_match('Illegal flag in Xtest.aff line 2: L', output)
775
Bram Moolenaar64e2db62020-09-09 22:43:19 +0200776 " missing character in UPP entry. The character table is used only in a
777 " non-utf8 encoding
778 call writefile(['FOL abc', 'LOW abc', 'UPP A'], 'Xtest.aff')
779 let save_encoding = &encoding
780 set encoding=cp949
781 call assert_fails('mkspell! Xtest.spl Xtest', 'E761:')
782 let &encoding = save_encoding
783
784 " character range doesn't match between FOL and LOW entries
785 call writefile(["FOL \u0102bc", 'LOW abc', 'UPP ABC'], 'Xtest.aff')
786 let save_encoding = &encoding
787 set encoding=cp949
788 call assert_fails('mkspell! Xtest.spl Xtest', 'E762:')
789 let &encoding = save_encoding
790
791 " character range doesn't match between FOL and UPP entries
792 call writefile(["FOL \u0102bc", "LOW \u0102bc", 'UPP ABC'], 'Xtest.aff')
793 let save_encoding = &encoding
794 set encoding=cp949
795 call assert_fails('mkspell! Xtest.spl Xtest', 'E762:')
796 let &encoding = save_encoding
797
798 " additional characters in LOW and UPP entries
799 call writefile(["FOL ab", "LOW abc", 'UPP ABC'], 'Xtest.aff')
800 let save_encoding = &encoding
801 set encoding=cp949
802 call assert_fails('mkspell! Xtest.spl Xtest', 'E761:')
803 let &encoding = save_encoding
804
Bram Moolenaar96fdf432020-09-11 18:11:50 +0200805 " missing UPP entry
806 call writefile(["FOL abc", "LOW abc"], 'Xtest.aff')
807 let save_encoding = &encoding
808 set encoding=cp949
809 let output = execute('mkspell! Xtest.spl Xtest')
810 call assert_match('Missing FOL/LOW/UPP line in Xtest.aff', output)
811 let &encoding = save_encoding
812
Bram Moolenaarb9fc1922020-08-25 21:19:36 +0200813 " duplicate word in the .dic file
814 call writefile(['2', 'good', 'good', 'good'], 'Xtest.dic')
815 call writefile(['NAME vim'], 'Xtest.aff')
816 let output = execute('mkspell! Xtest.spl Xtest')
817 call assert_match('First duplicate word in Xtest.dic line 3: good', output)
818 call assert_match('2 duplicate word(s) in Xtest.dic', output)
819
Bram Moolenaar96fdf432020-09-11 18:11:50 +0200820 " use multiple .aff files with different values for COMPOUNDWORDMAX and
821 " MIDWORD (number and string)
Bram Moolenaar56564962022-10-10 22:39:42 +0100822 call writefile(['1', 'world'], 'Xtest_US.dic', 'D')
823 call writefile(['1', 'world'], 'Xtest_CA.dic', 'D')
824 call writefile(["COMPOUNDWORDMAX 3", "MIDWORD '-"], 'Xtest_US.aff', 'D')
825 call writefile(["COMPOUNDWORDMAX 4", "MIDWORD '="], 'Xtest_CA.aff', 'D')
Bram Moolenaar96fdf432020-09-11 18:11:50 +0200826 let output = execute('mkspell! Xtest.spl Xtest_US Xtest_CA')
827 call assert_match('COMPOUNDWORDMAX value differs from what is used in another .aff file', output)
828 call assert_match('MIDWORD value differs from what is used in another .aff file', output)
Bram Moolenaar96fdf432020-09-11 18:11:50 +0200829
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +0200830 call delete('Xtest.spl')
831 call delete('Xtest.sug')
832endfunc
833
Bram Moolenaarfc2a47f2020-08-20 15:41:55 +0200834func Test_spell_add_word()
835 set spellfile=
836 call assert_fails('spellgood abc', 'E764:')
837
838 set spellfile=Xtest.utf-8.add
839 call assert_fails('2spellgood abc', 'E765:')
840
841 edit Xtest.utf-8.add
842 call setline(1, 'sample')
843 call assert_fails('spellgood abc', 'E139:')
844 set spellfile&
845 %bw!
846endfunc
847
Dominique Pelle5a6cfb32021-05-29 17:29:33 +0200848func Test_spellfile_verbose()
Bram Moolenaar56564962022-10-10 22:39:42 +0100849 call writefile(['1', 'one'], 'XtestVerbose.dic', 'D')
850 call writefile([], 'XtestVerbose.aff', 'D')
Dominique Pelle5a6cfb32021-05-29 17:29:33 +0200851 mkspell! XtestVerbose-utf8.spl XtestVerbose
852 set spell
853
854 " First time: the spl file should be read.
855 let a = execute('3verbose set spelllang=XtestVerbose-utf8.spl')
856 call assert_match('Reading spell file "XtestVerbose-utf8.spl"', a)
857
858 " Second time time: the spl file should not be read (already read).
859 let a = execute('3verbose set spelllang=XtestVerbose-utf8.spl')
860 call assert_notmatch('Reading spell file "XtestVerbose-utf8.spl"', a)
861
862 set spell& spelllang&
Dominique Pelle5a6cfb32021-05-29 17:29:33 +0200863 call delete('XtestVerbose-utf8.spl')
864endfunc
865
866" Test NOBREAK (see :help spell-NOBREAK)
867func Test_NOBREAK()
Bram Moolenaar56564962022-10-10 22:39:42 +0100868 call writefile(['3', 'one', 'two', 'three' ], 'XtestNOBREAK.dic', 'D')
869 call writefile(['NOBREAK' ], 'XtestNOBREAK.aff', 'D')
Dominique Pelle5a6cfb32021-05-29 17:29:33 +0200870
871 mkspell! XtestNOBREAK-utf8.spl XtestNOBREAK
872 set spell spelllang=XtestNOBREAK-utf8.spl
873
874 call assert_equal(['', ''], spellbadword('One two three onetwo onetwothree threetwoone'))
875
876 call assert_equal(['x', 'bad'], spellbadword('x'))
877 call assert_equal(['y', 'bad'], spellbadword('yone'))
878 call assert_equal(['z', 'bad'], spellbadword('onez'))
879 call assert_equal(['zero', 'bad'], spellbadword('Onetwozerothree'))
880
Dominique Pellebb162362021-05-31 20:04:07 +0200881 new
882 call setline(1, 'Onetwwothree')
883 norm! fw1z=
884 call assert_equal('Onetwothree', getline(1))
885 call setline(1, 'Onetwothre')
886 norm! fh1z=
887 call assert_equal('Onetwothree', getline(1))
888
889 bw!
Dominique Pelle5a6cfb32021-05-29 17:29:33 +0200890 set spell& spelllang&
Dominique Pelle5a6cfb32021-05-29 17:29:33 +0200891 call delete('XtestNOBREAK-utf8.spl')
892endfunc
893
Dominique Pelledc3275a2021-05-28 18:32:12 +0200894" Test CHECKCOMPOUNDPATTERN (see :help spell-CHECKCOMPOUNDPATTERN)
895func Test_spellfile_CHECKCOMPOUNDPATTERN()
896 call writefile(['4',
897 \ 'one/c',
898 \ 'two/c',
899 \ 'three/c',
Bram Moolenaar56564962022-10-10 22:39:42 +0100900 \ 'four'], 'XtestCHECKCOMPOUNDPATTERN.dic', 'D')
Dominique Pelledc3275a2021-05-28 18:32:12 +0200901 " Forbid compound words where first word ends with 'wo' and second starts with 'on'.
902 call writefile(['CHECKCOMPOUNDPATTERN 1',
903 \ 'CHECKCOMPOUNDPATTERN wo on',
Bram Moolenaar56564962022-10-10 22:39:42 +0100904 \ 'COMPOUNDFLAG c'], 'XtestCHECKCOMPOUNDPATTERN.aff', 'D')
Dominique Pelledc3275a2021-05-28 18:32:12 +0200905
Dominique Pelle5a6cfb32021-05-29 17:29:33 +0200906 mkspell! XtestCHECKCOMPOUNDPATTERN-utf8.spl XtestCHECKCOMPOUNDPATTERN
Dominique Pelledc3275a2021-05-28 18:32:12 +0200907 set spell spelllang=XtestCHECKCOMPOUNDPATTERN-utf8.spl
908
909 " Check valid words with and without valid compounds.
910 for goodword in ['one', 'two', 'three', 'four',
911 \ 'oneone', 'onetwo', 'onethree',
912 \ 'twotwo', 'twothree',
913 \ 'threeone', 'threetwo', 'threethree',
914 \ 'onetwothree', 'onethreetwo', 'twothreeone', 'oneoneone']
915 call assert_equal(['', ''], spellbadword(goodword), goodword)
916 endfor
917
918 " Compounds 'twoone' or 'threetwoone' should be forbidden by CHECKCOMPOUNPATTERN.
919 " 'four' does not have the 'c' flag in *.aff file so no compound.
920 " 'five' is not in the *.dic file.
921 for badword in ['five', 'onetwox',
922 \ 'twoone', 'threetwoone',
923 \ 'fourone', 'onefour']
924 call assert_equal([badword, 'bad'], spellbadword(badword))
925 endfor
926
927 set spell& spelllang&
Dominique Pelledc3275a2021-05-28 18:32:12 +0200928 call delete('XtestCHECKCOMPOUNDPATTERN-utf8.spl')
929endfunc
930
Dominique Pelle9c9472f2021-07-24 20:51:13 +0200931" Test NOCOMPOUNDSUGS (see :help spell-NOCOMPOUNDSUGS)
932func Test_spellfile_NOCOMPOUNDSUGS()
933 call writefile(['3',
934 \ 'one/c',
935 \ 'two/c',
Bram Moolenaar56564962022-10-10 22:39:42 +0100936 \ 'three/c'], 'XtestNOCOMPOUNDSUGS.dic', 'D')
Dominique Pelle9c9472f2021-07-24 20:51:13 +0200937
938 " pass 0 tests without NOCOMPOUNDSUGS, pass 1 tests with NOCOMPOUNDSUGS
939 for pass in [0, 1]
940 if pass == 0
Bram Moolenaar56564962022-10-10 22:39:42 +0100941 call writefile(['COMPOUNDFLAG c'], 'XtestNOCOMPOUNDSUGS.aff', 'D')
Dominique Pelle9c9472f2021-07-24 20:51:13 +0200942 else
943 call writefile(['NOCOMPOUNDSUGS',
Bram Moolenaar56564962022-10-10 22:39:42 +0100944 \ 'COMPOUNDFLAG c'], 'XtestNOCOMPOUNDSUGS.aff', 'D')
Dominique Pelle9c9472f2021-07-24 20:51:13 +0200945 endif
946
947 mkspell! XtestNOCOMPOUNDSUGS-utf8.spl XtestNOCOMPOUNDSUGS
948 set spell spelllang=XtestNOCOMPOUNDSUGS-utf8.spl
949
950 for goodword in ['one', 'two', 'three',
951 \ 'oneone', 'onetwo', 'onethree',
952 \ 'twoone', 'twotwo', 'twothree',
953 \ 'threeone', 'threetwo', 'threethree',
954 \ 'onetwothree', 'onethreetwo', 'twothreeone', 'oneoneone']
955 call assert_equal(['', ''], spellbadword(goodword), goodword)
956 endfor
957
958 for badword in ['four', 'onetwox', 'onexone']
959 call assert_equal([badword, 'bad'], spellbadword(badword))
960 endfor
961
962 if pass == 0
963 call assert_equal(['one', 'oneone'], spellsuggest('onne', 2))
964 call assert_equal(['onethree', 'one three'], spellsuggest('onethre', 2))
965 else
966 call assert_equal(['one', 'one one'], spellsuggest('onne', 2))
967 call assert_equal(['one three'], spellsuggest('onethre', 2))
968 endif
969 endfor
970
971 set spell& spelllang&
Dominique Pelle9c9472f2021-07-24 20:51:13 +0200972 call delete('XtestNOCOMPOUNDSUGS-utf8.spl')
973endfunc
974
Dominique Pelledc3275a2021-05-28 18:32:12 +0200975" Test COMMON (better suggestions with common words, see :help spell-COMMON)
976func Test_spellfile_COMMON()
977 call writefile(['7',
978 \ 'and',
979 \ 'ant',
980 \ 'end',
981 \ 'any',
982 \ 'tee',
983 \ 'the',
Bram Moolenaar56564962022-10-10 22:39:42 +0100984 \ 'ted'], 'XtestCOMMON.dic', 'D')
985 call writefile(['COMMON the and'], 'XtestCOMMON.aff', 'D')
Dominique Pelledc3275a2021-05-28 18:32:12 +0200986
Dominique Pelle5a6cfb32021-05-29 17:29:33 +0200987 mkspell! XtestCOMMON-utf8.spl XtestCOMMON
Dominique Pelledc3275a2021-05-28 18:32:12 +0200988 set spell spelllang=XtestCOMMON-utf8.spl
989
990 " COMMON words 'and' and 'the' should be the top suggestions.
991 call assert_equal(['and', 'ant'], spellsuggest('anr', 2))
992 call assert_equal(['and', 'end'], spellsuggest('ond', 2))
993 call assert_equal(['the', 'ted'], spellsuggest('tha', 2))
994 call assert_equal(['the', 'tee'], spellsuggest('dhe', 2))
995
996 set spell& spelllang&
Dominique Pelledc3275a2021-05-28 18:32:12 +0200997 call delete('XtestCOMMON-utf8.spl')
998endfunc
999
Dominique Pellebfb2bb12021-08-14 21:11:51 +02001000" Test NOSUGGEST (see :help spell-COMMON)
1001func Test_spellfile_NOSUGGEST()
Bram Moolenaar56564962022-10-10 22:39:42 +01001002 call writefile(['2', 'foo/X', 'fog'], 'XtestNOSUGGEST.dic', 'D')
1003 call writefile(['NOSUGGEST X'], 'XtestNOSUGGEST.aff', 'D')
Dominique Pellebfb2bb12021-08-14 21:11:51 +02001004
1005 mkspell! XtestNOSUGGEST-utf8.spl XtestNOSUGGEST
1006 set spell spelllang=XtestNOSUGGEST-utf8.spl
1007
1008 for goodword in ['foo', 'Foo', 'FOO', 'fog', 'Fog', 'FOG']
1009 call assert_equal(['', ''], spellbadword(goodword), goodword)
1010 endfor
1011 for badword in ['foO', 'fOO', 'fooo', 'foog', 'foofog', 'fogfoo']
1012 call assert_equal([badword, 'bad'], spellbadword(badword))
1013 endfor
1014
1015 call assert_equal(['fog'], spellsuggest('fooo', 1))
1016 call assert_equal(['fog'], spellsuggest('fOo', 1))
1017 call assert_equal(['fog'], spellsuggest('foG', 1))
1018 call assert_equal(['fog'], spellsuggest('fogg', 1))
1019
1020 set spell& spelllang&
Dominique Pellebfb2bb12021-08-14 21:11:51 +02001021 call delete('XtestNOSUGGEST-utf8.spl')
1022endfunc
1023
1024
Dominique Pelle5a6cfb32021-05-29 17:29:33 +02001025" Test CIRCUMFIX (see: :help spell-CIRCUMFIX)
1026func Test_spellfile_CIRCUMFIX()
1027 " Example taken verbatim from https://github.com/hunspell/hunspell/tree/master/tests
1028 call writefile(['1',
Bram Moolenaar56564962022-10-10 22:39:42 +01001029 \ 'nagy/C po:adj'], 'XtestCIRCUMFIX.dic', 'D')
Dominique Pelle5a6cfb32021-05-29 17:29:33 +02001030 call writefile(['# circumfixes: ~ obligate prefix/suffix combinations',
1031 \ '# superlative in Hungarian: leg- (prefix) AND -bb (suffix)',
1032 \ '',
1033 \ 'CIRCUMFIX X',
1034 \ '',
1035 \ 'PFX A Y 1',
1036 \ 'PFX A 0 leg/X .',
1037 \ '',
1038 \ 'PFX B Y 1',
1039 \ 'PFX B 0 legesleg/X .',
1040 \ '',
1041 \ 'SFX C Y 3',
1042 \ 'SFX C 0 obb . is:COMPARATIVE',
1043 \ 'SFX C 0 obb/AX . is:SUPERLATIVE',
Bram Moolenaar56564962022-10-10 22:39:42 +01001044 \ 'SFX C 0 obb/BX . is:SUPERSUPERLATIVE'], 'XtestCIRCUMFIX.aff', 'D')
Dominique Pelle5a6cfb32021-05-29 17:29:33 +02001045
1046 mkspell! XtestCIRCUMFIX-utf8.spl XtestCIRCUMFIX
1047 set spell spelllang=XtestCIRCUMFIX-utf8.spl
1048
1049 " From https://catalog.ldc.upenn.edu/docs/LDC2008T01/acta04.pdf:
1050 " Hungarian English
1051 " --------- -------
1052 " nagy great
1053 " nagyobb greater
1054 " legnagyobb greatest
1055 " legeslegnagyob most greatest
1056 call assert_equal(['', ''], spellbadword('nagy nagyobb legnagyobb legeslegnagyobb'))
1057
1058 for badword in ['legnagy', 'legeslegnagy', 'legobb', 'legeslegobb']
1059 call assert_equal([badword, 'bad'], spellbadword(badword))
1060 endfor
1061
1062 set spell& spelllang&
Dominique Pelle5a6cfb32021-05-29 17:29:33 +02001063 call delete('XtestCIRCUMFIX-utf8.spl')
1064endfunc
1065
Dominique Pellebb162362021-05-31 20:04:07 +02001066" Test SFX that strips/chops characters
1067func Test_spellfile_SFX_strip()
1068 " Simplified conjugation of Italian verbs ending in -are (first conjugation).
1069 call writefile(['SFX A Y 4',
1070 \ 'SFX A are iamo [^icg]are',
1071 \ 'SFX A are hiamo [cg]are',
1072 \ 'SFX A re mo iare',
1073 \ 'SFX A re vamo are'],
Bram Moolenaar56564962022-10-10 22:39:42 +01001074 \ 'XtestSFX.aff', 'D')
Dominique Pellebb162362021-05-31 20:04:07 +02001075 " Examples of Italian verbs:
1076 " - cantare = to sing
1077 " - cercare = to search
1078 " - odiare = to hate
Bram Moolenaar56564962022-10-10 22:39:42 +01001079 call writefile(['3', 'cantare/A', 'cercare/A', 'odiare/A'], 'XtestSFX.dic', 'D')
Dominique Pellebb162362021-05-31 20:04:07 +02001080
1081 mkspell! XtestSFX-utf8.spl XtestSFX
1082 set spell spelllang=XtestSFX-utf8.spl
1083
1084 " To sing, we're singing, we were singing.
1085 call assert_equal(['', ''], spellbadword('cantare cantiamo cantavamo'))
1086
1087 " To search, we're searching, we were searching.
1088 call assert_equal(['', ''], spellbadword('cercare cerchiamo cercavamo'))
1089
1090 " To hate, we hate, we were hating.
1091 call assert_equal(['', ''], spellbadword('odiare odiamo odiavamo'))
1092
1093 for badword in ['canthiamo', 'cerciamo', 'cantarevamo', 'odiiamo']
1094 call assert_equal([badword, 'bad'], spellbadword(badword))
1095 endfor
1096
1097 call assert_equal(['cantiamo'], spellsuggest('canthiamo', 1))
1098 call assert_equal(['cerchiamo'], spellsuggest('cerciamo', 1))
1099 call assert_equal(['cantavamo'], spellsuggest('cantarevamo', 1))
1100 call assert_equal(['odiamo'], spellsuggest('odiiamo', 1))
1101
1102 set spell& spelllang&
Dominique Pellebb162362021-05-31 20:04:07 +02001103 call delete('XtestSFX-utf8.spl')
1104endfunc
1105
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +02001106" When 'spellfile' is not set, adding a new good word will automatically set
1107" the 'spellfile'
1108func Test_init_spellfile()
1109 let save_rtp = &rtp
1110 let save_encoding = &encoding
Bram Moolenaar56564962022-10-10 22:39:42 +01001111 call mkdir('Xrtp/spell', 'pR')
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +02001112 call writefile(['vim'], 'Xrtp/spell/Xtest.dic')
1113 silent mkspell Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest.dic
1114 set runtimepath=./Xrtp
1115 set spelllang=Xtest
1116 set spell
1117 silent spellgood abc
1118 call assert_equal('./Xrtp/spell/Xtest.utf-8.add', &spellfile)
1119 call assert_equal(['abc'], readfile('Xrtp/spell/Xtest.utf-8.add'))
1120 call assert_true(filereadable('Xrtp/spell/Xtest.utf-8.spl'))
Bram Moolenaar56564962022-10-10 22:39:42 +01001121
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +02001122 set spell& spelllang& spellfile&
Bram Moolenaarc8ec5fe2020-08-24 20:28:56 +02001123 let &encoding = save_encoding
1124 let &rtp = save_rtp
1125 %bw!
1126endfunc
1127
Bram Moolenaarb9fc1922020-08-25 21:19:36 +02001128" Test for the 'mkspellmem' option
1129func Test_mkspellmem_opt()
1130 call assert_fails('set mkspellmem=1000', 'E474:')
1131 call assert_fails('set mkspellmem=1000,', 'E474:')
1132 call assert_fails('set mkspellmem=1000,50', 'E474:')
1133 call assert_fails('set mkspellmem=1000,50,', 'E474:')
1134 call assert_fails('set mkspellmem=1000,50,10,', 'E474:')
1135 call assert_fails('set mkspellmem=1000,50,0', 'E474:')
1136endfunc
1137
Bram Moolenaarbc49c5f2022-08-04 13:01:48 +01001138" 'spellfile' accepts '@' on top of 'isfname'.
1139def Test_spellfile_allow_at_character()
1140 mkdir('Xtest/the foo@bar,dir', 'p')
1141 &spellfile = './Xtest/the foo@bar,dir/Xspellfile.add'
1142 &spellfile = ''
1143 delete('Xtest', 'rf')
1144enddef
1145
Bram Moolenaar6669de12022-08-21 20:33:47 +01001146" this was using a NULL pointer
1147func Test_mkspell_empty_dic()
Bram Moolenaar56564962022-10-10 22:39:42 +01001148 call writefile(['1'], 'XtestEmpty.dic', 'D')
1149 call writefile(['SOFOFROM abcd', 'SOFOTO ABCD', 'SAL CIA X'], 'XtestEmpty.aff', 'D')
Bram Moolenaar6669de12022-08-21 20:33:47 +01001150 mkspell! XtestEmpty.spl XtestEmpty
1151
Bram Moolenaar6669de12022-08-21 20:33:47 +01001152 call delete('XtestEmpty.spl')
1153endfunc
1154
1155
Bram Moolenaar6d91bcb2020-08-12 18:50:36 +02001156" vim: shiftwidth=2 sts=2 expandtab