aboutsummaryrefslogtreecommitdiff
path: root/tests/drivers/lsp_growth_test.js
blob: b06230a6aba87a4efaaa33dc11aec06a630351ed (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
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');