133 lines
3.1 KiB
JavaScript
133 lines
3.1 KiB
JavaScript
const child_process = require("child_process");
|
|
const { loadTests, writeTests } = require("./utils");
|
|
|
|
updateTestOutputs("./corpus");
|
|
|
|
function updateTestOutputs(dirname) {
|
|
const tests = loadTests(dirname);
|
|
|
|
for (const [, testCases] of Object.entries(tests)) {
|
|
for (const [, testCase] of Object.entries(testCases)) {
|
|
testCase.output = "(x y: (z))";
|
|
}
|
|
}
|
|
|
|
writeTests(dirname, tests);
|
|
|
|
let stdout;
|
|
|
|
try {
|
|
child_process.execFileSync("./node_modules/.bin/tree-sitter", ["test"]);
|
|
} catch (error) {
|
|
stdout = error.stdout.toString();
|
|
}
|
|
|
|
const sexps = parseTestStdout(stdout);
|
|
|
|
for (const [basename, testCases] of Object.entries(sexps)) {
|
|
for (const [title, sexp] of Object.entries(testCases)) {
|
|
tests[basename][title].output = printSExpression(parseSExpression(sexp));
|
|
}
|
|
}
|
|
|
|
writeTests(dirname, tests);
|
|
}
|
|
|
|
function parseTestStdout(stdout) {
|
|
const [tocText, detailText] = stdout
|
|
.replace(/\u001b\[\d+m/g, "") // ansi color
|
|
.split(/\n\n\d+ failures?:\n\nexpected \/ actual\n\n/);
|
|
|
|
const indices = [];
|
|
const sexps = {};
|
|
|
|
let basename;
|
|
for (const lineText of tocText.trim().split("\n")) {
|
|
if (lineText.startsWith(" ")) {
|
|
const title = lineText.slice(" ✗ ".length);
|
|
indices.push([basename, title]);
|
|
} else {
|
|
basename = lineText.slice(0, -1) + ".txt";
|
|
}
|
|
}
|
|
|
|
let counter = 0;
|
|
detailText.split("\n").forEach((lineText, i) => {
|
|
if (i % 3 === 1) {
|
|
const sexp = lineText.replace(/\(x y: \(z\)\)\s*$/, "").trim();
|
|
const [basename, title] = indices[counter++];
|
|
sexps[basename] = sexps[basename] || {};
|
|
sexps[basename][title] = sexp;
|
|
}
|
|
});
|
|
|
|
return sexps;
|
|
}
|
|
|
|
function parseSExpression(text) {
|
|
let node;
|
|
|
|
let key = null;
|
|
const stack = [];
|
|
|
|
const pushNode = () => {
|
|
if (key) {
|
|
node.key = key;
|
|
key = null;
|
|
}
|
|
if (stack.length) {
|
|
stack[stack.length - 1].children.push(node);
|
|
}
|
|
stack.push(node);
|
|
};
|
|
|
|
for (let i = 0; i < text.length; i++) {
|
|
switch (text[i]) {
|
|
case "(":
|
|
node = {
|
|
type: /^MISSING/.test(text.slice(i + 1))
|
|
? text.slice(i + 1).match(/^[^) ]+( \w+)?/)[0]
|
|
: text.slice(i + 1).match(/^[^) ]+/)[0],
|
|
children: [],
|
|
};
|
|
i += node.type.length;
|
|
pushNode();
|
|
break;
|
|
case ")":
|
|
node = stack.pop();
|
|
case " ":
|
|
break;
|
|
default:
|
|
key = text.slice(i).match(/^[^:]+/)[0];
|
|
i += key.length;
|
|
break;
|
|
}
|
|
}
|
|
return node;
|
|
}
|
|
|
|
function printSExpression(node, indent = " ") {
|
|
if (node.children.length === 0) {
|
|
return `${printNodeHead(node)})`;
|
|
}
|
|
|
|
if (node.children.every(child => child.children.length === 0)) {
|
|
return `${printNodeHead(node)}\n ${node.children
|
|
.map(child => `${printNodeHead(child)})`)
|
|
.join(" ")})`;
|
|
}
|
|
|
|
return `${printNodeHead(node)}\n${node.children
|
|
.map(x =>
|
|
printSExpression(x, indent + " ")
|
|
.split("\n")
|
|
.map(x => ` ${x}`)
|
|
.join("\n"),
|
|
)
|
|
.join(`\n`)})`;
|
|
}
|
|
|
|
function printNodeHead(node) {
|
|
return node.key ? `${node.key}: (${node.type}` : `(${node.type}`;
|
|
}
|