Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(typescript-estree): correct storing regexp in snapshots #1393

Merged
merged 7 commits into from Jan 2, 2020
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .cspell.json
Expand Up @@ -9,7 +9,7 @@
"**/**/CHANGELOG.md",
"**/**/CONTRIBUTORS.md",
"**/**/ROADMAP.md",
"**/*.json"
"**/*.{json,snap}"
],
"dictionaries": [
"typescript",
Expand Down
2 changes: 0 additions & 2 deletions packages/typescript-estree/package.json
Expand Up @@ -55,12 +55,10 @@
"@types/debug": "^4.1.5",
"@types/glob": "^7.1.1",
"@types/is-glob": "^4.0.1",
"@types/lodash.isplainobject": "^4.0.4",
"@types/lodash.unescape": "^4.0.4",
"@types/semver": "^6.2.0",
"@types/tmp": "^0.1.0",
"@typescript-eslint/shared-fixtures": "2.14.0",
"lodash.isplainobject": "4.0.6",
"tmp": "^0.1.0",
"typescript": "*"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/typescript-estree/src/parser.ts
Expand Up @@ -366,7 +366,7 @@ function parseAndGenerateServices<T extends TSESTreeOptions = TSESTreeOptions>(
)!;

/**
* Determine whatever or not two-way maps of converted AST nodes should be preserved
* Determine if two-way maps of converted AST nodes should be preserved
bradzacher marked this conversation as resolved.
Show resolved Hide resolved
* during the conversion process
*/
const shouldPreserveNodeMaps =
Expand Down
9 changes: 2 additions & 7 deletions packages/typescript-estree/tests/ast-alignment/parse.ts
Expand Up @@ -3,7 +3,6 @@
import { ParserPlugin } from '@babel/parser';
import { codeFrameColumns } from '@babel/code-frame';
import * as parser from '../../src/parser';
import * as parseUtils from './utils';

function createError(
message: string,
Expand Down Expand Up @@ -92,14 +91,10 @@ export function parse(
try {
switch (opts.parser) {
case '@typescript-eslint/typescript-estree':
result.ast = parseUtils.normalizeNodeTypes(
parseWithTypeScriptESTree(text, opts.jsx),
);
result.ast = parseWithTypeScriptESTree(text, opts.jsx);
break;
case '@babel/parser':
result.ast = parseUtils.normalizeNodeTypes(
parseWithBabelParser(text, opts.jsx),
);
result.ast = parseWithBabelParser(text, opts.jsx);
break;
default:
throw new Error(
Expand Down
2 changes: 1 addition & 1 deletion packages/typescript-estree/tests/ast-alignment/spec.ts
Expand Up @@ -78,7 +78,7 @@ fixturesToTest.forEach(fixture => {
),
).toEqual(
parseUtils.removeLocationDataAndSourceTypeFromProgramNode(
typeScriptESTreeResult.ast,
parseUtils.preprocessTypescriptAST(typeScriptESTreeResult.ast),
fixture.ignoreSourceType,
),
);
Expand Down
118 changes: 31 additions & 87 deletions packages/typescript-estree/tests/ast-alignment/utils.ts
@@ -1,90 +1,25 @@
// babel types are something we don't really care about
/* eslint-disable @typescript-eslint/no-explicit-any */
import { AST_NODE_TYPES } from '../../src/ts-estree';
import isPlainObject from 'lodash.isplainobject';

/**
* By default, pretty-format (within Jest matchers) retains the names/types of nodes from the babylon AST,
* quick and dirty way to avoid that is to JSON.stringify and then JSON.parser the
* ASTs before comparing them with pretty-format
*
* @param {Object} ast raw AST
* @returns {Object} normalized AST
*/
export function normalizeNodeTypes(ast: any): any {
return JSON.parse(JSON.stringify(ast));
}

/**
* Removes the given keys from the given AST object recursively
* @param root A JavaScript object to remove keys from
* @param keysToOmit Names and predicate functions use to determine what keys to omit from the final object
* @param nodes advance ast modifications
* @returns {Object} formatted object
*/
export function omitDeep(
root: any,
keysToOmit: { key: string; predicate: Function }[],
nodes: Record<string, (node: any, parent: any) => void> = {},
): any {
function shouldOmit(keyName: string, val: any): boolean {
if (keysToOmit?.length) {
return keysToOmit.some(
keyConfig => keyConfig.key === keyName && keyConfig.predicate(val),
);
}
return false;
}

function visit(node: any, parent: any): void {
if (!node) {
return;
}

for (const prop in node) {
if (Object.prototype.hasOwnProperty.call(node, prop)) {
if (shouldOmit(prop, node[prop])) {
delete node[prop];
continue;
}

const child = node[prop];

if (Array.isArray(child)) {
for (const el of child) {
visit(el, node);
}
} else if (isPlainObject(child)) {
visit(child, node);
}
}
}

if (typeof node.type === 'string' && node.type in nodes) {
nodes[node.type](node, parent);
}
}

visit(root, null);
return root;
}
import { AST_NODE_TYPES, TSESTree } from '../../src/ts-estree';
import { deeplyCopy, omitDeep } from '../../tools/test-utils';
import * as BabelTypes from '@babel/types';

/**
* Common predicates for Babylon AST preprocessing
*/
const always = (): boolean => true;
const ifNumber = (val: any): boolean => typeof val === 'number';
const ifNumber = (val: unknown): boolean => typeof val === 'number';

/**
* - Babylon wraps the "Program" node in an extra "File" node, normalize this for simplicity for now...
* - Remove "start" and "end" values from Babylon nodes to reduce unimportant noise in diffs ("loc" data will still be in
* each final AST and compared).
*
* @param {Object} ast raw babylon AST
* @returns {Object} processed babylon AST
* @param ast raw babylon AST
* @returns processed babylon AST
*/
export function preprocessBabylonAST(ast: any): any {
return omitDeep(
export function preprocessBabylonAST(ast: BabelTypes.File): any {
return omitDeep<any>(
ast.program,
[
{
Expand Down Expand Up @@ -130,7 +65,7 @@ export function preprocessBabylonAST(ast: any): any {
/**
* Awaiting feedback on Babel issue https://github.com/babel/babel/issues/9231
*/
TSCallSignatureDeclaration(node: any) {
TSCallSignatureDeclaration(node) {
if (node.typeAnnotation) {
node.returnType = node.typeAnnotation;
delete node.typeAnnotation;
Expand All @@ -143,7 +78,7 @@ export function preprocessBabylonAST(ast: any): any {
/**
* Awaiting feedback on Babel issue https://github.com/babel/babel/issues/9231
*/
TSConstructSignatureDeclaration(node: any) {
TSConstructSignatureDeclaration(node) {
if (node.typeAnnotation) {
node.returnType = node.typeAnnotation;
delete node.typeAnnotation;
Expand All @@ -156,7 +91,7 @@ export function preprocessBabylonAST(ast: any): any {
/**
* Awaiting feedback on Babel issue https://github.com/babel/babel/issues/9231
*/
TSFunctionType(node: any) {
TSFunctionType(node) {
if (node.typeAnnotation) {
node.returnType = node.typeAnnotation;
delete node.typeAnnotation;
Expand All @@ -169,7 +104,7 @@ export function preprocessBabylonAST(ast: any): any {
/**
* Awaiting feedback on Babel issue https://github.com/babel/babel/issues/9231
*/
TSConstructorType(node: any) {
TSConstructorType(node) {
if (node.typeAnnotation) {
node.returnType = node.typeAnnotation;
delete node.typeAnnotation;
Expand All @@ -182,7 +117,7 @@ export function preprocessBabylonAST(ast: any): any {
/**
* Awaiting feedback on Babel issue https://github.com/babel/babel/issues/9231
*/
TSMethodSignature(node: any) {
TSMethodSignature(node) {
if (node.typeAnnotation) {
node.returnType = node.typeAnnotation;
delete node.typeAnnotation;
Expand Down Expand Up @@ -215,7 +150,7 @@ export function preprocessBabylonAST(ast: any): any {
};
}
},
ClassProperty(node: any) {
ClassProperty(node) {
/**
* Babel: ClassProperty + abstract: true
* ts-estree: TSAbstractClassProperty
Expand All @@ -233,7 +168,7 @@ export function preprocessBabylonAST(ast: any): any {
node.declare = false;
}
},
TSExpressionWithTypeArguments(node: any, parent: any) {
TSExpressionWithTypeArguments(node, parent: any) {
if (parent.type === 'TSInterfaceDeclaration') {
node.type = 'TSInterfaceHeritage';
} else if (
Expand Down Expand Up @@ -266,17 +201,17 @@ export function preprocessBabylonAST(ast: any): any {
* babel: sets optional property as true/undefined
* ts-estree: sets optional property as true/false
*/
MemberExpression(node: any) {
MemberExpression(node) {
if (!node.optional) {
node.optional = false;
}
},
CallExpression(node: any) {
CallExpression(node) {
if (!node.optional) {
node.optional = false;
}
},
OptionalCallExpression(node: any) {
OptionalCallExpression(node) {
if (!node.optional) {
node.optional = false;
}
Expand All @@ -286,7 +221,7 @@ export function preprocessBabylonAST(ast: any): any {
* babel: sets asserts property as true/undefined
* ts-estree: sets asserts property as true/false
*/
TSTypePredicate(node: any) {
TSTypePredicate(node) {
if (!node.asserts) {
node.asserts = false;
}
Expand All @@ -302,9 +237,9 @@ export function preprocessBabylonAST(ast: any): any {
*
* See: https://github.com/babel/babel/issues/6681
*
* @param {Object} ast the raw AST with a Program node at its top level
* @param {boolean} ignoreSourceType fix for issues with unambiguous type detection
* @returns {Object} the ast with the location data removed from the Program node
* @param ast the raw AST with a Program node at its top level
* @param ignoreSourceType fix for issues with unambiguous type detection
* @returns the ast with the location data removed from the Program node
*/
export function removeLocationDataAndSourceTypeFromProgramNode(
ast: any,
Expand All @@ -317,3 +252,12 @@ export function removeLocationDataAndSourceTypeFromProgramNode(
}
return ast;
}

/**
* Returns a raw copy of the typescript AST
* @param ast the AST object
* @returns copy of the AST object
*/
export function preprocessTypescriptAST<T = TSESTree.Program>(ast: T): T {
return deeplyCopy<T>(ast);
}
Expand Up @@ -132662,7 +132662,7 @@ Object {
"pattern": "foo.",
},
"type": "Literal",
"value": Object {},
"value": /foo\\./,
},
"loc": Object {
"end": Object {
Expand Down Expand Up @@ -132859,7 +132859,7 @@ Object {
"pattern": "[\\\\u{0000000000000061}-\\\\u{7A}]",
},
"type": "Literal",
"value": Object {},
"value": /\\[\\\\u\\{0000000000000061\\}-\\\\u\\{7A\\}\\]/u,
},
"loc": Object {
"end": Object {
Expand Down Expand Up @@ -133253,7 +133253,7 @@ Object {
"pattern": "foo",
},
"type": "Literal",
"value": Object {},
"value": /foo/u,
},
"loc": Object {
"end": Object {
Expand Down Expand Up @@ -133450,7 +133450,7 @@ Object {
"pattern": "foo",
},
"type": "Literal",
"value": Object {},
"value": /foo/y,
},
"loc": Object {
"end": Object {
Expand Down