aboutsummaryrefslogtreecommitdiff
path: root/tests/drivers/lsp_growth_test.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_growth_test.js
a
Diffstat (limited to 'tests/drivers/lsp_growth_test.js')
-rw-r--r--tests/drivers/lsp_growth_test.js53
1 files changed, 53 insertions, 0 deletions
diff --git a/tests/drivers/lsp_growth_test.js b/tests/drivers/lsp_growth_test.js
new file mode 100644
index 0000000..b06230a
--- /dev/null
+++ b/tests/drivers/lsp_growth_test.js
@@ -0,0 +1,53 @@
+// focused regressions for growing document, uri, hover, and name-set storage.
+// usage: node tests/drivers/lsp_growth_test.js path/to/zclsp-or-lsp.wasm
+const assert = require('assert');
+const cp = require('child_process');
+const { wasmProcess } = require('../../editors/vscode/client/wasmproc');
+const target = process.argv[2];
+const frame = m => {
+ const body = Buffer.from(JSON.stringify(m));
+ return Buffer.concat([Buffer.from('Content-Length: ' + body.length + '\r\n\r\n'), body]);
+};
+function parse(input) {
+ const messages = [];
+ for (let offset = 0; offset < input.length;) {
+ const end = input.indexOf('\r\n\r\n', offset);
+ assert.ok(end >= 0, 'complete response header');
+ const length = Number(/Content-Length:\s*(\d+)/i.exec(input.subarray(offset, end).toString())[1]);
+ const start = end + 4;
+ assert.ok(start + length <= input.length, 'complete response body');
+ messages.push(JSON.parse(input.subarray(start, start + length).toString()));
+ offset = start + length;
+ }
+ return messages;
+}
+const uri = 'file:///' + 'long-directory/'.repeat(30) + 'main.zc';
+const docs = '// **formatted** documentation with `inline code`.\n' + ('// a long paragraph of documentation.\n').repeat(150) + '// final documentation line\n';
+const source = docs + 'int helper() { return 1; }\nfn main() { return helper(); }\n';
+const messages = [{ jsonrpc: '2.0', id: 1, method: 'initialize', params: {} }];
+for (let i = 0; i < 32; i++) messages.push({ jsonrpc: '2.0', method: 'textDocument/didOpen', params: { textDocument: { uri: i === 31 ? uri : 'file:///doc' + i + '.zc', languageId: 'zc', version: 1, text: source } } });
+messages.push({ jsonrpc: '2.0', id: 2, method: 'textDocument/hover', params: { textDocument: { uri }, position: { line: source.split('\n').length - 2, character: 19 } } });
+messages.push({ jsonrpc: '2.0', method: 'exit' });
+let output;
+if (target.endsWith('.wasm')) {
+ const chunks = [];
+ const server = wasmProcess(target);
+ server.stdout.on('data', data => chunks.push(data));
+ for (const message of messages) assert.ok(server.stdin.write(frame(message)));
+ output = Buffer.concat(chunks);
+} else {
+ const result = cp.spawnSync(target, [], { input: Buffer.concat(messages.map(frame)), timeout: 30000, maxBuffer: 8 << 20 });
+ assert.strictEqual(result.status, 0, String(result.stderr));
+ output = result.stdout;
+}
+const responses = parse(output);
+const published = responses.filter(m => m.method === 'textDocument/publishDiagnostics');
+assert.strictEqual(published.length, 32, 'every open document is published');
+assert.strictEqual(published[31].params.uri, uri, 'a long uri is echoed without truncation');
+assert.ok(published.every(m => !m.params.diagnostics.some(d => d.severity === 1)), 'all documents check cleanly');
+const hover = responses.find(m => m.id === 2).result.contents;
+assert.strictEqual(hover.kind, 'markdown');
+assert.match(hover.value, /^```zc\nint helper\(\)\n```\n\n/);
+assert.ok(hover.value.includes('**formatted**'));
+assert.ok(hover.value.includes('final documentation line'), 'hover documentation grows past its initial buffer');
+console.log('ok lsp grows beyond 16 documents, 160 uri bytes, and 2300 hover characters');