Skip to content

Commit

Permalink
Merge pull request #1993 from satanTime/issues/1256
Browse files Browse the repository at this point in the history
feat(MockInstance): resets root overrides likewise properties #1256
  • Loading branch information
satanTime authored Mar 6, 2022
2 parents 90acfa5 + a903556 commit 65da18d
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 77 deletions.
8 changes: 0 additions & 8 deletions libs/ng-mocks/src/lib/common/ng-mocks-universe.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,6 @@ ngMocksUniverse.global.set('flags', {
onTestBedFlushNeed: coreConfig.onTestBedFlushNeed,
});

ngMocksUniverse.getLocalMocks = () => {
if (!ngMocksUniverse.global.has('local-mocks')) {
ngMocksUniverse.global.set('local-mocks', []);
}

return ngMocksUniverse.global.get('local-mocks');
};

ngMocksUniverse.getOverrides = globalMap('overrides');
ngMocksUniverse.getDefaults = globalMap('defaults');

Expand Down
13 changes: 7 additions & 6 deletions libs/ng-mocks/src/lib/mock-instance/mock-instance-apply.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ export default (def: any): any[] => {
const callbacks = [];

const config = ngMocksUniverse.configInstance.get(def);
if (config?.init) {
callbacks.push(config.init);
}
if (config?.overloads) {
for (const [name, stub, encapsulation] of config.overloads) {
callbacks.push((instance: any) => {
mockHelperStubMember(instance, name, stub, encapsulation);
});
if (name) {
callbacks.push((instance: any) => {
mockHelperStubMember(instance, name, stub, encapsulation);
});
} else {
callbacks.push(stub);
}
}
}

Expand Down
86 changes: 23 additions & 63 deletions libs/ng-mocks/src/lib/mock-instance/mock-instance.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,30 +26,6 @@ ngMocksStack.subscribePop((state, stack) => {
currentStack = stack[stack.length - 1];
});

ngMocksStack.subscribePush(() => {
// On start we have to flush any caches,
// they are not from this spec.
const set = ngMocksUniverse.getLocalMocks();
set.splice(0, set.length);
});
ngMocksStack.subscribePop(() => {
const set = ngMocksUniverse.getLocalMocks();
while (set.length) {
const [declaration, config] = set.pop() || /* istanbul ignore next */ [];
const universeConfig = ngMocksUniverse.configInstance.has(declaration)
? ngMocksUniverse.configInstance.get(declaration)
: /* istanbul ignore next */ {};
ngMocksUniverse.configInstance.set(declaration, {
...universeConfig,
...config,
});
}
});

const restore = (declaration: any, config: any): void => {
ngMocksUniverse.getLocalMocks().push([declaration, config]);
};

interface MockInstanceArgs {
accessor?: 'get' | 'set';
data?: any;
Expand All @@ -65,7 +41,10 @@ const parseMockInstanceArgs = (args: any[]): MockInstanceArgs => {
set.value = args[1];
set.accessor = args[2];
} else {
set.data = args[0];
set.value = args[0];
if (typeof set.value !== 'function') {
set.value = set.value?.init;
}
}

return set;
Expand All @@ -82,41 +61,9 @@ if (typeof beforeEach !== 'undefined') {
afterEach(() => (checkCollect = false));
}

const mockInstanceConfig = <T>(declaration: Type<T> | AbstractType<T> | InjectionToken<T>, data?: any): void => {
const config = typeof data === 'function' ? { init: data } : data;
const universeConfig = ngMocksUniverse.configInstance.has(declaration)
? ngMocksUniverse.configInstance.get(declaration)
: {};
restore(declaration, universeConfig);

if (config) {
ngMocksUniverse.configInstance.set(declaration, {
...universeConfig,
...config,
});
} else {
ngMocksUniverse.configInstance.set(declaration, {
...universeConfig,
init: undefined,
overloads: [],
});
}

if (!config) {
// When we are calling MockInstance without a config we need to reset it from the checks too.
for (let i = checkReset.length - 1; i >= 0; i -= 1) {
if (checkReset[i][0] === declaration && checkReset[i][2] === currentStack) {
checkReset.splice(i, 1);
}
}
} else if (checkCollect) {
checkReset.push([declaration, ngMocksUniverse.configInstance.get(declaration), currentStack]);
}
};

const mockInstanceMember = <T>(
const mockInstanceConfig = <T>(
declaration: Type<T> | AbstractType<T> | InjectionToken<T>,
name: string,
name: string | undefined,
stub: any,
encapsulation?: 'get' | 'set',
) => {
Expand Down Expand Up @@ -230,12 +177,25 @@ export function MockInstance<T>(
export function MockInstance<T>(declaration: Type<T> | AbstractType<T> | InjectionToken<T>, ...args: any[]) {
funcImportExists(declaration, 'MockInstance');

const { key, value, accessor, data } = parseMockInstanceArgs(args);
if (key) {
return mockInstanceMember(declaration, key, value, accessor);
const { key, value, accessor } = parseMockInstanceArgs(args);

if (value) {
return mockInstanceConfig(declaration, key, value, accessor);
}

mockInstanceConfig(declaration, data);
const config = ngMocksUniverse.configInstance.get(declaration) || /* istanbul ignore next */ {};

ngMocksUniverse.configInstance.set(declaration, {
...config,
overloads: [],
});

// When we are calling MockInstance without a config we need to reset it from the checks too.
for (let i = checkReset.length - 1; i >= 0; i -= 1) {
if (checkReset[i][0] === declaration && checkReset[i][2] === currentStack) {
checkReset.splice(i, 1);
}
}
}

/**
Expand Down
28 changes: 28 additions & 0 deletions tests/issue-1256/test.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { InjectionToken } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { MockInstance, MockProvider, MockReset } from 'ng-mocks';

const myToken = new InjectionToken('MY_TOKEN');

// @see https://github.com/ike18t/ng-mocks/issues/1256
// global MockInstance doesn't reset own customizations
describe('issue-1256', () => {
MockInstance.scope();

beforeEach(() =>
TestBed.configureTestingModule({
providers: [MockProvider(myToken, { test: 1 })],
}).compileComponents(),
);

it('changes value #1', () => {
MockInstance(myToken, () => ({ test: 2 }));
const value: any = TestBed.get(myToken);
expect(value.test).toEqual(2);
});

it('uses the default value', () => {
const value: any = TestBed.get(myToken);
expect(value.test).toEqual(1);
});
});

0 comments on commit 65da18d

Please sign in to comment.