1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
|
package editor
import (
"testing"
"glint/internal/spell"
)
func spellEditor(t *testing.T, content string) *Editor {
t.Helper()
d, err := spell.Load()
if err != nil {
t.Fatalf("spell.Load: %v", err)
}
e := New()
e.SetContent([]byte(content))
e.SetDict(d)
e.SetSpell(true)
return e
}
// wavyWords returns the set of span texts rendered with the misspell undercurl.
func wavyWords(e *Editor) map[string]bool {
got := map[string]bool{}
for _, vr := range e.buildVisual() {
for _, sp := range vr.spans {
if sp.Wavy {
got[sp.Text] = true
}
}
}
return got
}
func TestSpellFlagsMisspelledProse(t *testing.T) {
e := spellEditor(t, "This sentence has a recieve typo")
w := wavyWords(e)
if !w["recieve"] {
t.Errorf("misspelled \"recieve\" not flagged; wavy=%v", w)
}
if w["sentence"] || w["typo"] || w["This"] {
t.Errorf("correct words flagged; wavy=%v", w)
}
}
func TestSpellSkipsInlineCode(t *testing.T) {
e := spellEditor(t, "use the `recieve` function")
if wavyWords(e)["recieve"] {
t.Error("inline code content should not be spellchecked")
}
}
func TestSpellSkipsURLs(t *testing.T) {
e := spellEditor(t, "see https://recieve.example.com/seperate for more")
w := wavyWords(e)
if w["recieve"] || w["seperate"] {
t.Errorf("URL words should not be flagged; wavy=%v", w)
}
}
func TestSpellSkipsWikilinks(t *testing.T) {
e := spellEditor(t, "linked [[recieve note]] here")
if wavyWords(e)["recieve"] {
t.Error("wikilink target should not be spellchecked")
}
}
func TestSpellSkipsFrontmatter(t *testing.T) {
e := spellEditor(t, "---\ntitle: recieve draft\n---\nbody text")
if wavyWords(e)["recieve"] {
t.Error("frontmatter value should not be spellchecked")
}
}
func TestSpellSkipsAcronymsAndShortWords(t *testing.T) {
e := spellEditor(t, "the NASA API is ok")
w := wavyWords(e)
if w["NASA"] || w["API"] || w["ok"] || w["is"] {
t.Errorf("acronyms/short words should not be flagged; wavy=%v", w)
}
}
func TestSpellOffWhenDisabled(t *testing.T) {
e := spellEditor(t, "a recieve typo")
e.SetSpell(false)
if len(wavyWords(e)) != 0 {
t.Error("no words should be flagged when spellcheck is off")
}
}
func TestSpellOffForCodeFiles(t *testing.T) {
e := spellEditor(t, "recieve := 1")
e.SetLanguage("main.go") // code file: spellcheck must stay off
if len(wavyWords(e)) != 0 {
t.Error("code files should not be spellchecked")
}
}
func TestSpellHonorsPersonalAdd(t *testing.T) {
e := spellEditor(t, "my zzplonk word")
if !wavyWords(e)["zzplonk"] {
t.Fatal("precondition: zzplonk should flag")
}
e.AddToDictionary("zzplonk")
if wavyWords(e)["zzplonk"] {
t.Error("word added to dictionary should clear its underline live")
}
}
func TestFlaggedWordAtFindsMisspelling(t *testing.T) {
e := spellEditor(t, "a recieve here")
// "recieve" spans columns 2..9.
word, start, end, ok := e.FlaggedWordAt(0, 4)
if !ok || word != "recieve" {
t.Fatalf("FlaggedWordAt(0,4) = %q,%d,%d,%v; want recieve", word, start, end, ok)
}
if start != 2 || end != 9 {
t.Errorf("range = [%d,%d), want [2,9)", start, end)
}
}
func TestFlaggedWordAtNoneOnCorrectWord(t *testing.T) {
e := spellEditor(t, "all correct words here")
if _, _, _, ok := e.FlaggedWordAt(0, 2); ok {
t.Error("FlaggedWordAt found a flag on a correct line")
}
}
func TestReplaceWordAt(t *testing.T) {
e := spellEditor(t, "a recieve here")
e.ReplaceWordAt(0, 2, 9, "receive")
if e.Lines[0] != "a receive here" {
t.Errorf("after replace, line = %q", e.Lines[0])
}
if !e.Dirty {
t.Error("replace should mark the buffer dirty")
}
if wavyWords(e)["receive"] {
t.Error("replaced word should no longer be flagged")
}
}
func TestIgnoreWordClearsFlag(t *testing.T) {
e := spellEditor(t, "my zzplonk word")
if !wavyWords(e)["zzplonk"] {
t.Fatal("precondition: zzplonk flagged")
}
e.IgnoreWord("zzplonk")
if wavyWords(e)["zzplonk"] {
t.Error("ignored word should not be flagged for the session")
}
}
func TestEditorSuggest(t *testing.T) {
e := spellEditor(t, "recieve")
got := e.Suggest("recieve", 5)
found := false
for _, s := range got {
if s == "receive" {
found = true
}
}
if !found {
t.Errorf("Suggest(recieve) = %v, want receive", got)
}
}
|