Skip to content

Commit de0c91f

Browse files
authored
Merge pull request #1 from dlants/tests
Tests
2 parents bd6b48a + 2fc9619 commit de0c91f

File tree

7 files changed

+117
-26
lines changed

7 files changed

+117
-26
lines changed

.github/workflows/release.yml

+5
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ jobs:
2020
uses: actions/setup-node@v4
2121
with:
2222
node-version: 20.x
23+
- name: Setup Neovim
24+
uses: rhysd/action-setup-vim@v1
25+
with:
26+
neovim: true
27+
version: stable
2328
- name: Install bun
2429
uses: oven-sh/setup-bun@v2
2530
- name: Install dependencies

bun.lockb

-1.52 KB
Binary file not shown.

src/attach.test.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { describe, expect, it } from "bun:test";
2+
import { withNvimClient } from "../tests/preamble";
3+
4+
describe("src/attach.test.ts", () => {
5+
it("nvim_buf_set_lines with a large file", async () => {
6+
await withNvimClient(async (nvim) => {
7+
const lines: string[] = [];
8+
for (let line = 0; line < 500; line += 1) {
9+
lines.push("x".repeat(100));
10+
}
11+
await nvim.call("nvim_buf_set_lines", [0, 0, -1, false, lines]);
12+
const roundtripLines = await nvim.call("nvim_buf_get_lines", [0, 0, -1, false]);
13+
expect(roundtripLines).toEqual(lines);
14+
});
15+
});
16+
});

src/attach.ts

+23-20
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Packr, UnpackrStream, addExtension, unpack } from "msgpackr";
22
import { EventEmitter } from "node:events";
3+
import net from "node:net";
34
import { createLogger, prettyRPCMessage } from "./logger.ts";
45
import {
56
MessageType,
@@ -41,26 +42,28 @@ export async function attach<ApiInfo extends BaseEvents = BaseEvents>({
4142
let lastReqId = 0;
4243
let handlerId = 0;
4344

44-
const nvimSocket = await Bun.connect({
45-
unix: socket,
46-
socket: {
47-
binaryType: "uint8array",
48-
data(_, data) {
49-
// Sometimes RPC messages are split into multiple socket messages.
50-
// `unpackrStream` handles collecting all socket messages if the RPC message
51-
// is split and decoding it.
52-
unpackrStream.write(data);
53-
},
54-
error(_, error) {
55-
logger?.error("socket error", error);
56-
},
57-
end() {
58-
logger?.debug("connection closed by neovim");
59-
},
60-
close() {
61-
logger?.debug("connection closed by bunvim");
62-
},
63-
},
45+
const nvimSocket = await new Promise<net.Socket>((resolve, reject) => {
46+
const client = new net.Socket();
47+
client.once("error", reject);
48+
client.once("connect", () => {
49+
client
50+
.removeListener("error", reject)
51+
.on("data", (data: Buffer) => {
52+
unpackrStream.write(data);
53+
})
54+
.on("error", (error) => {
55+
logger?.error("socket error", error);
56+
})
57+
.on("end", () => {
58+
logger?.debug("connection closed by neovim");
59+
})
60+
.on("close", () => {
61+
logger?.debug("connection closed by bunvim");
62+
});
63+
resolve(client);
64+
});
65+
66+
client.connect(socket);
6467
});
6568

6669
function processMessageOutQueue() {

src/sample.test.ts

-5
This file was deleted.

tests/preamble.ts

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import { attach, type Nvim } from "../src/index.ts";
2+
import { unlink } from "node:fs/promises";
3+
import { spawn } from "child_process";
4+
import path from "path";
5+
6+
const SOCK = `/tmp/bunvim-test.sock`;
7+
export async function withNvimProcess(fn: (sock: string) => Promise<void>) {
8+
try {
9+
await unlink(SOCK);
10+
} catch (e) {
11+
if ((e as { code: string }).code !== "ENOENT") {
12+
console.error(e);
13+
}
14+
}
15+
16+
const nvimProcess = spawn(
17+
"nvim",
18+
["--headless", "-n", "--clean", "--listen", SOCK],
19+
{
20+
// root dir relative to this file
21+
cwd: path.resolve(path.dirname(__filename), "../"),
22+
},
23+
);
24+
25+
if (!nvimProcess.pid) {
26+
throw new Error("Failed to start nvim process");
27+
}
28+
29+
try {
30+
nvimProcess.on("error", (err) => {
31+
throw err;
32+
});
33+
34+
nvimProcess.on("exit", (code, signal) => {
35+
if (code !== 1) {
36+
throw new Error(
37+
`Nvim process exited with code ${code} and signal ${signal}`,
38+
);
39+
}
40+
});
41+
42+
// give enough time for socket to be created
43+
// TODO: poll for socket instead
44+
await new Promise((resolve) => setTimeout(resolve, 500));
45+
46+
await fn(SOCK);
47+
} finally {
48+
const res = nvimProcess.kill();
49+
console.log(`Killed process ${nvimProcess.pid} with result ${res}`);
50+
}
51+
}
52+
53+
export async function withNvimClient(fn: (nvim: Nvim) => Promise<void>) {
54+
return await withNvimProcess(async (sock) => {
55+
const nvim = await attach({
56+
socket: sock,
57+
client: { name: "test" },
58+
logging: { level: "debug" },
59+
});
60+
61+
try {
62+
await fn(nvim);
63+
} finally {
64+
nvim.detach();
65+
}
66+
});
67+
}
68+
69+
process.on("uncaughtException", (err) => {
70+
console.error(err);
71+
process.exit(1);
72+
});

tsconfig.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,5 +30,5 @@
3030
"checkJs": true,
3131
"esModuleInterop": true
3232
},
33-
"include": ["src", "./package.json"]
33+
"include": ["src", "test", "./package.json"]
3434
}

0 commit comments

Comments
 (0)