diff --git a/src/utils/__tests__/__snapshots__/resolveGenericTypeAnnotations-test.ts.snap b/src/utils/__tests__/__snapshots__/resolveGenericTypeAnnotations-test.ts.snap new file mode 100644 index 00000000000..3c8de4cee8d --- /dev/null +++ b/src/utils/__tests__/__snapshots__/resolveGenericTypeAnnotations-test.ts.snap @@ -0,0 +1,106 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`resolveGenericTypeAnnotation resolves type 1`] = ` +Node { + "callProperties": Array [], + "end": 57, + "exact": false, + "extra": undefined, + "indexers": Array [], + "inexact": false, + "innerComments": undefined, + "internalSlots": Array [], + "leadingComments": undefined, + "loc": SourceLocation { + "end": Position { + "column": 34, + "line": 3, + }, + "filename": undefined, + "identifierName": undefined, + "start": Position { + "column": 21, + "line": 3, + }, + }, + "properties": Array [ + Node { + "end": 55, + "extra": undefined, + "innerComments": undefined, + "key": Node { + "end": 47, + "extra": undefined, + "innerComments": undefined, + "leadingComments": undefined, + "loc": SourceLocation { + "end": Position { + "column": 24, + "line": 3, + }, + "filename": undefined, + "identifierName": "x", + "start": Position { + "column": 23, + "line": 3, + }, + }, + "name": "x", + "range": undefined, + "start": 46, + "trailingComments": undefined, + "type": "Identifier", + }, + "kind": "init", + "leadingComments": undefined, + "loc": SourceLocation { + "end": Position { + "column": 32, + "line": 3, + }, + "filename": undefined, + "identifierName": undefined, + "start": Position { + "column": 23, + "line": 3, + }, + }, + "method": false, + "optional": false, + "proto": false, + "range": undefined, + "start": 46, + "static": false, + "trailingComments": undefined, + "type": "ObjectTypeProperty", + "value": Node { + "end": 55, + "extra": undefined, + "innerComments": undefined, + "leadingComments": undefined, + "loc": SourceLocation { + "end": Position { + "column": 32, + "line": 3, + }, + "filename": undefined, + "identifierName": undefined, + "start": Position { + "column": 26, + "line": 3, + }, + }, + "range": undefined, + "start": 49, + "trailingComments": undefined, + "type": "StringTypeAnnotation", + }, + "variance": null, + }, + ], + "range": undefined, + "start": 44, + "trailingComments": undefined, + "type": "ObjectTypeAnnotation", +} +`; diff --git a/src/utils/__tests__/expressionTo-test.ts b/src/utils/__tests__/expressionTo-test.ts new file mode 100644 index 00000000000..be2774ea57c --- /dev/null +++ b/src/utils/__tests__/expressionTo-test.ts @@ -0,0 +1,42 @@ +import { expression, noopImporter } from '../../../tests/utils'; +import { Array as expressionToArray } from '../expressionTo'; + +describe('expressionTo', () => { + describe('MemberExpression', () => { + it('with only identifiers', () => { + expect( + expressionToArray(expression('foo.bar.baz'), noopImporter), + ).toEqual(['foo', 'bar', 'baz']); + }); + + it('with one computed literal', () => { + expect( + expressionToArray(expression('foo["bar"].baz'), noopImporter), + ).toEqual(['foo', '"bar"', 'baz']); + }); + + it('with one computed identifier', () => { + expect( + expressionToArray(expression('foo[bar].baz'), noopImporter), + ).toEqual(['foo', 'bar', 'baz']); + }); + + it('with one computed object', () => { + expect( + expressionToArray(expression('foo[{ a: "true"}].baz'), noopImporter), + ).toEqual(['foo', '{a: "true"}', 'baz']); + }); + + it('with one computed object with spread', () => { + expect( + expressionToArray(expression('foo[{ ...a }].baz'), noopImporter), + ).toEqual(['foo', '{...a}', 'baz']); + }); + + it('with one computed object with method', () => { + expect( + expressionToArray(expression('foo[{ a(){} }].baz'), noopImporter), + ).toEqual(['foo', '{a: }', 'baz']); + }); + }); +}); diff --git a/src/utils/__tests__/isUnreachableFlowType-test.ts b/src/utils/__tests__/isUnreachableFlowType-test.ts new file mode 100644 index 00000000000..6edd0df1e45 --- /dev/null +++ b/src/utils/__tests__/isUnreachableFlowType-test.ts @@ -0,0 +1,20 @@ +import { expression, statement } from '../../../tests/utils'; +import isUnreachableFlowType from '../isUnreachableFlowType'; + +describe('isUnreachableFlowType', () => { + it('considers Identifier as unreachable', () => { + expect(isUnreachableFlowType(expression('foo'))).toBe(true); + }); + + it('considers ImportDeclaration as unreachable', () => { + expect(isUnreachableFlowType(statement('import x from "";'))).toBe(true); + }); + + it('considers CallExpression as unreachable', () => { + expect(isUnreachableFlowType(expression('foo()'))).toBe(true); + }); + + it('considers VariableDeclaration not as unreachable', () => { + expect(isUnreachableFlowType(statement('const x = 1;'))).toBe(false); + }); +}); diff --git a/src/utils/__tests__/resolveGenericTypeAnnotations-test.ts b/src/utils/__tests__/resolveGenericTypeAnnotations-test.ts new file mode 100644 index 00000000000..94fe5874455 --- /dev/null +++ b/src/utils/__tests__/resolveGenericTypeAnnotations-test.ts @@ -0,0 +1,23 @@ +import { statement, noopImporter } from '../../../tests/utils'; +import resolveGenericTypeAnnotation from '../resolveGenericTypeAnnotation'; + +describe('resolveGenericTypeAnnotation', () => { + it('resolves type', () => { + const code = ` + var x: Props; + type Props = { x: string }; + `; + expect( + resolveGenericTypeAnnotation( + statement(code).get( + 'declarations', + 0, + 'id', + 'typeAnnotation', + 'typeAnnotation', + ), + noopImporter, + ), + ).toMatchSnapshot(); + }); +}); diff --git a/src/utils/expressionTo.ts b/src/utils/expressionTo.ts index d9467cb0b55..db4ab6407b8 100644 --- a/src/utils/expressionTo.ts +++ b/src/utils/expressionTo.ts @@ -40,16 +40,23 @@ function toArray(path: NodePath, importer: Importer): string[] { // @ts-ignore result.push(node.raw); continue; + } else if (t.FunctionExpression.check(node)) { + result.push(''); + continue; } else if (t.ThisExpression.check(node)) { result.push('this'); continue; } else if (t.ObjectExpression.check(node)) { const properties = path.get('properties').map(function (property) { - return ( - toString(property.get('key'), importer) + - ': ' + - toString(property.get('value'), importer) - ); + if (t.SpreadElement.check(property.node)) { + return `...${toString(property.get('argument'), importer)}`; + } else { + return ( + toString(property.get('key'), importer) + + ': ' + + toString(property.get('value'), importer) + ); + } }); result.push('{' + properties.join(', ') + '}'); continue;