vscode-tmgrammar-test
Version:
Test runner for VSCode textmate grammars
130 lines • 5.28 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.parseGrammarTestCase = exports.parseHeader = exports.parseScopeAssertion = void 0;
const os_1 = require("os");
const leftArrowAssertRegex = /^(\s*)<([~]*)([-]+)((?:\s*\w[-\w.]*)*)(?:\s*-)?((?:\s*\w[-\w.]*)*)\s*$/;
const upArrowAssertRegex = /^\s*((?:(?:\^+)\s*)+)((?:\s*\w[-\w.]*)*)(?:\s*-)?((?:\s*\w[-\w.]*)*)\s*$/;
function parseScopeAssertion(testCaseLineNumber, commentLength, as) {
let s = as.slice(commentLength);
if (s.trim().startsWith('^')) {
let upArrowMatch = upArrowAssertRegex.exec(s);
if (upArrowMatch !== null) {
let [, , scopes = '', exclusions = ''] = upArrowMatch;
if (scopes === '' && exclusions === '') {
throw new Error(`Invalid assertion at line ${testCaseLineNumber}:${os_1.EOL}${as}${os_1.EOL} Missing both required and prohibited scopes`);
}
else {
const result = [];
let startIdx = s.indexOf('^');
while (startIdx !== -1) {
let endIndx = startIdx;
while (s[endIndx + 1] === '^') {
endIndx++;
}
result.push({
from: commentLength + startIdx,
to: commentLength + endIndx + 1,
scopes: scopes.split(/\s+/).filter((x) => x),
exclude: exclusions.split(/\s+/).filter((x) => x)
});
startIdx = s.indexOf('^', endIndx + 1);
}
return result;
}
}
else {
throw new Error(`Invalid assertion at line ${testCaseLineNumber}:${os_1.EOL}${as}${os_1.EOL}`);
}
}
let leftArrowMatch = leftArrowAssertRegex.exec(s);
if (leftArrowMatch !== null) {
let [, , tildas, dashes, scopes = '', exclusions = ''] = leftArrowMatch;
if (scopes === '' && exclusions === '') {
throw new Error(`Invalid assertion at line ${testCaseLineNumber}:${os_1.EOL}${as}${os_1.EOL} Missing both required and prohibited scopes`);
}
else {
return [
{
from: tildas.length,
to: tildas.length + dashes.length,
scopes: scopes.split(/\s+/).filter((x) => x),
exclude: exclusions.split(/\s+/).filter((x) => x)
}
];
}
}
return [];
}
exports.parseScopeAssertion = parseScopeAssertion;
let headerErrorMessage = `Expecting the first line in the syntax test file to be in the following format:${os_1.EOL}` +
`<comment character(s)> SYNTAX TEST \"<language identifier>\" (\"description\")?${os_1.EOL}`;
let headerRegex = /^([^\s]+)\s+SYNTAX\s+TEST\s+"([^"]+)"(?:\s+\"([^"]+)\")?\s*$/;
/**
* parse the first line with the format:
* <comment character(s)> SYNTAX TEST "<language identifier>" <"description">? ([+-]<flag>)*
*/
function parseHeader(as) {
if (as.length < 1) {
throw new Error(headerErrorMessage);
}
let matchResult = headerRegex.exec(as[0]);
if (matchResult === null) {
throw new Error(headerErrorMessage);
}
else {
let [, commentToken, scope, description = ''] = matchResult;
return {
commentToken: commentToken,
scope: scope,
description: description
};
}
}
exports.parseHeader = parseHeader;
function parseGrammarTestCase(str) {
let headerLength = 1;
let lines = str.split(/\r\n|\n/);
let metadata = parseHeader(lines);
let { commentToken } = metadata;
let rest = lines.slice(headerLength);
let commentTokenLength = commentToken.length;
function isLineAssertion(s) {
return s.startsWith(commentToken) && /^\s*(\^|<[~]*[-]+)/.test(s.substring(commentTokenLength));
}
function emptyLineAssertion(tcLineNumber, srcLineNumber) {
return {
testCaseLineNumber: tcLineNumber,
sourceLineNumber: srcLineNumber,
scopeAssertions: []
};
}
var sourceLineNumber = 0;
let lineAssertions = [];
var currentLineAssertion = emptyLineAssertion(headerLength, 0);
let source = [];
rest.forEach((s, i) => {
let tcLineNumber = headerLength + i;
if (s.startsWith(commentToken) && isLineAssertion(s)) {
let as = parseScopeAssertion(tcLineNumber, commentToken.length, s);
currentLineAssertion.scopeAssertions = [...currentLineAssertion.scopeAssertions, ...as];
}
else {
if (currentLineAssertion.scopeAssertions.length !== 0) {
lineAssertions.push(currentLineAssertion);
}
currentLineAssertion = emptyLineAssertion(tcLineNumber, sourceLineNumber);
source.push(s);
sourceLineNumber++;
}
});
if (currentLineAssertion.scopeAssertions.length !== 0) {
lineAssertions.push(currentLineAssertion);
}
return {
metadata: metadata,
source: source,
assertions: lineAssertions
};
}
exports.parseGrammarTestCase = parseGrammarTestCase;
//# sourceMappingURL=parsing.js.map