Files
WRNexusJS/editors/vscode/test/language-server.test.js
Clintchiz 72e4d3eceb
Quality / quality (ubuntu-latest) (push) Failing after 12m19s
Quality / quality (windows-latest) (push) Canceled after 0s
release: WRNexusJS 0.8.0
2026-08-04 12:19:09 +05:30

142 lines
4.9 KiB
JavaScript

"use strict";
const assert = require("node:assert");
const { spawnSync } = require("node:child_process");
const fs = require("node:fs");
const path = require("node:path");
const { test } = require("node:test");
const root = path.resolve(__dirname, "../../..");
const server = path.join(root, "editors", "vscode", "src", "language-server.cjs");
function rpc(value) {
const body = Buffer.from(JSON.stringify(value));
return Buffer.concat([Buffer.from(`Content-Length: ${body.length}\r\n\r\n`), body]);
}
function parseResponses(output) {
const responses = [];
let position = 0;
while (position < output.length) {
const headerEnd = output.indexOf(Buffer.from("\r\n\r\n"), position);
if (headerEnd < 0) break;
const header = output.subarray(position, headerEnd).toString();
const length = Number(/Content-Length:\s*(\d+)/i.exec(header)?.[1] || 0);
const start = headerEnd + 4;
const end = start + length;
if (!length || end > output.length) break;
responses.push(JSON.parse(output.subarray(start, end).toString()));
position = end;
}
return responses;
}
function run(messages) {
const result = spawnSync(process.execPath, [server], {
cwd: root,
input: Buffer.concat(messages.map(rpc)),
timeout: 10_000,
});
assert.equal(result.status, 0, (result.stderr || Buffer.alloc(0)).toString());
return parseResponses(result.stdout || Buffer.alloc(0));
}
test("language server starts under Node and keeps official typed components clean", () => {
const files = [
path.join(root, "packages", "ui", "components", "AuthForm.wrn"),
path.join(root, "packages", "ui", "components", "FeatureGrid.wrn"),
];
const messages = [
{ jsonrpc: "2.0", id: 1, method: "initialize", params: { rootPath: root } },
{ jsonrpc: "2.0", method: "initialized", params: {} },
];
files.forEach((file, index) => {
messages.push({
jsonrpc: "2.0",
method: "textDocument/didOpen",
params: {
textDocument: {
uri: `file://${file}`,
languageId: "wrn",
version: index + 1,
text: fs.readFileSync(file, "utf8"),
},
},
});
});
messages.push({ jsonrpc: "2.0", id: 2, method: "shutdown", params: {} });
messages.push({ jsonrpc: "2.0", method: "exit", params: {} });
const responses = run(messages);
assert.equal(responses.find((item) => item.id === 1)?.result?.serverInfo?.version, "0.8.3");
const diagnostics = responses.filter((item) => item.method === "textDocument/publishDiagnostics");
assert.equal(diagnostics.length, 2);
assert.deepEqual(
diagnostics.map((item) => item.params.diagnostics),
[[], []],
);
});
test("language server formatter preserves code samples and compact sibling markup", () => {
const source = `page Docs {
view {
<pre><code><span class="muted">// One project, one language</span></code></pre>
<div class="strip"><span>Page</span><b>→</b><span>API</span></div>
}
}\n`;
const uri = "file:///tmp/wrnexus-docs.wrn";
const responses = run([
{ jsonrpc: "2.0", id: 1, method: "initialize", params: { rootPath: root } },
{ jsonrpc: "2.0", method: "initialized", params: {} },
{
jsonrpc: "2.0",
method: "textDocument/didOpen",
params: { textDocument: { uri, languageId: "wrn", version: 1, text: source } },
},
{
jsonrpc: "2.0",
id: 2,
method: "textDocument/formatting",
params: { textDocument: { uri }, options: { tabSize: 2, insertSpaces: true } },
},
{ jsonrpc: "2.0", id: 3, method: "shutdown", params: {} },
{ jsonrpc: "2.0", method: "exit", params: {} },
]);
const formatted = responses.find((item) => item.id === 2)?.result?.[0]?.newText;
assert.ok(formatted);
assert.match(formatted, /\/\/ One project, one language/);
assert.match(formatted, /<span>Page<\/span><b>→<\/b><span>API<\/span>/);
});
test("language server runs TypeScript diagnostics with workspace standard libraries", () => {
const uri = "file:///tmp/wrnexus-invalid-state.wrn";
const source = `component InvalidState {
outputs { save(payload: { id: string }) }
functions {
client function submit(value: string): void {
output.save({ id: 123 })
}
}
view { <button @click="submit('demo')"></button> }
}
`;
const responses = run([
{ jsonrpc: "2.0", id: 1, method: "initialize", params: { rootPath: root } },
{ jsonrpc: "2.0", method: "initialized", params: {} },
{
jsonrpc: "2.0",
method: "textDocument/didOpen",
params: { textDocument: { uri, languageId: "wrn", version: 1, text: source } },
},
{ jsonrpc: "2.0", id: 2, method: "shutdown", params: {} },
{ jsonrpc: "2.0", method: "exit", params: {} },
]);
const diagnostics = responses.find((item) => item.method === "textDocument/publishDiagnostics")
?.params?.diagnostics;
assert.ok(Array.isArray(diagnostics));
assert.ok(
diagnostics.some((diagnostic) => diagnostic.code === "WRN-TYPE-2322"),
JSON.stringify(diagnostics, null, 2),
);
});