Skip to content

Commit

Permalink
feat(hydrate-mocks): add create-hydrated-mock functionality
Browse files Browse the repository at this point in the history
* refactor(hydrate-mocks): remove duplicated code

* refactor(hydrate-mocks): revert changes

* feat(hydrate-mocks): red - add create-hydrated-mock type and transformation

* feat(hydrate-mocks): green - add support for basic createHydratedMock

* feat(hydrate-mocks): green - add support for union types

* feat(hydrate-mocks): green - make sure undefined union types will result in undefined

* feat(hydrate-mocks): green - refactor tests

* feat(hydrate-mocks): green - remove unnecessary check

* feat(hydrate-mocks): refactor - rename test file

* feat(hydrate-mocks): refactor - rename test description

* feat(hydrate-mocks): red - make sure createHydratedMock doesn't is independent from createMock

* feat(hydrate-mocks): red - remove unnecessary check in the test

* feat(hydrate-mocks): green - always returns a new mock when is hydrated

* feat(hydrate-mocks): red - add test when creatingMock with createMock after a mock has been created with createHydratedMock

* feat(hydrate-mocks): green - duplicate all the cache (declaration, factory and file registration) to support hydrated mocks

* feat(hydrate-mocks): refactor - extract modulesNameIdentifierPerFile

* feat(hydrate-mocks): green - add hydrated initial generic support

* feat(hydrate-mocks): red - add hydrated tests for generic with extends

* feat(hydrate-mocks): green - use the correct mock for generic extensions

* feat(hydrate-mocks): green - run createHydratedMock on ci

* feat(hydrate-mocks): green - add support for circular generic extensions

* feat(hydrate-mocks): green - add support for register mock

* feat(hydrate-mocks): green - add test for type of enum

* feat(hydrate-mocks): green - add test to make sure createMock and createHydratedMocks are independent

* feat(hydrate-mocks): green - add support for intersections

* feat(hydrate-mocks): refactor - create a function to handle type of declaration based on scope

* feat(hydrate-mocks): refactor - create clone static method on Scope so it will be easier to carry hydrated when creating a new scope

* feat(hydrate-mocks): refactor - remove duplicated code in register mock

* feat(hydrate-mocks): doc - add createHydratedMock documentation
  • Loading branch information
uittorio authored Jan 6, 2021
1 parent 34fa458 commit aa2ebad
Show file tree
Hide file tree
Showing 20 changed files with 667 additions and 137 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,12 @@
"build:transformer:definitelyTyped": "webpack --config config/modules/definitelyTypedTransformer/webpack.functions.js && webpack --config config/modules/definitelyTypedTransformer/webpack.js",
"build:transformer:definitelyTyped:debug": "cross-env DEBUG=true webpack --config config/modules/definitelyTypedTransformer/webpack.functions.js && cross-env DEBUG=true webpack --config config/modules/definitelyTypedTransformer/webpack.js",
"build:playground": "ttsc --project ./test/playground/tsconfig.build.json",
"test": "npm run test:transformer && npm run test:noTransformer && npm run test:framework:context && npm run test:framework && npm run test:frameworkDeprecated && npm run test:registerMock && npm run test:features && npm run test:filesFilter && npm run test:logs && npm run test:unit",
"test": "npm run test:transformer && npm run test:noTransformer && npm run test:framework:context && npm run test:framework && npm run test:frameworkDeprecated && npm run test:registerMock && npm run test:createHydratedMock && npm run test:features && npm run test:filesFilter && npm run test:logs && npm run test:unit",
"test:unit": "cross-env JASMINE_CONFIG=./test/unit/jasmine.json TSCONFIG=./test/tsconfig.json npm run test:common",
"test:transformer": "cross-env JASMINE_CONFIG=./test/transformer/jasmine.json TSCONFIG=./test/transformer/tsconfig.json npm run test:common",
"test:noTransformer": "cross-env JASMINE_CONFIG=./test/noTransformer/jasmine.json TSCONFIG=./test/tsconfig.json npm run test:common",
"test:registerMock": "cross-env JASMINE_CONFIG=./test/registerMock/jasmine.json TSCONFIG=./test/registerMock/tsconfig.json npm run test:common",
"test:createHydratedMock": "cross-env JASMINE_CONFIG=./test/createHydratedMock/jasmine.json TSCONFIG=./test/createHydratedMock/tsconfig.json npm run test:common",
"test:framework:context": "cross-env JASMINE_CONFIG=./test/frameworkContext/jasmine.json TSCONFIG=./test/frameworkContext/tsconfig.json npm run test:common",
"test:frameworkDeprecated": "cross-env JASMINE_CONFIG=./test/frameworkContext/jasmineDeprecated.json TSCONFIG=./test/frameworkContext/tsconfig.json npm run test:common",
"test:framework": "cross-env JASMINE_CONFIG=./test/framework/jasmine.json TSCONFIG=./test/framework/tsconfig.json npm run test:common",
Expand Down
9 changes: 9 additions & 0 deletions src/create-hydrated-mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { NoTransformerError } from './errors/no-transformer.error';

import { PartialDeep } from './partial/partial';

export function createHydratedMock<T extends object>(
_values?: PartialDeep<T>
): T {
throw new Error(NoTransformerError);
}
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export { createMock } from './create-mock';
export { createMockList } from './create-mock-list';
export { createHydratedMock } from './create-hydrated-mock';
export { registerMock } from './register-mock';
2 changes: 1 addition & 1 deletion src/transformer/descriptor/mock/mockProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export function GetMockPropertiesFromDeclarations(
return false;
}

if (member.questionToken) {
if (member.questionToken && !scope.hydrated) {
return false;
}

Expand Down
5 changes: 3 additions & 2 deletions src/transformer/descriptor/typeParameter/typeParameter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ export function GetTypeParameterDescriptor(
);
}

const genericKey: string = MockDefiner.instance.getDeclarationKeyMap(
typeDeclaration
const genericKey: string = MockDefiner.instance.getDeclarationKeyMapBasedOnScope(
typeDeclaration,
scope
);

return createFunctionToAccessToGenericValue(
Expand Down
5 changes: 4 additions & 1 deletion src/transformer/descriptor/typeQuery/typeQuery.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ export function GetTypeQueryDescriptorFromDeclaration(
// TODO: Use following two lines when issue #17552 on typescript github is resolved (https://github.com/microsoft/TypeScript/issues/17552)
// TheNewEmitResolver.ensureEmitOf(GetImportDeclarationOf(node.eprName as ts.Identifier);
// return node.exprName as ts.Identifier;
return GetMockFactoryCallTypeofEnum(declaration as ts.EnumDeclaration);
return GetMockFactoryCallTypeofEnum(
declaration as ts.EnumDeclaration,
scope
);
case ts.SyntaxKind.FunctionDeclaration:
case ts.SyntaxKind.MethodSignature:
return GetMethodDeclarationDescriptor(
Expand Down
6 changes: 3 additions & 3 deletions src/transformer/descriptor/typeReference/typeReference.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,16 @@ export function GetTypeReferenceDescriptor(
node.typeName
);

if (MockDefiner.instance.hasMockForDeclaration(declaration)) {
return GetMockFactoryCall(node, scope);
if (MockDefiner.instance.hasMockForDeclaration(declaration, scope)) {
return GetMockFactoryCall(node, declaration, scope);
}

if (IsTypescriptType(declaration)) {
return GetTypescriptTypeDescriptor(node, scope);
}

if (isTypeReferenceReusable(declaration)) {
return CreateMockFactory(node, scope);
return CreateMockFactory(node, declaration, scope);
}

return GetDescriptor(declaration, scope);
Expand Down
12 changes: 12 additions & 0 deletions src/transformer/descriptor/union/union.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ export function GetUnionDescriptor(
): ts.Expression {
const findNodes: ts.Node[] = GetTypes(node.types, scope);

if (scope.hydrated) {
const removeUndefinedNodes: ts.Node[] = findNodes.filter(
(typeNode: ts.TypeNode) => !isNotDefinedType(typeNode)
);

if (removeUndefinedNodes.length) {
return GetDescriptor(removeUndefinedNodes[0], scope);
}

return GetUndefinedDescriptor();
}

const notDefinedType: ts.Node[] = findNodes.filter((typeNode: ts.TypeNode) =>
isNotDefinedType(typeNode)
);
Expand Down
9 changes: 6 additions & 3 deletions src/transformer/genericDeclaration/genericDeclaration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,10 +132,13 @@ export function GenericDeclaration(scope: Scope): IGenericDeclaration {
genericNode.typeName
);

const typeParameterDeclarationKey: string = MockDefiner.instance.getDeclarationKeyMapBasedOnScope(
typeParameterDeclaration,
scope
);

const isExtendingItself: boolean =
MockDefiner.instance.getDeclarationKeyMap(
typeParameterDeclaration
) === declarationKey;
typeParameterDeclarationKey === declarationKey;
if (isExtendingItself) {
// FIXME: Currently, circular generics aren't supported. See
// https://github.com/Typescript-TDD/ts-auto-mock/pull/312 for more
Expand Down
21 changes: 21 additions & 0 deletions src/transformer/mock/mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ function getMockExpression(nodeToMock: ts.TypeNode): ts.Expression {
return GetDescriptor(nodeToMock, new Scope());
}

function getMockHydratedExpression(nodeToMock: ts.TypeNode): ts.Expression {
const scope: Scope = new Scope();
scope.hydrated = true;
return GetDescriptor(nodeToMock, scope);
}

function hasDefaultValues(node: ts.CallExpression): boolean {
return !!node.arguments.length && !!node.arguments[0];
}
Expand All @@ -41,6 +47,21 @@ export function getMock(
return mockExpression;
}

export function getHydratedMock(
nodeToMock: ts.TypeNode,
node: ts.CallExpression
): ts.Expression {
SetCurrentCreateMock(node);

const mockExpression: ts.Expression = getMockHydratedExpression(nodeToMock);

if (hasDefaultValues(node)) {
return getMockMergeExpression(mockExpression, node.arguments[0]);
}

return mockExpression;
}

export function getMockForList(
nodeToMock: ts.TypeNode,
node: ts.CallExpression
Expand Down
Loading

0 comments on commit aa2ebad

Please sign in to comment.