77 lines
3.1 KiB
JavaScript
77 lines
3.1 KiB
JavaScript
const assert = require('node:assert/strict');
|
|
const fs = require('node:fs');
|
|
const test = require('node:test');
|
|
|
|
const oniguruma = require('vscode-oniguruma');
|
|
const textmate = require('vscode-textmate');
|
|
|
|
async function loadGrammar() {
|
|
await oniguruma.loadWASM(fs.readFileSync(require.resolve('vscode-oniguruma/release/onig.wasm')).buffer);
|
|
|
|
const registry = new textmate.Registry({
|
|
onigLib: Promise.resolve({
|
|
createOnigScanner: patterns => new oniguruma.OnigScanner(patterns),
|
|
createOnigString: value => new oniguruma.OnigString(value)
|
|
}),
|
|
loadGrammar: async scopeName => scopeName === 'source.eftl'
|
|
? textmate.parseRawGrammar(
|
|
fs.readFileSync('syntaxes/eftl.tmLanguage.json', 'utf8'),
|
|
'eftl.tmLanguage.json'
|
|
)
|
|
: null
|
|
});
|
|
|
|
return registry.loadGrammar('source.eftl');
|
|
}
|
|
|
|
test('highlights nested VAR blocks, self-closing functions, and WHILE attributes', async () => {
|
|
const grammar = await loadGrammar();
|
|
const source = [
|
|
'[EFTL]',
|
|
'[VAR name="count" type="number"][SIZE_OF varname="items" /][/VAR]',
|
|
'[WHILE threshold="99"][CONDITION][% count > 0 %][/CONDITION][DO]',
|
|
'[VAR name="current" type="string"][VALUE_OF varname="items" index="count" /][/VAR]',
|
|
'[/DO][/WHILE]',
|
|
'[IF][CONDITION][% count == 0 %][/CONDITION][THEN]',
|
|
'[VAR name="empty" type="boolean"][% empty = true; %][/VAR]',
|
|
'[/THEN][/IF]',
|
|
'[/EFTL]'
|
|
];
|
|
let ruleStack = textmate.INITIAL;
|
|
const variableTokens = [];
|
|
const selfClosingFunctionTokens = [];
|
|
const thresholdTokens = [];
|
|
const thresholdValueTokens = [];
|
|
const whileTokens = [];
|
|
|
|
for (const line of source) {
|
|
const result = grammar.tokenizeLine(line, ruleStack);
|
|
ruleStack = result.ruleStack;
|
|
|
|
for (const token of result.tokens) {
|
|
const text = line.slice(token.startIndex, token.endIndex);
|
|
if (text === 'VAR' && line[token.startIndex - 1] !== '/') variableTokens.push(token);
|
|
if (text === 'SIZE_OF' || text === 'VALUE_OF') selfClosingFunctionTokens.push(token);
|
|
if (text === 'threshold') thresholdTokens.push(token);
|
|
if (text === '"99"') thresholdValueTokens.push(token);
|
|
if (text === 'WHILE') whileTokens.push(token);
|
|
}
|
|
}
|
|
|
|
assert.equal(variableTokens.length, 3);
|
|
for (const token of variableTokens) {
|
|
assert.ok(token.scopes.includes('storage.type.variable.eftl'));
|
|
}
|
|
|
|
for (const token of selfClosingFunctionTokens) {
|
|
assert.ok(token.scopes.includes('meta.function.eftl'));
|
|
assert.ok(!token.scopes.includes('meta.function.block.eftl'));
|
|
}
|
|
|
|
assert.equal(thresholdTokens.length, 1);
|
|
assert.ok(thresholdTokens[0].scopes.includes('entity.other.attribute-name.eftl'));
|
|
assert.equal(thresholdValueTokens.length, 1);
|
|
assert.ok(thresholdValueTokens[0].scopes.includes('string.quoted.double.eftl'));
|
|
assert.equal(whileTokens.length, 1);
|
|
assert.ok(whileTokens[0].scopes.includes('keyword.control.loop.eftl'));
|
|
}); |