From 4b889703015b3e718b5caf507fc5f388d1d2ee07 Mon Sep 17 00:00:00 2001 From: Armano Date: Tue, 1 Jan 2019 20:21:31 +0100 Subject: [PATCH] test: refactor omitDeep function to support name changes (#70) --- tests/ast-alignment/fixtures-to-test.ts | 12 - tests/ast-alignment/utils.ts | 187 ++++---- .../typescript/types/literal-number.src.ts | 1 + .../typescript/types/literal-string.src.ts | 1 + .../semantic-diagnostics-enabled.ts.snap | 4 + tests/lib/__snapshots__/typescript.ts.snap | 448 ++++++++++++++++++ yarn.lock | 38 +- 7 files changed, 559 insertions(+), 132 deletions(-) create mode 100644 tests/fixtures/typescript/types/literal-number.src.ts create mode 100644 tests/fixtures/typescript/types/literal-string.src.ts diff --git a/tests/ast-alignment/fixtures-to-test.ts b/tests/ast-alignment/fixtures-to-test.ts index b0cd1f8..01525c4 100644 --- a/tests/ast-alignment/fixtures-to-test.ts +++ b/tests/ast-alignment/fixtures-to-test.ts @@ -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 diff --git a/tests/ast-alignment/utils.ts b/tests/ast-alignment/utils.ts index 8dbf441..0345ab5 100644 --- a/tests/ast-alignment/utils.ts +++ b/tests/ast-alignment/utils.ts @@ -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 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; } /** @@ -84,50 +81,70 @@ 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); + } } - ]); + ); } /** @@ -135,7 +152,7 @@ export function preprocessBabylonAST(ast: any): any { * 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 diff --git a/tests/fixtures/typescript/types/literal-number.src.ts b/tests/fixtures/typescript/types/literal-number.src.ts new file mode 100644 index 0000000..1e234e3 --- /dev/null +++ b/tests/fixtures/typescript/types/literal-number.src.ts @@ -0,0 +1 @@ +let x: 0; diff --git a/tests/fixtures/typescript/types/literal-string.src.ts b/tests/fixtures/typescript/types/literal-string.src.ts new file mode 100644 index 0000000..926a42a --- /dev/null +++ b/tests/fixtures/typescript/types/literal-string.src.ts @@ -0,0 +1 @@ +let x: "foo"; diff --git a/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap b/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap index 367a390..c83f274 100644 --- a/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap +++ b/tests/lib/__snapshots__/semantic-diagnostics-enabled.ts.snap @@ -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"`; diff --git a/tests/lib/__snapshots__/typescript.ts.snap b/tests/lib/__snapshots__/typescript.ts.snap index a0ad01b..6058064 100644 --- a/tests/lib/__snapshots__/typescript.ts.snap +++ b/tests/lib/__snapshots__/typescript.ts.snap @@ -82208,6 +82208,454 @@ Object { } `; +exports[`typescript fixtures/types/literal-number.src 1`] = ` +Object { + "body": Array [ + Object { + "declarations": Array [ + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "name": "x", + "range": Array [ + 4, + 8, + ], + "type": "Identifier", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "range": Array [ + 5, + 8, + ], + "type": "TSTypeAnnotation", + "typeAnnotation": Object { + "literal": Object { + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 8, + ], + "raw": "0", + "type": "Literal", + "value": 0, + }, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 8, + ], + "type": "TSLiteralType", + }, + }, + }, + "init": null, + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "range": Array [ + 4, + 8, + ], + "type": "VariableDeclarator", + }, + ], + "kind": "let", + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 9, + ], + "type": "VariableDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 10, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 3, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 3, + ], + "type": "Keyword", + "value": "let", + }, + Object { + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "range": Array [ + 4, + 5, + ], + "type": "Identifier", + "value": "x", + }, + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "range": Array [ + 5, + 6, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 8, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 8, + ], + "type": "Numeric", + "value": "0", + }, + Object { + "loc": Object { + "end": Object { + "column": 9, + "line": 1, + }, + "start": Object { + "column": 8, + "line": 1, + }, + }, + "range": Array [ + 8, + 9, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", +} +`; + +exports[`typescript fixtures/types/literal-string.src 1`] = ` +Object { + "body": Array [ + Object { + "declarations": Array [ + Object { + "id": Object { + "loc": Object { + "end": Object { + "column": 12, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "name": "x", + "range": Array [ + 4, + 12, + ], + "type": "Identifier", + "typeAnnotation": Object { + "loc": Object { + "end": Object { + "column": 12, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "range": Array [ + 5, + 12, + ], + "type": "TSTypeAnnotation", + "typeAnnotation": Object { + "literal": Object { + "loc": Object { + "end": Object { + "column": 12, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 12, + ], + "raw": "\\"foo\\"", + "type": "Literal", + "value": "foo", + }, + "loc": Object { + "end": Object { + "column": 12, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 12, + ], + "type": "TSLiteralType", + }, + }, + }, + "init": null, + "loc": Object { + "end": Object { + "column": 12, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "range": Array [ + 4, + 12, + ], + "type": "VariableDeclarator", + }, + ], + "kind": "let", + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 13, + ], + "type": "VariableDeclaration", + }, + ], + "loc": Object { + "end": Object { + "column": 0, + "line": 2, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 14, + ], + "sourceType": "script", + "tokens": Array [ + Object { + "loc": Object { + "end": Object { + "column": 3, + "line": 1, + }, + "start": Object { + "column": 0, + "line": 1, + }, + }, + "range": Array [ + 0, + 3, + ], + "type": "Keyword", + "value": "let", + }, + Object { + "loc": Object { + "end": Object { + "column": 5, + "line": 1, + }, + "start": Object { + "column": 4, + "line": 1, + }, + }, + "range": Array [ + 4, + 5, + ], + "type": "Identifier", + "value": "x", + }, + Object { + "loc": Object { + "end": Object { + "column": 6, + "line": 1, + }, + "start": Object { + "column": 5, + "line": 1, + }, + }, + "range": Array [ + 5, + 6, + ], + "type": "Punctuator", + "value": ":", + }, + Object { + "loc": Object { + "end": Object { + "column": 12, + "line": 1, + }, + "start": Object { + "column": 7, + "line": 1, + }, + }, + "range": Array [ + 7, + 12, + ], + "type": "String", + "value": "\\"foo\\"", + }, + Object { + "loc": Object { + "end": Object { + "column": 13, + "line": 1, + }, + "start": Object { + "column": 12, + "line": 1, + }, + }, + "range": Array [ + 12, + 13, + ], + "type": "Punctuator", + "value": ";", + }, + ], + "type": "Program", +} +`; + exports[`typescript fixtures/types/mapped.src 1`] = ` Object { "body": Array [ diff --git a/yarn.lock b/yarn.lock index 9333764..65a041d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2279,7 +2279,7 @@ debug@^4.0.0, debug@^4.1.0: dependencies: ms "^2.1.1" -debuglog@*, debuglog@^1.0.1: +debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI= @@ -3470,7 +3470,7 @@ import-local@^1.0.0: pkg-dir "^2.0.0" resolve-cwd "^2.0.0" -imurmurhash@*, imurmurhash@^0.1.4: +imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= @@ -4677,11 +4677,6 @@ lockfile@^1.0.4: dependencies: signal-exit "^3.0.2" -lodash._baseindexof@*: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c" - integrity sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw= - lodash._baseuniq@~4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8" @@ -4690,33 +4685,11 @@ lodash._baseuniq@~4.6.0: lodash._createset "~4.0.0" lodash._root "~3.0.0" -lodash._bindcallback@*: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" - integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4= - -lodash._cacheindexof@*: - version "3.0.2" - resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92" - integrity sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI= - -lodash._createcache@*: - version "3.1.2" - resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093" - integrity sha1-VtagZAF2JeeevKa4AY4XRAvc8JM= - dependencies: - lodash._getnative "^3.0.0" - lodash._createset@~4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26" integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY= -lodash._getnative@*, lodash._getnative@^3.0.0: - version "3.9.1" - resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" - integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U= - lodash._reinterpolate@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" @@ -4797,11 +4770,6 @@ lodash.pick@4.4.0, lodash.pick@^4.4.0: resolved "https://registry.yarnpkg.com/lodash.pick/-/lodash.pick-4.4.0.tgz#52f05610fff9ded422611441ed1fc123a03001b3" integrity sha1-UvBWEP/53tQiYRRB7R/BI6AwAbM= -lodash.restparam@*: - version "3.6.1" - resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" - integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU= - lodash.set@^4.3.2: version "4.3.2" resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" @@ -6523,7 +6491,7 @@ readable-stream@~1.1.10: isarray "0.0.1" string_decoder "~0.10.x" -readdir-scoped-modules@*, readdir-scoped-modules@^1.0.0: +readdir-scoped-modules@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz#9fafa37d286be5d92cbaebdee030dc9b5f406747" integrity sha1-n6+jfShr5dksuuve4DDcm19AZ0c=