1" 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
28  " Test for zw
29  2
30  norm! $zw
31  1
32  norm! ]s
33  call assert_equal('2 goood', getline('.'))
34  let cnt=readfile('./Xspellfile.add')
35  call assert_equal('#oood', cnt[0])
36  call assert_equal('goood/!', cnt[1])
37
38  " Test for :spellrare
39  spellrare rare
40  let cnt=readfile('./Xspellfile.add')
41  call assert_equal(['#oood', 'goood/!', 'rare/?'], cnt)
42
43  " Make sure :spellundo works for rare words.
44  spellundo rare
45  let cnt=readfile('./Xspellfile.add')
46  call assert_equal(['#oood', 'goood/!', '#are/?'], cnt)
47
48  " Test for zg in visual mode
49  let a=execute('unsilent :norm! V$zg')
50  call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:])
51  1
52  norm! ]s
53  call assert_equal('3 goood', getline('.'))
54  let cnt=readfile('./Xspellfile.add')
55  call assert_equal('2 goood', cnt[3])
56  " Remove "2 good" from spellfile
57  2
58  let a=execute('unsilent norm! V$zw')
59  call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:])
60  let cnt=readfile('./Xspellfile.add')
61  call assert_equal('2 goood/!', cnt[4])
62
63  " Test for zG
64  let a=execute('unsilent norm! V$zG')
65  call assert_match("Word '2 goood' added to .*", a)
66  let fname=matchstr(a, 'to\s\+\zs\f\+$')
67  let cnt=readfile(fname)
68  call assert_equal('2 goood', cnt[0])
69
70  " Test for zW
71  let a=execute('unsilent norm! V$zW')
72  call assert_match("Word '2 goood' added to .*", a)
73  let cnt=readfile(fname)
74  call assert_equal('# goood', cnt[0])
75  call assert_equal('2 goood/!', cnt[1])
76
77  " Test for zuW
78  let a=execute('unsilent norm! V$zuW')
79  call assert_match("Word '2 goood' removed from .*", a)
80  let cnt=readfile(fname)
81  call assert_equal('# goood', cnt[0])
82  call assert_equal('# goood/!', cnt[1])
83
84  " Test for zuG
85  let a=execute('unsilent norm! $zG')
86  call assert_match("Word 'goood' added to .*", a)
87  let cnt=readfile(fname)
88  call assert_equal('# goood', cnt[0])
89  call assert_equal('# goood/!', cnt[1])
90  call assert_equal('goood', cnt[2])
91  let a=execute('unsilent norm! $zuG')
92  let cnt=readfile(fname)
93  call assert_match("Word 'goood' removed from .*", a)
94  call assert_equal('# goood', cnt[0])
95  call assert_equal('# goood/!', cnt[1])
96  call assert_equal('#oood', cnt[2])
97  " word not found in wordlist
98  let a=execute('unsilent norm! V$zuG')
99  let cnt=readfile(fname)
100  call assert_match("", a)
101  call assert_equal('# goood', cnt[0])
102  call assert_equal('# goood/!', cnt[1])
103  call assert_equal('#oood', cnt[2])
104
105  " Test for zug
106  call delete('./Xspellfile.add')
107  2
108  let a=execute('unsilent norm! $zg')
109  let cnt=readfile('./Xspellfile.add')
110  call assert_equal('goood', cnt[0])
111  let a=execute('unsilent norm! $zug')
112  call assert_match("Word 'goood' removed from \./Xspellfile.add", a)
113  let cnt=readfile('./Xspellfile.add')
114  call assert_equal('#oood', cnt[0])
115  " word not in wordlist
116  let a=execute('unsilent norm! V$zug')
117  call assert_match('', a)
118  let cnt=readfile('./Xspellfile.add')
119  call assert_equal('#oood', cnt[0])
120
121  " Test for zuw
122  call delete('./Xspellfile.add')
123  2
124  let a=execute('unsilent norm! Vzw')
125  let cnt=readfile('./Xspellfile.add')
126  call assert_equal('2 goood/!', cnt[0])
127  let a=execute('unsilent norm! Vzuw')
128  call assert_match("Word '2 goood' removed from \./Xspellfile.add", a)
129  let cnt=readfile('./Xspellfile.add')
130  call assert_equal('# goood/!', cnt[0])
131  " word not in wordlist
132  let a=execute('unsilent norm! $zug')
133  call assert_match('', a)
134  let cnt=readfile('./Xspellfile.add')
135  call assert_equal('# goood/!', cnt[0])
136
137  " add second entry to spellfile setting
138  set spellfile=./Xspellfile.add,./Xspellfile2.add
139  call delete('./Xspellfile.add')
140  2
141  let a=execute('unsilent norm! $2zg')
142  let cnt=readfile('./Xspellfile2.add')
143  call assert_match("Word 'goood' added to ./Xspellfile2.add", a)
144  call assert_equal('goood', cnt[0])
145
146  " Test for :spellgood!
147  let temp = execute(':spe!0/0')
148  call assert_match('Invalid region', temp)
149  let spellfile = matchstr(temp, 'Invalid region nr in \zs.*\ze line \d: 0')
150  call assert_equal(['# goood', '# goood/!', '#oood', '0/0'], readfile(spellfile))
151
152  " Test for :spellrare!
153  :spellrare! raare
154  call assert_equal(['# goood', '# goood/!', '#oood', '0/0', 'raare/?'], readfile(spellfile))
155  call delete(spellfile)
156
157  " clean up
158  exe "lang" oldlang
159  call delete("./Xspellfile.add")
160  call delete("./Xspellfile2.add")
161  call delete("./Xspellfile.add.spl")
162  call delete("./Xspellfile2.add.spl")
163
164  " zux -> no-op
165  2
166  norm! $zux
167  call assert_equal([], glob('Xspellfile.add',0,1))
168  call assert_equal([], glob('Xspellfile2.add',0,1))
169
170  set spellfile= spell& spelllang&
171  bw!
172endfunc
173
174" Spell file content test. Write 'content' to the spell file prefixed by the
175" spell file header and then enable spell checking. If 'emsg' is not empty,
176" then check for error.
177func Spellfile_Test(content, emsg)
178  let splfile = './Xtest/spell/Xtest.utf-8.spl'
179  " Add the spell file header and version (VIMspell2)
180  let v = 0z56494D7370656C6C32 + a:content
181  call writefile(v, splfile, 'b')
182  set runtimepath=./Xtest
183  set spelllang=Xtest
184  if a:emsg != ''
185    call assert_fails('set spell', a:emsg)
186  else
187    " FIXME: With some invalid spellfile contents, there are no error
188    " messages. So don't know how to check for the test result.
189    set spell
190  endif
191  set nospell spelllang& rtp&
192endfunc
193
194" Test for spell file format errors.
195" The spell file format is described in spellfile.c
196func Test_spellfile_format_error()
197  let save_rtp = &rtp
198  call mkdir('Xtest/spell', 'p')
199  let splfile = './Xtest/spell/Xtest.utf-8.spl'
200
201  " empty spell file
202  call writefile([], splfile)
203  set runtimepath=./Xtest
204  set spelllang=Xtest
205  call assert_fails('set spell', 'E757:')
206  set nospell spelllang&
207
208  " invalid file ID
209  call writefile(0z56494D, splfile, 'b')
210  set runtimepath=./Xtest
211  set spelllang=Xtest
212  call assert_fails('set spell', 'E757:')
213  set nospell spelllang&
214
215  " missing version number
216  call writefile(0z56494D7370656C6C, splfile, 'b')
217  set runtimepath=./Xtest
218  set spelllang=Xtest
219  call assert_fails('set spell', 'E771:')
220  set nospell spelllang&
221
222  " invalid version number
223  call writefile(0z56494D7370656C6C7A, splfile, 'b')
224  set runtimepath=./Xtest
225  set spelllang=Xtest
226  call assert_fails('set spell', 'E772:')
227  set nospell spelllang&
228
229  " no sections
230  call Spellfile_Test(0z, 'E758:')
231
232  " missing section length
233  call Spellfile_Test(0z00, 'E758:')
234
235  " unsupported required section
236  call Spellfile_Test(0z7A0100000004, 'E770:')
237
238  " unsupported not-required section
239  call Spellfile_Test(0z7A0000000004, 'E758:')
240
241  " SN_REGION: invalid number of region names
242  call Spellfile_Test(0z0000000000FF, 'E759:')
243
244  " SN_CHARFLAGS: missing <charflagslen> length
245  call Spellfile_Test(0z010000000004, 'E758:')
246
247  " SN_CHARFLAGS: invalid <charflagslen> length
248  call Spellfile_Test(0z0100000000010201, '')
249
250  " SN_CHARFLAGS: charflagslen == 0 and folcharslen != 0
251  call Spellfile_Test(0z01000000000400000101, 'E759:')
252
253  " SN_CHARFLAGS: missing <folcharslen> length
254  call Spellfile_Test(0z01000000000100, 'E758:')
255
256  " SN_PREFCOND: invalid prefcondcnt
257  call Spellfile_Test(0z03000000000100, 'E759:')
258
259  " SN_PREFCOND: invalid condlen
260  call Spellfile_Test(0z0300000000020001, 'E759:')
261
262  " SN_REP: invalid repcount
263  call Spellfile_Test(0z04000000000100, 'E758:')
264
265  " SN_REP: missing rep
266  call Spellfile_Test(0z0400000000020004, 'E758:')
267
268  " SN_REP: zero repfromlen
269  call Spellfile_Test(0z040000000003000100, 'E759:')
270
271  " SN_REP: invalid reptolen
272  call Spellfile_Test(0z0400000000050001014101, '')
273
274  " SN_REP: zero reptolen
275  call Spellfile_Test(0z0400000000050001014100, 'E759:')
276
277  " SN_SAL: missing salcount
278  call Spellfile_Test(0z05000000000102, 'E758:')
279
280  " SN_SAL: missing salfromlen
281  call Spellfile_Test(0z050000000003080001, 'E758:')
282
283  " SN_SAL: missing saltolen
284  call Spellfile_Test(0z0500000000050400010161, 'E758:')
285
286  " SN_WORDS: non-NUL terminated word
287  call Spellfile_Test(0z0D000000000376696D, 'E758:')
288
289  " SN_WORDS: very long word
290  let v = eval('0z0D000000012C' .. repeat('41', 300))
291  call Spellfile_Test(v, 'E759:')
292
293  " SN_SOFO: missing sofofromlen
294  call Spellfile_Test(0z06000000000100, 'E758:')
295
296  " SN_SOFO: missing sofotolen
297  call Spellfile_Test(0z06000000000400016100, 'E758:')
298
299  " SN_SOFO: missing sofoto
300  call Spellfile_Test(0z0600000000050001610000, 'E759:')
301
302  " SN_COMPOUND: compmax is less than 2
303  call Spellfile_Test(0z08000000000101, 'E759:')
304
305  " SN_COMPOUND: missing compsylmax and other options
306  call Spellfile_Test(0z0800000000020401, 'E759:')
307
308  " SN_COMPOUND: missing compoptions
309  call Spellfile_Test(0z080000000005040101, 'E758:')
310
311  " SN_INFO: missing info
312  call Spellfile_Test(0z0F0000000005040101, '')
313
314  " SN_MIDWORD: missing midword
315  call Spellfile_Test(0z0200000000040102, '')
316
317  " SN_MAP: missing midword
318  call Spellfile_Test(0z0700000000040102, '')
319
320  " SN_SYLLABLE: missing SYLLABLE item
321  call Spellfile_Test(0z0900000000040102, '')
322
323  " SN_SYLLABLE: More than SY_MAXLEN size
324  let v = eval('0z090000000022612F' .. repeat('62', 32))
325  call Spellfile_Test(v, '')
326
327  " LWORDTREE: missing
328  call Spellfile_Test(0zFF, 'E758:')
329
330  " LWORDTREE: missing tree node
331  call Spellfile_Test(0zFF00000004, 'E758:')
332
333  " LWORDTREE: missing tree node value
334  call Spellfile_Test(0zFF0000000402, 'E758:')
335
336  " KWORDTREE: missing tree node
337  call Spellfile_Test(0zFF0000000000000004, 'E758:')
338
339  " PREFIXTREE: missing tree node
340  call Spellfile_Test(0zFF000000000000000000000004, 'E758:')
341
342  let &rtp = save_rtp
343  call delete('Xtest', 'rf')
344endfunc
345
346" Test for format errors in suggest file
347func Test_sugfile_format_error()
348  let save_rtp = &rtp
349  call mkdir('Xtest/spell', 'p')
350  let splfile = './Xtest/spell/Xtest.utf-8.spl'
351  let sugfile = './Xtest/spell/Xtest.utf-8.sug'
352
353  " create an empty spell file with a suggest timestamp
354  call writefile(0z56494D7370656C6C320B00000000080000000000000044FF000000000000000000000000, splfile, 'b')
355
356  " 'encoding' is set before each test to clear the previously loaded suggest
357  " file from memory.
358
359  " empty suggest file
360  set encoding=utf-8
361  call writefile([], sugfile)
362  set runtimepath=./Xtest
363  set spelllang=Xtest
364  set spell
365  call assert_fails("let s = spellsuggest('abc')", 'E778:')
366  set nospell spelllang&
367
368  " zero suggest version
369  set encoding=utf-8
370  call writefile(0z56494D73756700, sugfile)
371  set runtimepath=./Xtest
372  set spelllang=Xtest
373  set spell
374  call assert_fails("let s = spellsuggest('abc')", 'E779:')
375  set nospell spelllang&
376
377  " unsupported suggest version
378  set encoding=utf-8
379  call writefile(0z56494D7375671F, sugfile)
380  set runtimepath=./Xtest
381  set spelllang=Xtest
382  set spell
383  call assert_fails("let s = spellsuggest('abc')", 'E780:')
384  set nospell spelllang&
385
386  " missing suggest timestamp
387  set encoding=utf-8
388  call writefile(0z56494D73756701, sugfile)
389  set runtimepath=./Xtest
390  set spelllang=Xtest
391  set spell
392  call assert_fails("let s = spellsuggest('abc')", 'E781:')
393  set nospell spelllang&
394
395  " incorrect suggest timestamp
396  set encoding=utf-8
397  call writefile(0z56494D7375670100000000000000FF, sugfile)
398  set runtimepath=./Xtest
399  set spelllang=Xtest
400  set spell
401  call assert_fails("let s = spellsuggest('abc')", 'E781:')
402  set nospell spelllang&
403
404  " missing suggest wordtree
405  set encoding=utf-8
406  call writefile(0z56494D737567010000000000000044, sugfile)
407  set runtimepath=./Xtest
408  set spelllang=Xtest
409  set spell
410  call assert_fails("let s = spellsuggest('abc')", 'E782:')
411  set nospell spelllang&
412
413  " invalid suggest word count in SUGTABLE
414  set encoding=utf-8
415  call writefile(0z56494D7375670100000000000000440000000022, sugfile)
416  set runtimepath=./Xtest
417  set spelllang=Xtest
418  set spell
419  call assert_fails("let s = spellsuggest('abc')", 'E782:')
420  set nospell spelllang&
421
422  " missing sugline in SUGTABLE
423  set encoding=utf-8
424  call writefile(0z56494D7375670100000000000000440000000000000005, sugfile)
425  set runtimepath=./Xtest
426  set spelllang=Xtest
427  set spell
428  call assert_fails("let s = spellsuggest('abc')", 'E782:')
429  set nospell spelllang&
430
431  let &rtp = save_rtp
432  call delete('Xtest', 'rf')
433endfunc
434
435" Test for using :mkspell to create a spell file from a list of words
436func Test_wordlist_dic()
437  " duplicate encoding
438  let lines =<< trim [END]
439    # This is an example word list
440
441    /encoding=latin1
442    /encoding=latin1
443    example
444  [END]
445  call writefile(lines, 'Xwordlist.dic')
446  let output = execute('mkspell Xwordlist.spl Xwordlist.dic')
447  call assert_match('Duplicate /encoding= line ignored in Xwordlist.dic line 4: /encoding=latin1', output)
448
449  " multiple encoding for a word
450  let lines =<< trim [END]
451    example
452    /encoding=latin1
453    example
454  [END]
455  call writefile(lines, 'Xwordlist.dic')
456  let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
457  call assert_match('/encoding= line after word ignored in Xwordlist.dic line 2: /encoding=latin1', output)
458
459  " unsupported encoding for a word
460  let lines =<< trim [END]
461    /encoding=Xtest
462    example
463  [END]
464  call writefile(lines, 'Xwordlist.dic')
465  let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
466  call assert_match('Conversion in Xwordlist.dic not supported: from Xtest to utf-8', output)
467
468  " duplicate region
469  let lines =<< trim [END]
470    /regions=usca
471    /regions=usca
472    example
473  [END]
474  call writefile(lines, 'Xwordlist.dic')
475  let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
476  call assert_match('Duplicate /regions= line ignored in Xwordlist.dic line 2: regions=usca', output)
477
478  " maximum regions
479  let lines =<< trim [END]
480    /regions=uscauscauscauscausca
481    example
482  [END]
483  call writefile(lines, 'Xwordlist.dic')
484  let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
485  call assert_match('Too many regions in Xwordlist.dic line 1: uscauscauscauscausca', output)
486
487  " unsupported '/' value
488  let lines =<< trim [END]
489    /test=abc
490    example
491  [END]
492  call writefile(lines, 'Xwordlist.dic')
493  let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
494  call assert_match('/ line ignored in Xwordlist.dic line 1: /test=abc', output)
495
496  " unsupported flag
497  let lines =<< trim [END]
498    example/+
499  [END]
500  call writefile(lines, 'Xwordlist.dic')
501  let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
502  call assert_match('Unrecognized flags in Xwordlist.dic line 1: +', output)
503
504  " non-ascii word
505  call writefile(["ʀʀ"], 'Xwordlist.dic')
506  let output = execute('mkspell! -ascii Xwordlist.spl Xwordlist.dic')
507  call assert_match('Ignored 1 words with non-ASCII characters', output)
508
509  call delete('Xwordlist.spl')
510  call delete('Xwordlist.dic')
511endfunc
512
513" Test for the :mkspell command
514func Test_mkspell()
515  call assert_fails('mkspell Xtest_us.spl', 'E751:')
516  call assert_fails('mkspell a b c d e f g h i j k', 'E754:')
517
518  call writefile([], 'Xtest.spl')
519  call writefile([], 'Xtest.dic')
520  call assert_fails('mkspell Xtest.spl Xtest.dic', 'E13:')
521  call delete('Xtest.spl')
522  call delete('Xtest.dic')
523
524  call mkdir('Xtest.spl')
525  call assert_fails('mkspell! Xtest.spl Xtest.dic', 'E17:')
526  call delete('Xtest.spl', 'rf')
527
528  call assert_fails('mkspell en en_US abc_xyz', 'E755:')
529endfunc
530
531" Tests for :mkspell with a .dic and .aff file
532func Test_aff_file_format_error()
533  " FIXME: For some reason, the :mkspell command below doesn't fail on the
534  " MS-Windows CI build. Disable this test on MS-Windows for now.
535  CheckNotMSWindows
536
537  " No word count in .dic file
538  call writefile([], 'Xtest.dic')
539  call writefile([], 'Xtest.aff')
540  call assert_fails('mkspell! Xtest.spl Xtest', 'E760:')
541
542  " create a .dic file for the tests below
543  call writefile(['1', 'work'], 'Xtest.dic')
544
545  " Invalid encoding in .aff file
546  call writefile(['# comment', 'SET Xinvalidencoding'], 'Xtest.aff')
547  let output = execute('mkspell! Xtest.spl Xtest')
548  call assert_match('Conversion in Xtest.aff not supported: from xinvalidencoding', output)
549
550  " Invalid flag in .aff file
551  call writefile(['FLAG xxx'], 'Xtest.aff')
552  let output = execute('mkspell! Xtest.spl Xtest')
553  call assert_match('Invalid value for FLAG in Xtest.aff line 1: xxx', output)
554
555  " set FLAGS after using flag for an affix
556  call writefile(['SFX L Y 1', 'SFX L 0 re [^x]', 'FLAG long'], 'Xtest.aff')
557  let output = execute('mkspell! Xtest.spl Xtest')
558  call assert_match('FLAG after using flags in Xtest.aff line 3: long', output)
559
560  " INFO in affix file
561  let save_encoding = &encoding
562  call mkdir('Xrtp/spell', 'p')
563  call writefile(['1', 'work'], 'Xrtp/spell/Xtest.dic')
564  call writefile(['NAME klingon', 'VERSION 1.4', 'AUTHOR Spock'],
565        \ 'Xrtp/spell/Xtest.aff')
566  silent mkspell! Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest
567  let save_rtp = &rtp
568  set runtimepath=./Xrtp
569  set spelllang=Xtest
570  set spell
571  let output = split(execute('spellinfo'), "\n")
572  call assert_equal("NAME klingon", output[1])
573  call assert_equal("VERSION 1.4", output[2])
574  call assert_equal("AUTHOR Spock", output[3])
575  let &rtp = save_rtp
576  call delete('Xrtp', 'rf')
577  set spell& spelllang& spellfile&
578  %bw!
579  " 'encoding' must be set again to clear the spell file in memory
580  let &encoding = save_encoding
581
582  " COMPOUNDFORBIDFLAG flag after PFX in an affix file
583  call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDFLAG c', 'COMPOUNDFORBIDFLAG x'],
584        \ 'Xtest.aff')
585  let output = execute('mkspell! Xtest.spl Xtest')
586  call assert_match('Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in Xtest.aff line 4', output)
587
588  " COMPOUNDPERMITFLAG flag after PFX in an affix file
589  call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDPERMITFLAG c'],
590        \ 'Xtest.aff')
591  let output = execute('mkspell! Xtest.spl Xtest')
592  call assert_match('Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in Xtest.aff line 3', output)
593
594  " Wrong COMPOUNDRULES flag value in an affix file
595  call writefile(['COMPOUNDRULES a'], 'Xtest.aff')
596  let output = execute('mkspell! Xtest.spl Xtest')
597  call assert_match('Wrong COMPOUNDRULES value in Xtest.aff line 1: a', output)
598
599  " Wrong COMPOUNDWORDMAX flag value in an affix file
600  call writefile(['COMPOUNDWORDMAX 0'], 'Xtest.aff')
601  let output = execute('mkspell! Xtest.spl Xtest')
602  call assert_match('Wrong COMPOUNDWORDMAX value in Xtest.aff line 1: 0', output)
603
604  " Wrong COMPOUNDMIN flag value in an affix file
605  call writefile(['COMPOUNDMIN 0'], 'Xtest.aff')
606  let output = execute('mkspell! Xtest.spl Xtest')
607  call assert_match('Wrong COMPOUNDMIN value in Xtest.aff line 1: 0', output)
608
609  " Wrong COMPOUNDSYLMAX flag value in an affix file
610  call writefile(['COMPOUNDSYLMAX 0'], 'Xtest.aff')
611  let output = execute('mkspell! Xtest.spl Xtest')
612  call assert_match('Wrong COMPOUNDSYLMAX value in Xtest.aff line 1: 0', output)
613
614  " Wrong CHECKCOMPOUNDPATTERN flag value in an affix file
615  call writefile(['CHECKCOMPOUNDPATTERN 0'], 'Xtest.aff')
616  let output = execute('mkspell! Xtest.spl Xtest')
617  call assert_match('Wrong CHECKCOMPOUNDPATTERN value in Xtest.aff line 1: 0', output)
618
619  " Duplicate affix entry in an affix file
620  call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L Y 1', 'PFX L 0 re x'],
621        \ 'Xtest.aff')
622  let output = execute('mkspell! Xtest.spl Xtest')
623  call assert_match('Duplicate affix in Xtest.aff line 3: L', output)
624
625  " Duplicate affix entry in an affix file
626  call writefile(['PFX L Y 1', 'PFX L Y 1'], 'Xtest.aff')
627  let output = execute('mkspell! Xtest.spl Xtest')
628  call assert_match('Unrecognized or duplicate item in Xtest.aff line 2: PFX', output)
629
630  " Different combining flags in an affix file
631  call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L N 1'], 'Xtest.aff')
632  let output = execute('mkspell! Xtest.spl Xtest')
633  call assert_match('Different combining flag in continued affix block in Xtest.aff line 3', output)
634
635  " Try to reuse a affix used for BAD flag
636  call writefile(['BAD x', 'PFX x Y 1', 'PFX x 0 re x'], 'Xtest.aff')
637  let output = execute('mkspell! Xtest.spl Xtest')
638  call assert_match('Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in Xtest.aff line 2: x', output)
639
640  " Trailing characters in an affix entry
641  call writefile(['PFX L Y 1 Test', 'PFX L 0 re x'], 'Xtest.aff')
642  let output = execute('mkspell! Xtest.spl Xtest')
643  call assert_match('Trailing text in Xtest.aff line 1: Test', output)
644
645  " Trailing characters in an affix entry
646  call writefile(['PFX L Y 1', 'PFX L 0 re x Test'], 'Xtest.aff')
647  let output = execute('mkspell! Xtest.spl Xtest')
648  call assert_match('Trailing text in Xtest.aff line 2: Test', output)
649
650  " Incorrect combine flag in an affix entry
651  call writefile(['PFX L X 1', 'PFX L 0 re x'], 'Xtest.aff')
652  let output = execute('mkspell! Xtest.spl Xtest')
653  call assert_match('Expected Y or N in Xtest.aff line 1: X', output)
654
655  " Invalid count for REP item
656  call writefile(['REP a'], 'Xtest.aff')
657  let output = execute('mkspell! Xtest.spl Xtest')
658  call assert_match('Expected REP(SAL) count in Xtest.aff line 1', output)
659
660  " Trailing characters in REP item
661  call writefile(['REP 1', 'REP f ph test'], 'Xtest.aff')
662  let output = execute('mkspell! Xtest.spl Xtest')
663  call assert_match('Trailing text in Xtest.aff line 2: test', output)
664
665  " Invalid count for MAP item
666  call writefile(['MAP a'], 'Xtest.aff')
667  let output = execute('mkspell! Xtest.spl Xtest')
668  call assert_match('Expected MAP count in Xtest.aff line 1', output)
669
670  " Duplicate character in a MAP item
671  call writefile(['MAP 2', 'MAP xx', 'MAP yy'], 'Xtest.aff')
672  let output = execute('mkspell! Xtest.spl Xtest')
673  call assert_match('Duplicate character in MAP in Xtest.aff line 2', output)
674
675  " Use COMPOUNDSYLMAX without SYLLABLE
676  call writefile(['COMPOUNDSYLMAX 2'], 'Xtest.aff')
677  let output = execute('mkspell! Xtest.spl Xtest')
678  call assert_match('COMPOUNDSYLMAX used without SYLLABLE', output)
679
680  " Missing SOFOTO
681  call writefile(['SOFOFROM abcdef'], 'Xtest.aff')
682  let output = execute('mkspell! Xtest.spl Xtest')
683  call assert_match('Missing SOFOTO line in Xtest.aff', output)
684
685  " Length of SOFOFROM and SOFOTO differ
686  call writefile(['SOFOFROM abcde', 'SOFOTO ABCD'], 'Xtest.aff')
687  call assert_fails('mkspell! Xtest.spl Xtest', 'E759:')
688
689  " Both SAL and SOFOFROM/SOFOTO items
690  call writefile(['SOFOFROM abcd', 'SOFOTO ABCD', 'SAL CIA X'], 'Xtest.aff')
691  let output = execute('mkspell! Xtest.spl Xtest')
692  call assert_match('Both SAL and SOFO lines in Xtest.aff', output)
693
694  " use an alphabet flag when FLAG is num
695  call writefile(['FLAG num', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff')
696  let output = execute('mkspell! Xtest.spl Xtest')
697  call assert_match('Flag is not a number in Xtest.aff line 2: L', output)
698
699  " use number and alphabet flag when FLAG is num
700  call writefile(['FLAG num', 'SFX 4f Y 1', 'SFX 4f 0 re [^x]'], 'Xtest.aff')
701  let output = execute('mkspell! Xtest.spl Xtest')
702  call assert_match('Affix name too long in Xtest.aff line 2: 4f', output)
703
704  " use a single character flag when FLAG is long
705  call writefile(['FLAG long', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff')
706  let output = execute('mkspell! Xtest.spl Xtest')
707  call assert_match('Illegal flag in Xtest.aff line 2: L', output)
708
709  " duplicate word in the .dic file
710  call writefile(['2', 'good', 'good', 'good'], 'Xtest.dic')
711  call writefile(['NAME vim'], 'Xtest.aff')
712  let output = execute('mkspell! Xtest.spl Xtest')
713  call assert_match('First duplicate word in Xtest.dic line 3: good', output)
714  call assert_match('2 duplicate word(s) in Xtest.dic', output)
715
716  call delete('Xtest.dic')
717  call delete('Xtest.aff')
718  call delete('Xtest.spl')
719  call delete('Xtest.sug')
720endfunc
721
722func Test_spell_add_word()
723  set spellfile=
724  call assert_fails('spellgood abc', 'E764:')
725
726  set spellfile=Xtest.utf-8.add
727  call assert_fails('2spellgood abc', 'E765:')
728
729  edit Xtest.utf-8.add
730  call setline(1, 'sample')
731  call assert_fails('spellgood abc', 'E139:')
732  set spellfile&
733  %bw!
734endfunc
735
736" When 'spellfile' is not set, adding a new good word will automatically set
737" the 'spellfile'
738func Test_init_spellfile()
739  let save_rtp = &rtp
740  let save_encoding = &encoding
741  call mkdir('Xrtp/spell', 'p')
742  call writefile(['vim'], 'Xrtp/spell/Xtest.dic')
743  silent mkspell Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest.dic
744  set runtimepath=./Xrtp
745  set spelllang=Xtest
746  set spell
747  silent spellgood abc
748  call assert_equal('./Xrtp/spell/Xtest.utf-8.add', &spellfile)
749  call assert_equal(['abc'], readfile('Xrtp/spell/Xtest.utf-8.add'))
750  call assert_true(filereadable('Xrtp/spell/Xtest.utf-8.spl'))
751  set spell& spelllang& spellfile&
752  call delete('Xrtp', 'rf')
753  let &encoding = save_encoding
754  let &rtp = save_rtp
755  %bw!
756endfunc
757
758" Test for the 'mkspellmem' option
759func Test_mkspellmem_opt()
760  call assert_fails('set mkspellmem=1000', 'E474:')
761  call assert_fails('set mkspellmem=1000,', 'E474:')
762  call assert_fails('set mkspellmem=1000,50', 'E474:')
763  call assert_fails('set mkspellmem=1000,50,', 'E474:')
764  call assert_fails('set mkspellmem=1000,50,10,', 'E474:')
765  call assert_fails('set mkspellmem=1000,50,0', 'E474:')
766endfunc
767
768" vim: shiftwidth=2 sts=2 expandtab
769