test: update tests

This commit is contained in:
Amaan Qureshi 2025-01-20 03:12:52 -05:00
parent 09cb4c5729
commit 1f66d156b5
6 changed files with 234 additions and 272 deletions

View file

@ -1,8 +1,8 @@
import { describe, it, expect, beforeAll, beforeEach, afterEach } from 'vitest';
import type { Parser as ParserType, Language, Tree, Node } from '../src';
import type { Language, Tree, Node } from '../src';
import { Parser } from '../src';
import helper from './helper';
let Parser: typeof ParserType;
let C: Language;
let JavaScript: Language;
let JSON: Language;
@ -40,11 +40,11 @@ function getAllNodes(tree: Tree): Node[] {
}
describe('Node', () => {
let parser: ParserType;
let parser: Parser;
let tree: Tree | null;
beforeAll(async () => {
({ Parser, C, EmbeddedTemplate, JavaScript, JSON, Python } = await helper);
({ C, EmbeddedTemplate, JavaScript, JSON, Python } = await helper);
});
beforeEach(() => {
@ -55,31 +55,24 @@ describe('Node', () => {
afterEach(() => {
parser.delete();
tree?.delete();
tree!.delete();
});
describe('.children', () => {
it('returns an array of child nodes', () => {
tree = parser.parse('x10 + 1000');
tree = parser.parse('x10 + 1000')!;
expect(tree.rootNode.children).toHaveLength(1);
const sumNode = tree.rootNode.firstChild?.firstChild;
expect(sumNode?.children.map(child => child?.type)).toEqual([
'identifier',
'+',
'number'
]);
const sumNode = tree.rootNode.firstChild!.firstChild!;
expect(sumNode.children.map(child => child!.type)).toEqual(['identifier', '+', 'number' ]);
});
});
describe('.namedChildren', () => {
it('returns an array of named child nodes', () => {
tree = parser.parse('x10 + 1000');
const sumNode = tree.rootNode.firstChild?.firstChild;
tree = parser.parse('x10 + 1000')!;
const sumNode = tree.rootNode.firstChild!.firstChild!;
expect(tree.rootNode.namedChildren).toHaveLength(1);
expect(sumNode?.namedChildren.map(child => child?.type)).toEqual([
'identifier',
'number'
]);
expect(sumNode.namedChildren.map(child => child!.type)).toEqual(['identifier', 'number']);
});
});
@ -96,13 +89,13 @@ describe('Node', () => {
elif four:
d()`;
tree = parser.parse(source);
const node = tree.rootNode.firstChild;
expect(node?.type).toBe('if_statement');
const alternatives = node?.childrenForFieldName('alternative');
const alternativeTexts = alternatives?.map(n => {
const condition = n?.childForFieldName('condition');
return source.slice(condition?.startIndex, condition?.endIndex);
tree = parser.parse(source)!;
const node = tree.rootNode.firstChild!;
expect(node.type).toBe('if_statement');
const alternatives = node.childrenForFieldName('alternative');
const alternativeTexts = alternatives.map(n => {
const condition = n!.childForFieldName('condition')!;
return source.slice(condition.startIndex, condition.endIndex);
});
expect(alternativeTexts).toEqual(['two', 'three', 'four']);
});
@ -110,30 +103,30 @@ describe('Node', () => {
describe('.startIndex and .endIndex', () => {
it('returns the character index where the node starts/ends in the text', () => {
tree = parser.parse('a👍👎1 / b👎c👎');
const quotientNode = tree.rootNode.firstChild?.firstChild;
tree = parser.parse('a👍👎1 / b👎c👎')!;
const quotientNode = tree.rootNode.firstChild!.firstChild!;
expect(quotientNode?.startIndex).toBe(0);
expect(quotientNode?.endIndex).toBe(15);
expect(quotientNode?.children.map(child => child?.startIndex)).toEqual([0, 7, 9]);
expect(quotientNode?.children.map(child => child?.endIndex)).toEqual([6, 8, 15]);
expect(quotientNode.startIndex).toBe(0);
expect(quotientNode.endIndex).toBe(15);
expect(quotientNode.children.map(child => child!.startIndex)).toEqual([0, 7, 9]);
expect(quotientNode.children.map(child => child!.endIndex)).toEqual([6, 8, 15]);
});
});
describe('.startPosition and .endPosition', () => {
it('returns the row and column where the node starts/ends in the text', () => {
tree = parser.parse('x10 + 1000');
const sumNode = tree.rootNode.firstChild?.firstChild;
expect(sumNode?.type).toBe('binary_expression');
tree = parser.parse('x10 + 1000')!;
const sumNode = tree.rootNode.firstChild!.firstChild!;
expect(sumNode.type).toBe('binary_expression');
expect(sumNode?.startPosition).toEqual({ row: 0, column: 0 });
expect(sumNode?.endPosition).toEqual({ row: 0, column: 10 });
expect(sumNode?.children.map((child) => child?.startPosition)).toEqual([
expect(sumNode.startPosition).toEqual({ row: 0, column: 0 });
expect(sumNode.endPosition).toEqual({ row: 0, column: 10 });
expect(sumNode.children.map((child) => child!.startPosition)).toEqual([
{ row: 0, column: 0 },
{ row: 0, column: 4 },
{ row: 0, column: 6 },
]);
expect(sumNode?.children.map((child) => child?.endPosition)).toEqual([
expect(sumNode.children.map((child) => child!.endPosition)).toEqual([
{ row: 0, column: 3 },
{ row: 0, column: 5 },
{ row: 0, column: 10 },
@ -141,9 +134,9 @@ describe('Node', () => {
});
it('handles characters that occupy two UTF16 code units', () => {
tree = parser.parse('a👍👎1 /\n b👎c👎');
const sumNode = tree.rootNode.firstChild?.firstChild;
expect(sumNode?.children.map(child => [child?.startPosition, child?.endPosition])).toEqual([
tree = parser.parse('a👍👎1 /\n b👎c👎')!;
const sumNode = tree.rootNode.firstChild!.firstChild!;
expect(sumNode.children.map(child => [child!.startPosition, child!.endPosition])).toEqual([
[{ row: 0, column: 0 }, { row: 0, column: 6 }],
[{ row: 0, column: 7 }, { row: 0, column: 8 }],
[{ row: 1, column: 1 }, { row: 1, column: 7 }]
@ -153,75 +146,75 @@ describe('Node', () => {
describe('.parent', () => {
it('returns the node\'s parent', () => {
tree = parser.parse('x10 + 1000');
const sumNode = tree.rootNode.firstChild;
const variableNode = sumNode?.firstChild;
expect(sumNode?.id).not.toBe(variableNode?.id);
expect(sumNode?.id).toBe(variableNode?.parent?.id);
expect(tree.rootNode.id).toBe(sumNode?.parent?.id);
tree = parser.parse('x10 + 1000')!;
const sumNode = tree.rootNode.firstChild!;
const variableNode = sumNode.firstChild!;
expect(sumNode.id).not.toBe(variableNode.id);
expect(sumNode.id).toBe(variableNode.parent!.id);
expect(tree.rootNode.id).toBe(sumNode.parent!.id);
});
});
describe('.child(), .firstChild, .lastChild', () => {
it('returns null when the node has no children', () => {
tree = parser.parse('x10 + 1000');
const sumNode = tree.rootNode.firstChild?.firstChild;
const variableNode = sumNode?.firstChild;
expect(variableNode?.firstChild).toBeNull();
expect(variableNode?.lastChild).toBeNull();
expect(variableNode?.firstNamedChild).toBeNull();
expect(variableNode?.lastNamedChild).toBeNull();
expect(variableNode?.child(1)).toBeNull();
tree = parser.parse('x10 + 1000')!;
const sumNode = tree.rootNode.firstChild!.firstChild!;
const variableNode = sumNode.firstChild!;
expect(variableNode.firstChild).toBeNull();
expect(variableNode.lastChild).toBeNull();
expect(variableNode.firstNamedChild).toBeNull();
expect(variableNode.lastNamedChild).toBeNull();
expect(variableNode.child(1)).toBeNull();
});
});
describe('.childForFieldName()', () => {
it('returns node for the given field name', () => {
tree = parser.parse('class A { b() {} }');
tree = parser.parse('class A { b() {} }')!;
const classNode = tree.rootNode.firstChild;
expect(classNode?.type).toBe('class_declaration');
const classNode = tree.rootNode.firstChild!;
expect(classNode.type).toBe('class_declaration');
const classNameNode = classNode?.childForFieldName('name');
expect(classNameNode?.type).toBe('identifier');
expect(classNameNode?.text).toBe('A');
const classNameNode = classNode.childForFieldName('name')!;
expect(classNameNode.type).toBe('identifier');
expect(classNameNode.text).toBe('A');
const bodyNode = classNode?.childForFieldName('body');
expect(bodyNode?.type).toBe('class_body');
expect(bodyNode?.text).toBe('{ b() {} }');
const bodyNode = classNode.childForFieldName('body')!;
expect(bodyNode.type).toBe('class_body');
expect(bodyNode.text).toBe('{ b() {} }');
const methodNode = bodyNode?.firstNamedChild;
expect(methodNode?.type).toBe('method_definition');
expect(methodNode?.text).toBe('b() {}');
const methodNode = bodyNode.firstNamedChild!;
expect(methodNode.type).toBe('method_definition');
expect(methodNode.text).toBe('b() {}');
});
});
describe('.nextSibling and .previousSibling', () => {
it('returns the node\'s next and previous sibling', () => {
tree = parser.parse('x10 + 1000');
const sumNode = tree.rootNode.firstChild?.firstChild;
expect(sumNode?.children[1]?.id).toBe(sumNode?.children[0]?.nextSibling?.id);
expect(sumNode?.children[2]?.id).toBe(sumNode?.children[1]?.nextSibling?.id);
expect(sumNode?.children[0]?.id).toBe(sumNode?.children[1]?.previousSibling?.id);
expect(sumNode?.children[1]?.id).toBe(sumNode?.children[2]?.previousSibling?.id);
tree = parser.parse('x10 + 1000')!;
const sumNode = tree.rootNode.firstChild!.firstChild!;
expect(sumNode.children[1]!.id).toBe(sumNode.children[0]!.nextSibling!.id);
expect(sumNode.children[2]!.id).toBe(sumNode.children[1]!.nextSibling!.id);
expect(sumNode.children[0]!.id).toBe(sumNode.children[1]!.previousSibling!.id);
expect(sumNode.children[1]!.id).toBe(sumNode.children[2]!.previousSibling!.id);
});
});
describe('.nextNamedSibling and .previousNamedSibling', () => {
it('returns the node\'s next and previous named sibling', () => {
tree = parser.parse('x10 + 1000');
const sumNode = tree.rootNode.firstChild?.firstChild;
expect(sumNode?.namedChildren[1]?.id).toBe(sumNode?.namedChildren[0]?.nextNamedSibling?.id);
expect(sumNode?.namedChildren[0]?.id).toBe(sumNode?.namedChildren[1]?.previousNamedSibling?.id);
tree = parser.parse('x10 + 1000')!;
const sumNode = tree.rootNode.firstChild!.firstChild!;
expect(sumNode.namedChildren[1]!.id).toBe(sumNode.namedChildren[0]!.nextNamedSibling!.id);
expect(sumNode.namedChildren[0]!.id).toBe(sumNode.namedChildren[1]!.previousNamedSibling!.id);
});
});
describe('.descendantForIndex(min, max)', () => {
it('returns the smallest node that spans the given range', () => {
tree = parser.parse('x10 + 1000');
const sumNode = tree.rootNode.firstChild?.firstChild;
expect(sumNode?.descendantForIndex(1, 2)?.type).toBe('identifier');
expect(sumNode?.descendantForIndex(4, 4)?.type).toBe('+');
tree = parser.parse('x10 + 1000')!;
const sumNode = tree.rootNode.firstChild!.firstChild!;
expect(sumNode.descendantForIndex(1, 2)!.type).toBe('identifier');
expect(sumNode.descendantForIndex(4, 4)!.type).toBe('+');
expect(() => {
// @ts-expect-error Testing invalid arguments
@ -237,28 +230,20 @@ describe('Node', () => {
describe('.namedDescendantForIndex', () => {
it('returns the smallest named node that spans the given range', () => {
tree = parser.parse('x10 + 1000');
tree = parser.parse('x10 + 1000')!;
const sumNode = tree.rootNode.firstChild!;
expect(sumNode.descendantForIndex(1, 2)?.type).toBe('identifier');
expect(sumNode.descendantForIndex(4, 4)?.type).toBe('+');
expect(sumNode.descendantForIndex(1, 2)!.type).toBe('identifier');
expect(sumNode.descendantForIndex(4, 4)!.type).toBe('+');
});
});
describe('.descendantForPosition', () => {
it('returns the smallest node that spans the given range', () => {
tree = parser.parse('x10 + 1000');
tree = parser.parse('x10 + 1000')!;
const sumNode = tree.rootNode.firstChild!;
expect(
sumNode.descendantForPosition(
{ row: 0, column: 1 },
{ row: 0, column: 2 }
)?.type
).toBe('identifier');
expect(
sumNode.descendantForPosition({ row: 0, column: 4 })?.type
).toBe('+');
expect(sumNode.descendantForPosition({ row: 0, column: 1 }, { row: 0, column: 2 })!.type).toBe('identifier');
expect(sumNode.descendantForPosition({ row: 0, column: 4 })!.type).toBe('+');
expect(() => {
// @ts-expect-error Testing invalid arguments
@ -274,75 +259,67 @@ describe('Node', () => {
describe('.namedDescendantForPosition(min, max)', () => {
it('returns the smallest named node that spans the given range', () => {
tree = parser.parse('x10 + 1000');
tree = parser.parse('x10 + 1000')!;
const sumNode = tree.rootNode.firstChild!;
expect(
sumNode.namedDescendantForPosition(
{ row: 0, column: 1 },
{ row: 0, column: 2 },
)?.type
).toBe('identifier')
expect(
sumNode.namedDescendantForPosition({ row: 0, column: 4 })?.type
).toBe('binary_expression');
expect(sumNode.namedDescendantForPosition({ row: 0, column: 1 }, { row: 0, column: 2 })!.type).toBe('identifier')
expect(sumNode.namedDescendantForPosition({ row: 0, column: 4 })!.type).toBe('binary_expression');
});
});
describe('.hasError', () => {
it('returns true if the node contains an error', () => {
tree = parser.parse('1 + 2 * * 3');
tree = parser.parse('1 + 2 * * 3')!;
const node = tree.rootNode;
expect(node.toString()).toBe(
'(program (expression_statement (binary_expression left: (number) right: (binary_expression left: (number) (ERROR) right: (number)))))'
);
const sum = node.firstChild?.firstChild;
expect(sum?.hasError).toBe(true);
expect(sum?.children[0]?.hasError).toBe(false);
expect(sum?.children[1]?.hasError).toBe(false);
expect(sum?.children[2]?.hasError).toBe(true);
const sum = node.firstChild!.firstChild!;
expect(sum.hasError).toBe(true);
expect(sum.children[0]!.hasError).toBe(false);
expect(sum.children[1]!.hasError).toBe(false);
expect(sum.children[2]!.hasError).toBe(true);
});
});
describe('.isError', () => {
it('returns true if the node is an error', () => {
tree = parser.parse('2 * * 3');
tree = parser.parse('2 * * 3')!;
const node = tree.rootNode;
expect(node.toString()).toBe(
'(program (expression_statement (binary_expression left: (number) (ERROR) right: (number))))'
);
const multi = node.firstChild?.firstChild;
expect(multi?.hasError).toBe(true);
expect(multi?.children[0]?.isError).toBe(false);
expect(multi?.children[1]?.isError).toBe(false);
expect(multi?.children[2]?.isError).toBe(true);
expect(multi?.children[3]?.isError).toBe(false);
const multi = node.firstChild!.firstChild!;
expect(multi.hasError).toBe(true);
expect(multi.children[0]!.isError).toBe(false);
expect(multi.children[1]!.isError).toBe(false);
expect(multi.children[2]!.isError).toBe(true);
expect(multi.children[3]!.isError).toBe(false);
});
});
describe('.isMissing', () => {
it('returns true if the node was inserted via error recovery', () => {
tree = parser.parse('(2 ||)');
tree = parser.parse('(2 ||)')!;
const node = tree.rootNode;
expect(node.toString()).toBe(
'(program (expression_statement (parenthesized_expression (binary_expression left: (number) right: (MISSING identifier)))))'
);
const sum = node.firstChild?.firstChild?.firstNamedChild;
expect(sum?.type).toBe('binary_expression');
expect(sum?.hasError).toBe(true);
expect(sum?.children[0]?.isMissing).toBe(false);
expect(sum?.children[1]?.isMissing).toBe(false);
expect(sum?.children[2]?.isMissing).toBe(true);
const sum = node.firstChild!.firstChild!.firstNamedChild!;
expect(sum.type).toBe('binary_expression');
expect(sum.hasError).toBe(true);
expect(sum.children[0]!.isMissing).toBe(false);
expect(sum.children[1]!.isMissing).toBe(false);
expect(sum.children[2]!.isMissing).toBe(true);
});
});
describe('.isExtra', () => {
it('returns true if the node is an extra node like comments', () => {
tree = parser.parse('foo(/* hi */);');
tree = parser.parse('foo(/* hi */);')!;
const node = tree.rootNode;
const commentNode = node.descendantForIndex(7, 7)!;
@ -362,15 +339,15 @@ describe('Node', () => {
}).forEach(([method, _parse]) => {
it(`returns the text of a node generated by ${method}`, () => {
const [numeratorSrc, denominatorSrc] = text.split(/\s*\/\s+/);
tree = parser.parse(_parse);
const quotientNode = tree.rootNode.firstChild?.firstChild;
const [numerator, slash, denominator] = quotientNode!.children;
tree = parser.parse(_parse)!;
const quotientNode = tree.rootNode.firstChild!.firstChild!;
const [numerator, slash, denominator] = quotientNode.children;
expect(tree.rootNode.text).toBe(text);
expect(denominator?.text).toBe(denominatorSrc);
expect(quotientNode?.text).toBe(text);
expect(numerator?.text).toBe(numeratorSrc);
expect(slash?.text).toBe('/');
expect(denominator!.text).toBe(denominatorSrc);
expect(quotientNode.text).toBe(text);
expect(numerator!.text).toBe(numeratorSrc);
expect(slash!.text).toBe('/');
});
});
});
@ -378,7 +355,7 @@ describe('Node', () => {
describe('.descendantCount', () => {
it('returns the number of descendants', () => {
parser.setLanguage(JSON);
tree = parser.parse(JSON_EXAMPLE);
tree = parser.parse(JSON_EXAMPLE)!;
const valueNode = tree.rootNode;
const allNodes = getAllNodes(tree);
@ -400,7 +377,7 @@ describe('Node', () => {
it('tests a single node tree', () => {
parser.setLanguage(EmbeddedTemplate);
tree = parser.parse('hello');
tree = parser.parse('hello')!;
const nodes = getAllNodes(tree);
expect(nodes).toHaveLength(2);
@ -420,19 +397,19 @@ describe('Node', () => {
describe('.rootNodeWithOffset', () => {
it('returns the root node of the tree, offset by the given byte offset', () => {
tree = parser.parse(' if (a) b');
tree = parser.parse(' if (a) b')!;
const node = tree.rootNodeWithOffset(6, { row: 2, column: 2 });
expect(node.startIndex).toBe(8);
expect(node.endIndex).toBe(16);
expect(node.startPosition).toEqual({ row: 2, column: 4 });
expect(node.endPosition).toEqual({ row: 2, column: 12 });
let child = node.firstChild?.child(2);
expect(child?.type).toBe('expression_statement');
expect(child?.startIndex).toBe(15);
expect(child?.endIndex).toBe(16);
expect(child?.startPosition).toEqual({ row: 2, column: 11 });
expect(child?.endPosition).toEqual({ row: 2, column: 12 });
let child = node.firstChild!.child(2)!;
expect(child.type).toBe('expression_statement');
expect(child.startIndex).toBe(15);
expect(child.endIndex).toBe(16);
expect(child.startPosition).toEqual({ row: 2, column: 11 });
expect(child.endPosition).toEqual({ row: 2, column: 12 });
const cursor = node.walk();
cursor.gotoFirstChild();
@ -451,40 +428,35 @@ describe('Node', () => {
const text = '10 / 5';
it('returns node parse state ids', () => {
tree = parser.parse(text);
const quotientNode = tree.rootNode.firstChild?.firstChild;
const [numerator, slash, denominator] = quotientNode!.children;
tree = parser.parse(text)!;
const quotientNode = tree.rootNode.firstChild!.firstChild!;
const [numerator, slash, denominator] = quotientNode.children;
expect(tree.rootNode.parseState).toBe(0);
// parse states will change on any change to the grammar so test that it
// returns something instead
expect(numerator?.parseState).toBeGreaterThan(0);
expect(slash?.parseState).toBeGreaterThan(0);
expect(denominator?.parseState).toBeGreaterThan(0);
expect(numerator!.parseState).toBeGreaterThan(0);
expect(slash!.parseState).toBeGreaterThan(0);
expect(denominator!.parseState).toBeGreaterThan(0);
});
it('returns next parse state equal to the language', () => {
tree = parser.parse(text);
const quotientNode = tree.rootNode.firstChild?.firstChild;
quotientNode?.children.forEach((node) => {
expect(node?.nextParseState).toBe(
JavaScript.nextState(node!.parseState, node!.grammarId)
);
tree = parser.parse(text)!;
const quotientNode = tree.rootNode.firstChild!.firstChild!;
quotientNode.children.forEach((node) => {
expect(node!.nextParseState).toBe(JavaScript.nextState(node!.parseState, node!.grammarId));
});
});
});
describe('.descendantsOfType', () => {
it('finds all descendants of a given type in the given range', () => {
tree = parser.parse('a + 1 * b * 2 + c + 3');
const outerSum = tree.rootNode.firstChild?.firstChild;
tree = parser.parse('a + 1 * b * 2 + c + 3')!;
const outerSum = tree.rootNode.firstChild!.firstChild!;
const descendants = outerSum?.descendantsOfType('number', { row: 0, column: 2 }, { row: 0, column: 15 }) ?? [];
expect(descendants.map(node => node?.startIndex)).toEqual([4, 12]);
expect(descendants.map(node => node?.endPosition)).toEqual([
{ row: 0, column: 5 },
{ row: 0, column: 13 },
]);
const descendants = outerSum.descendantsOfType('number', { row: 0, column: 2 }, { row: 0, column: 15 });
expect(descendants.map(node => node!.startIndex)).toEqual([4, 12]);
expect(descendants.map(node => node!.endPosition)).toEqual([{ row: 0, column: 5 }, { row: 0, column: 13 }]);
});
});
@ -492,57 +464,57 @@ describe('Node', () => {
describe('.firstChildForIndex(index)', () => {
it('returns the first child that contains or starts after the given index', () => {
tree = parser.parse('x10 + 1000');
const sumNode = tree.rootNode.firstChild?.firstChild;
tree = parser.parse('x10 + 1000')!;
const sumNode = tree.rootNode.firstChild!.firstChild!;
expect(sumNode?.firstChildForIndex(0)?.type).toBe('identifier');
expect(sumNode?.firstChildForIndex(1)?.type).toBe('identifier');
expect(sumNode?.firstChildForIndex(3)?.type).toBe('+');
expect(sumNode?.firstChildForIndex(5)?.type).toBe('number');
expect(sumNode.firstChildForIndex(0)!.type).toBe('identifier');
expect(sumNode.firstChildForIndex(1)!.type).toBe('identifier');
expect(sumNode.firstChildForIndex(3)!.type).toBe('+');
expect(sumNode.firstChildForIndex(5)!.type).toBe('number');
});
});
describe('.firstNamedChildForIndex(index)', () => {
it('returns the first child that contains or starts after the given index', () => {
tree = parser.parse('x10 + 1000');
const sumNode = tree.rootNode.firstChild?.firstChild;
tree = parser.parse('x10 + 1000')!;
const sumNode = tree.rootNode.firstChild!.firstChild!;
expect(sumNode?.firstNamedChildForIndex(0)?.type).toBe('identifier');
expect(sumNode?.firstNamedChildForIndex(1)?.type).toBe('identifier');
expect(sumNode?.firstNamedChildForIndex(3)?.type).toBe('number');
expect(sumNode.firstNamedChildForIndex(0)!.type).toBe('identifier');
expect(sumNode.firstNamedChildForIndex(1)!.type).toBe('identifier');
expect(sumNode.firstNamedChildForIndex(3)!.type).toBe('number');
});
});
describe('.equals(other)', () => {
it('returns true if the nodes are the same', () => {
tree = parser.parse('1 + 2');
tree = parser.parse('1 + 2')!;
const sumNode = tree.rootNode.firstChild?.firstChild;
const node1 = sumNode?.firstChild;
const node2 = sumNode?.firstChild;
expect(node1?.equals(node2!)).toBe(true);
const sumNode = tree.rootNode.firstChild!.firstChild!;
const node1 = sumNode.firstChild!;
const node2 = sumNode.firstChild!;
expect(node1.equals(node2)).toBe(true);
});
it('returns false if the nodes are not the same', () => {
tree = parser.parse('1 + 2');
tree = parser.parse('1 + 2')!;
const sumNode = tree.rootNode.firstChild?.firstChild;
const node1 = sumNode?.firstChild;
const node2 = node1?.nextSibling;
expect(node1?.equals(node2!)).toBe(false);
const sumNode = tree.rootNode.firstChild!.firstChild!;
const node1 = sumNode.firstChild!;
const node2 = node1.nextSibling!;
expect(node1.equals(node2)).toBe(false);
});
});
describe('.fieldNameForChild(index)', () => {
it('returns the field of a child or null', () => {
parser.setLanguage(C);
tree = parser.parse('int w = x + /* y is special! */ y;');
tree = parser.parse('int w = x + /* y is special! */ y;')!;
const translationUnitNode = tree.rootNode;
const declarationNode = translationUnitNode.firstChild;
const binaryExpressionNode = declarationNode!
.childForFieldName('declarator')!
.childForFieldName('value');
.childForFieldName('value')!;
// -------------------
// left: (identifier) 0
@ -551,26 +523,26 @@ describe('Node', () => {
// right: (identifier) 3
// -------------------
expect(binaryExpressionNode?.fieldNameForChild(0)).toBe('left');
expect(binaryExpressionNode?.fieldNameForChild(1)).toBe('operator');
expect(binaryExpressionNode.fieldNameForChild(0)).toBe('left');
expect(binaryExpressionNode.fieldNameForChild(1)).toBe('operator');
// The comment should not have a field name, as it's just an extra
expect(binaryExpressionNode?.fieldNameForChild(2)).toBeNull();
expect(binaryExpressionNode?.fieldNameForChild(3)).toBe('right');
expect(binaryExpressionNode.fieldNameForChild(2)).toBeNull();
expect(binaryExpressionNode.fieldNameForChild(3)).toBe('right');
// Negative test - Not a valid child index
expect(binaryExpressionNode?.fieldNameForChild(4)).toBeNull();
expect(binaryExpressionNode.fieldNameForChild(4)).toBeNull();
});
});
describe('.fieldNameForNamedChild(index)', () => {
it('returns the field of a named child or null', () => {
parser.setLanguage(C);
tree = parser.parse('int w = x + /* y is special! */ y;');
tree = parser.parse('int w = x + /* y is special! */ y;')!;
const translationUnitNode = tree.rootNode;
const declarationNode = translationUnitNode.firstNamedChild;
const binaryExpressionNode = declarationNode!
.childForFieldName('declarator')!
.childForFieldName('value');
.childForFieldName('value')!;
// -------------------
// left: (identifier) 0
@ -579,13 +551,13 @@ describe('Node', () => {
// right: (identifier) 2
// -------------------
expect(binaryExpressionNode?.fieldNameForNamedChild(0)).toBe('left');
expect(binaryExpressionNode.fieldNameForNamedChild(0)).toBe('left');
// The comment should not have a field name, as it's just an extra
expect(binaryExpressionNode?.fieldNameForNamedChild(1)).toBeNull();
expect(binaryExpressionNode.fieldNameForNamedChild(1)).toBeNull();
// The operator is not a named child, so the named child at index 2 is the right child
expect(binaryExpressionNode?.fieldNameForNamedChild(2)).toBe('right');
expect(binaryExpressionNode.fieldNameForNamedChild(2)).toBe('right');
// Negative test - Not a valid child index
expect(binaryExpressionNode?.fieldNameForNamedChild(3)).toBeNull();
expect(binaryExpressionNode.fieldNameForNamedChild(3)).toBeNull();
});
});
});