Skip to content

Commit

Permalink
test(typescript-estree): correct storing regexp in snapshots (#1393)
Browse files Browse the repository at this point in the history
  • Loading branch information
armano2 authored and bradzacher committed Jan 2, 2020
1 parent 3623cde commit c5ffe88
Show file tree
Hide file tree
Showing 9 changed files with 128 additions and 138 deletions.
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
* 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

0 comments on commit c5ffe88

Please sign in to comment.