1" Test for spell checking with 'encoding' set to utf-8
2
3source check.vim
4CheckFeature spell
5
6scriptencoding utf-8
7
8func TearDown()
9  set nospell
10  call delete('Xtest.aff')
11  call delete('Xtest.dic')
12  call delete('Xtest.utf-8.add')
13  call delete('Xtest.utf-8.add.spl')
14  call delete('Xtest.utf-8.spl')
15  call delete('Xtest.utf-8.sug')
16endfunc
17
18let g:test_data_aff1 = [
19      \"SET ISO8859-1",
20      \"TRY esianrtolcdugmphbyfvkwjkqxz-ëéèêïîäàâöüû'ESIANRTOLCDUGMPHBYFVKWJKQXZ",
21      \"",
22      \"FOL  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ",
23      \"LOW  àáâãäåæçèéêëìíîïðñòóôõöøùúûüýþßÿ",
24      \"UPP  ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßÿ",
25      \"",
26      \"SOFOFROM abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xBF",
27      \"SOFOTO   ebctefghejklnnepkrstevvkesebctefghejklnnepkrstevvkeseeeeeeeceeeeeeeedneeeeeeeeeeepseeeeeeeeceeeeeeeedneeeeeeeeeeep?",
28      \"",
29      \"MIDWORD\t'-",
30      \"",
31      \"KEP =",
32      \"RAR ?",
33      \"BAD !",
34      \"",
35      \"PFX I N 1",
36      \"PFX I 0 in .",
37      \"",
38      \"PFX O Y 1",
39      \"PFX O 0 out .",
40      \"",
41      \"SFX S Y 2",
42      \"SFX S 0 s [^s]",
43      \"SFX S 0 es s",
44      \"",
45      \"SFX N N 3",
46      \"SFX N 0 en [^n]",
47      \"SFX N 0 nen n",
48      \"SFX N 0 n .",
49      \"",
50      \"REP 3",
51      \"REP g ch",
52      \"REP ch g",
53      \"REP svp s.v.p.",
54      \"",
55      \"MAP 9",
56      \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
57      \"MAP e\xE8\xE9\xEA\xEB",
58      \"MAP i\xEC\xED\xEE\xEF",
59      \"MAP o\xF2\xF3\xF4\xF5\xF6",
60      \"MAP u\xF9\xFA\xFB\xFC",
61      \"MAP n\xF1",
62      \"MAP c\xE7",
63      \"MAP y\xFF\xFD",
64      \"MAP s\xDF"
65      \ ]
66let g:test_data_dic1 = [
67      \"123456",
68      \"test/NO",
69      \"# comment",
70      \"wrong",
71      \"Comment",
72      \"OK",
73      \"uk",
74      \"put/ISO",
75      \"the end",
76      \"deol",
77      \"d\xE9\xF4r",
78      \ ]
79let g:test_data_aff2 = [
80      \"SET ISO8859-1",
81      \"",
82      \"FOL  \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
83      \"LOW  \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
84      \"UPP  \xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xFF",
85      \"",
86      \"PFXPOSTPONE",
87      \"",
88      \"MIDWORD\t'-",
89      \"",
90      \"KEP =",
91      \"RAR ?",
92      \"BAD !",
93      \"",
94      \"PFX I N 1",
95      \"PFX I 0 in .",
96      \"",
97      \"PFX O Y 1",
98      \"PFX O 0 out [a-z]",
99      \"",
100      \"SFX S Y 2",
101      \"SFX S 0 s [^s]",
102      \"SFX S 0 es s",
103      \"",
104      \"SFX N N 3",
105      \"SFX N 0 en [^n]",
106      \"SFX N 0 nen n",
107      \"SFX N 0 n .",
108      \"",
109      \"REP 3",
110      \"REP g ch",
111      \"REP ch g",
112      \"REP svp s.v.p.",
113      \"",
114      \"MAP 9",
115      \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
116      \"MAP e\xE8\xE9\xEA\xEB",
117      \"MAP i\xEC\xED\xEE\xEF",
118      \"MAP o\xF2\xF3\xF4\xF5\xF6",
119      \"MAP u\xF9\xFA\xFB\xFC",
120      \"MAP n\xF1",
121      \"MAP c\xE7",
122      \"MAP y\xFF\xFD",
123      \"MAP s\xDF",
124      \ ]
125let g:test_data_aff3 = [
126      \"SET ISO8859-1",
127      \"",
128      \"COMPOUNDMIN 3",
129      \"COMPOUNDRULE m*",
130      \"NEEDCOMPOUND x",
131      \ ]
132let g:test_data_dic3 = [
133      \"1234",
134      \"foo/m",
135      \"bar/mx",
136      \"m\xEF/m",
137      \"la/mx",
138      \ ]
139let g:test_data_aff4 = [
140      \"SET ISO8859-1",
141      \"",
142      \"FOL  \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
143      \"LOW  \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
144      \"UPP  \xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xFF",
145      \"",
146      \"COMPOUNDRULE m+",
147      \"COMPOUNDRULE sm*e",
148      \"COMPOUNDRULE sm+",
149      \"COMPOUNDMIN 3",
150      \"COMPOUNDWORDMAX 3",
151      \"COMPOUNDFORBIDFLAG t",
152      \"",
153      \"COMPOUNDSYLMAX 5",
154      \"SYLLABLE a\xE1e\xE9i\xEDo\xF3\xF6\xF5u\xFA\xFC\xFBy/aa/au/ea/ee/ei/ie/oa/oe/oo/ou/uu/ui",
155      \"",
156      \"MAP 9",
157      \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
158      \"MAP e\xE8\xE9\xEA\xEB",
159      \"MAP i\xEC\xED\xEE\xEF",
160      \"MAP o\xF2\xF3\xF4\xF5\xF6",
161      \"MAP u\xF9\xFA\xFB\xFC",
162      \"MAP n\xF1",
163      \"MAP c\xE7",
164      \"MAP y\xFF\xFD",
165      \"MAP s\xDF",
166      \"",
167      \"NEEDAFFIX x",
168      \"",
169      \"PFXPOSTPONE",
170      \"",
171      \"MIDWORD '-",
172      \"",
173      \"SFX q N 1",
174      \"SFX q   0    -ok .",
175      \"",
176      \"SFX a Y 2",
177      \"SFX a 0 s .",
178      \"SFX a 0 ize/t .",
179      \"",
180      \"PFX p N 1",
181      \"PFX p 0 pre .",
182      \"",
183      \"PFX P N 1",
184      \"PFX P 0 nou .",
185      \ ]
186let g:test_data_dic4 = [
187      \"1234",
188      \"word/mP",
189      \"util/am",
190      \"pro/xq",
191      \"tomato/m",
192      \"bork/mp",
193      \"start/s",
194      \"end/e",
195      \ ]
196let g:test_data_aff5 = [
197      \"SET ISO8859-1",
198      \"",
199      \"FLAG long",
200      \"",
201      \"NEEDAFFIX !!",
202      \"",
203      \"COMPOUNDRULE ssmm*ee",
204      \"",
205      \"NEEDCOMPOUND xx",
206      \"COMPOUNDPERMITFLAG pp",
207      \"",
208      \"SFX 13 Y 1",
209      \"SFX 13 0 bork .",
210      \"",
211      \"SFX a1 Y 1",
212      \"SFX a1 0 a1 .",
213      \"",
214      \"SFX a\xE9 Y 1",
215      \"SFX a\xE9 0 a\xE9 .",
216      \"",
217      \"PFX zz Y 1",
218      \"PFX zz 0 pre/pp .",
219      \"",
220      \"PFX yy Y 1",
221      \"PFX yy 0 nou .",
222      \ ]
223let g:test_data_dic5 = [
224      \"1234",
225      \"foo/a1a\xE9!!",
226      \"bar/zz13ee",
227      \"start/ss",
228      \"end/eeyy",
229      \"middle/mmxx",
230      \ ]
231let g:test_data_aff6 = [
232      \"SET ISO8859-1",
233      \"",
234      \"FLAG caplong",
235      \"",
236      \"NEEDAFFIX A!",
237      \"",
238      \"COMPOUNDRULE sMm*Ee",
239      \"",
240      \"NEEDCOMPOUND Xx",
241      \"",
242      \"COMPOUNDPERMITFLAG p",
243      \"",
244      \"SFX N3 Y 1",
245      \"SFX N3 0 bork .",
246      \"",
247      \"SFX A1 Y 1",
248      \"SFX A1 0 a1 .",
249      \"",
250      \"SFX A\xE9 Y 1",
251      \"SFX A\xE9 0 a\xE9 .",
252      \"",
253      \"PFX Zz Y 1",
254      \"PFX Zz 0 pre/p .",
255      \ ]
256let g:test_data_dic6 = [
257      \"1234",
258      \"mee/A1A\xE9A!",
259      \"bar/ZzN3Ee",
260      \"lead/s",
261      \"end/Ee",
262      \"middle/MmXx",
263      \ ]
264let g:test_data_aff7 = [
265      \"SET ISO8859-1",
266      \"",
267      \"FLAG num",
268      \"",
269      \"NEEDAFFIX 9999",
270      \"",
271      \"COMPOUNDRULE 2,77*123",
272      \"",
273      \"NEEDCOMPOUND 1",
274      \"COMPOUNDPERMITFLAG 432",
275      \"",
276      \"SFX 61003 Y 1",
277      \"SFX 61003 0 meat .",
278      \"",
279      \"SFX 0 Y 1",
280      \"SFX 0 0 zero .",
281      \"",
282      \"SFX 391 Y 1",
283      \"SFX 391 0 a1 .",
284      \"",
285      \"SFX 111 Y 1",
286      \"SFX 111 0 a\xE9 .",
287      \"",
288      \"PFX 17 Y 1",
289      \"PFX 17 0 pre/432 .",
290      \ ]
291let g:test_data_dic7 = [
292      \"1234",
293      \"mee/0,391,111,9999",
294      \"bar/17,61003,123",
295      \"lead/2",
296      \"tail/123",
297      \"middle/77,1",
298      \ ]
299let g:test_data_aff8 = [
300      \"SET ISO8859-1",
301      \"",
302      \"NOSPLITSUGS",
303      \ ]
304let g:test_data_dic8 = [
305      \"1234",
306      \"foo",
307      \"bar",
308      \"faabar",
309      \ ]
310let g:test_data_aff9 = [
311      \ ]
312let g:test_data_dic9 = [
313      \"1234",
314      \"foo",
315      \"bar",
316      \ ]
317let g:test_data_aff10 = [
318      \"COMPOUNDRULE se",
319      \"COMPOUNDPERMITFLAG p",
320      \"",
321      \"SFX A Y 1",
322      \"SFX A 0 able/Mp .",
323      \"",
324      \"SFX M Y 1",
325      \"SFX M 0 s .",
326      \ ]
327let g:test_data_dic10 = [
328      \"1234",
329      \"drink/As",
330      \"table/e",
331      \ ]
332let g:test_data_aff_sal = [
333      \"SET ISO8859-1",
334      \"TRY esianrtolcdugmphbyfvkwjkqxz-\xEB\xE9\xE8\xEA\xEF\xEE\xE4\xE0\xE2\xF6\xFC\xFB'ESIANRTOLCDUGMPHBYFVKWJKQXZ",
335      \"",
336      \"FOL  \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
337      \"LOW  \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
338      \"UPP  \xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xFF",
339      \"",
340      \"MIDWORD\t'-",
341      \"",
342      \"KEP =",
343      \"RAR ?",
344      \"BAD !",
345      \"",
346      \"PFX I N 1",
347      \"PFX I 0 in .",
348      \"",
349      \"PFX O Y 1",
350      \"PFX O 0 out .",
351      \"",
352      \"SFX S Y 2",
353      \"SFX S 0 s [^s]",
354      \"SFX S 0 es s",
355      \"",
356      \"SFX N N 3",
357      \"SFX N 0 en [^n]",
358      \"SFX N 0 nen n",
359      \"SFX N 0 n .",
360      \"",
361      \"REP 3",
362      \"REP g ch",
363      \"REP ch g",
364      \"REP svp s.v.p.",
365      \"",
366      \"MAP 9",
367      \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
368      \"MAP e\xE8\xE9\xEA\xEB",
369      \"MAP i\xEC\xED\xEE\xEF",
370      \"MAP o\xF2\xF3\xF4\xF5\xF6",
371      \"MAP u\xF9\xFA\xFB\xFC",
372      \"MAP n\xF1",
373      \"MAP c\xE7",
374      \"MAP y\xFF\xFD",
375      \"MAP s\xDF",
376      \"",
377      \"SAL AH(AEIOUY)-^         *H",
378      \"SAL AR(AEIOUY)-^         *R",
379      \"SAL A(HR)^               *",
380      \"SAL A^                   *",
381      \"SAL AH(AEIOUY)-          H",
382      \"SAL AR(AEIOUY)-          R",
383      \"SAL A(HR)                _",
384      \"SAL \xC0^                   *",
385      \"SAL \xC5^                   *",
386      \"SAL BB-                  _",
387      \"SAL B                    B",
388      \"SAL CQ-                  _",
389      \"SAL CIA                  X",
390      \"SAL CH                   X",
391      \"SAL C(EIY)-              S",
392      \"SAL CK                   K",
393      \"SAL COUGH^               KF",
394      \"SAL CC<                  C",
395      \"SAL C                    K",
396      \"SAL DG(EIY)              K",
397      \"SAL DD-                  _",
398      \"SAL D                    T",
399      \"SAL \xC9<                   E",
400      \"SAL EH(AEIOUY)-^         *H",
401      \"SAL ER(AEIOUY)-^         *R",
402      \"SAL E(HR)^               *",
403      \"SAL ENOUGH^$             *NF",
404      \"SAL E^                   *",
405      \"SAL EH(AEIOUY)-          H",
406      \"SAL ER(AEIOUY)-          R",
407      \"SAL E(HR)                _",
408      \"SAL FF-                  _",
409      \"SAL F                    F",
410      \"SAL GN^                  N",
411      \"SAL GN$                  N",
412      \"SAL GNS$                 NS",
413      \"SAL GNED$                N",
414      \"SAL GH(AEIOUY)-          K",
415      \"SAL GH                   _",
416      \"SAL GG9                  K",
417      \"SAL G                    K",
418      \"SAL H                    H",
419      \"SAL IH(AEIOUY)-^         *H",
420      \"SAL IR(AEIOUY)-^         *R",
421      \"SAL I(HR)^               *",
422      \"SAL I^                   *",
423      \"SAL ING6                 N",
424      \"SAL IH(AEIOUY)-          H",
425      \"SAL IR(AEIOUY)-          R",
426      \"SAL I(HR)                _",
427      \"SAL J                    K",
428      \"SAL KN^                  N",
429      \"SAL KK-                  _",
430      \"SAL K                    K",
431      \"SAL LAUGH^               LF",
432      \"SAL LL-                  _",
433      \"SAL L                    L",
434      \"SAL MB$                  M",
435      \"SAL MM                   M",
436      \"SAL M                    M",
437      \"SAL NN-                  _",
438      \"SAL N                    N",
439      \"SAL OH(AEIOUY)-^         *H",
440      \"SAL OR(AEIOUY)-^         *R",
441      \"SAL O(HR)^               *",
442      \"SAL O^                   *",
443      \"SAL OH(AEIOUY)-          H",
444      \"SAL OR(AEIOUY)-          R",
445      \"SAL O(HR)                _",
446      \"SAL PH                   F",
447      \"SAL PN^                  N",
448      \"SAL PP-                  _",
449      \"SAL P                    P",
450      \"SAL Q                    K",
451      \"SAL RH^                  R",
452      \"SAL ROUGH^               RF",
453      \"SAL RR-                  _",
454      \"SAL R                    R",
455      \"SAL SCH(EOU)-            SK",
456      \"SAL SC(IEY)-             S",
457      \"SAL SH                   X",
458      \"SAL SI(AO)-              X",
459      \"SAL SS-                  _",
460      \"SAL S                    S",
461      \"SAL TI(AO)-              X",
462      \"SAL TH                   @",
463      \"SAL TCH--                _",
464      \"SAL TOUGH^               TF",
465      \"SAL TT-                  _",
466      \"SAL T                    T",
467      \"SAL UH(AEIOUY)-^         *H",
468      \"SAL UR(AEIOUY)-^         *R",
469      \"SAL U(HR)^               *",
470      \"SAL U^                   *",
471      \"SAL UH(AEIOUY)-          H",
472      \"SAL UR(AEIOUY)-          R",
473      \"SAL U(HR)                _",
474      \"SAL V^                   W",
475      \"SAL V                    F",
476      \"SAL WR^                  R",
477      \"SAL WH^                  W",
478      \"SAL W(AEIOU)-            W",
479      \"SAL X^                   S",
480      \"SAL X                    KS",
481      \"SAL Y(AEIOU)-            Y",
482      \"SAL ZZ-                  _",
483      \"SAL Z                    S",
484      \ ]
485
486func LoadAffAndDic(aff_contents, dic_contents)
487  set enc=utf-8
488  set spellfile=
489  call writefile(a:aff_contents, "Xtest.aff")
490  call writefile(a:dic_contents, "Xtest.dic")
491  " Generate a .spl file from a .dic and .aff file.
492  mkspell! Xtest Xtest
493  " use that spell file
494  set spl=Xtest.utf-8.spl spell
495endfunc
496
497func ListWords()
498  spelldump
499  %yank
500  quit
501  return split(@", "\n")
502endfunc
503
504func TestGoodBadBase()
505  exe '1;/^good:'
506  normal 0f:]s
507  let prevbad = ''
508  let result = []
509  while 1
510    let [bad, a] = spellbadword()
511    if bad == '' || bad == prevbad || bad == 'badend'
512      break
513    endif
514    let prevbad = bad
515    let lst = bad->spellsuggest(3)
516    normal mm
517
518    call add(result, [bad, lst])
519    normal `m]s
520  endwhile
521  return result
522endfunc
523
524func RunGoodBad(good, bad, expected_words, expected_bad_words)
525  %bwipe!
526  call setline(1, ['', "good: ", a:good,  a:bad, " badend "])
527  let words = ListWords()
528  call assert_equal(a:expected_words, words[1:-1])
529  let bad_words = TestGoodBadBase()
530  call assert_equal(a:expected_bad_words, bad_words)
531  %bwipe!
532endfunc
533
534func Test_spell_basic()
535  call LoadAffAndDic(g:test_data_aff1, g:test_data_dic1)
536  call RunGoodBad("wrong OK puts. Test the end",
537        \ "bad: inputs comment ok Ok. test d\u00E9\u00F4l end the",
538        \["Comment", "deol", "d\u00E9\u00F4r", "input", "OK", "output", "outputs", "outtest", "put", "puts",
539        \  "test", "testen", "testn", "the end", "uk", "wrong"],
540        \[
541        \   ["bad", ["put", "uk", "OK"]],
542        \   ["inputs", ["input", "puts", "outputs"]],
543        \   ["comment", ["Comment", "outtest", "the end"]],
544        \   ["ok", ["OK", "uk", "put"]],
545        \   ["Ok", ["OK", "Uk", "Put"]],
546        \   ["test", ["Test", "testn", "testen"]],
547        \   ["d\u00E9\u00F4l", ["deol", "d\u00E9\u00F4r", "test"]],
548        \   ["end", ["put", "uk", "test"]],
549        \   ["the", ["put", "uk", "test"]],
550        \ ]
551        \ )
552
553  call assert_equal("gebletegek", soundfold('goobledygoook'))
554  call assert_equal("kepereneven", 'kóopërÿnôven'->soundfold())
555  call assert_equal("everles gesvets etele", soundfold('oeverloos gezwets edale'))
556endfunc
557
558" Postponed prefixes
559func Test_spell_prefixes()
560  call LoadAffAndDic(g:test_data_aff2, g:test_data_dic1)
561  call RunGoodBad("puts",
562        \ "bad: inputs comment ok Ok end the. test d\u00E9\u00F4l",
563        \ ["Comment", "deol", "d\u00E9\u00F4r", "OK", "put", "input", "output", "puts", "outputs", "test", "outtest", "testen", "testn", "the end", "uk", "wrong"],
564        \ [
565        \   ["bad", ["put", "uk", "OK"]],
566        \   ["inputs", ["input", "puts", "outputs"]],
567        \   ["comment", ["Comment"]],
568        \   ["ok", ["OK", "uk", "put"]],
569        \   ["Ok", ["OK", "Uk", "Put"]],
570        \   ["end", ["put", "uk", "deol"]],
571        \   ["the", ["put", "uk", "test"]],
572        \   ["test", ["Test", "testn", "testen"]],
573        \   ["d\u00E9\u00F4l", ["deol", "d\u00E9\u00F4r", "test"]],
574        \ ])
575endfunc
576
577"Compound words
578func Test_spell_compound()
579  call LoadAffAndDic(g:test_data_aff3, g:test_data_dic3)
580  call RunGoodBad("foo m\u00EF foobar foofoobar barfoo barbarfoo",
581        \ "bad: bar la foom\u00EF barm\u00EF m\u00EFfoo m\u00EFbar m\u00EFm\u00EF lala m\u00EFla lam\u00EF foola labar",
582        \ ["foo", "m\u00EF"],
583        \ [
584        \   ["bad", ["foo", "m\u00EF"]],
585        \   ["bar", ["barfoo", "foobar", "foo"]],
586        \   ["la", ["m\u00EF", "foo"]],
587        \   ["foom\u00EF", ["foo m\u00EF", "foo", "foofoo"]],
588        \   ["barm\u00EF", ["barfoo", "m\u00EF", "barbar"]],
589        \   ["m\u00EFfoo", ["m\u00EF foo", "foo", "foofoo"]],
590        \   ["m\u00EFbar", ["foobar", "barbar", "m\u00EF"]],
591        \   ["m\u00EFm\u00EF", ["m\u00EF m\u00EF", "m\u00EF"]],
592        \   ["lala", []],
593        \   ["m\u00EFla", ["m\u00EF", "m\u00EF m\u00EF"]],
594        \   ["lam\u00EF", ["m\u00EF", "m\u00EF m\u00EF"]],
595        \   ["foola", ["foo", "foobar", "foofoo"]],
596        \   ["labar", ["barbar", "foobar"]],
597        \ ])
598
599  call LoadAffAndDic(g:test_data_aff4, g:test_data_dic4)
600  call RunGoodBad("word util bork prebork start end wordutil wordutils pro-ok bork borkbork borkborkbork borkborkborkbork borkborkborkborkbork tomato tomatotomato startend startword startwordword startwordend startwordwordend startwordwordwordend prebork preborkbork preborkborkbork nouword",
601        \ "bad: wordutilize pro borkborkborkborkborkbork tomatotomatotomato endstart endend startstart wordend wordstart preborkprebork  preborkpreborkbork startwordwordwordwordend borkpreborkpreborkbork utilsbork  startnouword",
602        \ ["bork", "prebork", "end", "pro-ok", "start", "tomato", "util", "utilize", "utils", "word", "nouword"],
603        \ [
604        \   ["bad", ["end", "bork", "word"]],
605        \   ["wordutilize", ["word utilize", "wordutils", "wordutil"]],
606        \   ["pro", ["bork", "word", "end"]],
607        \   ["borkborkborkborkborkbork", ["bork borkborkborkborkbork", "borkbork borkborkborkbork", "borkborkbork borkborkbork"]],
608        \   ["tomatotomatotomato", ["tomato tomatotomato", "tomatotomato tomato", "tomato tomato tomato"]],
609        \   ["endstart", ["end start", "start"]],
610        \   ["endend", ["end end", "end"]],
611        \   ["startstart", ["start start"]],
612        \   ["wordend", ["word end", "word", "wordword"]],
613        \   ["wordstart", ["word start", "bork start"]],
614        \   ["preborkprebork", ["prebork prebork", "preborkbork", "preborkborkbork"]],
615        \   ["preborkpreborkbork", ["prebork preborkbork", "preborkborkbork", "preborkborkborkbork"]],
616        \   ["startwordwordwordwordend", ["startwordwordwordword end", "startwordwordwordword", "start wordwordwordword end"]],
617        \   ["borkpreborkpreborkbork", ["bork preborkpreborkbork", "bork prebork preborkbork", "bork preborkprebork bork"]],
618        \   ["utilsbork", ["utilbork", "utils bork", "util bork"]],
619        \   ["startnouword", ["start nouword", "startword", "startborkword"]],
620        \ ])
621
622endfunc
623
624" Test affix flags with two characters
625func Test_spell_affix()
626  call LoadAffAndDic(g:test_data_aff5, g:test_data_dic5)
627  call RunGoodBad("fooa1 fooa\u00E9 bar prebar barbork prebarbork  startprebar start end startend  startmiddleend nouend",
628        \ "bad: foo fooa2 prabar probarbirk middle startmiddle middleend endstart startprobar startnouend",
629        \ ["bar", "barbork", "end", "fooa1", "fooa\u00E9", "nouend", "prebar", "prebarbork", "start"],
630        \ [
631        \   ["bad", ["bar", "end", "fooa1"]],
632        \   ["foo", ["fooa1", "fooa\u00E9", "bar"]],
633        \   ["fooa2", ["fooa1", "fooa\u00E9", "bar"]],
634        \   ["prabar", ["prebar", "bar", "bar bar"]],
635        \   ["probarbirk", ["prebarbork"]],
636        \   ["middle", []],
637        \   ["startmiddle", ["startmiddleend", "startmiddlebar"]],
638        \   ["middleend", []],
639        \   ["endstart", ["end start", "start"]],
640        \   ["startprobar", ["startprebar", "start prebar", "startbar"]],
641        \   ["startnouend", ["start nouend", "startend"]],
642        \ ])
643
644  call LoadAffAndDic(g:test_data_aff6, g:test_data_dic6)
645  call RunGoodBad("meea1 meea\u00E9 bar prebar barbork prebarbork  leadprebar lead end leadend  leadmiddleend",
646        \  "bad: mee meea2 prabar probarbirk middle leadmiddle middleend endlead leadprobar",
647        \ ["bar", "barbork", "end", "lead", "meea1", "meea\u00E9", "prebar", "prebarbork"],
648        \ [
649        \   ["bad", ["bar", "end", "lead"]],
650        \   ["mee", ["meea1", "meea\u00E9", "bar"]],
651        \   ["meea2", ["meea1", "meea\u00E9", "lead"]],
652        \   ["prabar", ["prebar", "bar", "leadbar"]],
653        \   ["probarbirk", ["prebarbork"]],
654        \   ["middle", []],
655        \   ["leadmiddle", ["leadmiddleend", "leadmiddlebar"]],
656        \   ["middleend", []],
657        \   ["endlead", ["end lead", "lead", "end end"]],
658        \   ["leadprobar", ["leadprebar", "lead prebar", "leadbar"]],
659        \ ])
660
661  call LoadAffAndDic(g:test_data_aff7, g:test_data_dic7)
662  call RunGoodBad("meea1 meezero meea\u00E9 bar prebar barmeat prebarmeat  leadprebar lead tail leadtail  leadmiddletail",
663        \ "bad: mee meea2 prabar probarmaat middle leadmiddle middletail taillead leadprobar",
664        \ ["bar", "barmeat", "lead", "meea1", "meea\u00E9", "meezero", "prebar", "prebarmeat", "tail"],
665        \ [
666        \   ["bad", ["bar", "lead", "tail"]],
667        \   ["mee", ["meea1", "meea\u00E9", "bar"]],
668        \   ["meea2", ["meea1", "meea\u00E9", "lead"]],
669        \   ["prabar", ["prebar", "bar", "leadbar"]],
670        \   ["probarmaat", ["prebarmeat"]],
671        \   ["middle", []],
672        \   ["leadmiddle", ["leadmiddlebar"]],
673        \   ["middletail", []],
674        \   ["taillead", ["tail lead", "tail"]],
675        \   ["leadprobar", ["leadprebar", "lead prebar", "leadbar"]],
676        \ ])
677endfunc
678
679func Test_spell_NOSLITSUGS()
680  call LoadAffAndDic(g:test_data_aff8, g:test_data_dic8)
681  call RunGoodBad("foo bar faabar", "bad: foobar barfoo",
682        \ ["bar", "faabar", "foo"],
683        \ [
684        \   ["bad", ["bar", "foo"]],
685        \   ["foobar", ["faabar", "foo bar", "bar"]],
686        \   ["barfoo", ["bar foo", "bar", "foo"]],
687        \ ])
688endfunc
689
690" Numbers
691func Test_spell_Numbers()
692  call LoadAffAndDic(g:test_data_aff9, g:test_data_dic9)
693  call RunGoodBad("0b1011 0777 1234 0x01ff", "",
694        \ ["bar", "foo"],
695        \ [
696        \ ])
697endfunc
698
699" Affix flags
700func Test_spell_affix_flags()
701  call LoadAffAndDic(g:test_data_aff10, g:test_data_dic10)
702  call RunGoodBad("drink drinkable drinkables drinktable drinkabletable",
703	\ "bad: drinks drinkstable drinkablestable",
704        \ ["drink", "drinkable", "drinkables", "table"],
705        \ [['bad', []],
706	\ ['drinks', ['drink']],
707	\ ['drinkstable', ['drinktable', 'drinkable', 'drink table']],
708        \ ['drinkablestable', ['drinkabletable', 'drinkables table', 'drinkable table']],
709	\ ])
710endfunc
711
712function FirstSpellWord()
713  call feedkeys("/^start:\n", 'tx')
714  normal ]smm
715  let [str, a] = spellbadword()
716  return str
717endfunc
718
719function SecondSpellWord()
720  normal `m]s
721  let [str, a] = spellbadword()
722  return str
723endfunc
724
725" Test with SAL instead of SOFO items; test automatic reloading
726func Test_spell_sal_and_addition()
727  set spellfile=
728  call writefile(g:test_data_dic1, "Xtest.dic")
729  call writefile(g:test_data_aff_sal, "Xtest.aff")
730  mkspell! Xtest Xtest
731  set spl=Xtest.utf-8.spl spell
732  call assert_equal('kbltykk', soundfold('goobledygoook'))
733  call assert_equal('kprnfn', soundfold('kóopërÿnôven'))
734  call assert_equal('*fls kswts tl', soundfold('oeverloos gezwets edale'))
735
736  "also use an addition file
737  call writefile(["/regions=usgbnz", "elequint/2", "elekwint/3"], "Xtest.utf-8.add")
738  mkspell! Xtest.utf-8.add.spl Xtest.utf-8.add
739
740  bwipe!
741  call setline(1, ["start: elequint test elekwint test elekwent asdf"])
742
743  set spellfile=Xtest.utf-8.add
744  call assert_equal("elekwent", FirstSpellWord())
745
746  set spl=Xtest_us.utf-8.spl
747  call assert_equal("elequint", FirstSpellWord())
748  call assert_equal("elekwint", SecondSpellWord())
749
750  set spl=Xtest_gb.utf-8.spl
751  call assert_equal("elekwint", FirstSpellWord())
752  call assert_equal("elekwent", SecondSpellWord())
753
754  set spl=Xtest_nz.utf-8.spl
755  call assert_equal("elequint", FirstSpellWord())
756  call assert_equal("elekwent", SecondSpellWord())
757
758  set spl=Xtest_ca.utf-8.spl
759  call assert_equal("elequint", FirstSpellWord())
760  call assert_equal("elekwint", SecondSpellWord())
761endfunc
762
763func Test_spellfile_value()
764  set spellfile=Xdir/Xtest.utf-8.add
765  set spellfile=Xdir/Xtest.utf-8.add,Xtest_other.add
766endfunc
767
768func Test_no_crash_with_weird_text()
769  new
770  let lines =<< trim END
771      r<sfile>
772773
774
775776  END
777  call setline(1, lines)
778  exe "%norm \<C-v>ez=>\<C-v>wzG"
779
780  bwipe!
781endfunc
782
783
784" vim: shiftwidth=2 sts=2 expandtab
785