github.com/aretext/aretext@v1.3.0/locate/word_test.go (about) 1 package locate 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/stretchr/testify/assert" 8 "github.com/stretchr/testify/require" 9 10 "github.com/aretext/aretext/text" 11 "github.com/aretext/aretext/text/segment" 12 ) 13 14 func TestNextWordStart(t *testing.T) { 15 testCases := []struct { 16 name string 17 inputString string 18 pos uint64 19 count uint64 20 withPunct bool 21 stopAtEndOfLastLine bool 22 expectedPos uint64 23 }{ 24 { 25 name: "empty", 26 inputString: "", 27 pos: 0, 28 count: 1, 29 expectedPos: 0, 30 }, 31 { 32 name: "next word from current word, same line", 33 inputString: "abc defg hij", 34 pos: 1, 35 count: 1, 36 expectedPos: 6, 37 }, 38 { 39 name: "next word from whitespace, same line", 40 inputString: "abc defg hij", 41 pos: 4, 42 count: 1, 43 expectedPos: 6, 44 }, 45 { 46 name: "next word from different line", 47 inputString: "abc\n 123", 48 pos: 1, 49 count: 1, 50 expectedPos: 7, 51 }, 52 { 53 name: "next word to empty line", 54 inputString: "abc\n\n 123", 55 pos: 1, 56 count: 1, 57 expectedPos: 4, 58 }, 59 { 60 name: "line ending with punctuation", 61 inputString: "abc.\n123", 62 pos: 3, 63 count: 1, 64 expectedPos: 5, 65 }, 66 { 67 name: "line ending with punctuation", 68 inputString: "abc.\n123", 69 pos: 3, 70 count: 1, 71 expectedPos: 5, 72 withPunct: true, 73 }, 74 { 75 name: "punctuation before whitespace", 76 inputString: "- foo", 77 pos: 0, 78 count: 1, 79 expectedPos: 4, 80 }, 81 { 82 name: "punctuation before whitespace", 83 inputString: "- foo", 84 pos: 0, 85 count: 1, 86 expectedPos: 4, 87 withPunct: true, 88 }, 89 { 90 name: "empty line to next word", 91 inputString: "abc\n\n 123", 92 pos: 4, 93 count: 1, 94 expectedPos: 8, 95 }, 96 { 97 name: "multiple empty lines", 98 inputString: "\n\n\n\n", 99 pos: 1, 100 count: 1, 101 expectedPos: 2, 102 }, 103 { 104 name: "non-punctuation to punctuation", 105 inputString: "abc/def/ghi", 106 pos: 1, 107 count: 1, 108 expectedPos: 3, 109 }, 110 { 111 name: "non-punctuation to punctuation", 112 inputString: "abc/def/ghi", 113 pos: 1, 114 count: 1, 115 expectedPos: 11, 116 withPunct: true, 117 }, 118 { 119 name: "punctuation to non-punctuation", 120 inputString: "abc/def/ghi", 121 pos: 3, 122 count: 1, 123 expectedPos: 4, 124 }, 125 { 126 name: "punctuation to non-punctuation", 127 inputString: "abc/def/ghi", 128 pos: 3, 129 count: 1, 130 expectedPos: 11, 131 withPunct: true, 132 }, 133 { 134 name: "repeated punctuation", 135 inputString: "abc////cde", 136 pos: 3, 137 count: 1, 138 expectedPos: 7, 139 }, 140 { 141 name: "repeated punctuation", 142 inputString: "abc////cde", 143 pos: 3, 144 count: 1, 145 expectedPos: 10, 146 withPunct: true, 147 }, 148 { 149 name: "underscores treated as non-punctuation", 150 inputString: "abc_def ghi", 151 pos: 0, 152 count: 1, 153 expectedPos: 8, 154 }, 155 { 156 name: "underscores treated as non-punctuation", 157 inputString: "abc_def ghi", 158 pos: 0, 159 count: 1, 160 expectedPos: 8, 161 withPunct: true, 162 }, 163 { 164 name: "last word in document", 165 inputString: "foo bar", 166 pos: 5, 167 count: 1, 168 expectedPos: 7, 169 }, 170 { 171 name: "count zero", 172 inputString: "lorem ipsum dolor sit amet", 173 pos: 2, 174 count: 0, 175 expectedPos: 2, 176 }, 177 { 178 name: "count three", 179 inputString: "lorem ipsum dolor sit amet", 180 pos: 2, 181 count: 3, 182 expectedPos: 18, 183 }, 184 { 185 name: "stop at end of last line", 186 inputString: "foo bar\nbaz bat\n", 187 pos: 4, 188 count: 1, 189 stopAtEndOfLastLine: true, 190 expectedPos: 7, 191 }, 192 { 193 name: "stop at end of last line, on empty line", 194 inputString: "foo\n\nbaz bat\n", 195 pos: 3, 196 count: 1, 197 stopAtEndOfLastLine: true, 198 expectedPos: 3, 199 }, 200 { 201 name: "stop at end of last line with count", 202 inputString: "foo bar\nbaz bat\nlorem", 203 pos: 0, 204 count: 4, 205 stopAtEndOfLastLine: true, 206 expectedPos: 15, 207 }, 208 } 209 210 for _, tc := range testCases { 211 t.Run(tc.name, func(t *testing.T) { 212 textTree, err := text.NewTreeFromString(tc.inputString) 213 require.NoError(t, err) 214 actualPos := NextWordStart(textTree, tc.pos, tc.count, tc.withPunct, tc.stopAtEndOfLastLine) 215 assert.Equal(t, tc.expectedPos, actualPos) 216 }) 217 } 218 } 219 220 func TestNextWordEnd(t *testing.T) { 221 testCases := []struct { 222 name string 223 inputString string 224 pos uint64 225 count uint64 226 expectedPos uint64 227 withPunct bool 228 }{ 229 { 230 name: "empty", 231 inputString: "", 232 pos: 0, 233 count: 1, 234 expectedPos: 0, 235 }, 236 { 237 name: "end of word from start of current word", 238 inputString: "abc defg hij", 239 pos: 6, 240 count: 1, 241 expectedPos: 9, 242 }, 243 { 244 name: "end of word from middle of current word", 245 inputString: "abc defg hij", 246 pos: 7, 247 count: 1, 248 expectedPos: 9, 249 }, 250 { 251 name: "next word from end of current word", 252 inputString: "abc defg hij", 253 pos: 2, 254 count: 1, 255 expectedPos: 9, 256 }, 257 { 258 name: "next word from whitespace", 259 inputString: "abc defg hij", 260 pos: 4, 261 count: 1, 262 expectedPos: 9, 263 }, 264 { 265 name: "next word past empty line", 266 inputString: "abc\n\n 123 xyz", 267 pos: 2, 268 count: 1, 269 expectedPos: 10, 270 }, 271 { 272 name: "empty line to next word", 273 inputString: "abc\n\n 123 xyz", 274 pos: 4, 275 count: 1, 276 expectedPos: 10, 277 }, 278 { 279 name: "punctuation", 280 inputString: "abc/def/ghi", 281 pos: 1, 282 count: 1, 283 expectedPos: 2, 284 }, 285 { 286 name: "punctuation", 287 inputString: "abc/def/ghi", 288 pos: 1, 289 count: 1, 290 expectedPos: 10, 291 withPunct: true, 292 }, 293 { 294 name: "last word in document, third to last character", 295 inputString: "foo bar", 296 pos: 4, 297 count: 1, 298 expectedPos: 6, 299 }, 300 { 301 name: "last word in document, second to last character", 302 inputString: "foo bar", 303 pos: 5, 304 count: 1, 305 expectedPos: 6, 306 }, 307 { 308 name: "last word in document, last character", 309 inputString: "foo bar", 310 pos: 6, 311 count: 1, 312 expectedPos: 6, 313 }, 314 { 315 name: "count zero", 316 inputString: "lorem ipsum dolor sit amet", 317 pos: 2, 318 count: 0, 319 expectedPos: 2, 320 }, 321 { 322 name: "count three", 323 inputString: "lorem ipsum dolor sit amet", 324 pos: 2, 325 count: 3, 326 expectedPos: 16, 327 }, 328 } 329 330 for _, tc := range testCases { 331 t.Run(tc.name, func(t *testing.T) { 332 textTree, err := text.NewTreeFromString(tc.inputString) 333 require.NoError(t, err) 334 actualPos := NextWordEnd(textTree, tc.pos, tc.count, tc.withPunct) 335 assert.Equal(t, tc.expectedPos, actualPos) 336 }) 337 } 338 } 339 340 func TestPrevWordStart(t *testing.T) { 341 testCases := []struct { 342 name string 343 inputString string 344 pos uint64 345 count uint64 346 expectedPos uint64 347 withPunct bool 348 }{ 349 { 350 name: "empty", 351 inputString: "", 352 pos: 0, 353 count: 1, 354 expectedPos: 0, 355 }, 356 { 357 name: "prev word from current word, same line", 358 inputString: "abc defg hij", 359 pos: 6, 360 count: 1, 361 expectedPos: 0, 362 }, 363 { 364 name: "prev word from whitespace, same line", 365 inputString: "abc defg hij", 366 pos: 12, 367 count: 1, 368 expectedPos: 6, 369 }, 370 { 371 name: "prev word from different line", 372 inputString: "abc\n 123", 373 pos: 7, 374 count: 1, 375 expectedPos: 0, 376 }, 377 { 378 name: "prev word to empty line", 379 inputString: "abc\n\n 123", 380 pos: 8, 381 count: 1, 382 expectedPos: 4, 383 }, 384 { 385 name: "empty line to prev word", 386 inputString: "abc\n\n 123", 387 pos: 4, 388 count: 1, 389 expectedPos: 0, 390 }, 391 { 392 name: "multiple empty lines", 393 inputString: "\n\n\n\n", 394 pos: 2, 395 count: 1, 396 expectedPos: 1, 397 }, 398 { 399 name: "punctuation", 400 inputString: "abc/def/ghi", 401 pos: 5, 402 count: 1, 403 expectedPos: 4, 404 }, 405 { 406 name: "line ending with punctuation", 407 inputString: "abc.\n123", 408 pos: 5, 409 count: 1, 410 expectedPos: 3, 411 }, 412 { 413 name: "punctuation before whitespace", 414 inputString: "- foo", 415 pos: 4, 416 count: 1, 417 expectedPos: 0, 418 }, 419 { 420 name: "count zero", 421 inputString: "lorem ipsum dolor sit amet", 422 pos: 18, 423 count: 0, 424 expectedPos: 18, 425 }, 426 { 427 name: "count three", 428 inputString: "lorem ipsum dolor sit amet", 429 pos: 25, 430 count: 3, 431 expectedPos: 12, 432 }, 433 { 434 name: "count three, with punctuation", 435 inputString: "lorem, ipsum, dolor, sit, amet", 436 withPunct: true, 437 pos: 29, 438 count: 3, 439 expectedPos: 14, 440 }, 441 } 442 443 for _, tc := range testCases { 444 t.Run(tc.name, func(t *testing.T) { 445 textTree, err := text.NewTreeFromString(tc.inputString) 446 require.NoError(t, err) 447 actualPos := PrevWordStart(textTree, tc.pos, tc.count, tc.withPunct) 448 assert.Equal(t, tc.expectedPos, actualPos) 449 }) 450 } 451 } 452 453 func TestWordObject(t *testing.T) { 454 testCases := []struct { 455 name string 456 inputString string 457 pos uint64 458 count uint64 459 expectedStartPos uint64 460 expectedEndPos uint64 461 }{ 462 { 463 name: "empty", 464 inputString: "", 465 pos: 0, 466 count: 1, 467 expectedStartPos: 0, 468 expectedEndPos: 0, 469 }, 470 { 471 name: "on start of leading whitespace before word", 472 inputString: "abc def ghi", 473 pos: 3, 474 count: 1, 475 expectedStartPos: 3, 476 expectedEndPos: 9, 477 }, 478 { 479 name: "on middle of leading whitespace before word", 480 inputString: "abc def ghi", 481 pos: 4, 482 count: 1, 483 expectedStartPos: 3, 484 expectedEndPos: 9, 485 }, 486 { 487 name: "on end of leading whitespace before word", 488 inputString: "abc def ghi", 489 pos: 5, 490 count: 1, 491 expectedStartPos: 3, 492 expectedEndPos: 9, 493 }, 494 { 495 name: "on start of word with trailing whitespace", 496 inputString: "abc def ghi", 497 pos: 4, 498 count: 1, 499 expectedStartPos: 4, 500 expectedEndPos: 11, 501 }, 502 { 503 name: "on middle of word with trailing whitespace", 504 inputString: "abc def ghi", 505 pos: 5, 506 count: 1, 507 expectedStartPos: 4, 508 expectedEndPos: 11, 509 }, 510 { 511 name: "on end of word with trailing whitespace", 512 inputString: "abc def ghi", 513 pos: 6, 514 count: 1, 515 expectedStartPos: 4, 516 expectedEndPos: 11, 517 }, 518 { 519 name: "start of word after punctuation", 520 inputString: "abc/def/ghi", 521 pos: 4, 522 count: 1, 523 expectedStartPos: 4, 524 expectedEndPos: 7, 525 }, 526 { 527 name: "middle of word after punctuation", 528 inputString: "abc/def/ghi", 529 pos: 5, 530 count: 1, 531 expectedStartPos: 4, 532 expectedEndPos: 7, 533 }, 534 { 535 name: "end of word after punctuation", 536 inputString: "abc/def/ghi", 537 pos: 6, 538 count: 1, 539 expectedStartPos: 4, 540 expectedEndPos: 7, 541 }, 542 { 543 name: "on punctuation surrounded by words", 544 inputString: "abc/def/ghi", 545 pos: 3, 546 count: 1, 547 expectedStartPos: 3, 548 expectedEndPos: 4, 549 }, 550 { 551 name: "on punctuation surrounded by whitespace", 552 inputString: "a / b", 553 pos: 4, 554 count: 1, 555 expectedStartPos: 4, 556 expectedEndPos: 8, 557 }, 558 { 559 name: "on multiple punctuation chars", 560 inputString: "abc///ghi", 561 pos: 4, 562 count: 1, 563 expectedStartPos: 3, 564 expectedEndPos: 6, 565 }, 566 { 567 name: "on leading whitespace before punctuation", 568 inputString: "foo {bar", 569 pos: 3, 570 count: 1, 571 expectedStartPos: 3, 572 expectedEndPos: 6, 573 }, 574 { 575 name: "whitespace at start of line", 576 inputString: "abc\n xyz", 577 pos: 6, 578 count: 1, 579 expectedStartPos: 4, 580 expectedEndPos: 11, 581 }, 582 { 583 584 name: "empty line, indentation", 585 inputString: "abc\n\n 123", 586 pos: 4, 587 count: 1, 588 expectedStartPos: 4, 589 expectedEndPos: 11, 590 }, 591 { 592 593 name: "empty line, no indentation", 594 inputString: "abc\n\n123", 595 pos: 4, 596 count: 1, 597 expectedStartPos: 4, 598 expectedEndPos: 8, 599 }, 600 { 601 name: "start of word at end of document", 602 inputString: "abcd", 603 pos: 0, 604 count: 1, 605 expectedStartPos: 0, 606 expectedEndPos: 4, 607 }, 608 { 609 name: "middle of word at end of document", 610 inputString: "abcd", 611 pos: 2, 612 count: 1, 613 expectedStartPos: 0, 614 expectedEndPos: 4, 615 }, 616 { 617 name: "end of word at end of document", 618 inputString: "abcd", 619 pos: 3, 620 count: 1, 621 expectedStartPos: 0, 622 expectedEndPos: 4, 623 }, 624 625 { 626 name: "on word before whitespace at end of document", 627 inputString: "abc ", 628 pos: 2, 629 count: 1, 630 expectedStartPos: 0, 631 expectedEndPos: 7, 632 }, 633 { 634 name: "on whitespace at end of document", 635 inputString: "abc ", 636 pos: 4, 637 count: 1, 638 expectedStartPos: 3, 639 expectedEndPos: 7, 640 }, 641 { 642 name: "count zero", 643 inputString: "lorem ipsum dolor sit amet", 644 pos: 7, 645 count: 0, 646 expectedStartPos: 7, 647 expectedEndPos: 7, 648 }, 649 { 650 name: "count three with leading whitespace", 651 inputString: "lorem ipsum dolor sit amet", 652 pos: 5, 653 count: 3, 654 expectedStartPos: 5, 655 expectedEndPos: 21, 656 }, 657 { 658 name: "count three with trailing whitespace", 659 inputString: "lorem ipsum dolor sit amet", 660 pos: 7, 661 count: 3, 662 expectedStartPos: 6, 663 expectedEndPos: 22, 664 }, 665 { 666 name: "count three with punctuation", 667 inputString: "lorem.ipsum.dolor.sit.amet", 668 pos: 5, 669 count: 3, 670 expectedStartPos: 5, 671 expectedEndPos: 12, 672 }, 673 { 674 name: "count three with punctuation with leading whitespace", 675 inputString: "lorem ipsum.dolor.sit.amet", 676 pos: 6, 677 count: 3, 678 expectedStartPos: 5, 679 expectedEndPos: 19, 680 }, 681 { 682 name: "count with multiple whitespace, leading whitespace", 683 inputString: "lorem ipsum dolor sit amet", 684 pos: 7, 685 count: 2, 686 expectedStartPos: 5, 687 expectedEndPos: 26, 688 }, 689 { 690 name: "count with multiple whitespace, trailing whitespace", 691 inputString: "lorem ipsum dolor sit amet", 692 pos: 2, 693 count: 2, 694 expectedStartPos: 0, 695 expectedEndPos: 21, 696 }, 697 } 698 699 for _, tc := range testCases { 700 t.Run(tc.name, func(t *testing.T) { 701 textTree, err := text.NewTreeFromString(tc.inputString) 702 require.NoError(t, err) 703 startPos, endPos := WordObject(textTree, tc.pos, tc.count) 704 assert.Equal(t, tc.expectedStartPos, startPos) 705 assert.Equal(t, tc.expectedEndPos, endPos) 706 }) 707 } 708 } 709 710 func TestInnerWordObject(t *testing.T) { 711 testCases := []struct { 712 name string 713 inputString string 714 pos uint64 715 count uint64 716 expectedStartPos uint64 717 expectedEndPos uint64 718 }{ 719 { 720 name: "empty", 721 inputString: "", 722 pos: 0, 723 count: 1, 724 expectedStartPos: 0, 725 expectedEndPos: 0, 726 }, 727 { 728 name: "on start of leading whitespace before word", 729 inputString: "abc def ghi", 730 pos: 3, 731 count: 1, 732 expectedStartPos: 3, 733 expectedEndPos: 6, 734 }, 735 { 736 name: "on middle of leading whitespace before word", 737 inputString: "abc def ghi", 738 pos: 4, 739 count: 1, 740 expectedStartPos: 3, 741 expectedEndPos: 6, 742 }, 743 { 744 name: "on end of leading whitespace before word", 745 inputString: "abc def ghi", 746 pos: 5, 747 count: 1, 748 expectedStartPos: 3, 749 expectedEndPos: 6, 750 }, 751 { 752 name: "on start of word with trailing whitespace", 753 inputString: "abc def ghi", 754 pos: 4, 755 count: 1, 756 expectedStartPos: 4, 757 expectedEndPos: 7, 758 }, 759 { 760 name: "on middle of word with trailing whitespace", 761 inputString: "abc def ghi", 762 pos: 5, 763 count: 1, 764 expectedStartPos: 4, 765 expectedEndPos: 7, 766 }, 767 { 768 name: "on end of word with trailing whitespace", 769 inputString: "abc def ghi", 770 pos: 6, 771 count: 1, 772 expectedStartPos: 4, 773 expectedEndPos: 7, 774 }, 775 { 776 name: "start of word after punctuation", 777 inputString: "abc/def/ghi", 778 pos: 4, 779 count: 1, 780 expectedStartPos: 4, 781 expectedEndPos: 7, 782 }, 783 { 784 name: "middle of word after punctuation", 785 inputString: "abc/def/ghi", 786 pos: 5, 787 count: 1, 788 expectedStartPos: 4, 789 expectedEndPos: 7, 790 }, 791 { 792 name: "end of word after punctuation", 793 inputString: "abc/def/ghi", 794 pos: 6, 795 count: 1, 796 expectedStartPos: 4, 797 expectedEndPos: 7, 798 }, 799 { 800 name: "on punctuation surrounded by words", 801 inputString: "abc/def/ghi", 802 pos: 3, 803 count: 1, 804 expectedStartPos: 3, 805 expectedEndPos: 4, 806 }, 807 { 808 name: "on punctuation surrounded by whitespace", 809 inputString: "a / b", 810 pos: 4, 811 count: 1, 812 expectedStartPos: 4, 813 expectedEndPos: 5, 814 }, 815 { 816 name: "on multiple punctuation chars", 817 inputString: "abc///ghi", 818 pos: 4, 819 count: 1, 820 expectedStartPos: 3, 821 expectedEndPos: 6, 822 }, 823 { 824 name: "on leading whitespace before punctuation", 825 inputString: "foo {bar", 826 pos: 3, 827 count: 1, 828 expectedStartPos: 3, 829 expectedEndPos: 5, 830 }, 831 { 832 name: "whitespace at start of line", 833 inputString: "abc\n xyz", 834 pos: 6, 835 count: 1, 836 expectedStartPos: 4, 837 expectedEndPos: 8, 838 }, 839 { 840 841 name: "empty line, indentation", 842 inputString: "abc\n\n 123", 843 pos: 4, 844 count: 1, 845 expectedStartPos: 4, 846 expectedEndPos: 4, 847 }, 848 { 849 850 name: "empty line, no indentation", 851 inputString: "abc\n\n123", 852 pos: 4, 853 count: 1, 854 expectedStartPos: 4, 855 expectedEndPos: 4, 856 }, 857 { 858 name: "word at end of line", 859 inputString: "foo bar\nbaz\nbat", 860 pos: 5, 861 count: 1, 862 expectedStartPos: 4, 863 expectedEndPos: 7, 864 }, 865 { 866 name: "start of word at end of document", 867 inputString: "abcd", 868 pos: 0, 869 count: 1, 870 expectedStartPos: 0, 871 expectedEndPos: 4, 872 }, 873 { 874 name: "middle of word at end of document", 875 inputString: "abcd", 876 pos: 2, 877 count: 1, 878 expectedStartPos: 0, 879 expectedEndPos: 4, 880 }, 881 { 882 name: "end of word at end of document", 883 inputString: "abcd", 884 pos: 3, 885 count: 1, 886 expectedStartPos: 0, 887 expectedEndPos: 4, 888 }, 889 890 { 891 name: "on word before whitespace at end of document", 892 inputString: "abc ", 893 pos: 2, 894 count: 1, 895 expectedStartPos: 0, 896 expectedEndPos: 3, 897 }, 898 { 899 name: "on whitespace at end of document", 900 inputString: "abc ", 901 pos: 4, 902 count: 1, 903 expectedStartPos: 3, 904 expectedEndPos: 7, 905 }, 906 { 907 name: "count zero", 908 inputString: "lorem ipsum dolor sit amet", 909 pos: 7, 910 count: 0, 911 expectedStartPos: 7, 912 expectedEndPos: 7, 913 }, 914 { 915 name: "count three", 916 inputString: "lorem ipsum dolor sit amet", 917 pos: 7, 918 count: 3, 919 expectedStartPos: 6, 920 expectedEndPos: 17, 921 }, 922 { 923 name: "count past end of line", 924 inputString: "lorem ipsum\ndolor\nsit amet", 925 pos: 1, 926 count: 5, 927 expectedStartPos: 0, 928 expectedEndPos: 21, 929 }, 930 } 931 932 for _, tc := range testCases { 933 t.Run(tc.name, func(t *testing.T) { 934 textTree, err := text.NewTreeFromString(tc.inputString) 935 require.NoError(t, err) 936 startPos, endPos := InnerWordObject(textTree, tc.pos, tc.count) 937 assert.Equal(t, tc.expectedStartPos, startPos) 938 assert.Equal(t, tc.expectedEndPos, endPos) 939 }) 940 } 941 } 942 943 func TestIsPunct(t *testing.T) { 944 testCases := []struct { 945 r rune 946 expectPunct bool 947 }{ 948 {r: '\x00', expectPunct: false}, 949 {r: '\x01', expectPunct: false}, 950 {r: '\x02', expectPunct: false}, 951 {r: '\x03', expectPunct: false}, 952 {r: '\x04', expectPunct: false}, 953 {r: '\x05', expectPunct: false}, 954 {r: '\x06', expectPunct: false}, 955 {r: '\a', expectPunct: false}, 956 {r: '\b', expectPunct: false}, 957 {r: '\t', expectPunct: false}, 958 {r: '\n', expectPunct: false}, 959 {r: '\v', expectPunct: false}, 960 {r: '\f', expectPunct: false}, 961 {r: '\r', expectPunct: false}, 962 {r: '\x0e', expectPunct: false}, 963 {r: '\x0f', expectPunct: false}, 964 {r: '\x10', expectPunct: false}, 965 {r: '\x11', expectPunct: false}, 966 {r: '\x12', expectPunct: false}, 967 {r: '\x13', expectPunct: false}, 968 {r: '\x14', expectPunct: false}, 969 {r: '\x15', expectPunct: false}, 970 {r: '\x16', expectPunct: false}, 971 {r: '\x17', expectPunct: false}, 972 {r: '\x18', expectPunct: false}, 973 {r: '\x19', expectPunct: false}, 974 {r: '\x1a', expectPunct: false}, 975 {r: '\x1b', expectPunct: false}, 976 {r: '\x1c', expectPunct: false}, 977 {r: '\x1d', expectPunct: false}, 978 {r: '\x1e', expectPunct: false}, 979 {r: '\x1f', expectPunct: false}, 980 {r: ' ', expectPunct: false}, 981 {r: '!', expectPunct: true}, 982 {r: '"', expectPunct: true}, 983 {r: '#', expectPunct: true}, 984 {r: '$', expectPunct: true}, 985 {r: '%', expectPunct: true}, 986 {r: '&', expectPunct: true}, 987 {r: '\'', expectPunct: true}, 988 {r: '(', expectPunct: true}, 989 {r: ')', expectPunct: true}, 990 {r: '*', expectPunct: true}, 991 {r: '+', expectPunct: true}, 992 {r: ',', expectPunct: true}, 993 {r: '-', expectPunct: true}, 994 {r: '.', expectPunct: true}, 995 {r: '/', expectPunct: true}, 996 {r: '0', expectPunct: false}, 997 {r: '1', expectPunct: false}, 998 {r: '2', expectPunct: false}, 999 {r: '3', expectPunct: false}, 1000 {r: '4', expectPunct: false}, 1001 {r: '5', expectPunct: false}, 1002 {r: '6', expectPunct: false}, 1003 {r: '7', expectPunct: false}, 1004 {r: '8', expectPunct: false}, 1005 {r: '9', expectPunct: false}, 1006 {r: ':', expectPunct: true}, 1007 {r: ';', expectPunct: true}, 1008 {r: '<', expectPunct: true}, 1009 {r: '=', expectPunct: true}, 1010 {r: '>', expectPunct: true}, 1011 {r: '?', expectPunct: true}, 1012 {r: '@', expectPunct: true}, 1013 {r: 'A', expectPunct: false}, 1014 {r: 'B', expectPunct: false}, 1015 {r: 'C', expectPunct: false}, 1016 {r: 'D', expectPunct: false}, 1017 {r: 'E', expectPunct: false}, 1018 {r: 'F', expectPunct: false}, 1019 {r: 'G', expectPunct: false}, 1020 {r: 'H', expectPunct: false}, 1021 {r: 'I', expectPunct: false}, 1022 {r: 'J', expectPunct: false}, 1023 {r: 'K', expectPunct: false}, 1024 {r: 'L', expectPunct: false}, 1025 {r: 'M', expectPunct: false}, 1026 {r: 'N', expectPunct: false}, 1027 {r: 'O', expectPunct: false}, 1028 {r: 'P', expectPunct: false}, 1029 {r: 'Q', expectPunct: false}, 1030 {r: 'R', expectPunct: false}, 1031 {r: 'S', expectPunct: false}, 1032 {r: 'T', expectPunct: false}, 1033 {r: 'U', expectPunct: false}, 1034 {r: 'V', expectPunct: false}, 1035 {r: 'W', expectPunct: false}, 1036 {r: 'X', expectPunct: false}, 1037 {r: 'Y', expectPunct: false}, 1038 {r: 'Z', expectPunct: false}, 1039 {r: '[', expectPunct: true}, 1040 {r: '\\', expectPunct: true}, 1041 {r: ']', expectPunct: true}, 1042 {r: '^', expectPunct: true}, 1043 {r: '_', expectPunct: false}, 1044 {r: '`', expectPunct: true}, 1045 {r: 'a', expectPunct: false}, 1046 {r: 'b', expectPunct: false}, 1047 {r: 'c', expectPunct: false}, 1048 {r: 'd', expectPunct: false}, 1049 {r: 'e', expectPunct: false}, 1050 {r: 'f', expectPunct: false}, 1051 {r: 'g', expectPunct: false}, 1052 {r: 'h', expectPunct: false}, 1053 {r: 'i', expectPunct: false}, 1054 {r: 'j', expectPunct: false}, 1055 {r: 'k', expectPunct: false}, 1056 {r: 'l', expectPunct: false}, 1057 {r: 'm', expectPunct: false}, 1058 {r: 'n', expectPunct: false}, 1059 {r: 'o', expectPunct: false}, 1060 {r: 'p', expectPunct: false}, 1061 {r: 'q', expectPunct: false}, 1062 {r: 'r', expectPunct: false}, 1063 {r: 's', expectPunct: false}, 1064 {r: 't', expectPunct: false}, 1065 {r: 'u', expectPunct: false}, 1066 {r: 'v', expectPunct: false}, 1067 {r: 'w', expectPunct: false}, 1068 {r: 'x', expectPunct: false}, 1069 {r: 'y', expectPunct: false}, 1070 {r: 'z', expectPunct: false}, 1071 {r: '{', expectPunct: true}, 1072 {r: '|', expectPunct: true}, 1073 {r: '}', expectPunct: true}, 1074 {r: '~', expectPunct: true}, 1075 {r: '\u007f', expectPunct: false}, 1076 } 1077 1078 for _, tc := range testCases { 1079 t.Run(fmt.Sprintf("%q", tc.r), func(t *testing.T) { 1080 seg := segment.Empty() 1081 seg.Append(tc.r) 1082 assert.Equal(t, tc.expectPunct, isPunct(seg)) 1083 }) 1084 } 1085 }