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  " 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
40  " 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
182  set spellfile= spell& spelllang&
183  bw!
184endfunc
185
186" 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')
194
195  " 'encoding' is set before each test to clear the previously loaded suggest
196  " file from memory.
197  set encoding=utf-8
198
199  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
213func Test_spellfile_format_error()
214  let save_rtp = &rtp
215  call mkdir('Xtest/spell', 'p')
216  let splfile = './Xtest/spell/Xtest.utf-8.spl'
217
218  " empty spell file
219  call writefile([], splfile)
220  set runtimepath=./Xtest
221  set spelllang=Xtest
222  call assert_fails('set spell', 'E757:')
223  set nospell spelllang&
224
225  " invalid file ID
226  call writefile(0z56494D, splfile, 'b')
227  set runtimepath=./Xtest
228  set spelllang=Xtest
229  call assert_fails('set spell', 'E757:')
230  set nospell spelllang&
231
232  " missing version number
233  call writefile(0z56494D7370656C6C, splfile, 'b')
234  set runtimepath=./Xtest
235  set spelllang=Xtest
236  call assert_fails('set spell', 'E771:')
237  set nospell spelllang&
238
239  " invalid version number
240  call writefile(0z56494D7370656C6C7A, splfile, 'b')
241  set runtimepath=./Xtest
242  set spelllang=Xtest
243  call assert_fails('set spell', 'E772:')
244  set nospell spelllang&
245
246  " no sections
247  call Spellfile_Test(0z, 'E758:')
248
249  " missing section length
250  call Spellfile_Test(0z00, 'E758:')
251
252  " unsupported required section
253  call Spellfile_Test(0z7A0100000004, 'E770:')
254
255  " unsupported not-required section
256  call Spellfile_Test(0z7A0000000004, 'E758:')
257
258  " SN_REGION: invalid number of region names
259  call Spellfile_Test(0z0000000000FF, 'E759:')
260
261  " SN_CHARFLAGS: missing <charflagslen> length
262  call Spellfile_Test(0z010000000004, 'E758:')
263
264  " SN_CHARFLAGS: invalid <charflagslen> length
265  call Spellfile_Test(0z0100000000010201, '')
266
267  " SN_CHARFLAGS: charflagslen == 0 and folcharslen != 0
268  call Spellfile_Test(0z01000000000400000101, 'E759:')
269
270  " SN_CHARFLAGS: missing <folcharslen> length
271  call Spellfile_Test(0z01000000000100, 'E758:')
272
273  " SN_PREFCOND: invalid prefcondcnt
274  call Spellfile_Test(0z03000000000100, 'E759:')
275
276  " SN_PREFCOND: invalid condlen
277  call Spellfile_Test(0z0300000000020001, 'E759:')
278
279  " SN_REP: invalid repcount
280  call Spellfile_Test(0z04000000000100, 'E758:')
281
282  " SN_REP: missing rep
283  call Spellfile_Test(0z0400000000020004, 'E758:')
284
285  " SN_REP: zero repfromlen
286  call Spellfile_Test(0z040000000003000100, 'E759:')
287
288  " SN_REP: invalid reptolen
289  call Spellfile_Test(0z0400000000050001014101, '')
290
291  " SN_REP: zero reptolen
292  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
319  " SN_SOFO: empty sofofrom and sofoto
320  call Spellfile_Test(0z06000000000400000000FF000000000000000000000000, '')
321
322  " SN_SOFO: multi-byte characters in sofofrom and sofoto
323  call Spellfile_Test(0z0600000000080002CF810002CF82FF000000000000000000000000, '')
324
325  " 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
334  " SN_COMPOUND: missing comppattern
335  call Spellfile_Test(0z08000000000704010100000001, 'E758:')
336
337  " SN_COMPOUND: incorrect comppatlen
338  call Spellfile_Test(0z080000000007040101000000020165, 'E758:')
339
340  " 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
349  " SN_MAP: empty map string
350  call Spellfile_Test(0z070000000000FF000000000000000000000000, '')
351
352  " SN_MAP: duplicate multibyte character
353  call Spellfile_Test(0z070000000004DC81DC81, 'E783:')
354
355  " 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
371  " LWORDTREE: incorrect sibling node count
372  call Spellfile_Test(0zFF00000001040000000000000000, 'E759:')
373
374  " KWORDTREE: missing tree node
375  call Spellfile_Test(0zFF0000000000000004, 'E758:')
376
377  " PREFIXTREE: missing tree node
378  call Spellfile_Test(0zFF000000000000000000000004, 'E758:')
379
380  " PREFIXTREE: incorrect prefcondnr
381  call Spellfile_Test(0zFF000000000000000000000002010200000020, 'E759:')
382
383  " PREFIXTREE: invalid nodeidx
384  call Spellfile_Test(0zFF00000000000000000000000201010000, 'E759:')
385
386  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)
406  set runtimepath=./Xtest
407  set spelllang=Xtest
408  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:')
455  set nospell spelllang&
456
457  " 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
475  let &rtp = save_rtp
476  call delete('Xtest', 'rf')
477endfunc
478
479" 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
553  " 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
561  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:')
568  call assert_fails('mkspell Xtest.spl abc', 'E484:')
569  call assert_fails('mkspell a b c d e f g h i j k', 'E754:')
570
571  " 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
576  call writefile([], 'Xtest.spl')
577  call writefile([], 'Xtest.dic')
578  call assert_fails('mkspell Xtest.spl Xtest.dic', 'E13:')
579  call delete('Xtest.spl')
580  call delete('Xtest.dic')
581
582  call mkdir('Xtest.spl')
583  call assert_fails('mkspell! Xtest.spl Xtest.dic', 'E17:')
584  call delete('Xtest.spl', 'rf')
585
586  call assert_fails('mkspell en en_US abc_xyz', 'E755:')
587endfunc
588
589" Tests for :mkspell with a .dic and .aff file
590func Test_aff_file_format_error()
591  " FIXME: For some reason, the :mkspell command below doesn't fail on the
592  " MS-Windows CI build. Disable this test on MS-Windows for now.
593  CheckNotMSWindows
594
595  " No word count in .dic file
596  call writefile([], 'Xtest.dic')
597  call writefile([], 'Xtest.aff')
598  call assert_fails('mkspell! Xtest.spl Xtest', 'E760:')
599
600  " create a .dic file for the tests below
601  call writefile(['1', 'work'], 'Xtest.dic')
602
603  " Invalid encoding in .aff file
604  call writefile(['# comment', 'SET Xinvalidencoding'], 'Xtest.aff')
605  let output = execute('mkspell! Xtest.spl Xtest')
606  call assert_match('Conversion in Xtest.aff not supported: from xinvalidencoding', output)
607
608  " Invalid flag in .aff file
609  call writefile(['FLAG xxx'], 'Xtest.aff')
610  let output = execute('mkspell! Xtest.spl Xtest')
611  call assert_match('Invalid value for FLAG in Xtest.aff line 1: xxx', output)
612
613  " set FLAGS after using flag for an affix
614  call writefile(['SFX L Y 1', 'SFX L 0 re [^x]', 'FLAG long'], 'Xtest.aff')
615  let output = execute('mkspell! Xtest.spl Xtest')
616  call assert_match('FLAG after using flags in Xtest.aff line 3: long', output)
617
618  " INFO in affix file
619  let save_encoding = &encoding
620  call mkdir('Xrtp/spell', 'p')
621  call writefile(['1', 'work'], 'Xrtp/spell/Xtest.dic')
622  call writefile(['NAME klingon', 'VERSION 1.4', 'AUTHOR Spock'],
623        \ 'Xrtp/spell/Xtest.aff')
624  silent mkspell! Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest
625  let save_rtp = &rtp
626  set runtimepath=./Xrtp
627  set spelllang=Xtest
628  set spell
629  let output = split(execute('spellinfo'), "\n")
630  call assert_equal("NAME klingon", output[1])
631  call assert_equal("VERSION 1.4", output[2])
632  call assert_equal("AUTHOR Spock", output[3])
633  let &rtp = save_rtp
634  call delete('Xrtp', 'rf')
635  set spell& spelllang& spellfile&
636  %bw!
637  " 'encoding' must be set again to clear the spell file in memory
638  let &encoding = save_encoding
639
640  " COMPOUNDFORBIDFLAG flag after PFX in an affix file
641  call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDFLAG c', 'COMPOUNDFORBIDFLAG x'],
642        \ 'Xtest.aff')
643  let output = execute('mkspell! Xtest.spl Xtest')
644  call assert_match('Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in Xtest.aff line 4', output)
645
646  " COMPOUNDPERMITFLAG flag after PFX in an affix file
647  call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDPERMITFLAG c'],
648        \ 'Xtest.aff')
649  let output = execute('mkspell! Xtest.spl Xtest')
650  call assert_match('Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in Xtest.aff line 3', output)
651
652  " Wrong COMPOUNDRULES flag value in an affix file
653  call writefile(['COMPOUNDRULES a'], 'Xtest.aff')
654  let output = execute('mkspell! Xtest.spl Xtest')
655  call assert_match('Wrong COMPOUNDRULES value in Xtest.aff line 1: a', output)
656
657  " Wrong COMPOUNDWORDMAX flag value in an affix file
658  call writefile(['COMPOUNDWORDMAX 0'], 'Xtest.aff')
659  let output = execute('mkspell! Xtest.spl Xtest')
660  call assert_match('Wrong COMPOUNDWORDMAX value in Xtest.aff line 1: 0', output)
661
662  " Wrong COMPOUNDMIN flag value in an affix file
663  call writefile(['COMPOUNDMIN 0'], 'Xtest.aff')
664  let output = execute('mkspell! Xtest.spl Xtest')
665  call assert_match('Wrong COMPOUNDMIN value in Xtest.aff line 1: 0', output)
666
667  " Wrong COMPOUNDSYLMAX flag value in an affix file
668  call writefile(['COMPOUNDSYLMAX 0'], 'Xtest.aff')
669  let output = execute('mkspell! Xtest.spl Xtest')
670  call assert_match('Wrong COMPOUNDSYLMAX value in Xtest.aff line 1: 0', output)
671
672  " Wrong CHECKCOMPOUNDPATTERN flag value in an affix file
673  call writefile(['CHECKCOMPOUNDPATTERN 0'], 'Xtest.aff')
674  let output = execute('mkspell! Xtest.spl Xtest')
675  call assert_match('Wrong CHECKCOMPOUNDPATTERN value in Xtest.aff line 1: 0', output)
676
677  " Duplicate affix entry in an affix file
678  call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L Y 1', 'PFX L 0 re x'],
679        \ 'Xtest.aff')
680  let output = execute('mkspell! Xtest.spl Xtest')
681  call assert_match('Duplicate affix in Xtest.aff line 3: L', output)
682
683  " Duplicate affix entry in an affix file
684  call writefile(['PFX L Y 1', 'PFX L Y 1'], 'Xtest.aff')
685  let output = execute('mkspell! Xtest.spl Xtest')
686  call assert_match('Unrecognized or duplicate item in Xtest.aff line 2: PFX', output)
687
688  " Different combining flags in an affix file
689  call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L N 1'], 'Xtest.aff')
690  let output = execute('mkspell! Xtest.spl Xtest')
691  call assert_match('Different combining flag in continued affix block in Xtest.aff line 3', output)
692
693  " Try to reuse a affix used for BAD flag
694  call writefile(['BAD x', 'PFX x Y 1', 'PFX x 0 re x'], 'Xtest.aff')
695  let output = execute('mkspell! Xtest.spl Xtest')
696  call assert_match('Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in Xtest.aff line 2: x', output)
697
698  " Trailing characters in an affix entry
699  call writefile(['PFX L Y 1 Test', 'PFX L 0 re x'], 'Xtest.aff')
700  let output = execute('mkspell! Xtest.spl Xtest')
701  call assert_match('Trailing text in Xtest.aff line 1: Test', output)
702
703  " Trailing characters in an affix entry
704  call writefile(['PFX L Y 1', 'PFX L 0 re x Test'], 'Xtest.aff')
705  let output = execute('mkspell! Xtest.spl Xtest')
706  call assert_match('Trailing text in Xtest.aff line 2: Test', output)
707
708  " Incorrect combine flag in an affix entry
709  call writefile(['PFX L X 1', 'PFX L 0 re x'], 'Xtest.aff')
710  let output = execute('mkspell! Xtest.spl Xtest')
711  call assert_match('Expected Y or N in Xtest.aff line 1: X', output)
712
713  " Invalid count for REP item
714  call writefile(['REP a'], 'Xtest.aff')
715  let output = execute('mkspell! Xtest.spl Xtest')
716  call assert_match('Expected REP(SAL) count in Xtest.aff line 1', output)
717
718  " Trailing characters in REP item
719  call writefile(['REP 1', 'REP f ph test'], 'Xtest.aff')
720  let output = execute('mkspell! Xtest.spl Xtest')
721  call assert_match('Trailing text in Xtest.aff line 2: test', output)
722
723  " Invalid count for MAP item
724  call writefile(['MAP a'], 'Xtest.aff')
725  let output = execute('mkspell! Xtest.spl Xtest')
726  call assert_match('Expected MAP count in Xtest.aff line 1', output)
727
728  " Duplicate character in a MAP item
729  call writefile(['MAP 2', 'MAP xx', 'MAP yy'], 'Xtest.aff')
730  let output = execute('mkspell! Xtest.spl Xtest')
731  call assert_match('Duplicate character in MAP in Xtest.aff line 2', output)
732
733  " Use COMPOUNDSYLMAX without SYLLABLE
734  call writefile(['COMPOUNDSYLMAX 2'], 'Xtest.aff')
735  let output = execute('mkspell! Xtest.spl Xtest')
736  call assert_match('COMPOUNDSYLMAX used without SYLLABLE', output)
737
738  " Missing SOFOTO
739  call writefile(['SOFOFROM abcdef'], 'Xtest.aff')
740  let output = execute('mkspell! Xtest.spl Xtest')
741  call assert_match('Missing SOFOTO line in Xtest.aff', output)
742
743  " Length of SOFOFROM and SOFOTO differ
744  call writefile(['SOFOFROM abcde', 'SOFOTO ABCD'], 'Xtest.aff')
745  call assert_fails('mkspell! Xtest.spl Xtest', 'E759:')
746
747  " Both SAL and SOFOFROM/SOFOTO items
748  call writefile(['SOFOFROM abcd', 'SOFOTO ABCD', 'SAL CIA X'], 'Xtest.aff')
749  let output = execute('mkspell! Xtest.spl Xtest')
750  call assert_match('Both SAL and SOFO lines in Xtest.aff', output)
751
752  " use an alphabet flag when FLAG is num
753  call writefile(['FLAG num', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff')
754  let output = execute('mkspell! Xtest.spl Xtest')
755  call assert_match('Flag is not a number in Xtest.aff line 2: L', output)
756
757  " use number and alphabet flag when FLAG is num
758  call writefile(['FLAG num', 'SFX 4f Y 1', 'SFX 4f 0 re [^x]'], 'Xtest.aff')
759  let output = execute('mkspell! Xtest.spl Xtest')
760  call assert_match('Affix name too long in Xtest.aff line 2: 4f', output)
761
762  " use a single character flag when FLAG is long
763  call writefile(['FLAG long', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff')
764  let output = execute('mkspell! Xtest.spl Xtest')
765  call assert_match('Illegal flag in Xtest.aff line 2: L', output)
766
767  " missing character in UPP entry. The character table is used only in a
768  " non-utf8 encoding
769  call writefile(['FOL abc', 'LOW abc', 'UPP A'], 'Xtest.aff')
770  let save_encoding = &encoding
771  set encoding=cp949
772  call assert_fails('mkspell! Xtest.spl Xtest', 'E761:')
773  let &encoding = save_encoding
774
775  " character range doesn't match between FOL and LOW entries
776  call writefile(["FOL \u0102bc", 'LOW abc', 'UPP ABC'], 'Xtest.aff')
777  let save_encoding = &encoding
778  set encoding=cp949
779  call assert_fails('mkspell! Xtest.spl Xtest', 'E762:')
780  let &encoding = save_encoding
781
782  " character range doesn't match between FOL and UPP entries
783  call writefile(["FOL \u0102bc", "LOW \u0102bc", 'UPP ABC'], 'Xtest.aff')
784  let save_encoding = &encoding
785  set encoding=cp949
786  call assert_fails('mkspell! Xtest.spl Xtest', 'E762:')
787  let &encoding = save_encoding
788
789  " additional characters in LOW and UPP entries
790  call writefile(["FOL ab", "LOW abc", 'UPP ABC'], 'Xtest.aff')
791  let save_encoding = &encoding
792  set encoding=cp949
793  call assert_fails('mkspell! Xtest.spl Xtest', 'E761:')
794  let &encoding = save_encoding
795
796  " missing UPP entry
797  call writefile(["FOL abc", "LOW abc"], 'Xtest.aff')
798  let save_encoding = &encoding
799  set encoding=cp949
800  let output = execute('mkspell! Xtest.spl Xtest')
801  call assert_match('Missing FOL/LOW/UPP line in Xtest.aff', output)
802  let &encoding = save_encoding
803
804  " duplicate word in the .dic file
805  call writefile(['2', 'good', 'good', 'good'], 'Xtest.dic')
806  call writefile(['NAME vim'], 'Xtest.aff')
807  let output = execute('mkspell! Xtest.spl Xtest')
808  call assert_match('First duplicate word in Xtest.dic line 3: good', output)
809  call assert_match('2 duplicate word(s) in Xtest.dic', output)
810
811  " use multiple .aff files with different values for COMPOUNDWORDMAX and
812  " MIDWORD (number and string)
813  call writefile(['1', 'world'], 'Xtest_US.dic')
814  call writefile(['1', 'world'], 'Xtest_CA.dic')
815  call writefile(["COMPOUNDWORDMAX 3", "MIDWORD '-"], 'Xtest_US.aff')
816  call writefile(["COMPOUNDWORDMAX 4", "MIDWORD '="], 'Xtest_CA.aff')
817  let output = execute('mkspell! Xtest.spl Xtest_US Xtest_CA')
818  call assert_match('COMPOUNDWORDMAX value differs from what is used in another .aff file', output)
819  call assert_match('MIDWORD value differs from what is used in another .aff file', output)
820  call delete('Xtest_US.dic')
821  call delete('Xtest_CA.dic')
822  call delete('Xtest_US.aff')
823  call delete('Xtest_CA.aff')
824
825  call delete('Xtest.dic')
826  call delete('Xtest.aff')
827  call delete('Xtest.spl')
828  call delete('Xtest.sug')
829endfunc
830
831func Test_spell_add_word()
832  set spellfile=
833  call assert_fails('spellgood abc', 'E764:')
834
835  set spellfile=Xtest.utf-8.add
836  call assert_fails('2spellgood abc', 'E765:')
837
838  edit Xtest.utf-8.add
839  call setline(1, 'sample')
840  call assert_fails('spellgood abc', 'E139:')
841  set spellfile&
842  %bw!
843endfunc
844
845" When 'spellfile' is not set, adding a new good word will automatically set
846" the 'spellfile'
847func Test_init_spellfile()
848  let save_rtp = &rtp
849  let save_encoding = &encoding
850  call mkdir('Xrtp/spell', 'p')
851  call writefile(['vim'], 'Xrtp/spell/Xtest.dic')
852  silent mkspell Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest.dic
853  set runtimepath=./Xrtp
854  set spelllang=Xtest
855  set spell
856  silent spellgood abc
857  call assert_equal('./Xrtp/spell/Xtest.utf-8.add', &spellfile)
858  call assert_equal(['abc'], readfile('Xrtp/spell/Xtest.utf-8.add'))
859  call assert_true(filereadable('Xrtp/spell/Xtest.utf-8.spl'))
860  set spell& spelllang& spellfile&
861  call delete('Xrtp', 'rf')
862  let &encoding = save_encoding
863  let &rtp = save_rtp
864  %bw!
865endfunc
866
867" Test for the 'mkspellmem' option
868func Test_mkspellmem_opt()
869  call assert_fails('set mkspellmem=1000', 'E474:')
870  call assert_fails('set mkspellmem=1000,', 'E474:')
871  call assert_fails('set mkspellmem=1000,50', 'E474:')
872  call assert_fails('set mkspellmem=1000,50,', 'E474:')
873  call assert_fails('set mkspellmem=1000,50,10,', 'E474:')
874  call assert_fails('set mkspellmem=1000,50,0', 'E474:')
875endfunc
876
877" vim: shiftwidth=2 sts=2 expandtab
878