Skip to content

Commit

Permalink
fix(MockBuilder): params support tokens and modules with providers #762
Browse files Browse the repository at this point in the history
  • Loading branch information
satanTime committed Jun 30, 2021
1 parent 399162d commit d58693e
Show file tree
Hide file tree
Showing 7 changed files with 230 additions and 21 deletions.
13 changes: 5 additions & 8 deletions libs/ng-mocks/src/lib/mock-builder/mock-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,19 @@ import { InjectionToken } from '@angular/core';

import { flatten } from '../common/core.helpers';
import { AnyType } from '../common/core.types';
import { NgModuleWithProviders } from '../common/func.is-ng-module-def-with-providers';

import { MockBuilderPerformance } from './mock-builder.performance';
import { IMockBuilder } from './types';

export type MockBuilderParam = string | AnyType<any> | InjectionToken<any> | NgModuleWithProviders;

/**
* @see https://ng-mocks.sudo.eu/api/MockBuilder
*/
export function MockBuilder(
keepDeclaration?:
| string
| AnyType<any>
| InjectionToken<any>
| Array<string | AnyType<any> | InjectionToken<any>>
| null
| undefined,
itsModuleToMock?: AnyType<any> | Array<AnyType<any>> | null | undefined,
keepDeclaration?: MockBuilderParam | MockBuilderParam[] | null | undefined,
itsModuleToMock?: MockBuilderParam | MockBuilderParam[] | null | undefined,
): IMockBuilder {
const instance = new MockBuilderPerformance();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default (ngModule: NgMeta, { keepDef, configDef }: BuilderData): void =>
continue;
}

if (isNgInjectionToken(def)) {
if (isNgInjectionToken(def) || typeof def === 'string') {
ngMocksUniverse.touches.add(def);
continue;
}
Expand Down
16 changes: 8 additions & 8 deletions libs/ng-mocks/src/lib/mock-builder/promise/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ import { Type } from '../../common/core.types';
import { NgModuleWithProviders } from '../../common/func.is-ng-module-def-with-providers';

export type BuilderData = {
configDef: Map<Type<any> | InjectionToken<any>, any>;
defProviders: Map<Type<any> | InjectionToken<any>, Provider[]>;
defValue: Map<Type<any> | InjectionToken<any>, any>;
excludeDef: Set<Type<any> | InjectionToken<any>>;
keepDef: Set<Type<any> | InjectionToken<any>>;
mockDef: Set<Type<any> | InjectionToken<any>>;
providerDef: Map<Type<any> | InjectionToken<any>, Provider>;
replaceDef: Set<Type<any> | InjectionToken<any>>;
configDef: Map<Type<any> | InjectionToken<any> | string, any>;
defProviders: Map<Type<any> | InjectionToken<any> | string, Provider[]>;
defValue: Map<Type<any> | InjectionToken<any> | string, any>;
excludeDef: Set<Type<any> | InjectionToken<any> | string>;
keepDef: Set<Type<any> | InjectionToken<any> | string>;
mockDef: Set<Type<any> | InjectionToken<any> | string>;
providerDef: Map<Type<any> | InjectionToken<any> | string, Provider>;
replaceDef: Set<Type<any> | InjectionToken<any> | string>;
};

export type NgMeta = {
Expand Down
8 changes: 4 additions & 4 deletions tests-failures/mock-builder-constructor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,16 +60,16 @@ MockBuilder(null, undefined);
MockBuilder(undefined, null);
MockBuilder(undefined, undefined);

// @ts-expect-error: does not support not modules.
// supports tokens.
MockBuilder(null, TOKEN_UNKNOWN);

// @ts-expect-error: does not support not modules.
// supports not string tokens.
MockBuilder(null, 'param');

// @ts-expect-error: does not support modules with providers.
// supports modules with providers.
MockBuilder(null, moduleWithProviders);

// @ts-expect-error: does not support modules with providers.
// supports modules with providers.
MockBuilder(moduleWithProviders);

const promise: Promise<IMockBuilderResult> =
Expand Down
71 changes: 71 additions & 0 deletions tests/issue-762/module.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { Injectable, NgModule } from '@angular/core';
import {
MockBuilder,
MockRender,
NgModuleWithProviders,
} from 'ng-mocks';

@Injectable()
class TargetService {
public readonly name?: string = 'target';
}

@NgModule()
class TargetModule {
public static forRoot(): NgModuleWithProviders<TargetModule> {
return {
ngModule: TargetModule,
providers: [TargetService],
};
}
}

describe('issue-762:module', () => {
describe('as keep single', () => {
beforeEach(() => MockBuilder(TargetModule.forRoot()));

it('works correctly', () => {
const fixture = MockRender(TargetService);
expect(fixture.point.componentInstance).toEqual(
jasmine.any(TargetService),
);
expect(fixture.point.componentInstance.name).toEqual('target');
});
});

describe('as keep multi', () => {
beforeEach(() => MockBuilder([TargetModule.forRoot()]));

it('works correctly', () => {
const fixture = MockRender(TargetService);
expect(fixture.point.componentInstance).toEqual(
jasmine.any(TargetService),
);
expect(fixture.point.componentInstance.name).toEqual('target');
});
});

describe('as mock single', () => {
beforeEach(() => MockBuilder(null, TargetModule.forRoot()));

it('works correctly', () => {
const fixture = MockRender(TargetService);
expect(fixture.point.componentInstance).toEqual(
jasmine.any(TargetService),
);
expect(fixture.point.componentInstance.name).toEqual(undefined);
});
});

describe('as mock multi', () => {
beforeEach(() => MockBuilder(null, [TargetModule.forRoot()]));

it('works correctly', () => {
const fixture = MockRender(TargetService);
expect(fixture.point.componentInstance).toEqual(
jasmine.any(TargetService),
);
expect(fixture.point.componentInstance.name).toEqual(undefined);
});
});
});
70 changes: 70 additions & 0 deletions tests/issue-762/string.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { NgModule } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { MockBuilder } from 'ng-mocks';

@NgModule({
providers: [
{
provide: 'STRING',
useValue: 'TOKEN',
},
],
})
class TargetModule {}

describe('issue-762:string', () => {
describe('as keep single lonely', () => {
beforeEach(() => MockBuilder('STRING'));

it('works correctly', () => {
expect(() => TestBed.get('STRING')).toThrowError(
/No provider for STRING/,
);
});
});

describe('as keep single', () => {
beforeEach(() => MockBuilder('STRING', TargetModule));

it('works correctly', () => {
const token = TestBed.get('STRING');
expect(token).toEqual('TOKEN');
});
});

describe('as keep multi', () => {
beforeEach(() => MockBuilder(['STRING'], TargetModule));

it('works correctly', () => {
const token = TestBed.get('STRING');
expect(token).toEqual('TOKEN');
});
});

describe('as mock single lonely', () => {
beforeEach(() => MockBuilder(null, 'STRING'));

it('works correctly', () => {
const token = TestBed.get('STRING');
expect(token).toEqual(undefined);
});
});

describe('as mock single', () => {
beforeEach(() => MockBuilder(TargetModule, 'STRING'));

it('works correctly', () => {
const token = TestBed.get('STRING');
expect(token).toEqual(undefined);
});
});

describe('as mock multi', () => {
beforeEach(() => MockBuilder(TargetModule, ['STRING']));

it('works correctly', () => {
const token = TestBed.get('STRING');
expect(token).toEqual(undefined);
});
});
});
71 changes: 71 additions & 0 deletions tests/issue-762/token.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { InjectionToken, NgModule } from '@angular/core';
import { MockBuilder, MockRender } from 'ng-mocks';

const TOKEN = new InjectionToken('TOKEN');

@NgModule({
providers: [
{
provide: TOKEN,
useValue: 'TOKEN',
},
],
})
class TargetModule {}

describe('issue-762:token', () => {
describe('as keep single lonely', () => {
beforeEach(() => MockBuilder(TOKEN));

it('works correctly', () => {
expect(() => MockRender(TOKEN)).toThrowError(
/No provider for InjectionToken TOKEN/,
);
});
});

describe('as keep single', () => {
beforeEach(() => MockBuilder(TOKEN, TargetModule));

it('works correctly', () => {
const fixture = MockRender(TOKEN);
expect(fixture.point.componentInstance).toEqual('TOKEN');
});
});

describe('as keep multi', () => {
beforeEach(() => MockBuilder([TOKEN], TargetModule));

it('works correctly', () => {
const fixture = MockRender(TOKEN);
expect(fixture.point.componentInstance).toEqual('TOKEN');
});
});

describe('as mock single lonely', () => {
beforeEach(() => MockBuilder(null, TOKEN));

it('works correctly', () => {
const fixture = MockRender(TOKEN);
expect(fixture.point.componentInstance).toEqual(undefined);
});
});

describe('as mock single', () => {
beforeEach(() => MockBuilder(TargetModule, TOKEN));

it('works correctly', () => {
const fixture = MockRender(TOKEN);
expect(fixture.point.componentInstance).toEqual(undefined);
});
});

describe('as mock multi', () => {
beforeEach(() => MockBuilder(TargetModule, [TOKEN]));

it('works correctly', () => {
const fixture = MockRender(TOKEN);
expect(fixture.point.componentInstance).toEqual(undefined);
});
});
});

0 comments on commit d58693e

Please sign in to comment.