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
183  " 'encoding' is set before each test to clear the previously loaded suggest
184  " file from memory.
185  set encoding=utf-8
186
187  set runtimepath=./Xtest
188  set spelllang=Xtest
189  if a:emsg != ''
190    call assert_fails('set spell', a:emsg)
191  else
192    " FIXME: With some invalid spellfile contents, there are no error
193    " messages. So don't know how to check for the test result.
194    set spell
195  endif
196  set nospell spelllang& rtp&
197endfunc
198
199" Test for spell file format errors.
200" The spell file format is described in spellfile.c
201func Test_spellfile_format_error()
202  let save_rtp = &rtp
203  call mkdir('Xtest/spell', 'p')
204  let splfile = './Xtest/spell/Xtest.utf-8.spl'
205
206  " empty spell file
207  call writefile([], splfile)
208  set runtimepath=./Xtest
209  set spelllang=Xtest
210  call assert_fails('set spell', 'E757:')
211  set nospell spelllang&
212
213  " invalid file ID
214  call writefile(0z56494D, splfile, 'b')
215  set runtimepath=./Xtest
216  set spelllang=Xtest
217  call assert_fails('set spell', 'E757:')
218  set nospell spelllang&
219
220  " missing version number
221  call writefile(0z56494D7370656C6C, splfile, 'b')
222  set runtimepath=./Xtest
223  set spelllang=Xtest
224  call assert_fails('set spell', 'E771:')
225  set nospell spelllang&
226
227  " invalid version number
228  call writefile(0z56494D7370656C6C7A, splfile, 'b')
229  set runtimepath=./Xtest
230  set spelllang=Xtest
231  call assert_fails('set spell', 'E772:')
232  set nospell spelllang&
233
234  " no sections
235  call Spellfile_Test(0z, 'E758:')
236
237  " missing section length
238  call Spellfile_Test(0z00, 'E758:')
239
240  " unsupported required section
241  call Spellfile_Test(0z7A0100000004, 'E770:')
242
243  " unsupported not-required section
244  call Spellfile_Test(0z7A0000000004, 'E758:')
245
246  " SN_REGION: invalid number of region names
247  call Spellfile_Test(0z0000000000FF, 'E759:')
248
249  " SN_CHARFLAGS: missing <charflagslen> length
250  call Spellfile_Test(0z010000000004, 'E758:')
251
252  " SN_CHARFLAGS: invalid <charflagslen> length
253  call Spellfile_Test(0z0100000000010201, '')
254
255  " SN_CHARFLAGS: charflagslen == 0 and folcharslen != 0
256  call Spellfile_Test(0z01000000000400000101, 'E759:')
257
258  " SN_CHARFLAGS: missing <folcharslen> length
259  call Spellfile_Test(0z01000000000100, 'E758:')
260
261  " SN_PREFCOND: invalid prefcondcnt
262  call Spellfile_Test(0z03000000000100, 'E759:')
263
264  " SN_PREFCOND: invalid condlen
265  call Spellfile_Test(0z0300000000020001, 'E759:')
266
267  " SN_REP: invalid repcount
268  call Spellfile_Test(0z04000000000100, 'E758:')
269
270  " SN_REP: missing rep
271  call Spellfile_Test(0z0400000000020004, 'E758:')
272
273  " SN_REP: zero repfromlen
274  call Spellfile_Test(0z040000000003000100, 'E759:')
275
276  " SN_REP: invalid reptolen
277  call Spellfile_Test(0z0400000000050001014101, '')
278
279  " SN_REP: zero reptolen
280  call Spellfile_Test(0z0400000000050001014100, 'E759:')
281
282  " SN_SAL: missing salcount
283  call Spellfile_Test(0z05000000000102, 'E758:')
284
285  " SN_SAL: missing salfromlen
286  call Spellfile_Test(0z050000000003080001, 'E758:')
287
288  " SN_SAL: missing saltolen
289  call Spellfile_Test(0z0500000000050400010161, 'E758:')
290
291  " SN_WORDS: non-NUL terminated word
292  call Spellfile_Test(0z0D000000000376696D, 'E758:')
293
294  " SN_WORDS: very long word
295  let v = eval('0z0D000000012C' .. repeat('41', 300))
296  call Spellfile_Test(v, 'E759:')
297
298  " SN_SOFO: missing sofofromlen
299  call Spellfile_Test(0z06000000000100, 'E758:')
300
301  " SN_SOFO: missing sofotolen
302  call Spellfile_Test(0z06000000000400016100, 'E758:')
303
304  " SN_SOFO: missing sofoto
305  call Spellfile_Test(0z0600000000050001610000, 'E759:')
306
307  " SN_SOFO: empty sofofrom and sofoto
308  call Spellfile_Test(0z06000000000400000000FF000000000000000000000000, '')
309
310  " SN_SOFO: multi-byte characters in sofofrom and sofoto
311  call Spellfile_Test(0z0600000000080002CF810002CF82FF000000000000000000000000, '')
312
313  " SN_COMPOUND: compmax is less than 2
314  call Spellfile_Test(0z08000000000101, 'E759:')
315
316  " SN_COMPOUND: missing compsylmax and other options
317  call Spellfile_Test(0z0800000000020401, 'E759:')
318
319  " SN_COMPOUND: missing compoptions
320  call Spellfile_Test(0z080000000005040101, 'E758:')
321
322  " SN_COMPOUND: missing comppattern
323  call Spellfile_Test(0z08000000000704010100000001, 'E758:')
324
325  " SN_COMPOUND: incorrect comppatlen
326  call Spellfile_Test(0z080000000007040101000000020165, 'E758:')
327
328  " SN_INFO: missing info
329  call Spellfile_Test(0z0F0000000005040101, '')
330
331  " SN_MIDWORD: missing midword
332  call Spellfile_Test(0z0200000000040102, '')
333
334  " SN_MAP: missing midword
335  call Spellfile_Test(0z0700000000040102, '')
336
337  " SN_MAP: empty map string
338  call Spellfile_Test(0z070000000000FF000000000000000000000000, '')
339
340  " SN_MAP: duplicate multibyte character
341  call Spellfile_Test(0z070000000004DC81DC81, 'E783:')
342
343  " SN_SYLLABLE: missing SYLLABLE item
344  call Spellfile_Test(0z0900000000040102, '')
345
346  " SN_SYLLABLE: More than SY_MAXLEN size
347  let v = eval('0z090000000022612F' .. repeat('62', 32))
348  call Spellfile_Test(v, '')
349
350  " LWORDTREE: missing
351  call Spellfile_Test(0zFF, 'E758:')
352
353  " LWORDTREE: missing tree node
354  call Spellfile_Test(0zFF00000004, 'E758:')
355
356  " LWORDTREE: missing tree node value
357  call Spellfile_Test(0zFF0000000402, 'E758:')
358
359  " LWORDTREE: incorrect sibling node count
360  call Spellfile_Test(0zFF00000001040000000000000000, 'E759:')
361
362  " KWORDTREE: missing tree node
363  call Spellfile_Test(0zFF0000000000000004, 'E758:')
364
365  " PREFIXTREE: missing tree node
366  call Spellfile_Test(0zFF000000000000000000000004, 'E758:')
367
368  " PREFIXTREE: incorrect prefcondnr
369  call Spellfile_Test(0zFF000000000000000000000002010200000020, 'E759:')
370
371  " PREFIXTREE: invalid nodeidx
372  call Spellfile_Test(0zFF00000000000000000000000201010000, 'E759:')
373
374  let &rtp = save_rtp
375  call delete('Xtest', 'rf')
376endfunc
377
378" Test for format errors in suggest file
379func Test_sugfile_format_error()
380  let save_rtp = &rtp
381  call mkdir('Xtest/spell', 'p')
382  let splfile = './Xtest/spell/Xtest.utf-8.spl'
383  let sugfile = './Xtest/spell/Xtest.utf-8.sug'
384
385  " create an empty spell file with a suggest timestamp
386  call writefile(0z56494D7370656C6C320B00000000080000000000000044FF000000000000000000000000, splfile, 'b')
387
388  " 'encoding' is set before each test to clear the previously loaded suggest
389  " file from memory.
390
391  " empty suggest file
392  set encoding=utf-8
393  call writefile([], sugfile)
394  set runtimepath=./Xtest
395  set spelllang=Xtest
396  set spell
397  call assert_fails("let s = spellsuggest('abc')", 'E778:')
398  set nospell spelllang&
399
400  " zero suggest version
401  set encoding=utf-8
402  call writefile(0z56494D73756700, sugfile)
403  set runtimepath=./Xtest
404  set spelllang=Xtest
405  set spell
406  call assert_fails("let s = spellsuggest('abc')", 'E779:')
407  set nospell spelllang&
408
409  " unsupported suggest version
410  set encoding=utf-8
411  call writefile(0z56494D7375671F, sugfile)
412  set runtimepath=./Xtest
413  set spelllang=Xtest
414  set spell
415  call assert_fails("let s = spellsuggest('abc')", 'E780:')
416  set nospell spelllang&
417
418  " missing suggest timestamp
419  set encoding=utf-8
420  call writefile(0z56494D73756701, sugfile)
421  set runtimepath=./Xtest
422  set spelllang=Xtest
423  set spell
424  call assert_fails("let s = spellsuggest('abc')", 'E781:')
425  set nospell spelllang&
426
427  " incorrect suggest timestamp
428  set encoding=utf-8
429  call writefile(0z56494D7375670100000000000000FF, sugfile)
430  set runtimepath=./Xtest
431  set spelllang=Xtest
432  set spell
433  call assert_fails("let s = spellsuggest('abc')", 'E781:')
434  set nospell spelllang&
435
436  " missing suggest wordtree
437  set encoding=utf-8
438  call writefile(0z56494D737567010000000000000044, sugfile)
439  set runtimepath=./Xtest
440  set spelllang=Xtest
441  set spell
442  call assert_fails("let s = spellsuggest('abc')", 'E782:')
443  set nospell spelllang&
444
445  " invalid suggest word count in SUGTABLE
446  set encoding=utf-8
447  call writefile(0z56494D7375670100000000000000440000000022, sugfile)
448  set runtimepath=./Xtest
449  set spelllang=Xtest
450  set spell
451  call assert_fails("let s = spellsuggest('abc')", 'E782:')
452  set nospell spelllang&
453
454  " missing sugline in SUGTABLE
455  set encoding=utf-8
456  call writefile(0z56494D7375670100000000000000440000000000000005, sugfile)
457  set runtimepath=./Xtest
458  set spelllang=Xtest
459  set spell
460  call assert_fails("let s = spellsuggest('abc')", 'E782:')
461  set nospell spelllang&
462
463  let &rtp = save_rtp
464  call delete('Xtest', 'rf')
465endfunc
466
467" Test for using :mkspell to create a spell file from a list of words
468func Test_wordlist_dic()
469  " duplicate encoding
470  let lines =<< trim [END]
471    # This is an example word list
472
473    /encoding=latin1
474    /encoding=latin1
475    example
476  [END]
477  call writefile(lines, 'Xwordlist.dic')
478  let output = execute('mkspell Xwordlist.spl Xwordlist.dic')
479  call assert_match('Duplicate /encoding= line ignored in Xwordlist.dic line 4: /encoding=latin1', output)
480
481  " multiple encoding for a word
482  let lines =<< trim [END]
483    example
484    /encoding=latin1
485    example
486  [END]
487  call writefile(lines, 'Xwordlist.dic')
488  let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
489  call assert_match('/encoding= line after word ignored in Xwordlist.dic line 2: /encoding=latin1', output)
490
491  " unsupported encoding for a word
492  let lines =<< trim [END]
493    /encoding=Xtest
494    example
495  [END]
496  call writefile(lines, 'Xwordlist.dic')
497  let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
498  call assert_match('Conversion in Xwordlist.dic not supported: from Xtest to utf-8', output)
499
500  " duplicate region
501  let lines =<< trim [END]
502    /regions=usca
503    /regions=usca
504    example
505  [END]
506  call writefile(lines, 'Xwordlist.dic')
507  let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
508  call assert_match('Duplicate /regions= line ignored in Xwordlist.dic line 2: regions=usca', output)
509
510  " maximum regions
511  let lines =<< trim [END]
512    /regions=uscauscauscauscausca
513    example
514  [END]
515  call writefile(lines, 'Xwordlist.dic')
516  let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
517  call assert_match('Too many regions in Xwordlist.dic line 1: uscauscauscauscausca', output)
518
519  " unsupported '/' value
520  let lines =<< trim [END]
521    /test=abc
522    example
523  [END]
524  call writefile(lines, 'Xwordlist.dic')
525  let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
526  call assert_match('/ line ignored in Xwordlist.dic line 1: /test=abc', output)
527
528  " unsupported flag
529  let lines =<< trim [END]
530    example/+
531  [END]
532  call writefile(lines, 'Xwordlist.dic')
533  let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
534  call assert_match('Unrecognized flags in Xwordlist.dic line 1: +', output)
535
536  " non-ascii word
537  call writefile(["ʀʀ"], 'Xwordlist.dic')
538  let output = execute('mkspell! -ascii Xwordlist.spl Xwordlist.dic')
539  call assert_match('Ignored 1 words with non-ASCII characters', output)
540
541  " keep case of a word
542  let lines =<< trim [END]
543    example/=
544  [END]
545  call writefile(lines, 'Xwordlist.dic')
546  let output = execute('mkspell! Xwordlist.spl Xwordlist.dic')
547  call assert_match('Compressed keep-case:', output)
548
549  call delete('Xwordlist.spl')
550  call delete('Xwordlist.dic')
551endfunc
552
553" Test for the :mkspell command
554func Test_mkspell()
555  call assert_fails('mkspell Xtest_us.spl', 'E751:')
556  call assert_fails('mkspell Xtest.spl abc', 'E484:')
557  call assert_fails('mkspell a b c d e f g h i j k', 'E754:')
558
559  " create a .aff file but not the .dic file
560  call writefile([], 'Xtest.aff')
561  call assert_fails('mkspell Xtest.spl Xtest', 'E484:')
562  call delete('Xtest.aff')
563
564  call writefile([], 'Xtest.spl')
565  call writefile([], 'Xtest.dic')
566  call assert_fails('mkspell Xtest.spl Xtest.dic', 'E13:')
567  call delete('Xtest.spl')
568  call delete('Xtest.dic')
569
570  call mkdir('Xtest.spl')
571  call assert_fails('mkspell! Xtest.spl Xtest.dic', 'E17:')
572  call delete('Xtest.spl', 'rf')
573
574  call assert_fails('mkspell en en_US abc_xyz', 'E755:')
575endfunc
576
577" Tests for :mkspell with a .dic and .aff file
578func Test_aff_file_format_error()
579  " FIXME: For some reason, the :mkspell command below doesn't fail on the
580  " MS-Windows CI build. Disable this test on MS-Windows for now.
581  CheckNotMSWindows
582
583  " No word count in .dic file
584  call writefile([], 'Xtest.dic')
585  call writefile([], 'Xtest.aff')
586  call assert_fails('mkspell! Xtest.spl Xtest', 'E760:')
587
588  " create a .dic file for the tests below
589  call writefile(['1', 'work'], 'Xtest.dic')
590
591  " Invalid encoding in .aff file
592  call writefile(['# comment', 'SET Xinvalidencoding'], 'Xtest.aff')
593  let output = execute('mkspell! Xtest.spl Xtest')
594  call assert_match('Conversion in Xtest.aff not supported: from xinvalidencoding', output)
595
596  " Invalid flag in .aff file
597  call writefile(['FLAG xxx'], 'Xtest.aff')
598  let output = execute('mkspell! Xtest.spl Xtest')
599  call assert_match('Invalid value for FLAG in Xtest.aff line 1: xxx', output)
600
601  " set FLAGS after using flag for an affix
602  call writefile(['SFX L Y 1', 'SFX L 0 re [^x]', 'FLAG long'], 'Xtest.aff')
603  let output = execute('mkspell! Xtest.spl Xtest')
604  call assert_match('FLAG after using flags in Xtest.aff line 3: long', output)
605
606  " INFO in affix file
607  let save_encoding = &encoding
608  call mkdir('Xrtp/spell', 'p')
609  call writefile(['1', 'work'], 'Xrtp/spell/Xtest.dic')
610  call writefile(['NAME klingon', 'VERSION 1.4', 'AUTHOR Spock'],
611        \ 'Xrtp/spell/Xtest.aff')
612  silent mkspell! Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest
613  let save_rtp = &rtp
614  set runtimepath=./Xrtp
615  set spelllang=Xtest
616  set spell
617  let output = split(execute('spellinfo'), "\n")
618  call assert_equal("NAME klingon", output[1])
619  call assert_equal("VERSION 1.4", output[2])
620  call assert_equal("AUTHOR Spock", output[3])
621  let &rtp = save_rtp
622  call delete('Xrtp', 'rf')
623  set spell& spelllang& spellfile&
624  %bw!
625  " 'encoding' must be set again to clear the spell file in memory
626  let &encoding = save_encoding
627
628  " COMPOUNDFORBIDFLAG flag after PFX in an affix file
629  call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDFLAG c', 'COMPOUNDFORBIDFLAG x'],
630        \ 'Xtest.aff')
631  let output = execute('mkspell! Xtest.spl Xtest')
632  call assert_match('Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in Xtest.aff line 4', output)
633
634  " COMPOUNDPERMITFLAG flag after PFX in an affix file
635  call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDPERMITFLAG c'],
636        \ 'Xtest.aff')
637  let output = execute('mkspell! Xtest.spl Xtest')
638  call assert_match('Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in Xtest.aff line 3', output)
639
640  " Wrong COMPOUNDRULES flag value in an affix file
641  call writefile(['COMPOUNDRULES a'], 'Xtest.aff')
642  let output = execute('mkspell! Xtest.spl Xtest')
643  call assert_match('Wrong COMPOUNDRULES value in Xtest.aff line 1: a', output)
644
645  " Wrong COMPOUNDWORDMAX flag value in an affix file
646  call writefile(['COMPOUNDWORDMAX 0'], 'Xtest.aff')
647  let output = execute('mkspell! Xtest.spl Xtest')
648  call assert_match('Wrong COMPOUNDWORDMAX value in Xtest.aff line 1: 0', output)
649
650  " Wrong COMPOUNDMIN flag value in an affix file
651  call writefile(['COMPOUNDMIN 0'], 'Xtest.aff')
652  let output = execute('mkspell! Xtest.spl Xtest')
653  call assert_match('Wrong COMPOUNDMIN value in Xtest.aff line 1: 0', output)
654
655  " Wrong COMPOUNDSYLMAX flag value in an affix file
656  call writefile(['COMPOUNDSYLMAX 0'], 'Xtest.aff')
657  let output = execute('mkspell! Xtest.spl Xtest')
658  call assert_match('Wrong COMPOUNDSYLMAX value in Xtest.aff line 1: 0', output)
659
660  " Wrong CHECKCOMPOUNDPATTERN flag value in an affix file
661  call writefile(['CHECKCOMPOUNDPATTERN 0'], 'Xtest.aff')
662  let output = execute('mkspell! Xtest.spl Xtest')
663  call assert_match('Wrong CHECKCOMPOUNDPATTERN value in Xtest.aff line 1: 0', output)
664
665  " Duplicate affix entry in an affix file
666  call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L Y 1', 'PFX L 0 re x'],
667        \ 'Xtest.aff')
668  let output = execute('mkspell! Xtest.spl Xtest')
669  call assert_match('Duplicate affix in Xtest.aff line 3: L', output)
670
671  " Duplicate affix entry in an affix file
672  call writefile(['PFX L Y 1', 'PFX L Y 1'], 'Xtest.aff')
673  let output = execute('mkspell! Xtest.spl Xtest')
674  call assert_match('Unrecognized or duplicate item in Xtest.aff line 2: PFX', output)
675
676  " Different combining flags in an affix file
677  call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L N 1'], 'Xtest.aff')
678  let output = execute('mkspell! Xtest.spl Xtest')
679  call assert_match('Different combining flag in continued affix block in Xtest.aff line 3', output)
680
681  " Try to reuse a affix used for BAD flag
682  call writefile(['BAD x', 'PFX x Y 1', 'PFX x 0 re x'], 'Xtest.aff')
683  let output = execute('mkspell! Xtest.spl Xtest')
684  call assert_match('Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in Xtest.aff line 2: x', output)
685
686  " Trailing characters in an affix entry
687  call writefile(['PFX L Y 1 Test', 'PFX L 0 re x'], 'Xtest.aff')
688  let output = execute('mkspell! Xtest.spl Xtest')
689  call assert_match('Trailing text in Xtest.aff line 1: Test', output)
690
691  " Trailing characters in an affix entry
692  call writefile(['PFX L Y 1', 'PFX L 0 re x Test'], 'Xtest.aff')
693  let output = execute('mkspell! Xtest.spl Xtest')
694  call assert_match('Trailing text in Xtest.aff line 2: Test', output)
695
696  " Incorrect combine flag in an affix entry
697  call writefile(['PFX L X 1', 'PFX L 0 re x'], 'Xtest.aff')
698  let output = execute('mkspell! Xtest.spl Xtest')
699  call assert_match('Expected Y or N in Xtest.aff line 1: X', output)
700
701  " Invalid count for REP item
702  call writefile(['REP a'], 'Xtest.aff')
703  let output = execute('mkspell! Xtest.spl Xtest')
704  call assert_match('Expected REP(SAL) count in Xtest.aff line 1', output)
705
706  " Trailing characters in REP item
707  call writefile(['REP 1', 'REP f ph test'], 'Xtest.aff')
708  let output = execute('mkspell! Xtest.spl Xtest')
709  call assert_match('Trailing text in Xtest.aff line 2: test', output)
710
711  " Invalid count for MAP item
712  call writefile(['MAP a'], 'Xtest.aff')
713  let output = execute('mkspell! Xtest.spl Xtest')
714  call assert_match('Expected MAP count in Xtest.aff line 1', output)
715
716  " Duplicate character in a MAP item
717  call writefile(['MAP 2', 'MAP xx', 'MAP yy'], 'Xtest.aff')
718  let output = execute('mkspell! Xtest.spl Xtest')
719  call assert_match('Duplicate character in MAP in Xtest.aff line 2', output)
720
721  " Use COMPOUNDSYLMAX without SYLLABLE
722  call writefile(['COMPOUNDSYLMAX 2'], 'Xtest.aff')
723  let output = execute('mkspell! Xtest.spl Xtest')
724  call assert_match('COMPOUNDSYLMAX used without SYLLABLE', output)
725
726  " Missing SOFOTO
727  call writefile(['SOFOFROM abcdef'], 'Xtest.aff')
728  let output = execute('mkspell! Xtest.spl Xtest')
729  call assert_match('Missing SOFOTO line in Xtest.aff', output)
730
731  " Length of SOFOFROM and SOFOTO differ
732  call writefile(['SOFOFROM abcde', 'SOFOTO ABCD'], 'Xtest.aff')
733  call assert_fails('mkspell! Xtest.spl Xtest', 'E759:')
734
735  " Both SAL and SOFOFROM/SOFOTO items
736  call writefile(['SOFOFROM abcd', 'SOFOTO ABCD', 'SAL CIA X'], 'Xtest.aff')
737  let output = execute('mkspell! Xtest.spl Xtest')
738  call assert_match('Both SAL and SOFO lines in Xtest.aff', output)
739
740  " use an alphabet flag when FLAG is num
741  call writefile(['FLAG num', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff')
742  let output = execute('mkspell! Xtest.spl Xtest')
743  call assert_match('Flag is not a number in Xtest.aff line 2: L', output)
744
745  " use number and alphabet flag when FLAG is num
746  call writefile(['FLAG num', 'SFX 4f Y 1', 'SFX 4f 0 re [^x]'], 'Xtest.aff')
747  let output = execute('mkspell! Xtest.spl Xtest')
748  call assert_match('Affix name too long in Xtest.aff line 2: 4f', output)
749
750  " use a single character flag when FLAG is long
751  call writefile(['FLAG long', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff')
752  let output = execute('mkspell! Xtest.spl Xtest')
753  call assert_match('Illegal flag in Xtest.aff line 2: L', output)
754
755  " missing character in UPP entry. The character table is used only in a
756  " non-utf8 encoding
757  call writefile(['FOL abc', 'LOW abc', 'UPP A'], 'Xtest.aff')
758  let save_encoding = &encoding
759  set encoding=cp949
760  call assert_fails('mkspell! Xtest.spl Xtest', 'E761:')
761  let &encoding = save_encoding
762
763  " character range doesn't match between FOL and LOW entries
764  call writefile(["FOL \u0102bc", 'LOW abc', 'UPP ABC'], 'Xtest.aff')
765  let save_encoding = &encoding
766  set encoding=cp949
767  call assert_fails('mkspell! Xtest.spl Xtest', 'E762:')
768  let &encoding = save_encoding
769
770  " character range doesn't match between FOL and UPP entries
771  call writefile(["FOL \u0102bc", "LOW \u0102bc", 'UPP ABC'], 'Xtest.aff')
772  let save_encoding = &encoding
773  set encoding=cp949
774  call assert_fails('mkspell! Xtest.spl Xtest', 'E762:')
775  let &encoding = save_encoding
776
777  " additional characters in LOW and UPP entries
778  call writefile(["FOL ab", "LOW abc", 'UPP ABC'], '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  " missing UPP entry
785  call writefile(["FOL abc", "LOW abc"], 'Xtest.aff')
786  let save_encoding = &encoding
787  set encoding=cp949
788  let output = execute('mkspell! Xtest.spl Xtest')
789  call assert_match('Missing FOL/LOW/UPP line in Xtest.aff', output)
790  let &encoding = save_encoding
791
792  " duplicate word in the .dic file
793  call writefile(['2', 'good', 'good', 'good'], 'Xtest.dic')
794  call writefile(['NAME vim'], 'Xtest.aff')
795  let output = execute('mkspell! Xtest.spl Xtest')
796  call assert_match('First duplicate word in Xtest.dic line 3: good', output)
797  call assert_match('2 duplicate word(s) in Xtest.dic', output)
798
799  " use multiple .aff files with different values for COMPOUNDWORDMAX and
800  " MIDWORD (number and string)
801  call writefile(['1', 'world'], 'Xtest_US.dic')
802  call writefile(['1', 'world'], 'Xtest_CA.dic')
803  call writefile(["COMPOUNDWORDMAX 3", "MIDWORD '-"], 'Xtest_US.aff')
804  call writefile(["COMPOUNDWORDMAX 4", "MIDWORD '="], 'Xtest_CA.aff')
805  let output = execute('mkspell! Xtest.spl Xtest_US Xtest_CA')
806  call assert_match('COMPOUNDWORDMAX value differs from what is used in another .aff file', output)
807  call assert_match('MIDWORD value differs from what is used in another .aff file', output)
808  call delete('Xtest_US.dic')
809  call delete('Xtest_CA.dic')
810  call delete('Xtest_US.aff')
811  call delete('Xtest_CA.aff')
812
813  call delete('Xtest.dic')
814  call delete('Xtest.aff')
815  call delete('Xtest.spl')
816  call delete('Xtest.sug')
817endfunc
818
819func Test_spell_add_word()
820  set spellfile=
821  call assert_fails('spellgood abc', 'E764:')
822
823  set spellfile=Xtest.utf-8.add
824  call assert_fails('2spellgood abc', 'E765:')
825
826  edit Xtest.utf-8.add
827  call setline(1, 'sample')
828  call assert_fails('spellgood abc', 'E139:')
829  set spellfile&
830  %bw!
831endfunc
832
833" When 'spellfile' is not set, adding a new good word will automatically set
834" the 'spellfile'
835func Test_init_spellfile()
836  let save_rtp = &rtp
837  let save_encoding = &encoding
838  call mkdir('Xrtp/spell', 'p')
839  call writefile(['vim'], 'Xrtp/spell/Xtest.dic')
840  silent mkspell Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest.dic
841  set runtimepath=./Xrtp
842  set spelllang=Xtest
843  set spell
844  silent spellgood abc
845  call assert_equal('./Xrtp/spell/Xtest.utf-8.add', &spellfile)
846  call assert_equal(['abc'], readfile('Xrtp/spell/Xtest.utf-8.add'))
847  call assert_true(filereadable('Xrtp/spell/Xtest.utf-8.spl'))
848  set spell& spelllang& spellfile&
849  call delete('Xrtp', 'rf')
850  let &encoding = save_encoding
851  let &rtp = save_rtp
852  %bw!
853endfunc
854
855" Test for the 'mkspellmem' option
856func Test_mkspellmem_opt()
857  call assert_fails('set mkspellmem=1000', 'E474:')
858  call assert_fails('set mkspellmem=1000,', 'E474:')
859  call assert_fails('set mkspellmem=1000,50', 'E474:')
860  call assert_fails('set mkspellmem=1000,50,', 'E474:')
861  call assert_fails('set mkspellmem=1000,50,10,', 'E474:')
862  call assert_fails('set mkspellmem=1000,50,0', 'E474:')
863endfunc
864
865" vim: shiftwidth=2 sts=2 expandtab
866