Skip to content

Commit

Permalink
test(classes): add more tests to classes plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
nartc committed Jan 15, 2021
1 parent 9734abd commit 9fb3388
Show file tree
Hide file tree
Showing 20 changed files with 711 additions and 47 deletions.
17 changes: 13 additions & 4 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,23 +14,32 @@
"depConstraints": [
{
"sourceTag": "type:plugin",
"onlyDependOnLibsWithTags": ["type:library", "type:type-defs"]
"onlyDependOnLibsWithTags": [
"type:library",
"type:type-defs",
"type:util"
]
},
{
"sourceTag": "type:library",
"onlyDependOnLibsWithTags": ["type:type-defs"]
"onlyDependOnLibsWithTags": ["type:type-defs", "type:util"]
},
{
"sourceTag": "type:integration",
"onlyDependOnLibsWithTags": ["type:library", "type:type-defs"]
"onlyDependOnLibsWithTags": [
"type:library",
"type:type-defs",
"type:util"
]
},
{
"sourceTag": "type:test",
"onlyDependOnLibsWithTags": [
"type:library",
"type:plugin",
"type:integration",
"type:type-defs"
"type:type-defs",
"type:util"
]
}
]
Expand Down
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@ module.exports = {
'<rootDir>/packages/pojos',
'<rootDir>/packages/nestjs',
'<rootDir>/packages/nestjs-integration-test',
'<rootDir>/packages/test-util',
],
};
47 changes: 12 additions & 35 deletions nx.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
{
"npmScope": "automapper",
"affected": {
"defaultBase": "main"
},
"affected": { "defaultBase": "main" },
"implicitDependencies": {
"workspace.json": "*",
"package.json": {
"dependencies": "*",
"devDependencies": "*"
},
"package.json": { "dependencies": "*", "devDependencies": "*" },
"tsconfig.base.json": "*",
"tslint.json": "*",
".eslintrc.json": "*",
Expand All @@ -17,36 +12,18 @@
"tasksRunnerOptions": {
"default": {
"runner": "@nrwl/workspace/tasks-runners/default",
"options": {
"cacheableOperations": ["build", "lint", "test", "e2e"]
}
"options": { "cacheableOperations": ["build", "lint", "test", "e2e"] }
}
},
"projects": {
"core": {
"tags": ["type:library"]
},
"classes": {
"tags": ["type:plugin"]
},
"types": {
"tags": ["type:type-defs"]
},
"integration-test": {
"tags": ["type:test"]
},
"pojos": {
"tags": ["type:plugin"]
},
"nestjs": {
"tags": ["type:integration"]
},
"nestjs-integration-test": {
"tags": ["type:test"]
}
"core": { "tags": ["type:library"] },
"classes": { "tags": ["type:plugin"] },
"types": { "tags": ["type:type-defs"] },
"integration-test": { "tags": ["type:test"] },
"pojos": { "tags": ["type:plugin"] },
"nestjs": { "tags": ["type:integration"] },
"nestjs-integration-test": { "tags": ["type:test"] },
"test-util": { "tags": ["type:util"] }
},
"workspaceLayout": {
"appsDir": "packages",
"libsDir": "packages"
}
"workspaceLayout": { "appsDir": "packages", "libsDir": "packages" }
}
16 changes: 9 additions & 7 deletions packages/classes/src/lib/utils/is-class.util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@
*
* @param {Function} fn
*/
export function isClass(fn: unknown): boolean {
// eslint-disable-next-line @typescript-eslint/ban-types
export function isClass(fn: Function): boolean {
const typeOfFn = typeof fn;
const constructorFnString = fn.constructor?.toString();
const fnString = fn.toString();
const constructorFnString = fn.prototype?.constructor?.toString();
return (
(typeOfFn === 'object' || typeOfFn === 'function') &&
fn.constructor &&
(/^\s*function/.test(constructorFnString) ||
/^\s*class/.test(constructorFnString)) &&
constructorFnString.includes(fn.constructor.name)
typeOfFn === 'function' &&
!!constructorFnString &&
(/^\s*function/.test(fnString) || /^\s*class/.test(fnString)) &&
!!fn.name &&
fnString.includes(fn.name)
);
}
165 changes: 165 additions & 0 deletions packages/classes/src/lib/utils/specs/instantiate.util.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
// eslint-disable-next-line @nrwl/nx/enforce-module-boundaries
import {
createSpyObject,
resetAllWhenMocks,
when,
} from '@automapper/test-util';
import { ClassInstanceStorage, ClassMetadataStorage } from '../../storages';
import { instantiate } from '../instantiate.util';

describe('instantiate', () => {
const mockedInstanceStorage = createSpyObject(ClassInstanceStorage, {
resetAllCount: jest.fn(),
getDepthAndCount: jest.fn(),
resetCount: jest.fn(),
setCount: jest.fn(),
});

const mockedMetadataStorage = createSpyObject(ClassMetadataStorage, {
getMetadata: jest.fn(),
});

class Bar {
bar: string;
date: Date;
}

class Foo {
foo: string;
bar: Bar;
}

const defaultDate = new Date('10/14/1991');
const defaultFoo: Foo = new Foo();
defaultFoo.foo = 'foo';
defaultFoo.bar = new Bar();
defaultFoo.bar.bar = 'bar';
defaultFoo.bar.date = defaultDate;

let parameterizedInstantiate: () => [Foo, unknown[]?];

describe('without default value', () => {
beforeEach(() => {
parameterizedInstantiate = () =>
instantiate(mockedInstanceStorage, mockedMetadataStorage, Foo);
});

afterEach(() => {
resetAllWhenMocks();
});

it('should return raw instance if meta is empty', () => {
mockEmpty();

const result = parameterizedInstantiate();
expect(result).toEqual([new Foo()]);
});

it('should return proper instance with metadata', () => {
mockWithoutDepth();

const fooInstance = new Foo();
fooInstance.foo = undefined;
fooInstance.bar = new Bar();

const result = parameterizedInstantiate();
expect(result).toEqual([fooInstance, [['bar', Bar]]]);
});

it('should return proper instance with depth', () => {
mockWithDepth();

const fooInstance = new Foo();
fooInstance.foo = undefined;
fooInstance.bar = new Bar();
fooInstance.bar.bar = undefined;
fooInstance.bar.date = defaultDate;

const result = parameterizedInstantiate();
result[0].bar.date = defaultDate;
expect(result).toEqual([fooInstance, [['bar', Bar]]]);
});
});

describe('with default value', () => {
beforeEach(() => {
parameterizedInstantiate = () =>
instantiate(
mockedInstanceStorage,
mockedMetadataStorage,
Foo,
defaultFoo
);
});

afterEach(() => {
resetAllWhenMocks();
});

it('should return raw instance if meta is empty', () => {
mockEmpty();

const result = parameterizedInstantiate();
expect(result).toEqual([defaultFoo]);
});

it('should return proper instance with metadata', () => {
mockWithoutDepth();

const result = parameterizedInstantiate();
expect(result).toEqual([defaultFoo, [['bar', Bar]]]);
});

it('should return proper instance with depth', () => {
mockWithDepth();

const result = parameterizedInstantiate();
expect(result).toEqual([defaultFoo, [['bar', Bar]]]);
});
});

function mockEmpty() {
when(mockedInstanceStorage.getDepthAndCount)
.calledWith(Foo, 'bar')
.mockReturnValueOnce([0, 0]);
when(mockedMetadataStorage.getMetadata)
.calledWith(Foo)
.mockReturnValueOnce([]);
}

function mockWithoutDepth() {
when(mockedInstanceStorage.getDepthAndCount)
.calledWith(Foo, 'bar')
.mockReturnValueOnce([0, 0]);
when(mockedMetadataStorage.getMetadata)
.calledWith(Foo)
.mockReturnValueOnce([
['foo', () => String],
['bar', () => Bar],
]);
when(mockedMetadataStorage.getMetadata)
.calledWith(Bar)
.mockReturnValueOnce([
['bar', () => String],
['date', () => Date],
]);
}

function mockWithDepth() {
when(mockedInstanceStorage.getDepthAndCount)
.calledWith(Foo, 'bar')
.mockReturnValueOnce([1, 0]);
when(mockedMetadataStorage.getMetadata)
.calledWith(Foo)
.mockReturnValueOnce([
['foo', () => String],
['bar', () => Bar],
]);
when(mockedMetadataStorage.getMetadata)
.calledWith(Bar)
.mockReturnValueOnce([
['bar', () => String],
['date', () => Date],
]);
}
});
28 changes: 28 additions & 0 deletions packages/classes/src/lib/utils/specs/is-class.util.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { isClass } from '../is-class.util';

describe('isClass', () => {
it('should work', () => {
expect(isClass(String)).toEqual(true);
expect(isClass(Number)).toEqual(true);
expect(
isClass(function something() {
console.log('');
})
).toEqual(true);
expect(
isClass(() => {
console.log('');
})
).toEqual(false);

expect(
isClass(function () {
console.log('');
})
).toEqual(false);

class Foo {}

expect(isClass(Foo)).toEqual(true);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { isDateConstructor } from '../is-date-constructor.util';

describe('isDateConstructor', () => {
it('should work', () => {
expect(isDateConstructor(Date)).toEqual(true);
expect(isDateConstructor(String)).toEqual(false);
expect(isDateConstructor(Number)).toEqual(false);
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { isPrimitiveConstructor } from '../is-primitive-constructor.util';

describe('isPrimitiveConstructor', () => {
it('should work', () => {
expect(isPrimitiveConstructor(String)).toEqual(true);
expect(isPrimitiveConstructor(Number)).toEqual(true);
expect(isPrimitiveConstructor(Boolean)).toEqual(true);
expect(isPrimitiveConstructor(Date)).toEqual(false);
});
});
1 change: 1 addition & 0 deletions packages/test-util/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{ "extends": "../../.eslintrc.json", "ignorePatterns": ["!**/*"], "rules": {} }
7 changes: 7 additions & 0 deletions packages/test-util/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# test-util

This library was generated with [Nx](https://nx.dev).

## Running unit tests

Run `nx test test-util` to execute the unit tests via [Jest](https://jestjs.io).
15 changes: 15 additions & 0 deletions packages/test-util/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
displayName: 'test-util',
preset: '../../jest.preset.js',
globals: {
'ts-jest': {
tsConfig: '<rootDir>/tsconfig.spec.json',
},
},
testEnvironment: 'node',
transform: {
'^.+\\.[tj]sx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
coverageDirectory: '../../coverage/packages/test-util',
};
2 changes: 2 additions & 0 deletions packages/test-util/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './lib/create-spy-object';
export * from './lib/when';
Loading

0 comments on commit 9fb3388

Please sign in to comment.