Skip to content

Commit

Permalink
feat(ngMocks): keep CommonModule #5047
Browse files Browse the repository at this point in the history
  • Loading branch information
satanTime committed Mar 5, 2023
1 parent 0946da5 commit af1bd9e
Show file tree
Hide file tree
Showing 21 changed files with 421 additions and 39 deletions.
29 changes: 22 additions & 7 deletions docs/articles/extra/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,27 @@ Simply add the next code to `src/test.ts` or `src/setup-jest.ts` / `src/test-set
and comment / uncomment related blocks:

```ts title="src/test.ts"
import { MockInstance, ngMocks } from 'ng-mocks';
import { MockInstance, ngMocks } from 'ng-mocks'; // eslint-disable-line import/order

// auto spy
ngMocks.autoSpy('jasmine');
// in case of jest
// ngMocks.autoSpy('jest');

// In case, if you use @angular/router and Angular 14+.
// You might want to set a mock of DefaultTitleStrategy as TitleStrategy.
// A14 fix: making DefaultTitleStrategy to be a default mock for TitleStrategy
import { DefaultTitleStrategy, TitleStrategy } from "@angular/router";
import { MockService, ngMocks } from 'ng-mocks';
import { DefaultTitleStrategy, TitleStrategy } from '@angular/router'; // eslint-disable-line import/order
ngMocks.defaultMock(TitleStrategy, () => MockService(DefaultTitleStrategy));

// auto spy
ngMocks.autoSpy('jasmine');
// in case of jest
// ngMocks.autoSpy('jest');
// Usually, *ngIf and other declarations from CommonModule aren't expected to be mocked.
// The code below keeps them.
import { CommonModule } from '@angular/common'; // eslint-disable-line import/order
import { ApplicationModule } from "@angular/core"; // eslint-disable-line import/order
import { BrowserModule } from "@angular/platform-browser"; // eslint-disable-line import/order
ngMocks.globalKeep(ApplicationModule, true);
ngMocks.globalKeep(CommonModule, true);
ngMocks.globalKeep(BrowserModule, true);

// auto restore for jasmine and jest <27
// declare const jasmine: any;
Expand Down Expand Up @@ -80,3 +88,10 @@ jasmine.getEnv().addReporter({
// },
// });
```

## Restoring `src/test.ts` in Angular 15

If you are using Angular 15+, then you might not find `src/test.ts`.
However, this file is required to provide global configuration for your tests.

Please use this [answer on stackoverflow to restore `src/test.ts`](https://stackoverflow.com/a/75323651/13112018).
14 changes: 12 additions & 2 deletions e2e/a14/src/setup-jest.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import 'jest-preset-angular/setup-jest';
import { DefaultTitleStrategy, TitleStrategy } from '@angular/router';
import { MockService, ngMocks } from 'ng-mocks';

import { MockService, ngMocks } from 'ng-mocks'; // eslint-disable-line import/order

ngMocks.autoSpy('jest');

// In case, if you use @angular/router and Angular 14+.
// You might want to set a mock of DefaultTitleStrategy as TitleStrategy.
// A14 fix: making DefaultTitleStrategy to be a default mock for TitleStrategy
import { DefaultTitleStrategy, TitleStrategy } from '@angular/router'; // eslint-disable-line import/order
ngMocks.defaultMock(TitleStrategy, () => MockService(DefaultTitleStrategy));

// Usually, *ngIf and other declarations from CommonModule aren't expected to be mocked.
// The code below keeps them.
import { CommonModule } from '@angular/common'; // eslint-disable-line import/order
import { ApplicationModule } from '@angular/core'; // eslint-disable-line import/order
import { BrowserModule } from '@angular/platform-browser'; // eslint-disable-line import/order
ngMocks.globalKeep(ApplicationModule, true);
ngMocks.globalKeep(CommonModule, true);
ngMocks.globalKeep(BrowserModule, true);
13 changes: 11 additions & 2 deletions e2e/a14/src/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,25 @@
import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
import { DefaultTitleStrategy, TitleStrategy } from '@angular/router';
import { MockService, ngMocks } from 'ng-mocks';
import { MockService, ngMocks } from 'ng-mocks'; // eslint-disable-line import/order

ngMocks.autoSpy('jasmine');

// In case, if you use @angular/router and Angular 14+.
// You might want to set a mock of DefaultTitleStrategy as TitleStrategy.
// A14 fix: making DefaultTitleStrategy to be a default mock for TitleStrategy
import { DefaultTitleStrategy, TitleStrategy } from '@angular/router'; // eslint-disable-line import/order
ngMocks.defaultMock(TitleStrategy, () => MockService(DefaultTitleStrategy));

// Usually, *ngIf and other declarations from CommonModule aren't expected to be mocked.
// The code below keeps them.
import { CommonModule } from '@angular/common'; // eslint-disable-line import/order
import { ApplicationModule } from '@angular/core'; // eslint-disable-line import/order
import { BrowserModule } from '@angular/platform-browser'; // eslint-disable-line import/order
ngMocks.globalKeep(ApplicationModule, true);
ngMocks.globalKeep(CommonModule, true);
ngMocks.globalKeep(BrowserModule, true);

declare const require: {
context(
path: string,
Expand Down
14 changes: 12 additions & 2 deletions e2e/a15/src/setup-jest.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import 'jest-preset-angular/setup-jest';
import { DefaultTitleStrategy, TitleStrategy } from '@angular/router';
import { MockService, ngMocks } from 'ng-mocks';

import { MockService, ngMocks } from 'ng-mocks'; // eslint-disable-line import/order

ngMocks.autoSpy('jest');

// In case, if you use @angular/router and Angular 14+.
// You might want to set a mock of DefaultTitleStrategy as TitleStrategy.
// A14 fix: making DefaultTitleStrategy to be a default mock for TitleStrategy
import { DefaultTitleStrategy, TitleStrategy } from '@angular/router'; // eslint-disable-line import/order
ngMocks.defaultMock(TitleStrategy, () => MockService(DefaultTitleStrategy));

// Usually, *ngIf and other declarations from CommonModule aren't expected to be mocked.
// The code below keeps them.
import { CommonModule } from '@angular/common'; // eslint-disable-line import/order
import { ApplicationModule } from '@angular/core'; // eslint-disable-line import/order
import { BrowserModule } from '@angular/platform-browser'; // eslint-disable-line import/order
ngMocks.globalKeep(ApplicationModule, true);
ngMocks.globalKeep(CommonModule, true);
ngMocks.globalKeep(BrowserModule, true);
13 changes: 11 additions & 2 deletions e2e/a15/src/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,25 @@
import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
import { DefaultTitleStrategy, TitleStrategy } from '@angular/router';
import { MockService, ngMocks } from 'ng-mocks';
import { MockService, ngMocks } from 'ng-mocks'; // eslint-disable-line import/order

ngMocks.autoSpy('jasmine');

// In case, if you use @angular/router and Angular 14+.
// You might want to set a mock of DefaultTitleStrategy as TitleStrategy.
// A14 fix: making DefaultTitleStrategy to be a default mock for TitleStrategy
import { DefaultTitleStrategy, TitleStrategy } from '@angular/router'; // eslint-disable-line import/order
ngMocks.defaultMock(TitleStrategy, () => MockService(DefaultTitleStrategy));

// Usually, *ngIf and other declarations from CommonModule aren't expected to be mocked.
// The code below keeps them.
import { CommonModule } from '@angular/common'; // eslint-disable-line import/order
import { ApplicationModule } from '@angular/core'; // eslint-disable-line import/order
import { BrowserModule } from '@angular/platform-browser'; // eslint-disable-line import/order
ngMocks.globalKeep(ApplicationModule, true);
ngMocks.globalKeep(CommonModule, true);
ngMocks.globalKeep(BrowserModule, true);

jasmine.getEnv().allowRespy(true);

// First, initialize the Angular testing environment.
Expand Down
13 changes: 11 additions & 2 deletions e2e/jasmine/src/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,25 @@
import 'zone.js/testing';
import { getTestBed } from '@angular/core/testing';
import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
import { DefaultTitleStrategy, TitleStrategy } from '@angular/router';
import { MockService, ngMocks } from 'ng-mocks';
import { MockService, ngMocks } from 'ng-mocks'; // eslint-disable-line import/order

ngMocks.autoSpy('jasmine');

// In case, if you use @angular/router and Angular 14+.
// You might want to set a mock of DefaultTitleStrategy as TitleStrategy.
// A14 fix: making DefaultTitleStrategy to be a default mock for TitleStrategy
import { DefaultTitleStrategy, TitleStrategy } from '@angular/router'; // eslint-disable-line import/order
ngMocks.defaultMock(TitleStrategy, () => MockService(DefaultTitleStrategy));

// Usually, *ngIf and other declarations from CommonModule aren't expected to be mocked.
// The code below keeps them.
import { CommonModule } from '@angular/common'; // eslint-disable-line import/order
import { ApplicationModule } from '@angular/core'; // eslint-disable-line import/order
import { BrowserModule } from '@angular/platform-browser'; // eslint-disable-line import/order
ngMocks.globalKeep(ApplicationModule, true);
ngMocks.globalKeep(CommonModule, true);
ngMocks.globalKeep(BrowserModule, true);

jasmine.getEnv().allowRespy(true);

// First, initialize the Angular testing environment.
Expand Down
17 changes: 16 additions & 1 deletion e2e/jest/src/setup-jest.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,20 @@
import 'jest-preset-angular/setup-jest';

import { ngMocks } from 'ng-mocks';
import { MockService, ngMocks } from 'ng-mocks'; // eslint-disable-line import/order

ngMocks.autoSpy('jest');

// In case, if you use @angular/router and Angular 14+.
// You might want to set a mock of DefaultTitleStrategy as TitleStrategy.
// A14 fix: making DefaultTitleStrategy to be a default mock for TitleStrategy
import { DefaultTitleStrategy, TitleStrategy } from '@angular/router'; // eslint-disable-line import/order
ngMocks.defaultMock(TitleStrategy, () => MockService(DefaultTitleStrategy));

// Usually, *ngIf and other declarations from CommonModule aren't expected to be mocked.
// The code below keeps them.
import { CommonModule } from '@angular/common'; // eslint-disable-line import/order
import { ApplicationModule } from '@angular/core'; // eslint-disable-line import/order
import { BrowserModule } from '@angular/platform-browser'; // eslint-disable-line import/order
ngMocks.globalKeep(ApplicationModule, true);
ngMocks.globalKeep(CommonModule, true);
ngMocks.globalKeep(BrowserModule, true);
14 changes: 12 additions & 2 deletions e2e/nx/apps/a-nx/src/test-setup.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
import 'jest-preset-angular/setup-jest';
import { DefaultTitleStrategy, TitleStrategy } from '@angular/router';
import { MockService, ngMocks } from 'ng-mocks';

import { MockService, ngMocks } from 'ng-mocks'; // eslint-disable-line import/order

ngMocks.autoSpy('jest');

// In case, if you use @angular/router and Angular 14+.
// You might want to set a mock of DefaultTitleStrategy as TitleStrategy.
// A14 fix: making DefaultTitleStrategy to be a default mock for TitleStrategy
import { DefaultTitleStrategy, TitleStrategy } from '@angular/router'; // eslint-disable-line import/order
ngMocks.defaultMock(TitleStrategy, () => MockService(DefaultTitleStrategy));

// Usually, *ngIf and other declarations from CommonModule aren't expected to be mocked.
// The code below keeps them.
import { CommonModule } from '@angular/common'; // eslint-disable-line import/order
import { ApplicationModule } from '@angular/core'; // eslint-disable-line import/order
import { BrowserModule } from '@angular/platform-browser'; // eslint-disable-line import/order
ngMocks.globalKeep(ApplicationModule, true);
ngMocks.globalKeep(CommonModule, true);
ngMocks.globalKeep(BrowserModule, true);
32 changes: 32 additions & 0 deletions libs/ng-mocks/src/lib/common/func.iterate-declaration.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import collectDeclarations from '../resolve/collect-declarations';

import coreConfig from './core.config';
import { flatten } from './core.helpers';
import { AnyDeclaration } from './core.types';
import funcGetType from './func.get-type';

const iterator = <T = any>(
source: AnyDeclaration<T>,
callback: (source: AnyDeclaration<T>) => void,
scanned = new Set<any>(),
): void => {
const meta = collectDeclarations(source);
for (const decorator of meta.decorators) {
for (const key of coreConfig.dependencies) {
if (!meta[decorator][key]) {
continue;
}
for (const def of flatten(meta[decorator][key])) {
const declaration = funcGetType(def);
if (!declaration || scanned.has(declaration)) {
continue;
}
scanned.add(declaration);
callback(declaration);
iterator(declaration, callback, scanned);
}
}
}
};

export default iterator;
Original file line number Diff line number Diff line change
@@ -1,18 +1,28 @@
import { Component } from '@angular/core';
import { Component, Injectable } from '@angular/core';

import ngMocksUniverse from '../common/ng-mocks-universe';

import mockHelperGlobalExclude from './mock-helper.global-exclude';
import mockHelperGlobalWipe from './mock-helper.global-wipe';

@Injectable()
class TargetService {}

@Component({
selector: 'target',
template: '{{ name }}',
providers: [TargetService],
})
class TargetComponent {
public readonly name = 'target';
}

describe('mock-helper.default-exclude', () => {
afterEach(() => {
mockHelperGlobalWipe(TargetComponent);
mockHelperGlobalWipe(TargetService);
});

afterAll(() => {
ngMocksUniverse.config.delete('ngMocksDepsSkip');
});
Expand All @@ -32,4 +42,36 @@ describe('mock-helper.default-exclude', () => {
ngMocksUniverse.config.get('ngMocksDepsSkip').size,
).toEqual(0);
});

it('adds TargetComponent with exclude flag', () => {
expect(
ngMocksUniverse.getDefaults().get(TargetComponent),
).toEqual(undefined);
expect(ngMocksUniverse.getDefaults().get(TargetService)).toEqual(
undefined,
);
mockHelperGlobalExclude(TargetComponent);
expect(
ngMocksUniverse.getDefaults().get(TargetComponent),
).toEqual(['exclude']);
expect(ngMocksUniverse.getDefaults().get(TargetService)).toEqual(
undefined,
);
});

it('adds TargetComponent with exclude flag recursively', () => {
expect(
ngMocksUniverse.getDefaults().get(TargetComponent),
).toEqual(undefined);
expect(ngMocksUniverse.getDefaults().get(TargetService)).toEqual(
undefined,
);
mockHelperGlobalExclude(TargetComponent, true);
expect(
ngMocksUniverse.getDefaults().get(TargetComponent),
).toEqual(['exclude']);
expect(ngMocksUniverse.getDefaults().get(TargetService)).toEqual([
'exclude',
]);
});
});
12 changes: 10 additions & 2 deletions libs/ng-mocks/src/lib/mock-helper/mock-helper.global-exclude.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
import { AnyDeclaration } from '../common/core.types';
import funcIterateDeclaration from '../common/func.iterate-declaration';
import ngMocksUniverse from '../common/ng-mocks-universe';

import funcGlobalPrepare from './func.global-prepare';

export default (source: AnyDeclaration<any>): void => {
funcGlobalPrepare();
const action = (source: AnyDeclaration<any>): void => {
ngMocksUniverse.getDefaults().set(source, ['exclude']);
};
export default (source: AnyDeclaration<any>, recursively = false): void => {
funcGlobalPrepare();
action(source);

if (recursively) {
funcIterateDeclaration(source, action);
}
};
Loading

0 comments on commit af1bd9e

Please sign in to comment.