81 lines
2.2 KiB
JavaScript
81 lines
2.2 KiB
JavaScript
const {assert} = require('chai');
|
|
let Parser, JavaScript;
|
|
|
|
describe("Query", () => {
|
|
let parser, tree, query;
|
|
|
|
before(async () =>
|
|
({Parser, JavaScript} = await require('./helper'))
|
|
);
|
|
|
|
beforeEach(() => {
|
|
parser = new Parser().setLanguage(JavaScript);
|
|
});
|
|
|
|
afterEach(() => {
|
|
parser.delete();
|
|
if (tree) tree.delete();
|
|
if (query) query.delete();
|
|
});
|
|
|
|
it('throws an error on invalid syntax', () => {
|
|
assert.throws(() => {
|
|
JavaScript.query("(function_declaration wat)")
|
|
}, "Bad syntax at offset 22: \'wat)\'...");
|
|
assert.throws(() => {
|
|
JavaScript.query("(non_existent)")
|
|
}, "Bad node name 'non_existent'");
|
|
assert.throws(() => {
|
|
JavaScript.query("(a)")
|
|
}, "Bad node name 'a'");
|
|
assert.throws(() => {
|
|
JavaScript.query("(function_declaration non_existent:(identifier))")
|
|
}, "Bad field name 'non_existent'");
|
|
});
|
|
|
|
it('matches simple queries', () => {
|
|
tree = parser.parse("function one() { two(); function three() {} }");
|
|
query = JavaScript.query(`
|
|
(function_declaration name:(identifier) @fn-def)
|
|
(call_expression function:(identifier) @fn-ref)
|
|
`);
|
|
const matches = query.exec(tree.rootNode);
|
|
assert.deepEqual(
|
|
formatMatches(matches),
|
|
[
|
|
{pattern: 0, captures: [{name: 'fn-def', text: 'one'}]},
|
|
{pattern: 1, captures: [{name: 'fn-ref', text: 'two'}]},
|
|
{pattern: 0, captures: [{name: 'fn-def', text: 'three'}]},
|
|
]
|
|
);
|
|
});
|
|
|
|
it('matches queries in specified ranges', () => {
|
|
tree = parser.parse("[a, b,\nc, d,\ne, f,\ng, h]");
|
|
query = JavaScript.query('(identifier) @element');
|
|
const matches = query.exec(
|
|
tree.rootNode,
|
|
{row: 1, column: 1},
|
|
{row: 3, column: 1}
|
|
);
|
|
assert.deepEqual(
|
|
formatMatches(matches),
|
|
[
|
|
{pattern: 0, captures: [{name: 'element', text: 'd'}]},
|
|
{pattern: 0, captures: [{name: 'element', text: 'e'}]},
|
|
{pattern: 0, captures: [{name: 'element', text: 'f'}]},
|
|
{pattern: 0, captures: [{name: 'element', text: 'g'}]},
|
|
]
|
|
);
|
|
});
|
|
});
|
|
|
|
function formatMatches(matches) {
|
|
return matches.map(({pattern, captures}) => ({
|
|
pattern,
|
|
captures: captures.map(({name, node}) => ({
|
|
name,
|
|
text: node.text
|
|
}))
|
|
}))
|
|
}
|