From 9e1658355f0d626fd1c80697c5b4628bf4b10324 Mon Sep 17 00:00:00 2001 From: uittorio Date: Sun, 12 Jan 2020 11:54:14 +0000 Subject: [PATCH 1/2] add support for multiple declarations functions for types and values, refactoring internal ts auto mock variables names to be in one place, reset playground file --- config/test/webpack.js | 2 +- src/transformer/descriptor/descriptor.ts | 2 ++ src/transformer/descriptor/helper/helper.ts | 20 ++++++++++++++++++- src/transformer/descriptor/mock/mockCall.ts | 8 +++----- .../descriptor/mock/mockDeclarationName.ts | 13 ------------ .../descriptor/mock/mockProperty.ts | 8 +++----- .../descriptor/typeParameter/typeParameter.ts | 8 ++++---- .../descriptor/typeQuery/typeQuery.ts | 2 +- .../genericDeclaration/genericDeclaration.ts | 6 +++--- src/transformer/log.ts | 17 ++++++++++++++++ src/transformer/mock/mock.ts | 1 - src/transformer/mockDefiner/mockDefiner.ts | 4 ++-- .../mockFactoryCall/mockFactoryCall.ts | 4 ++-- .../mockGeneric/mockGenericParameter.ts | 5 ----- .../mockIdentifier/mockIdentifier.ts | 8 ++++++++ test/playground/enums.ts | 5 ----- test/playground/playground.test.ts | 16 ++++++--------- .../declarations/declarations.test.ts | 17 ++++++++++++++++ .../descriptor/typeQuery/typeQuery.test.ts | 20 ++++++++++++++++++- 19 files changed, 107 insertions(+), 59 deletions(-) delete mode 100644 src/transformer/descriptor/mock/mockDeclarationName.ts create mode 100644 src/transformer/log.ts delete mode 100644 src/transformer/mockGeneric/mockGenericParameter.ts create mode 100644 src/transformer/mockIdentifier/mockIdentifier.ts delete mode 100644 test/playground/enums.ts diff --git a/config/test/webpack.js b/config/test/webpack.js index 5c36e2375..7a2812a50 100644 --- a/config/test/webpack.js +++ b/config/test/webpack.js @@ -25,7 +25,7 @@ module.exports = function (debug, disableCache) { options: { getCustomTransformers: (program) => ({ before: [transformer.default(program, { - debug: debug ? 'file' : false, + debug: debug ? debug : false, cacheBetweenTests: disableCache !== 'true' })] }) diff --git a/src/transformer/descriptor/descriptor.ts b/src/transformer/descriptor/descriptor.ts index 4f170e490..4abfe9713 100644 --- a/src/transformer/descriptor/descriptor.ts +++ b/src/transformer/descriptor/descriptor.ts @@ -116,6 +116,8 @@ export function GetDescriptor(node: ts.Node, scope: Scope): ts.Expression { case ts.SyntaxKind.IndexedAccessType: return GetIndexedAccessTypeDescriptor(node as ts.IndexedAccessTypeNode, scope); case ts.SyntaxKind.BooleanKeyword: + case ts.SyntaxKind.TypePredicate: + case ts.SyntaxKind.FirstTypeNode: return GetBooleanDescriptor(); case ts.SyntaxKind.ObjectKeyword: return GetMockPropertiesFromSymbol([], [], scope); diff --git a/src/transformer/descriptor/helper/helper.ts b/src/transformer/descriptor/helper/helper.ts index 6448b6adc..774e9a43c 100644 --- a/src/transformer/descriptor/helper/helper.ts +++ b/src/transformer/descriptor/helper/helper.ts @@ -29,6 +29,16 @@ export namespace TypescriptHelper { return declaration; } + export function GetConcreteDeclarationFromSymbol(symbol: ts.Symbol): ts.Declaration { + const declaration: ts.Declaration = symbol.declarations[0]; + + if (ts.isImportSpecifier(declaration) || ts.isImportEqualsDeclaration(declaration)) { + return GetConcreteDeclarationForImport(declaration); + } + + return declaration; + } + export function GetDeclarationForImport(node: ts.ImportClause | ts.ImportSpecifier | ts.ImportEqualsDeclaration): ts.Declaration { const typeChecker: ts.TypeChecker = TypeChecker(); const symbol: ts.Symbol = typeChecker.getSymbolAtLocation(node.name); @@ -37,6 +47,14 @@ export namespace TypescriptHelper { return GetFirstValidDeclaration(originalSymbol.declarations); } + export function GetConcreteDeclarationForImport(node: ts.ImportClause | ts.ImportSpecifier | ts.ImportEqualsDeclaration): ts.Declaration { + const typeChecker: ts.TypeChecker = TypeChecker(); + const symbol: ts.Symbol = typeChecker.getSymbolAtLocation(node.name); + const originalSymbol: ts.Symbol = typeChecker.getAliasedSymbol(symbol); + + return originalSymbol.declarations[0]; + } + export function GetParameterOfNode(node: ts.EntityName): ts.NodeArray { const declaration: ts.Declaration = GetDeclarationFromNode(node); @@ -73,7 +91,7 @@ export namespace TypescriptHelper { function GetFirstValidDeclaration(declarations: ts.Declaration[]): ts.Declaration { return declarations.find((declaration: ts.Declaration) => { - return !ts.isVariableDeclaration(declaration); + return !ts.isVariableDeclaration(declaration) && !ts.isFunctionDeclaration(declaration); }) || declarations[0]; } diff --git a/src/transformer/descriptor/mock/mockCall.ts b/src/transformer/descriptor/mock/mockCall.ts index 02b721675..ba74c3cba 100644 --- a/src/transformer/descriptor/mock/mockCall.ts +++ b/src/transformer/descriptor/mock/mockCall.ts @@ -1,15 +1,13 @@ import * as ts from 'typescript'; import { TypescriptCreator } from '../../helper/creator'; -import { GetMockInternalValuesName, GetMockObjectReturnValueName } from './mockDeclarationName'; +import { MockIdentifierInternalValues, MockIdentifierObjectReturnValue } from '../../mockIdentifier/mockIdentifier'; import { GetMockMarkerProperty, Property } from './mockMarker'; export function GetMockCall(properties: ts.PropertyAssignment[], signature: ts.Expression): ts.CallExpression { - const mockObjectReturnValueName: ts.Identifier = GetMockObjectReturnValueName(); - const mockInternalValuesName: ts.Identifier = GetMockInternalValuesName(); - + const mockObjectReturnValueName: ts.Identifier = MockIdentifierObjectReturnValue; const statements: ts.Statement[] = [ ts.createVariableStatement([], [ - TypescriptCreator.createVariableDeclaration(mockInternalValuesName, ts.createObjectLiteral()), + TypescriptCreator.createVariableDeclaration(MockIdentifierInternalValues, ts.createObjectLiteral()), TypescriptCreator.createVariableDeclaration(mockObjectReturnValueName, ts.createObjectLiteral()), ]), ]; diff --git a/src/transformer/descriptor/mock/mockDeclarationName.ts b/src/transformer/descriptor/mock/mockDeclarationName.ts deleted file mode 100644 index 4d37fe751..000000000 --- a/src/transformer/descriptor/mock/mockDeclarationName.ts +++ /dev/null @@ -1,13 +0,0 @@ -import * as ts from 'typescript'; - -export function GetMockInternalValuesName(): ts.Identifier { - return ts.createIdentifier('declarations'); -} - -export function GetMockObjectReturnValueName(): ts.Identifier { - return ts.createIdentifier('mockObjectReturnValue'); -} - -export function GetMockSetParameterName(): ts.Identifier { - return ts.createIdentifier('value'); -} diff --git a/src/transformer/descriptor/mock/mockProperty.ts b/src/transformer/descriptor/mock/mockProperty.ts index 856bcebea..33bf3fdc7 100644 --- a/src/transformer/descriptor/mock/mockProperty.ts +++ b/src/transformer/descriptor/mock/mockProperty.ts @@ -1,9 +1,9 @@ import * as ts from 'typescript'; import { TypescriptCreator } from '../../helper/creator'; +import { MockIdentifierInternalValues, MockIdentifierSetParameterName } from '../../mockIdentifier/mockIdentifier'; import { Scope } from '../../scope/scope'; import { GetDescriptor } from '../descriptor'; import { TypescriptHelper } from '../helper/helper'; -import { GetMockInternalValuesName, GetMockSetParameterName } from './mockDeclarationName'; import { PropertyLike } from './propertyLike'; export function GetMockProperty(member: PropertyLike, scope: Scope): ts.PropertyAssignment { @@ -11,10 +11,8 @@ export function GetMockProperty(member: PropertyLike, scope: Scope): ts.Property const propertyName: string = TypescriptHelper.GetStringPropertyName(member.name); - const declarations: ts.Identifier = GetMockInternalValuesName(); - - const variableDeclarationName: ts.ElementAccessExpression = ts.createElementAccess(declarations, ts.createStringLiteral(propertyName)); - const setVariableParameterName: ts.Identifier = GetMockSetParameterName(); + const variableDeclarationName: ts.ElementAccessExpression = ts.createElementAccess(MockIdentifierInternalValues, ts.createStringLiteral(propertyName)); + const setVariableParameterName: ts.Identifier = MockIdentifierSetParameterName; const expressionGetAssignment: ts.BinaryExpression = ts.createBinary(variableDeclarationName, ts.SyntaxKind.EqualsToken, descriptor); diff --git a/src/transformer/descriptor/typeParameter/typeParameter.ts b/src/transformer/descriptor/typeParameter/typeParameter.ts index 821ca2380..aa80d09b3 100644 --- a/src/transformer/descriptor/typeParameter/typeParameter.ts +++ b/src/transformer/descriptor/typeParameter/typeParameter.ts @@ -1,7 +1,7 @@ import * as ts from 'typescript'; import { TypescriptCreator } from '../../helper/creator'; import { MockDefiner } from '../../mockDefiner/mockDefiner'; -import { MockGenericParameter, MockGenericParameterIds, MockGenericParameterValue } from '../../mockGeneric/mockGenericParameter'; +import { MockIdentifierGenericParameter, MockIdentifierGenericParameterIds, MockIdentifierGenericParameterValue } from '../../mockIdentifier/mockIdentifier'; import { Scope } from '../../scope/scope'; import { TypeChecker } from '../../typeChecker/typeChecker'; import { GetDescriptor } from '../descriptor'; @@ -43,7 +43,7 @@ function createFunctionToAccessToGenericValue(key: string, descriptor: ts.Expres function createFindGeneric(genericKey: string): ts.CallExpression { return ts.createCall( ts.createPropertyAccess( - MockGenericParameter, + MockIdentifierGenericParameter, ts.createIdentifier('find'), ), undefined, @@ -53,7 +53,7 @@ function createFindGeneric(genericKey: string): ts.CallExpression { ts.createPropertyAccess( ts.createPropertyAccess( ts.createIdentifier('generic'), - MockGenericParameterIds, + MockIdentifierGenericParameterIds, ), ts.createIdentifier('indexOf'), ), @@ -89,7 +89,7 @@ function getValueFromGenericIfExist(): ts.IfStatement { [ts.createReturn(ts.createCall( ts.createPropertyAccess( ts.createIdentifier('generic'), - MockGenericParameterValue, + MockIdentifierGenericParameterValue, ), undefined, [], diff --git a/src/transformer/descriptor/typeQuery/typeQuery.ts b/src/transformer/descriptor/typeQuery/typeQuery.ts index cd7632283..cad8bd8ae 100644 --- a/src/transformer/descriptor/typeQuery/typeQuery.ts +++ b/src/transformer/descriptor/typeQuery/typeQuery.ts @@ -93,5 +93,5 @@ function getTypeQueryDeclarationFromSymbol(symbol: ts.Symbol): ts.NamedDeclarati return declaration; } - return TypescriptHelper.GetDeclarationFromSymbol(symbol); + return TypescriptHelper.GetConcreteDeclarationFromSymbol(symbol); } diff --git a/src/transformer/genericDeclaration/genericDeclaration.ts b/src/transformer/genericDeclaration/genericDeclaration.ts index 481ce9070..7c614e1ee 100644 --- a/src/transformer/genericDeclaration/genericDeclaration.ts +++ b/src/transformer/genericDeclaration/genericDeclaration.ts @@ -2,7 +2,7 @@ import * as ts from 'typescript'; import { GetDescriptor } from '../descriptor/descriptor'; import { TypescriptHelper } from '../descriptor/helper/helper'; import { TypescriptCreator } from '../helper/creator'; -import { MockGenericParameterIds, MockGenericParameterValue } from '../mockGeneric/mockGenericParameter'; +import { MockIdentifierGenericParameterIds, MockIdentifierGenericParameterValue } from '../mockIdentifier/mockIdentifier'; import { Scope } from '../scope/scope'; import { IGenericDeclaration } from './genericDeclaration.interface'; import { GenericDeclarationSupported } from './genericDeclarationSupported'; @@ -110,7 +110,7 @@ export function GenericDeclaration(scope: Scope): IGenericDeclaration { return ts.createObjectLiteral( [ ts.createPropertyAssignment( - MockGenericParameterIds, + MockIdentifierGenericParameterIds, ts.createArrayLiteral( s.ids.map((arr: string) => { return ts.createStringLiteral(arr); @@ -119,7 +119,7 @@ export function GenericDeclaration(scope: Scope): IGenericDeclaration { ), ), ts.createPropertyAssignment( - MockGenericParameterValue, + MockIdentifierGenericParameterValue, s.value, ), ], diff --git a/src/transformer/log.ts b/src/transformer/log.ts new file mode 100644 index 000000000..d5d54ff19 --- /dev/null +++ b/src/transformer/log.ts @@ -0,0 +1,17 @@ +import * as ts from 'typescript'; +import { Logger } from '../logger/logger'; +import { ILogger } from '../logger/logger.interface'; +const PrintNodeLogger: ILogger = Logger('PrintNode'); + +export function PrintNode(node: ts.Node): void { + const resultFile: ts.SourceFile = ts.createSourceFile('someFileName.ts', '', ts.ScriptTarget.Latest, /*setParentNodes*/ false, ts.ScriptKind.TS); + const printer: ts.Printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed }); + + try { + const result: string = printer.printNode(ts.EmitHint.Unspecified, node, resultFile); + PrintNodeLogger.info(result); + } catch (e) { + PrintNodeLogger.warning('There was an error printing the node'); + } + +} diff --git a/src/transformer/mock/mock.ts b/src/transformer/mock/mock.ts index 342be224b..c358df284 100644 --- a/src/transformer/mock/mock.ts +++ b/src/transformer/mock/mock.ts @@ -3,7 +3,6 @@ import { Logger } from '../../logger/logger'; import { ArrayHelper } from '../array/array'; import { GetDescriptor } from '../descriptor/descriptor'; import { TypescriptHelper } from '../descriptor/helper/helper'; -import { TypescriptCreator } from '../helper/creator'; import { getMockMergeExpression, getMockMergeIteratorExpression } from '../mergeExpression/mergeExpression'; import { MockDefiner } from '../mockDefiner/mockDefiner'; import { Scope } from '../scope/scope'; diff --git a/src/transformer/mockDefiner/mockDefiner.ts b/src/transformer/mockDefiner/mockDefiner.ts index b3b0c6f3e..cebb1a333 100644 --- a/src/transformer/mockDefiner/mockDefiner.ts +++ b/src/transformer/mockDefiner/mockDefiner.ts @@ -5,7 +5,7 @@ import { GetProperties } from '../descriptor/properties/properties'; import { GetTypeofEnumDescriptor } from '../descriptor/typeQuery/enumTypeQuery'; import { TypescriptCreator } from '../helper/creator'; import { createImportOnIdentifier } from '../helper/import'; -import { MockGenericParameter } from '../mockGeneric/mockGenericParameter'; +import { MockIdentifierGenericParameter } from '../mockIdentifier/mockIdentifier'; import { Scope } from '../scope/scope'; import { DeclarationCache } from './cache/declarationCache'; import { DeclarationListCache } from './cache/declarationListCache'; @@ -312,6 +312,6 @@ export class MockDefiner { } private _getMockGenericParameter(): ts.ParameterDeclaration { - return ts.createParameter([], [], undefined, MockGenericParameter); + return ts.createParameter([], [], undefined, MockIdentifierGenericParameter); } } diff --git a/src/transformer/mockFactoryCall/mockFactoryCall.ts b/src/transformer/mockFactoryCall/mockFactoryCall.ts index b04da3378..3ad0890a5 100644 --- a/src/transformer/mockFactoryCall/mockFactoryCall.ts +++ b/src/transformer/mockFactoryCall/mockFactoryCall.ts @@ -4,7 +4,7 @@ import { GenericDeclaration } from '../genericDeclaration/genericDeclaration'; import { IGenericDeclaration } from '../genericDeclaration/genericDeclaration.interface'; import { GenericDeclarationSupported } from '../genericDeclaration/genericDeclarationSupported'; import { MockDefiner } from '../mockDefiner/mockDefiner'; -import { MockGenericParameter } from '../mockGeneric/mockGenericParameter'; +import { MockIdentifierGenericParameter } from '../mockIdentifier/mockIdentifier'; import { Scope } from '../scope/scope'; export function GetMockFactoryCall(typeReferenceNode: ts.TypeReferenceNode, scope: Scope): ts.Expression { @@ -63,7 +63,7 @@ export function GetMockFactoryCallForThis(mockKey: string): ts.Expression { return ts.createCall( mockFactoryCall, [], - [MockGenericParameter], + [MockIdentifierGenericParameter], ); } diff --git a/src/transformer/mockGeneric/mockGenericParameter.ts b/src/transformer/mockGeneric/mockGenericParameter.ts deleted file mode 100644 index 95c6fbacb..000000000 --- a/src/transformer/mockGeneric/mockGenericParameter.ts +++ /dev/null @@ -1,5 +0,0 @@ -import * as ts from 'typescript'; - -export const MockGenericParameter: ts.Identifier = ts.createIdentifier('__tsAutoMockGenericParameter'); -export const MockGenericParameterIds: ts.Identifier = ts.createIdentifier('ids'); -export const MockGenericParameterValue: ts.Identifier = ts.createIdentifier('value'); diff --git a/src/transformer/mockIdentifier/mockIdentifier.ts b/src/transformer/mockIdentifier/mockIdentifier.ts new file mode 100644 index 000000000..572c76047 --- /dev/null +++ b/src/transformer/mockIdentifier/mockIdentifier.ts @@ -0,0 +1,8 @@ +import * as ts from 'typescript'; + +export const MockIdentifierGenericParameter: ts.Identifier = ts.createIdentifier('t'); +export const MockIdentifierGenericParameterIds: ts.Identifier = ts.createIdentifier('i'); +export const MockIdentifierGenericParameterValue: ts.Identifier = ts.createIdentifier('w'); +export const MockIdentifierInternalValues: ts.Identifier = ts.createIdentifier('d'); +export const MockIdentifierObjectReturnValue: ts.Identifier = ts.createIdentifier('m'); +export const MockIdentifierSetParameterName: ts.Identifier = ts.createIdentifier('v'); diff --git a/test/playground/enums.ts b/test/playground/enums.ts deleted file mode 100644 index 814df06f4..000000000 --- a/test/playground/enums.ts +++ /dev/null @@ -1,5 +0,0 @@ -export enum MyEnum { - A, - B, - C = "OK" -} \ No newline at end of file diff --git a/test/playground/playground.test.ts b/test/playground/playground.test.ts index 904bf5c61..7b4a5dbea 100644 --- a/test/playground/playground.test.ts +++ b/test/playground/playground.test.ts @@ -1,5 +1,4 @@ -import { createMock, registerMock } from 'ts-auto-mock'; -import { MyEnum } from './enums'; +import { createMock } from 'ts-auto-mock'; /* USE THIS FILE ONLY FOR TESTING NEW IMPLEMENTATION @@ -10,13 +9,10 @@ import { MyEnum } from './enums'; */ it('should work', () => { - interface A { - a: string; - } - const enumm2: typeof MyEnum = createMock(); - expect(createMock().a).toBe("ok"); + interface A { + a: string; + } - expect(enumm2.A).toEqual(0); - - expect(createMock().a).toBe("ok"); + const type: A = createMock(); + expect(type).toBeDefined(); }); diff --git a/test/transformer/descriptor/declarations/declarations.test.ts b/test/transformer/descriptor/declarations/declarations.test.ts index 88d23cb06..e69273492 100644 --- a/test/transformer/descriptor/declarations/declarations.test.ts +++ b/test/transformer/descriptor/declarations/declarations.test.ts @@ -135,6 +135,23 @@ describe('declarations', () => { }); }); + describe('function and interface', () => { + // @ts-ignore + interface AAA { + b: number + } + + function AAA(): AAA { + // @ts-ignore + return { a: 'ss' }; + } + + it('should return the properties from the interface', () => { + const properties: AAA = createMock(); + expect(properties.b).toBe(0); + }); + }); + describe('interface imported', () => { it('should ignore variables declaration', () => { const properties: MultipleInterfaceDeclaration = createMock(); diff --git a/test/transformer/descriptor/typeQuery/typeQuery.test.ts b/test/transformer/descriptor/typeQuery/typeQuery.test.ts index 6675761c7..4c6a0245f 100644 --- a/test/transformer/descriptor/typeQuery/typeQuery.test.ts +++ b/test/transformer/descriptor/typeQuery/typeQuery.test.ts @@ -58,6 +58,24 @@ describe('typeQuery', () => { expect(functionMock).toBeUndefined(); }); + + it('should return correct properties with multiple declarations', () => { + function MultipleDeclaration(): MultipleDeclaration { + // @ts-ignore + return { a: 's'}; + } + + interface MultipleDeclaration { + b: string; + } + + const functionMock: typeof MultipleDeclaration = createMock(); + + // @ts-ignore + expect(functionMock()).toEqual({ + b: '', + }); + }); }); describe('for class', () => { @@ -102,7 +120,7 @@ describe('typeQuery', () => { it('should assign the enum to the mock', () => { enum Enum { A, - B = 'some' + B = 'some', } const enumMock: typeof Enum = createMock(); From 77bd8e224d7761653f1f78ad72c58594b59688d0 Mon Sep 17 00:00:00 2001 From: Vittorio Guerriero Date: Mon, 13 Jan 2020 04:04:54 +0000 Subject: [PATCH 2/2] rename print node and move instantiation inside function --- src/transformer/{log.ts => printNode.ts} | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) rename src/transformer/{log.ts => printNode.ts} (91%) diff --git a/src/transformer/log.ts b/src/transformer/printNode.ts similarity index 91% rename from src/transformer/log.ts rename to src/transformer/printNode.ts index d5d54ff19..67a85fb79 100644 --- a/src/transformer/log.ts +++ b/src/transformer/printNode.ts @@ -1,9 +1,10 @@ import * as ts from 'typescript'; import { Logger } from '../logger/logger'; import { ILogger } from '../logger/logger.interface'; -const PrintNodeLogger: ILogger = Logger('PrintNode'); export function PrintNode(node: ts.Node): void { + const PrintNodeLogger: ILogger = Logger('PrintNode'); + const resultFile: ts.SourceFile = ts.createSourceFile('someFileName.ts', '', ts.ScriptTarget.Latest, /*setParentNodes*/ false, ts.ScriptKind.TS); const printer: ts.Printer = ts.createPrinter({ newLine: ts.NewLineKind.LineFeed });