Ejemplo
@typescript-eslint/typescript-estree 8.67.0: visitorKeys
Muestra verificada para npm @typescript-eslint/typescript-estree 8.67.0: visitorKeys. El contrato se ejecutó en node 22 · linux debian/x64 · docker y pasó.
sha256:a3d06e8a220269efdd355e97291b0af9e0ee22e034b936a927d49a5e68cac39b
Esta red ofrece una sola cosa: una muestra que compila. La ejecutó en un sandbox y guardó el recibo firmado. No califica ni garantiza nada: si el mismo código compila donde estás no es algo que haya medido.
Cuántas claves de firma distintas presentaron un recibo de contrato aprobado. Una es solo el autor; más de una significa que alguien más también lo compiló. Una clave se genera sola y no tiene identidad registrada detrás, así que cuenta claves, no personas.
MIT-0
Evidencia de ejecución
El entorno declarado y las ejecuciones firmadas se muestran por separado, para que veas exactamente qué ejecutó esta muestra y dónde.
- Base de evidencia
- Contrato firmado aprobado
- Recibos de verificación
- 1
- Claves de firma que lo compilaron
- 1
Entorno declarado
linux 24 · ubuntu · glibc 2.39 x64 npm
Entornos de las ejecuciones de verificación
| Entorno | Contrato | Etapas | Ejecución |
|---|---|---|---|
| node 22 · linux debian/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1node:22@sha256:8a34c4ab3ea2… |
2026-09-02 |
Caso
HOW- Objetivo
- verify visitorKeys in pkg:npm/%40typescript-eslint/typescript-estree@8.67.0
- Símbolos
-
- visitorKeys
- Creado
- 2026-09-02T00:58:33Z
Contrato
- simpleTraverse traverses TypeScript and ESTree AST nodes using default visitorKeys
- simpleTraverse supports custom visitorKeys to selectively restrict or customize AST traversal
- simpleTraverse with visitorKeys and visitors map dispatches to specific node type visitors
- simpleTraverse attaches parent references to traversed AST nodes when setParentPointers is true
- simpleTraverse handles empty visitorKeys and leaf AST nodes gracefully without recursion
- findNodesByType uses simpleTraverse and visitorKeys to filter targeted AST node types
Archivos
- PROMPT.md
- README.md
- csx.json
- package-lock.json
- package.json
- spec.json
- src/index.js
- test/contract.mjs
Código fuente
Clean-room public code sample — generation instructions
Write a brand-new, minimal, self-contained code sample in this clean-room directory.
Do not copy, paraphrase, or reference any existing project source. Work only from this spec.
A csx.json manifest scaffold already exists. Do not recreate it from memory. Preserve its case.goal, packages and symbols; fill its empty case.contract with exact assertions and correct its environment, commands and verifierAdapter for the files you generate.
Goal: verify visitorKeys in pkg:npm/%40typescript-eslint/typescript-estree@8.67.0
Kind: HOW
Use EXACTLY these public packages and versions:
- pkg:npm/%40typescript-eslint/typescript-estree@8.67.0
Demonstrate these symbols/APIs:
- visitorKeys
Rules:
- One focused purpose; the smallest project that proves the goal.
- Include a contract test (test/contract.*) that runs OFFLINE and exits 0 exactly when the goal behavior works.
- Pin every dependency with a lockfile so resolution is reproducible.
- No secrets, credentials, or tokens. No real URLs (only example.com or localhost). No absolute paths.
- No personal names, emails, company names, or project identifiers of any kind.
- No binaries and no generated output (node_modules, dist, target, venv, .git, .env).
- Keep it under 200 files and 256KB packed.
# @typescript-eslint/typescript-estree visitorKeys sample
This sample demonstrates and verifies AST traversal using `simpleTraverse` and custom or default `visitorKeys` from `@typescript-eslint/typescript-estree`.
## Features
- AST parsing using `parse`
- AST traversal using `simpleTraverse` with default visitor keys
- Custom `visitorKeys` configuration to prune or target specific AST subtrees
- Traversing with typed node visitors
- Attaching parent node pointers via `setParentPointers`
{"case":{"caseId":"case:sha256:dbbc8ecaa899e905a39070b292b144f63e55e6cd02b5cd69cdfdf9581a6b6165","contract":["simpleTraverse traverses TypeScript and ESTree AST nodes using default visitorKeys","simpleTraverse supports custom visitorKeys to selectively restrict or customize AST traversal","simpleTraverse with visitorKeys and visitors map dispatches to specific node type visitors","simpleTraverse attaches parent references to traversed AST nodes when setParentPointers is true","simpleTraverse handles empty visitorKeys and leaf AST nodes gracefully without recursion","findNodesByType uses simpleTraverse and visitorKeys to filter targeted AST node types"],"goal":"verify visitorKeys in pkg:npm/%40typescript-eslint/typescript-estree@8.67.0","kind":"HOW","packages":["pkg:npm/%40typescript-eslint/typescript-estree@8.67.0"],"schemaVersion":1,"symbols":["visitorKeys"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","distro":"ubuntu","ecosystem":"npm","libc":"glibc","libcVersion":"2.39","os":"linux","osVersionBucket":"24","packageManager":"npm","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/%40typescript-eslint/typescript-estree@8.67.0"],"schemaVersion":1,"subject":"pkg:npm/%40typescript-eslint/typescript-estree@8.67.0","symbols":["visitorKeys"],"verifierAdapter":"node-typescript@1"}
{
"name": "sample-typescript-estree-visitor-keys",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "sample-typescript-estree-visitor-keys",
"version": "1.0.0",
"dependencies": {
"@typescript-eslint/typescript-estree": "8.67.0"
}
},
"node_modules/@typescript-eslint/project-service": {
"version": "8.67.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.67.0.tgz",
"integrity": "sha512-cvE8c7ulYeXN9fYuszhCeCsbzyVEXuhrRCybnBre7TUmqb5nRmBfQAwCj0O3WJFDeyAZt4VYv51vMCC9LHSdYw==",
"license": "MIT",
"dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.67.0",
"@typescript-eslint/types": "^8.67.0",
"debug": "^4.4.3"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.67.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.67.0.tgz",
"integrity": "sha512-vV+LUSv5njUWsknE71fqKTlXUva+R76SaeORd6Zojcunk/6DvKFXONU3BrAs2H49mbygUXt6gbYunzwqNwlhdg==",
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/types": {
"version": "8.67.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.67.0.tgz",
"integrity": "sha512-sBtgslww8nsMYUjhdPBiSyUqSzT8uR6g93A2QXnQC8+cGdjz0CyaOdqHDRJb1AtORbZCNUJBBeFA/tNR2uQmww==",
"license": "MIT",
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "8.67.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.67.0.tgz",
"integrity": "sha512-EKQBCE9yNlRJYm7jdTW5AhDacDUmSwQb0FAJAmK2EKYrNXIsa2vxcSZx6PvJ/dEdI6lS+Y9W+EXckLj0iPFGcw==",
"license": "MIT",
"dependencies": {
"@typescript-eslint/project-service": "8.67.0",
"@typescript-eslint/tsconfig-utils": "8.67.0",
"@typescript-eslint/types": "8.67.0",
"@typescript-eslint/visitor-keys": "8.67.0",
"debug": "^4.4.3",
"minimatch": "^10.2.2",
"semver": "^7.7.3",
"tinyglobby": "^0.2.15",
"ts-api-utils": "^2.5.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"typescript": ">=4.8.4 <6.1.0"
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "8.67.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.67.0.tgz",
"integrity": "sha512-fkv8dHRDqfGtTHuJeebdrQ7cX6Ad4WAS00rgHh9UGvMycF1mjBfsxry1XsLIFhWZ6Judlh6UdzK+TYlbpCXgnA==",
"license": "MIT",
"dependencies": {
"@typescript-eslint/types": "8.67.0",
"eslint-visitor-keys": "^5.0.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
}
},
"node_modules/balanced-match": {
"version": "4.0.4",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
"integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
"license": "MIT",
"engines": {
"node": "18 || 20 || >=22"
}
},
"node_modules/brace-expansion": {
"version": "5.0.9",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz",
"integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==",
"license": "MIT",
"dependencies": {
"balanced-match": "^4.0.2"
},
"engines": {
"node": "20 || >=22"
}
},
"node_modules/debug": {
"version": "4.4.3",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
"integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
},
"engines": {
"node": ">=6.0"
},
"peerDependenciesMeta": {
"supports-color": {
"optional": true
}
}
},
"node_modules/eslint-visitor-keys": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz",
"integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==",
"license": "Apache-2.0",
"engines": {
"node": "^20.19.0 || ^22.13.0 || >=24"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/fdir": {
"version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
"integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"license": "MIT",
"engines": {
"node": ">=12.0.0"
},
"peerDependencies": {
"picomatch": "^3 || ^4"
},
"peerDependenciesMeta": {
"picomatch": {
"optional": true
}
}
},
"node_modules/minimatch": {
"version": "10.2.6",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.6.tgz",
"integrity": "sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==",
"license": "BlueOak-1.0.0",
"dependencies": {
"brace-expansion": "^5.0.8"
},
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"license": "MIT"
},
"node_modules/picomatch": {
"version": "4.0.7",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.7.tgz",
"integrity": "sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==",
"license": "MIT",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/semver": {
"version": "7.8.5",
"resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz",
"integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==",
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
},
"engines": {
"node": ">=10"
}
},
"node_modules/tinyglobby": {
"version": "0.2.17",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz",
"integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==",
"license": "MIT",
"dependencies": {
"fdir": "^6.5.0",
"picomatch": "^4.0.4"
},
"engines": {
"node": ">=12.0.0"
},
"funding": {
"url": "https://github.com/sponsors/SuperchupuDev"
}
},
"node_modules/ts-api-utils": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz",
"integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==",
"license": "MIT",
"engines": {
"node": ">=18.12"
},
"peerDependencies": {
"typescript": ">=4.8.4"
}
},
"node_modules/typescript": {
"version": "6.0.3",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-6.0.3.tgz",
"integrity": "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw==",
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
},
"engines": {
"node": ">=14.17"
}
}
}
}
{
"name": "sample-typescript-estree-visitor-keys",
"version": "1.0.0",
"type": "module",
"scripts": {
"test": "node test/contract.mjs"
},
"dependencies": {
"@typescript-eslint/typescript-estree": "8.67.0"
}
}
{
"schemaVersion": 1,
"goal": "verify visitorKeys in pkg:npm/%40typescript-eslint/typescript-estree@8.67.0",
"kind": "HOW",
"packages": [
"pkg:npm/%40typescript-eslint/typescript-estree@8.67.0"
],
"symbols": [
"visitorKeys"
]
}
import { parse, simpleTraverse, AST_NODE_TYPES } from '@typescript-eslint/typescript-estree';
/**
* Traverses an AST and collects all visited node types using simpleTraverse and visitorKeys.
*
* @param {import('@typescript-eslint/typescript-estree').TSESTree.Node} ast - AST root node.
* @param {Record<string, readonly string[]>} [customVisitorKeys] - Optional custom visitor keys mapping.
* @returns {string[]} Array of visited node types in traversal order.
*/
export function collectNodeTypes(ast, customVisitorKeys) {
const types = [];
const options = {
enter(node) {
if (node && typeof node.type === 'string') {
types.push(node.type);
}
},
};
if (customVisitorKeys) {
options.visitorKeys = customVisitorKeys;
}
simpleTraverse(ast, options);
return types;
}
/**
* Traverses an AST with selective node visitor callbacks and optional custom visitorKeys.
*
* @param {import('@typescript-eslint/typescript-estree').TSESTree.Node} ast - AST root node.
* @param {Record<string, Function>} visitors - Mapping of node type names to visitor handler functions.
* @param {Record<string, readonly string[]>} [customVisitorKeys] - Optional custom visitor keys mapping.
*/
export function traverseWithVisitors(ast, visitors, customVisitorKeys) {
const options = {
visitors,
};
if (customVisitorKeys) {
options.visitorKeys = customVisitorKeys;
}
simpleTraverse(ast, options);
}
/**
* Traverses an AST while establishing parent node references.
*
* @param {import('@typescript-eslint/typescript-estree').TSESTree.Node} ast - AST root node.
* @param {Record<string, readonly string[]>} [customVisitorKeys] - Optional custom visitor keys mapping.
* @returns {import('@typescript-eslint/typescript-estree').TSESTree.Node} The root AST node with parent pointers established.
*/
export function traverseWithParentPointers(ast, customVisitorKeys) {
const options = {
enter() {},
};
if (customVisitorKeys) {
options.visitorKeys = customVisitorKeys;
}
simpleTraverse(ast, options, true);
return ast;
}
/**
* Parses TypeScript source code into a TSESTree AST.
*
* @param {string} code - TypeScript source code string.
* @param {object} [options] - Additional parser options.
* @returns {import('@typescript-eslint/typescript-estree').TSESTree.Program}
*/
export function parseCode(code, options = {}) {
return parse(code, {
loc: true,
range: true,
tokens: true,
...options,
});
}
/**
* Filters and extracts AST nodes matching specific type names using simpleTraverse.
*
* @param {import('@typescript-eslint/typescript-estree').TSESTree.Node} ast - AST root node.
* @param {string[]} targetTypes - Array of target AST node types to collect.
* @param {Record<string, readonly string[]>} [customVisitorKeys] - Optional custom visitor keys mapping.
* @returns {import('@typescript-eslint/typescript-estree').TSESTree.Node[]}
*/
export function findNodesByType(ast, targetTypes, customVisitorKeys) {
const targetSet = new Set(targetTypes);
const found = [];
const options = {
enter(node) {
if (node && targetSet.has(node.type)) {
found.push(node);
}
},
};
if (customVisitorKeys) {
options.visitorKeys = customVisitorKeys;
}
simpleTraverse(ast, options);
return found;
}
export { parse, simpleTraverse, AST_NODE_TYPES };
import assert from 'node:assert/strict';
import {
parse,
simpleTraverse,
AST_NODE_TYPES,
collectNodeTypes,
traverseWithVisitors,
traverseWithParentPointers,
parseCode,
findNodesByType,
} from '../src/index.js';
async function runContract() {
const tsCode = `
interface UserProfile {
id: string;
age: number;
}
function calculateDiscount(price: number, rate: number): number {
const discount = price * rate;
return discount;
}
`;
// 1. simpleTraverse traverses TypeScript and ESTree AST nodes using default visitorKeys
const ast = parseCode(tsCode);
assert.strictEqual(ast.type, AST_NODE_TYPES.Program);
const defaultVisitedTypes = collectNodeTypes(ast);
assert.ok(defaultVisitedTypes.length > 0);
assert.ok(defaultVisitedTypes.includes(AST_NODE_TYPES.Program));
assert.ok(defaultVisitedTypes.includes(AST_NODE_TYPES.TSInterfaceDeclaration));
assert.ok(defaultVisitedTypes.includes(AST_NODE_TYPES.TSPropertySignature));
assert.ok(defaultVisitedTypes.includes(AST_NODE_TYPES.TSTypeAnnotation));
assert.ok(defaultVisitedTypes.includes(AST_NODE_TYPES.TSStringKeyword));
assert.ok(defaultVisitedTypes.includes(AST_NODE_TYPES.TSNumberKeyword));
assert.ok(defaultVisitedTypes.includes(AST_NODE_TYPES.FunctionDeclaration));
assert.ok(defaultVisitedTypes.includes(AST_NODE_TYPES.Identifier));
assert.ok(defaultVisitedTypes.includes(AST_NODE_TYPES.BlockStatement));
assert.ok(defaultVisitedTypes.includes(AST_NODE_TYPES.VariableDeclaration));
assert.ok(defaultVisitedTypes.includes(AST_NODE_TYPES.BinaryExpression));
assert.ok(defaultVisitedTypes.includes(AST_NODE_TYPES.ReturnStatement));
// 2. simpleTraverse supports custom visitorKeys to selectively restrict or customize AST traversal
const customVisitorKeys = {
Program: ['body'],
TSInterfaceDeclaration: ['id'], // intentionally ignore interface body/properties
FunctionDeclaration: ['id', 'params'], // ignore function body
Identifier: [],
TSTypeAnnotation: [],
};
const customVisitedTypes = collectNodeTypes(ast, customVisitorKeys);
assert.ok(customVisitedTypes.includes(AST_NODE_TYPES.Program));
assert.ok(customVisitedTypes.includes(AST_NODE_TYPES.TSInterfaceDeclaration));
assert.ok(customVisitedTypes.includes(AST_NODE_TYPES.FunctionDeclaration));
// Since interface body and function body were excluded from visitorKeys, their children must not be visited
assert.strictEqual(customVisitedTypes.includes(AST_NODE_TYPES.TSInterfaceBody), false);
assert.strictEqual(customVisitedTypes.includes(AST_NODE_TYPES.TSPropertySignature), false);
assert.strictEqual(customVisitedTypes.includes(AST_NODE_TYPES.BlockStatement), false);
assert.strictEqual(customVisitedTypes.includes(AST_NODE_TYPES.VariableDeclaration), false);
assert.strictEqual(customVisitedTypes.includes(AST_NODE_TYPES.ReturnStatement), false);
// 3. simpleTraverse with visitorKeys and visitors map dispatches to specific node type visitors
const visitedIdentifiers = [];
let visitedInterfaceCount = 0;
traverseWithVisitors(
ast,
{
Identifier(node, parent) {
visitedIdentifiers.push(node.name);
assert.ok(parent !== undefined);
},
TSInterfaceDeclaration(node, parent) {
visitedInterfaceCount++;
assert.strictEqual(parent.type, AST_NODE_TYPES.Program);
},
}
);
assert.strictEqual(visitedInterfaceCount, 1);
assert.ok(visitedIdentifiers.includes('UserProfile'));
assert.ok(visitedIdentifiers.includes('id'));
assert.ok(visitedIdentifiers.includes('age'));
assert.ok(visitedIdentifiers.includes('calculateDiscount'));
assert.ok(visitedIdentifiers.includes('price'));
assert.ok(visitedIdentifiers.includes('rate'));
assert.ok(visitedIdentifiers.includes('discount'));
// 4. simpleTraverse attaches parent references to traversed AST nodes when setParentPointers is true
const freshAst = parseCode('const answer: number = 42;');
traverseWithParentPointers(freshAst);
const idNode = freshAst.body[0].declarations[0].id;
assert.strictEqual(idNode.parent, freshAst.body[0].declarations[0]);
assert.strictEqual(idNode.parent.parent, freshAst.body[0]);
assert.strictEqual(idNode.parent.parent.parent, freshAst);
// 5. simpleTraverse handles empty visitorKeys and leaf AST nodes gracefully without recursion
const leafOnlyVisitorKeys = {
Program: [],
};
const leafVisitedTypes = collectNodeTypes(ast, leafOnlyVisitorKeys);
assert.deepStrictEqual(leafVisitedTypes, [AST_NODE_TYPES.Program]);
// Non-node and null inputs are handled safely
let dummyCalled = false;
simpleTraverse(null, {
enter() {
dummyCalled = true;
},
});
simpleTraverse(undefined, {
enter() {
dummyCalled = true;
},
});
simpleTraverse({ notAValidNode: true }, {
enter() {
dummyCalled = true;
},
});
assert.strictEqual(dummyCalled, false);
// 6. findNodesByType uses simpleTraverse and visitorKeys to filter targeted AST node types
const interfaces = findNodesByType(ast, [AST_NODE_TYPES.TSInterfaceDeclaration]);
assert.strictEqual(interfaces.length, 1);
assert.strictEqual(interfaces[0].id.name, 'UserProfile');
const functions = findNodesByType(ast, [AST_NODE_TYPES.FunctionDeclaration]);
assert.strictEqual(functions.length, 1);
assert.strictEqual(functions[0].id.name, 'calculateDiscount');
console.log('Contract assertions passed successfully.');
}
runContract().catch((err) => {
console.error('Contract test failed:', err);
process.exit(1);
});
Seeder de origen
anónimo