Skip to content
This repository has been archived by the owner on Jan 14, 2019. It is now read-only.

Commit

Permalink
test: refactor omitDeep function to support name changes (#70)
Browse files Browse the repository at this point in the history
  • Loading branch information
armano2 authored and JamesHenry committed Jan 1, 2019
1 parent 5a1a5ca commit 4b88970
Show file tree
Hide file tree
Showing 7 changed files with 559 additions and 132 deletions.
12 changes: 0 additions & 12 deletions tests/ast-alignment/fixtures-to-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -377,18 +377,6 @@ let fixturePatternConfigsToTest = [
* tsep: TSBigIntKeyword
*/
'typed-keyword-bigint',
/**
* Awaiting feedback on Babel issue https://github.com/babel/babel/issues/9228
* Babel: BooleanLiteral
* tsep: Literal
*/
'typed-keyword-true',
/**
* Not yet supported in Babel https://github.com/babel/babel/issues/9228
* Babel: BooleanLiteral
* tsep: Literal
*/
'typed-keyword-false',
/**
* Not yet supported in Babel https://github.com/babel/babel/issues/9228
* Directive field is not added to module and namespace
Expand Down
187 changes: 102 additions & 85 deletions tests/ast-alignment/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,59 +14,56 @@ export function normalizeNodeTypes(ast: any): any {

/**
* Removes the given keys from the given AST object recursively
* @param {Object} obj A JavaScript object to remove keys from
* @param {Object[]} keysToOmit Names and predicate functions use to determine what keys to omit from the final object
* @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(
obj: any,
keysToOmit: { key: string; predicate: Function }[]
): any {
keysToOmit = keysToOmit || [];
function shouldOmit(keyName: string, val: any) {
if (!keysToOmit || !keysToOmit.length) {
return false;
}
for (const keyConfig of keysToOmit) {
if (keyConfig.key !== keyName) {
continue;
}
return keyConfig.predicate(val);
root: any,
keysToOmit: { key: string; predicate: Function }[],
nodes: Record<string, (node: any, parent: any) => void> = {}
) {
function shouldOmit(keyName: string, val: any): boolean {
if (keysToOmit && keysToOmit.length) {
return keysToOmit.some(
keyConfig => keyConfig.key === keyName && keyConfig.predicate(val)
);
}
return false;
}

for (const key in obj) {
if (!obj.hasOwnProperty(key)) {
continue;
function visit(node: any, parent: any) {
if (!node) {
return;
}
const val = (obj as any)[key];
if (isPlainObject(val)) {
if (shouldOmit(key, val)) {
delete (obj as any)[key];
// re-run with the same arguments
// in case the object has multiple keys to omit
return omitDeep(obj, keysToOmit);
}
omitDeep(val, keysToOmit);
} else if (Array.isArray(val)) {
if (shouldOmit(key, val)) {
delete (obj as any)[key];
// re-run with the same arguments
// in case the object has multiple keys to omit
return omitDeep(obj, keysToOmit);
}
for (const i of val) {
omitDeep(i, keysToOmit);

for (const prop in node) {
if (node.hasOwnProperty(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);
}
}
} else if (shouldOmit(key, val)) {
delete (obj as any)[key];
// re-run with the same arguments
// in case the object has multiple keys to omit
return omitDeep(obj, keysToOmit);
}

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

visit(root, null);
return root;
}

/**
Expand All @@ -84,58 +81,78 @@ const ifNumber = (val: any) => typeof val === 'number';
* @returns {Object} processed babylon AST
*/
export function preprocessBabylonAST(ast: any): any {
return omitDeep(ast.program, [
{
key: 'start',
// only remove the "start" number (not the "start" object within loc)
predicate: ifNumber
},
{
key: 'end',
// only remove the "end" number (not the "end" object within loc)
predicate: ifNumber
},
{
key: 'identifierName',
predicate: always
},
{
key: 'extra',
predicate: always
},
{
key: 'directives',
predicate: always
},
{
key: 'innerComments',
predicate: always
},
{
key: 'leadingComments',
predicate: always
},
{
key: 'trailingComments',
predicate: always
},
{
key: 'guardedHandlers',
predicate: always
},
return omitDeep(
ast.program,
[
{
key: 'start',
// only remove the "start" number (not the "start" object within loc)
predicate: ifNumber
},
{
key: 'end',
// only remove the "end" number (not the "end" object within loc)
predicate: ifNumber
},
{
key: 'identifierName',
predicate: always
},
{
key: 'extra',
predicate: always
},
{
key: 'innerComments',
predicate: always
},
{
key: 'leadingComments',
predicate: always
},
{
key: 'trailingComments',
predicate: always
},
{
key: 'guardedHandlers',
predicate: always
},
{
key: 'interpreter',
predicate: always
}
],
{
key: 'interpreter',
predicate: always
/**
* Not yet supported in Babel https://github.com/babel/babel/issues/9228
*/
StringLiteral(node: any) {
node.type = 'Literal';
},
/**
* Not yet supported in Babel https://github.com/babel/babel/issues/9228
*/
NumericLiteral(node: any) {
node.type = 'Literal';
},
/**
* Not yet supported in Babel https://github.com/babel/babel/issues/9228
*/
BooleanLiteral(node: any) {
node.type = 'Literal';
node.raw = String(node.value);
}
}
]);
);
}

/**
* There is currently a really awkward difference in location data for Program nodes
* between different parsers in the ecosystem. Hack around this by removing the data
* before comparing the ASTs.
*
* See: https://github.com/babel/babylon/issues/673
* 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
Expand Down
1 change: 1 addition & 0 deletions tests/fixtures/typescript/types/literal-number.src.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let x: 0;
1 change: 1 addition & 0 deletions tests/fixtures/typescript/types/literal-string.src.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
let x: "foo";
4 changes: 4 additions & 0 deletions tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -1896,6 +1896,10 @@ exports[`Parse all fixtures with "errorOnTypeScriptSyntaticAndSemanticIssues" en

exports[`Parse all fixtures with "errorOnTypeScriptSyntaticAndSemanticIssues" enabled fixtures/typescript/types/intersection-type.src.ts.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;

exports[`Parse all fixtures with "errorOnTypeScriptSyntaticAndSemanticIssues" enabled fixtures/typescript/types/literal-number.src.ts.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;

exports[`Parse all fixtures with "errorOnTypeScriptSyntaticAndSemanticIssues" enabled fixtures/typescript/types/literal-string.src.ts.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;

exports[`Parse all fixtures with "errorOnTypeScriptSyntaticAndSemanticIssues" enabled fixtures/typescript/types/mapped.src.ts.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;

exports[`Parse all fixtures with "errorOnTypeScriptSyntaticAndSemanticIssues" enabled fixtures/typescript/types/mapped-readonly.src.ts.src 1`] = `"TEST OUTPUT: No semantic or syntactic issues found"`;
Expand Down
Loading

0 comments on commit 4b88970

Please sign in to comment.