aboutsummaryrefslogtreecommitdiff
path: root/tests/drivers/lsp_live.js
diff options
context:
space:
mode:
authorGravatar Moon Flower <moonflower@elhenney.local> 2026-10-12 08:46:23 +0330
committerGravatar Moon Flower <moonflower@elhenney.local> 2026-10-12 08:46:23 +0330
commitecc350ca5c2eb50be8309c5f14f8bf0d87db9a02 (patch)
tree70e0af76a1b13affff7c6cc8aac7b3e6ef960478 /tests/drivers/lsp_live.js
a
Diffstat (limited to 'tests/drivers/lsp_live.js')
-rw-r--r--tests/drivers/lsp_live.js23
1 files changed, 23 insertions, 0 deletions
diff --git a/tests/drivers/lsp_live.js b/tests/drivers/lsp_live.js
new file mode 100644
index 0000000..b5fe805
--- /dev/null
+++ b/tests/drivers/lsp_live.js
@@ -0,0 +1,23 @@
+// the native server must answer while the client keeps the pipe open and waits, as an editor
+// does: one message in, the answer out, before anything else is sent. an output buffer that
+// is only flushed at exit, or an end-of-input peek that waits for the next message, fails this.
+// usage: node tests/drivers/lsp_live.js path/to/zclsp
+const cp = require('child_process');
+const p = cp.spawn(process.argv[2], []);
+let inbox = Buffer.alloc(0), step = 0, done = false;
+const frame = m => { const b = Buffer.from(JSON.stringify(m)); return Buffer.concat([Buffer.from('Content-Length: ' + b.length + '\r\n\r\n'), b]); };
+const finish = (ok, what) => { if (done) return; done = true; p.kill(); console.log((ok ? 'ok ' : 'FAIL ') + what); process.exit(ok ? 0 : 1); };
+const timer = setTimeout(() => finish(false, 'lsp live: no answer in 5 s while the pipe stayed open (step ' + step + ')'), 5000);
+p.stdout.on('data', d => {
+ inbox = Buffer.concat([inbox, d]);
+ const e = inbox.indexOf('\r\n\r\n'); if (e < 0) return;
+ const n = parseInt(/Content-Length: (\d+)/.exec(inbox.slice(0, e).toString())[1], 10);
+ if (inbox.length < e + 4 + n) return;
+ const m = JSON.parse(inbox.slice(e + 4, e + 4 + n).toString());
+ inbox = inbox.slice(e + 4 + n);
+ if (step === 0 && m.id === 1) {
+ step = 1; // the answer came with the pipe still open: ask for something else
+ p.stdin.write(frame({ jsonrpc: '2.0', id: 2, method: 'shutdown', params: null }));
+ } else if (step === 1 && m.id === 2) { clearTimeout(timer); finish(true, 'lsp live: initialize and shutdown are answered while the pipe stays open'); }
+});
+p.stdin.write(frame({ jsonrpc: '2.0', id: 1, method: 'initialize', params: { processId: 1, capabilities: {} } }));