turbo-editors/turbo-corepublic Fork 0
v1.0.2
Commits
Clone
git clone https://git.rickub.com/turbo-editors/turbo-core.git
git clone ssh://git@rickub.com/turbo-editors/turbo-core.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

save_test.go · 196 lines · 6.7 KBGo Blame HistoryRaw
🛟 Updated. 28d5985 k33g 20h ago1package app
2
3import (
4 "path/filepath"
5 "testing"
📦 Turbo Core — a save that creates a file tells the server (workspace/didChangeWatchedFiles), so moon-lsp diagnoses a new .mbt from its first save 3561e52 k33g 11h ago6 "time"
7
8 "rickub.com/turbo-editors/turbo-core/lsp"
🛟 Updated. 28d5985 k33g 20h ago9)
10
11// These tests cover what saving says to the language server. The defect they
12// were written against: a window that started Untitled gains its path through
13// Save As, afterSave sent only didSave, and a server ignores didSave for a
14// document it was never told is open — so the window had no completion until
15// the editor was restarted.
16
17func TestSavingAnUntitledWindowAnnouncesItsDocument(t *testing.T) {
18 project := t.TempDir()
19 t.Chdir(project)
20 a, _ := newTestApp(t)
21 client, server := newFakeLanguage(t, a)
22 connectLanguage(a, client)
23 a.Tick() // the start-up announcement runs, and finds nothing to tell
24
25 a.NewFile()
26 typeText(a, "package main")
27 path := filepath.Join(project, "main.go")
28 a.save(a.ActiveView(), path)
29
30 waitForMethod(t, server, "textDocument/didOpen")
31 if got := server.methodCount("textDocument/didSave"); got != 0 {
32 t.Errorf("didSave was sent %d times for a document the server was never told is open", got)
33 }
34 if !a.language.Knows(path) {
35 t.Errorf("after the save, the server still does not know %q", path)
36 }
37}
38
39func TestSaveAsUnderANewNameClosesTheOldDocument(t *testing.T) {
40 project := t.TempDir()
41 t.Chdir(project)
42 a, _ := newTestApp(t)
43 client, server := newFakeLanguage(t, a)
44 connectLanguage(a, client)
45
46 writeTestFile(t, filepath.Join(project, "old.go"), "package main\n")
47 a.Open("old.go")
48 waitForMethod(t, server, "textDocument/didOpen")
49
50 newPath := filepath.Join(project, "new.go")
51 a.save(a.ActiveView(), newPath)
52
53 waitForMethod(t, server, "textDocument/didClose")
54 if a.language.Knows("old.go") {
55 t.Errorf("the old document is still open on the server after Save As gave the buffer a new name")
56 }
57 if !a.language.Knows(newPath) {
58 t.Errorf("the new document was never announced to the server")
59 }
60}
61
62func TestSaveAsToTheSamePathClosesNothing(t *testing.T) {
63 // Save As offered the file's own name and the user accepted it: that is a
64 // write, not a rename, however the dialog spelt the path.
65 project := t.TempDir()
66 t.Chdir(project)
67 a, _ := newTestApp(t)
68 client, server := newFakeLanguage(t, a)
69 connectLanguage(a, client)
70
71 writeTestFile(t, filepath.Join(project, "main.go"), "package main\n")
72 a.Open("main.go") // relative, as the command line gives it
73 waitForMethod(t, server, "textDocument/didOpen")
74
75 a.save(a.ActiveView(), filepath.Join(project, "main.go")) // absolute, as the dialog gives it
76
77 waitForMethod(t, server, "textDocument/didSave")
78 if got := server.methodCount("textDocument/didClose"); got != 0 {
79 t.Errorf("didClose was sent %d times for a save that renamed nothing", got)
80 }
81}
82
83func TestSavingAKnownDocumentReportsTheWrite(t *testing.T) {
84 project := t.TempDir()
85 t.Chdir(project)
86 a, _ := newTestApp(t)
87 client, server := newFakeLanguage(t, a)
88 connectLanguage(a, client)
89
90 writeTestFile(t, filepath.Join(project, "main.go"), "package main\n")
91 a.Open("main.go")
92 waitForMethod(t, server, "textDocument/didOpen")
93
94 a.save(a.ActiveView(), a.ActiveView().Buffer().Path())
95
96 waitForMethod(t, server, "textDocument/didSave")
97 if got := server.methodCount("textDocument/didOpen"); got != 1 {
98 t.Errorf("didOpen was sent %d times; saving an open document must not re-announce it", got)
99 }
100}
📦 Turbo Core — a save that creates a file tells the server (workspace/didChangeWatchedFiles), so moon-lsp diagnoses a new .mbt from its first save 3561e52 k33g 11h ago101
102func TestSavingANewFileTellsTheServerTheFileExists(t *testing.T) {
103 // To moon-lsp a document being open and a file existing are two facts,
104 // and it works a package's files out from the directory: a .mbt saved for
105 // the first time got no diagnostics, however loudly the document had been
106 // announced, until the server was told the file is there. Found on macOS
107 // the first time Turbo MoonBit's suite ran there; confirmed at the
108 // protocol level — the same file is diagnosed the moment
109 // workspace/didChangeWatchedFiles names it.
110 project := t.TempDir()
111 t.Chdir(project)
112 a, _ := newTestApp(t)
113 client, server := newFakeLanguage(t, a)
114 connectLanguage(a, client)
115 a.Tick()
116
117 a.NewFile()
118 typeText(a, "package main")
119 path := filepath.Join(project, "main.go")
120 a.save(a.ActiveView(), path)
121
122 waitForMethod(t, server, "workspace/didChangeWatchedFiles")
123 events := server.lastFileEvents()
124 if len(events) != 1 || events[0].Type != lsp.FileCreated {
125 t.Fatalf("the server was told %+v, want one created file", events)
126 }
127 if want := lsp.PathToURI(path); events[0].URI != want {
128 t.Errorf("the created file is %q, want %q", events[0].URI, want)
129 }
130 // The document first, then the file: the order the fix was verified in.
131 methods := server.methodsSeen()
132 if open, created := firstIndexOf(methods, "textDocument/didOpen"), firstIndexOf(methods, "workspace/didChangeWatchedFiles"); open < 0 || created < open {
133 t.Errorf("the file was reported before the document was announced: %v", methods)
134 }
135}
136
137func TestSavingAnExistingFileDoesNotClaimItWasCreated(t *testing.T) {
138 // A file that was already on disk is not news to the server, and a save
139 // that claimed otherwise would have moon-lsp rescan the package on every
140 // Ctrl-S.
141 project := t.TempDir()
142 t.Chdir(project)
143 t.Setenv(testProfile().SnippetDirEnvVar(), t.TempDir())
144 a, _ := newTestApp(t)
145 client, server := newFakeLanguage(t, a)
146 connectLanguage(a, client)
147 path := filepath.Join(project, "main.go")
148 writeTestFile(t, path, "package main\n")
149 a.Open(path)
150 a.Tick()
151
152 a.save(a.ActiveView(), path)
153
154 waitForMethod(t, server, "textDocument/didSave")
155 if got := server.methodCount("workspace/didChangeWatchedFiles"); got != 0 {
156 t.Errorf("saving a file that already existed reported it created %d time(s)", got)
157 }
158}
159
160func TestAutosaveOfANewlyNamedFileTellsTheServerTheFileExists(t *testing.T) {
161 // The other way a file gets written. `turbo-moonbit new.mbt` opens a
162 // buffer for a file that is not on disk yet; the first automatic save
163 // creates it, and the server has to hear that from this path too.
164 project := t.TempDir()
165 t.Chdir(project)
166 t.Setenv(testProfile().SnippetDirEnvVar(), t.TempDir())
167 a, _ := newTestApp(t)
168 client, server := newFakeLanguage(t, a)
169 connectLanguage(a, client)
170 path := filepath.Join(project, "new.go")
171 a.Open(path) // not on disk: an empty buffer with that name
172 a.Tick()
173 a.SetAutosave(true, time.Millisecond)
174
175 typeText(a, "package main")
176 deadline := time.Now().Add(2 * time.Second)
177 for server.methodCount("workspace/didChangeWatchedFiles") == 0 && time.Now().Before(deadline) {
178 time.Sleep(2 * time.Millisecond)
179 a.Tick()
180 }
181
182 events := server.lastFileEvents()
183 if len(events) != 1 || events[0].Type != lsp.FileCreated || events[0].URI != lsp.PathToURI(path) {
184 t.Errorf("autosave reported %+v, want %s created", events, path)
185 }
186}
187
188// firstIndexOf returns where a string first appears in a list, or -1.
189func firstIndexOf(list []string, want string) int {
190 for i, s := range list {
191 if s == want {
192 return i
193 }
194 }
195 return -1
196}