diff options
| author | 2026-10-12 08:46:23 +0330 | |
|---|---|---|
| committer | 2026-10-12 08:46:23 +0330 | |
| commit | ecc350ca5c2eb50be8309c5f14f8bf0d87db9a02 (patch) | |
| tree | 70e0af76a1b13affff7c6cc8aac7b3e6ef960478 /tests/drivers/lsp_growth_test.js | |
a
Diffstat (limited to 'tests/drivers/lsp_growth_test.js')
| -rw-r--r-- | tests/drivers/lsp_growth_test.js | 53 |
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'); |
