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 " can't write the .spl file as its directory does not exist 587 call writefile([], 'Xtest.aff') 588 call writefile([], 'Xtest.dic') 589 call assert_fails('mkspell DOES_NOT_EXIT/Xtest.spl Xtest.dic', 'E484:') 590 call delete('Xtest.aff') 591 call delete('Xtest.dic') 592 593 call assert_fails('mkspell en en_US abc_xyz', 'E755:') 594endfunc 595 596" Tests for :mkspell with a .dic and .aff file 597func Test_aff_file_format_error() 598 " FIXME: For some reason, the :mkspell command below doesn't fail on the 599 " MS-Windows CI build. Disable this test on MS-Windows for now. 600 CheckNotMSWindows 601 602 " No word count in .dic file 603 call writefile([], 'Xtest.dic') 604 call writefile([], 'Xtest.aff') 605 call assert_fails('mkspell! Xtest.spl Xtest', 'E760:') 606 607 " create a .dic file for the tests below 608 call writefile(['1', 'work'], 'Xtest.dic') 609 610 " Invalid encoding in .aff file 611 call writefile(['# comment', 'SET Xinvalidencoding'], 'Xtest.aff') 612 let output = execute('mkspell! Xtest.spl Xtest') 613 call assert_match('Conversion in Xtest.aff not supported: from xinvalidencoding', output) 614 615 " Invalid flag in .aff file 616 call writefile(['FLAG xxx'], 'Xtest.aff') 617 let output = execute('mkspell! Xtest.spl Xtest') 618 call assert_match('Invalid value for FLAG in Xtest.aff line 1: xxx', output) 619 620 " set FLAGS after using flag for an affix 621 call writefile(['SFX L Y 1', 'SFX L 0 re [^x]', 'FLAG long'], 'Xtest.aff') 622 let output = execute('mkspell! Xtest.spl Xtest') 623 call assert_match('FLAG after using flags in Xtest.aff line 3: long', output) 624 625 " INFO in affix file 626 let save_encoding = &encoding 627 call mkdir('Xrtp/spell', 'p') 628 call writefile(['1', 'work'], 'Xrtp/spell/Xtest.dic') 629 call writefile(['NAME klingon', 'VERSION 1.4', 'AUTHOR Spock'], 630 \ 'Xrtp/spell/Xtest.aff') 631 silent mkspell! Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest 632 let save_rtp = &rtp 633 set runtimepath=./Xrtp 634 set spelllang=Xtest 635 set spell 636 let output = split(execute('spellinfo'), "\n") 637 call assert_equal("NAME klingon", output[1]) 638 call assert_equal("VERSION 1.4", output[2]) 639 call assert_equal("AUTHOR Spock", output[3]) 640 let &rtp = save_rtp 641 call delete('Xrtp', 'rf') 642 set spell& spelllang& spellfile& 643 %bw! 644 " 'encoding' must be set again to clear the spell file in memory 645 let &encoding = save_encoding 646 647 " COMPOUNDFORBIDFLAG flag after PFX in an affix file 648 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDFLAG c', 'COMPOUNDFORBIDFLAG x'], 649 \ 'Xtest.aff') 650 let output = execute('mkspell! Xtest.spl Xtest') 651 call assert_match('Defining COMPOUNDFORBIDFLAG after PFX item may give wrong results in Xtest.aff line 4', output) 652 653 " COMPOUNDPERMITFLAG flag after PFX in an affix file 654 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'COMPOUNDPERMITFLAG c'], 655 \ 'Xtest.aff') 656 let output = execute('mkspell! Xtest.spl Xtest') 657 call assert_match('Defining COMPOUNDPERMITFLAG after PFX item may give wrong results in Xtest.aff line 3', output) 658 659 " Wrong COMPOUNDRULES flag value in an affix file 660 call writefile(['COMPOUNDRULES a'], 'Xtest.aff') 661 let output = execute('mkspell! Xtest.spl Xtest') 662 call assert_match('Wrong COMPOUNDRULES value in Xtest.aff line 1: a', output) 663 664 " Wrong COMPOUNDWORDMAX flag value in an affix file 665 call writefile(['COMPOUNDWORDMAX 0'], 'Xtest.aff') 666 let output = execute('mkspell! Xtest.spl Xtest') 667 call assert_match('Wrong COMPOUNDWORDMAX value in Xtest.aff line 1: 0', output) 668 669 " Wrong COMPOUNDMIN flag value in an affix file 670 call writefile(['COMPOUNDMIN 0'], 'Xtest.aff') 671 let output = execute('mkspell! Xtest.spl Xtest') 672 call assert_match('Wrong COMPOUNDMIN value in Xtest.aff line 1: 0', output) 673 674 " Wrong COMPOUNDSYLMAX flag value in an affix file 675 call writefile(['COMPOUNDSYLMAX 0'], 'Xtest.aff') 676 let output = execute('mkspell! Xtest.spl Xtest') 677 call assert_match('Wrong COMPOUNDSYLMAX value in Xtest.aff line 1: 0', output) 678 679 " Wrong CHECKCOMPOUNDPATTERN flag value in an affix file 680 call writefile(['CHECKCOMPOUNDPATTERN 0'], 'Xtest.aff') 681 let output = execute('mkspell! Xtest.spl Xtest') 682 call assert_match('Wrong CHECKCOMPOUNDPATTERN value in Xtest.aff line 1: 0', output) 683 684 " Duplicate affix entry in an affix file 685 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L Y 1', 'PFX L 0 re x'], 686 \ 'Xtest.aff') 687 let output = execute('mkspell! Xtest.spl Xtest') 688 call assert_match('Duplicate affix in Xtest.aff line 3: L', output) 689 690 " Duplicate affix entry in an affix file 691 call writefile(['PFX L Y 1', 'PFX L Y 1'], 'Xtest.aff') 692 let output = execute('mkspell! Xtest.spl Xtest') 693 call assert_match('Unrecognized or duplicate item in Xtest.aff line 2: PFX', output) 694 695 " Different combining flags in an affix file 696 call writefile(['PFX L Y 1', 'PFX L 0 re x', 'PFX L N 1'], 'Xtest.aff') 697 let output = execute('mkspell! Xtest.spl Xtest') 698 call assert_match('Different combining flag in continued affix block in Xtest.aff line 3', output) 699 700 " Try to reuse a affix used for BAD flag 701 call writefile(['BAD x', 'PFX x Y 1', 'PFX x 0 re x'], 'Xtest.aff') 702 let output = execute('mkspell! Xtest.spl Xtest') 703 call assert_match('Affix also used for BAD/RARE/KEEPCASE/NEEDAFFIX/NEEDCOMPOUND/NOSUGGEST in Xtest.aff line 2: x', output) 704 705 " Trailing characters in an affix entry 706 call writefile(['PFX L Y 1 Test', 'PFX L 0 re x'], 'Xtest.aff') 707 let output = execute('mkspell! Xtest.spl Xtest') 708 call assert_match('Trailing text in Xtest.aff line 1: Test', output) 709 710 " Trailing characters in an affix entry 711 call writefile(['PFX L Y 1', 'PFX L 0 re x Test'], 'Xtest.aff') 712 let output = execute('mkspell! Xtest.spl Xtest') 713 call assert_match('Trailing text in Xtest.aff line 2: Test', output) 714 715 " Incorrect combine flag in an affix entry 716 call writefile(['PFX L X 1', 'PFX L 0 re x'], 'Xtest.aff') 717 let output = execute('mkspell! Xtest.spl Xtest') 718 call assert_match('Expected Y or N in Xtest.aff line 1: X', output) 719 720 " Invalid count for REP item 721 call writefile(['REP a'], 'Xtest.aff') 722 let output = execute('mkspell! Xtest.spl Xtest') 723 call assert_match('Expected REP(SAL) count in Xtest.aff line 1', output) 724 725 " Trailing characters in REP item 726 call writefile(['REP 1', 'REP f ph test'], 'Xtest.aff') 727 let output = execute('mkspell! Xtest.spl Xtest') 728 call assert_match('Trailing text in Xtest.aff line 2: test', output) 729 730 " Invalid count for MAP item 731 call writefile(['MAP a'], 'Xtest.aff') 732 let output = execute('mkspell! Xtest.spl Xtest') 733 call assert_match('Expected MAP count in Xtest.aff line 1', output) 734 735 " Duplicate character in a MAP item 736 call writefile(['MAP 2', 'MAP xx', 'MAP yy'], 'Xtest.aff') 737 let output = execute('mkspell! Xtest.spl Xtest') 738 call assert_match('Duplicate character in MAP in Xtest.aff line 2', output) 739 740 " Use COMPOUNDSYLMAX without SYLLABLE 741 call writefile(['COMPOUNDSYLMAX 2'], 'Xtest.aff') 742 let output = execute('mkspell! Xtest.spl Xtest') 743 call assert_match('COMPOUNDSYLMAX used without SYLLABLE', output) 744 745 " Missing SOFOTO 746 call writefile(['SOFOFROM abcdef'], 'Xtest.aff') 747 let output = execute('mkspell! Xtest.spl Xtest') 748 call assert_match('Missing SOFOTO line in Xtest.aff', output) 749 750 " Length of SOFOFROM and SOFOTO differ 751 call writefile(['SOFOFROM abcde', 'SOFOTO ABCD'], 'Xtest.aff') 752 call assert_fails('mkspell! Xtest.spl Xtest', 'E759:') 753 754 " Both SAL and SOFOFROM/SOFOTO items 755 call writefile(['SOFOFROM abcd', 'SOFOTO ABCD', 'SAL CIA X'], 'Xtest.aff') 756 let output = execute('mkspell! Xtest.spl Xtest') 757 call assert_match('Both SAL and SOFO lines in Xtest.aff', output) 758 759 " use an alphabet flag when FLAG is num 760 call writefile(['FLAG num', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff') 761 let output = execute('mkspell! Xtest.spl Xtest') 762 call assert_match('Flag is not a number in Xtest.aff line 2: L', output) 763 764 " use number and alphabet flag when FLAG is num 765 call writefile(['FLAG num', 'SFX 4f Y 1', 'SFX 4f 0 re [^x]'], 'Xtest.aff') 766 let output = execute('mkspell! Xtest.spl Xtest') 767 call assert_match('Affix name too long in Xtest.aff line 2: 4f', output) 768 769 " use a single character flag when FLAG is long 770 call writefile(['FLAG long', 'SFX L Y 1', 'SFX L 0 re [^x]'], 'Xtest.aff') 771 let output = execute('mkspell! Xtest.spl Xtest') 772 call assert_match('Illegal flag in Xtest.aff line 2: L', output) 773 774 " missing character in UPP entry. The character table is used only in a 775 " non-utf8 encoding 776 call writefile(['FOL abc', 'LOW abc', 'UPP A'], 'Xtest.aff') 777 let save_encoding = &encoding 778 set encoding=cp949 779 call assert_fails('mkspell! Xtest.spl Xtest', 'E761:') 780 let &encoding = save_encoding 781 782 " character range doesn't match between FOL and LOW entries 783 call writefile(["FOL \u0102bc", 'LOW abc', '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 " character range doesn't match between FOL and UPP entries 790 call writefile(["FOL \u0102bc", "LOW \u0102bc", 'UPP ABC'], 'Xtest.aff') 791 let save_encoding = &encoding 792 set encoding=cp949 793 call assert_fails('mkspell! Xtest.spl Xtest', 'E762:') 794 let &encoding = save_encoding 795 796 " additional characters in LOW and UPP entries 797 call writefile(["FOL ab", "LOW abc", 'UPP ABC'], 'Xtest.aff') 798 let save_encoding = &encoding 799 set encoding=cp949 800 call assert_fails('mkspell! Xtest.spl Xtest', 'E761:') 801 let &encoding = save_encoding 802 803 " missing UPP entry 804 call writefile(["FOL abc", "LOW abc"], 'Xtest.aff') 805 let save_encoding = &encoding 806 set encoding=cp949 807 let output = execute('mkspell! Xtest.spl Xtest') 808 call assert_match('Missing FOL/LOW/UPP line in Xtest.aff', output) 809 let &encoding = save_encoding 810 811 " duplicate word in the .dic file 812 call writefile(['2', 'good', 'good', 'good'], 'Xtest.dic') 813 call writefile(['NAME vim'], 'Xtest.aff') 814 let output = execute('mkspell! Xtest.spl Xtest') 815 call assert_match('First duplicate word in Xtest.dic line 3: good', output) 816 call assert_match('2 duplicate word(s) in Xtest.dic', output) 817 818 " use multiple .aff files with different values for COMPOUNDWORDMAX and 819 " MIDWORD (number and string) 820 call writefile(['1', 'world'], 'Xtest_US.dic') 821 call writefile(['1', 'world'], 'Xtest_CA.dic') 822 call writefile(["COMPOUNDWORDMAX 3", "MIDWORD '-"], 'Xtest_US.aff') 823 call writefile(["COMPOUNDWORDMAX 4", "MIDWORD '="], 'Xtest_CA.aff') 824 let output = execute('mkspell! Xtest.spl Xtest_US Xtest_CA') 825 call assert_match('COMPOUNDWORDMAX value differs from what is used in another .aff file', output) 826 call assert_match('MIDWORD value differs from what is used in another .aff file', output) 827 call delete('Xtest_US.dic') 828 call delete('Xtest_CA.dic') 829 call delete('Xtest_US.aff') 830 call delete('Xtest_CA.aff') 831 832 call delete('Xtest.dic') 833 call delete('Xtest.aff') 834 call delete('Xtest.spl') 835 call delete('Xtest.sug') 836endfunc 837 838func Test_spell_add_word() 839 set spellfile= 840 call assert_fails('spellgood abc', 'E764:') 841 842 set spellfile=Xtest.utf-8.add 843 call assert_fails('2spellgood abc', 'E765:') 844 845 edit Xtest.utf-8.add 846 call setline(1, 'sample') 847 call assert_fails('spellgood abc', 'E139:') 848 set spellfile& 849 %bw! 850endfunc 851 852func Test_spellfile_verbose() 853 call writefile(['1', 'one'], 'XtestVerbose.dic') 854 call writefile([], 'XtestVerbose.aff') 855 mkspell! XtestVerbose-utf8.spl XtestVerbose 856 set spell 857 858 " First time: the spl file should be read. 859 let a = execute('3verbose set spelllang=XtestVerbose-utf8.spl') 860 call assert_match('Reading spell file "XtestVerbose-utf8.spl"', a) 861 862 " Second time time: the spl file should not be read (already read). 863 let a = execute('3verbose set spelllang=XtestVerbose-utf8.spl') 864 call assert_notmatch('Reading spell file "XtestVerbose-utf8.spl"', a) 865 866 set spell& spelllang& 867 call delete('XtestVerbose.dic') 868 call delete('XtestVerbose.aff') 869 call delete('XtestVerbose-utf8.spl') 870endfunc 871 872" Test NOBREAK (see :help spell-NOBREAK) 873func Test_NOBREAK() 874 call writefile(['3', 'one', 'two', 'three' ], 'XtestNOBREAK.dic') 875 call writefile(['NOBREAK' ], 'XtestNOBREAK.aff') 876 877 mkspell! XtestNOBREAK-utf8.spl XtestNOBREAK 878 set spell spelllang=XtestNOBREAK-utf8.spl 879 880 call assert_equal(['', ''], spellbadword('One two three onetwo onetwothree threetwoone')) 881 882 call assert_equal(['x', 'bad'], spellbadword('x')) 883 call assert_equal(['y', 'bad'], spellbadword('yone')) 884 call assert_equal(['z', 'bad'], spellbadword('onez')) 885 call assert_equal(['zero', 'bad'], spellbadword('Onetwozerothree')) 886 887 set spell& spelllang& 888 call delete('XtestNOBREAK.dic') 889 call delete('XtestNOBREAK.aff') 890 call delete('XtestNOBREAK-utf8.spl') 891endfunc 892 893" Test CHECKCOMPOUNDPATTERN (see :help spell-CHECKCOMPOUNDPATTERN) 894func Test_spellfile_CHECKCOMPOUNDPATTERN() 895 call writefile(['4', 896 \ 'one/c', 897 \ 'two/c', 898 \ 'three/c', 899 \ 'four'], 'XtestCHECKCOMPOUNDPATTERN.dic') 900 " Forbid compound words where first word ends with 'wo' and second starts with 'on'. 901 call writefile(['CHECKCOMPOUNDPATTERN 1', 902 \ 'CHECKCOMPOUNDPATTERN wo on', 903 \ 'COMPOUNDFLAG c'], 'XtestCHECKCOMPOUNDPATTERN.aff') 904 905 mkspell! XtestCHECKCOMPOUNDPATTERN-utf8.spl XtestCHECKCOMPOUNDPATTERN 906 set spell spelllang=XtestCHECKCOMPOUNDPATTERN-utf8.spl 907 908 " Check valid words with and without valid compounds. 909 for goodword in ['one', 'two', 'three', 'four', 910 \ 'oneone', 'onetwo', 'onethree', 911 \ 'twotwo', 'twothree', 912 \ 'threeone', 'threetwo', 'threethree', 913 \ 'onetwothree', 'onethreetwo', 'twothreeone', 'oneoneone'] 914 call assert_equal(['', ''], spellbadword(goodword), goodword) 915 endfor 916 917 " Compounds 'twoone' or 'threetwoone' should be forbidden by CHECKCOMPOUNPATTERN. 918 " 'four' does not have the 'c' flag in *.aff file so no compound. 919 " 'five' is not in the *.dic file. 920 for badword in ['five', 'onetwox', 921 \ 'twoone', 'threetwoone', 922 \ 'fourone', 'onefour'] 923 call assert_equal([badword, 'bad'], spellbadword(badword)) 924 endfor 925 926 set spell& spelllang& 927 call delete('XtestCHECKCOMPOUNDPATTERN.dic') 928 call delete('XtestCHECKCOMPOUNDPATTERN.aff') 929 call delete('XtestCHECKCOMPOUNDPATTERN-utf8.spl') 930endfunc 931 932" Test COMMON (better suggestions with common words, see :help spell-COMMON) 933func Test_spellfile_COMMON() 934 call writefile(['7', 935 \ 'and', 936 \ 'ant', 937 \ 'end', 938 \ 'any', 939 \ 'tee', 940 \ 'the', 941 \ 'ted'], 'XtestCOMMON.dic') 942 call writefile(['COMMON the and'], 'XtestCOMMON.aff') 943 944 mkspell! XtestCOMMON-utf8.spl XtestCOMMON 945 set spell spelllang=XtestCOMMON-utf8.spl 946 947 " COMMON words 'and' and 'the' should be the top suggestions. 948 call assert_equal(['and', 'ant'], spellsuggest('anr', 2)) 949 call assert_equal(['and', 'end'], spellsuggest('ond', 2)) 950 call assert_equal(['the', 'ted'], spellsuggest('tha', 2)) 951 call assert_equal(['the', 'tee'], spellsuggest('dhe', 2)) 952 953 set spell& spelllang& 954 call delete('XtestCOMMON.dic') 955 call delete('XtestCOMMON.aff') 956 call delete('XtestCOMMON-utf8.spl') 957endfunc 958 959" Test CIRCUMFIX (see: :help spell-CIRCUMFIX) 960func Test_spellfile_CIRCUMFIX() 961 " Example taken verbatim from https://github.com/hunspell/hunspell/tree/master/tests 962 call writefile(['1', 963 \ 'nagy/C po:adj'], 'XtestCIRCUMFIX.dic') 964 call writefile(['# circumfixes: ~ obligate prefix/suffix combinations', 965 \ '# superlative in Hungarian: leg- (prefix) AND -bb (suffix)', 966 \ '', 967 \ 'CIRCUMFIX X', 968 \ '', 969 \ 'PFX A Y 1', 970 \ 'PFX A 0 leg/X .', 971 \ '', 972 \ 'PFX B Y 1', 973 \ 'PFX B 0 legesleg/X .', 974 \ '', 975 \ 'SFX C Y 3', 976 \ 'SFX C 0 obb . is:COMPARATIVE', 977 \ 'SFX C 0 obb/AX . is:SUPERLATIVE', 978 \ 'SFX C 0 obb/BX . is:SUPERSUPERLATIVE'], 'XtestCIRCUMFIX.aff') 979 980 mkspell! XtestCIRCUMFIX-utf8.spl XtestCIRCUMFIX 981 set spell spelllang=XtestCIRCUMFIX-utf8.spl 982 983 " From https://catalog.ldc.upenn.edu/docs/LDC2008T01/acta04.pdf: 984 " Hungarian English 985 " --------- ------- 986 " nagy great 987 " nagyobb greater 988 " legnagyobb greatest 989 " legeslegnagyob most greatest 990 call assert_equal(['', ''], spellbadword('nagy nagyobb legnagyobb legeslegnagyobb')) 991 992 for badword in ['legnagy', 'legeslegnagy', 'legobb', 'legeslegobb'] 993 call assert_equal([badword, 'bad'], spellbadword(badword)) 994 endfor 995 996 set spell& spelllang& 997 call delete('XtestCIRCUMFIX.dic') 998 call delete('XtestCIRCUMFIX.aff') 999 call delete('XtestCIRCUMFIX-utf8.spl') 1000endfunc 1001 1002" When 'spellfile' is not set, adding a new good word will automatically set 1003" the 'spellfile' 1004func Test_init_spellfile() 1005 let save_rtp = &rtp 1006 let save_encoding = &encoding 1007 call mkdir('Xrtp/spell', 'p') 1008 call writefile(['vim'], 'Xrtp/spell/Xtest.dic') 1009 silent mkspell Xrtp/spell/Xtest.utf-8.spl Xrtp/spell/Xtest.dic 1010 set runtimepath=./Xrtp 1011 set spelllang=Xtest 1012 set spell 1013 silent spellgood abc 1014 call assert_equal('./Xrtp/spell/Xtest.utf-8.add', &spellfile) 1015 call assert_equal(['abc'], readfile('Xrtp/spell/Xtest.utf-8.add')) 1016 call assert_true(filereadable('Xrtp/spell/Xtest.utf-8.spl')) 1017 set spell& spelllang& spellfile& 1018 call delete('Xrtp', 'rf') 1019 let &encoding = save_encoding 1020 let &rtp = save_rtp 1021 %bw! 1022endfunc 1023 1024" Test for the 'mkspellmem' option 1025func Test_mkspellmem_opt() 1026 call assert_fails('set mkspellmem=1000', 'E474:') 1027 call assert_fails('set mkspellmem=1000,', 'E474:') 1028 call assert_fails('set mkspellmem=1000,50', 'E474:') 1029 call assert_fails('set mkspellmem=1000,50,', 'E474:') 1030 call assert_fails('set mkspellmem=1000,50,10,', 'E474:') 1031 call assert_fails('set mkspellmem=1000,50,0', 'E474:') 1032endfunc 1033 1034" vim: shiftwidth=2 sts=2 expandtab 1035