Skip to content

Commit 95f076b

Browse files
authored
Merge pull request #405 from vim-denops/split-tests
🌿 split server.vim tests
2 parents df8b125 + 8bf5663 commit 95f076b

File tree

6 files changed

+1373
-1334
lines changed

6 files changed

+1373
-1334
lines changed
Lines changed: 246 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,246 @@
1+
import {
2+
assert,
3+
assertEquals,
4+
assertMatch,
5+
assertRejects,
6+
} from "jsr:@std/assert@^1.0.1";
7+
import { delay } from "jsr:@std/async@^0.224.0/delay";
8+
import { AsyncDisposableStack } from "jsr:@nick/dispose@^1.1.0/async-disposable-stack";
9+
import { testHost } from "/denops-testutil/host.ts";
10+
import { useSharedServer } from "/denops-testutil/shared_server.ts";
11+
import { wait } from "/denops-testutil/wait.ts";
12+
13+
const MESSAGE_DELAY = 200;
14+
15+
testHost({
16+
name: "denops#server#close()",
17+
mode: "all",
18+
postlude: [
19+
// NOTE: The `plugin/denops.vim` must be sourced to initialize the environment.
20+
"runtime plugin/denops.vim",
21+
// NOTE: Disable startup on VimEnter.
22+
"autocmd! denops_plugin_internal_startup VimEnter",
23+
],
24+
fn: async ({ host, t, stderr }) => {
25+
let outputs: string[] = [];
26+
stderr.pipeTo(
27+
new WritableStream({ write: (s) => void outputs.push(s) }),
28+
).catch(() => {});
29+
30+
await host.call("execute", [
31+
"autocmd User DenopsClosed let g:__test_denops_closed_fired = 1",
32+
], "");
33+
34+
await t.step("if not yet connected", async (t) => {
35+
await host.call("execute", [
36+
"silent! unlet g:__test_denops_closed_fired",
37+
"call denops#server#close()",
38+
"let g:__test_denops_server_status_when_close_called = denops#server#status()",
39+
], "");
40+
41+
await t.step("does not change status from 'stopped'", async () => {
42+
const actual = await host.call(
43+
"eval",
44+
"g:__test_denops_server_status_when_close_called",
45+
);
46+
assertEquals(actual, "stopped");
47+
});
48+
49+
await t.step("does not fire DenopsClosed", async () => {
50+
await assertRejects(
51+
() =>
52+
wait(
53+
() => host.call("exists", "g:__test_denops_closed_fired"),
54+
{ timeout: 1000, interval: 100 },
55+
),
56+
Error,
57+
"Timeout",
58+
);
59+
});
60+
});
61+
62+
await t.step("if already connected to local-server", async (t) => {
63+
await using stack = new AsyncDisposableStack();
64+
stack.defer(async () => {
65+
await host.call("denops#server#stop");
66+
await wait(
67+
() => host.call("eval", "denops#server#status() ==# 'stopped'"),
68+
);
69+
});
70+
await host.call("denops#server#start");
71+
await wait(
72+
() => host.call("eval", "denops#server#status() ==# 'running'"),
73+
);
74+
75+
await host.call("execute", [
76+
"call denops#server#close()",
77+
"let g:__test_denops_server_status_when_close_called = denops#server#status()",
78+
"silent! unlet g:__test_denops_closed_fired",
79+
], "");
80+
81+
await t.step("changes status to 'closing' immediately", async () => {
82+
const actual = await host.call(
83+
"eval",
84+
"g:__test_denops_server_status_when_close_called",
85+
);
86+
assertEquals(actual, "closing");
87+
});
88+
89+
await t.step("fires DenopsClosed", async () => {
90+
await wait(() => host.call("exists", "g:__test_denops_closed_fired"));
91+
});
92+
93+
await t.step("changes status to 'closed' asynchronously", async () => {
94+
const actual = await host.call("denops#server#status");
95+
assertEquals(actual, "closed");
96+
});
97+
98+
await t.step("does not stop the local-server", async () => {
99+
await assertRejects(
100+
() =>
101+
wait(
102+
() => host.call("eval", "denops#server#status() ==# 'stopped'"),
103+
{ timeout: 1000, interval: 100 },
104+
),
105+
Error,
106+
"Timeout",
107+
);
108+
});
109+
110+
await host.call("denops#server#stop");
111+
await wait(
112+
() => host.call("eval", "denops#server#status() ==# 'stopped'"),
113+
);
114+
await host.call("denops#server#start");
115+
await wait(
116+
() => host.call("eval", "denops#server#status() ==# 'running'"),
117+
);
118+
119+
await t.step("if timeouted", async (t) => {
120+
outputs = [];
121+
122+
await host.call("execute", [
123+
"silent! unlet g:__test_denops_closed_fired",
124+
"let g:denops#server#close_timeout = 0",
125+
"call denops#server#close()",
126+
], "");
127+
128+
await host.call("execute", [
129+
"let g:__test_denops_server_status_after_close_called = denops#server#status()",
130+
], "");
131+
132+
await t.step("closes the channel forcibly", async () => {
133+
const actual = await host.call(
134+
"eval",
135+
"g:__test_denops_server_status_after_close_called",
136+
);
137+
assertEquals(actual, "closed");
138+
});
139+
140+
await t.step("fires DenopsClosed", async () => {
141+
assert(await host.call("exists", "g:__test_denops_closed_fired"));
142+
});
143+
144+
await t.step("outputs warning message after delayed", async () => {
145+
await delay(MESSAGE_DELAY);
146+
assertMatch(
147+
outputs.join(""),
148+
/Channel cannot close gracefully within 0 millisec, force close/,
149+
);
150+
});
151+
152+
await t.step("does not stop the local-server", async () => {
153+
await assertRejects(
154+
() =>
155+
wait(
156+
() => host.call("eval", "denops#server#status() ==# 'stopped'"),
157+
{ timeout: 1000, interval: 100 },
158+
),
159+
Error,
160+
"Timeout",
161+
);
162+
});
163+
});
164+
});
165+
166+
await t.step("if already connected to shared-server", async (t) => {
167+
await using stack = new AsyncDisposableStack();
168+
const server = stack.use(await useSharedServer());
169+
stack.defer(async () => {
170+
await host.call("denops#server#close");
171+
await wait(
172+
() => host.call("eval", "denops#server#status() ==# 'stopped'"),
173+
);
174+
});
175+
176+
await host.call("execute", [
177+
`let g:denops_server_addr = '${server.addr}'`,
178+
"call denops#server#connect()",
179+
], "");
180+
await wait(
181+
() => host.call("eval", "denops#server#status() ==# 'running'"),
182+
);
183+
184+
await host.call("execute", [
185+
"call denops#server#close()",
186+
"let g:__test_denops_server_status_when_close_called = denops#server#status()",
187+
"silent! unlet g:__test_denops_closed_fired",
188+
], "");
189+
190+
await t.step("changes status to 'closing' immediately", async () => {
191+
const actual = await host.call(
192+
"eval",
193+
"g:__test_denops_server_status_when_close_called",
194+
);
195+
assertEquals(actual, "closing");
196+
});
197+
198+
await t.step("fires DenopsClosed", async () => {
199+
await wait(() => host.call("exists", "g:__test_denops_closed_fired"));
200+
});
201+
202+
await t.step("changes status to 'stopped' asynchronously", async () => {
203+
assertEquals(await host.call("denops#server#status"), "stopped");
204+
});
205+
206+
await host.call("denops#server#connect");
207+
await wait(
208+
() => host.call("eval", "denops#server#status() ==# 'running'"),
209+
);
210+
211+
await t.step("if timeouted", async (t) => {
212+
outputs = [];
213+
214+
await host.call("execute", [
215+
"silent! unlet g:__test_denops_closed_fired",
216+
"let g:denops#server#close_timeout = 0",
217+
"call denops#server#close()",
218+
], "");
219+
220+
await host.call("execute", [
221+
"let g:__test_denops_server_status_after_close_called = denops#server#status()",
222+
], "");
223+
224+
await t.step("closes the channel forcibly", async () => {
225+
const actual = await host.call(
226+
"eval",
227+
"g:__test_denops_server_status_after_close_called",
228+
);
229+
assertEquals(actual, "stopped");
230+
});
231+
232+
await t.step("fires DenopsClosed", async () => {
233+
assert(await host.call("exists", "g:__test_denops_closed_fired"));
234+
});
235+
236+
await t.step("outputs warning message after delayed", async () => {
237+
await delay(MESSAGE_DELAY);
238+
assertMatch(
239+
outputs.join(""),
240+
/Channel cannot close gracefully within 0 millisec, force close/,
241+
);
242+
});
243+
});
244+
});
245+
},
246+
});

0 commit comments

Comments
 (0)