Skip to content

Commit

Permalink
fix(mock-render): skipping proxy for bindings from factory #621
Browse files Browse the repository at this point in the history
  • Loading branch information
satanTime committed May 31, 2021
1 parent fda5d7a commit f4dae60
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 7 deletions.
10 changes: 8 additions & 2 deletions libs/ng-mocks/src/lib/mock-render/func.install-prop-reader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,18 @@ const extractAllKeys = (instance: object) => [

const extractOwnKeys = (instance: object) => [...Object.getOwnPropertyNames(instance), ...Object.keys(instance)];

export default (reader: Record<keyof any, any>, source?: Record<keyof any, any>, force: boolean = false): void => {
export default (
reader: Record<keyof any, any>,
source: Record<keyof any, any> | undefined,
extra: string[],
force: boolean = false,
): void => {
if (!source) {
return;
}
const exists = extractOwnKeys(reader);
for (const key of extractAllKeys(source)) {
const fields = [...extractAllKeys(source), ...extra];
for (const key of fields) {
if (!force && exists.indexOf(key) !== -1) {
continue;
}
Expand Down
10 changes: 5 additions & 5 deletions libs/ng-mocks/src/lib/mock-render/mock-render-factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const renderDeclaration = (fixture: any, template: any, params: any): void => {
get: () => ngMocks.get(fixture.point, template),
});
}
tryWhen(!params, () => funcInstallPropReader(fixture.componentInstance, fixture.point?.componentInstance));
tryWhen(!params, () => funcInstallPropReader(fixture.componentInstance, fixture.point?.componentInstance, []));
};

const renderInjection = (fixture: any, template: any, params: any): void => {
Expand All @@ -45,7 +45,7 @@ const renderInjection = (fixture: any, template: any, params: any): void => {
componentInstance: instance,
nativeElement: MockService(HTMLElement),
});
funcInstallPropReader(fixture.componentInstance, fixture.point.componentInstance, true);
funcInstallPropReader(fixture.componentInstance, fixture.point.componentInstance, [], true);
};

const tryWhen = (flag: boolean, callback: () => void) => {
Expand Down Expand Up @@ -87,11 +87,11 @@ const flushTestBed = (flags: Record<string, any>): void => {
}
};

const generateFactory = (componentCtor: Type<any>, bindings: undefined | null | any[], template: any) => {
const generateFactory = (componentCtor: Type<any>, bindings: undefined | null | string[], template: any) => {
const result = (params: any, detectChanges?: boolean) => {
const fixture: any = TestBed.createComponent(componentCtor);

funcInstallPropReader(fixture.componentInstance, params);
funcInstallPropReader(fixture.componentInstance, params ?? {}, bindings ?? []);
coreDefineProperty(fixture, 'ngMocksStackId', ngMocksUniverse.global.get('reporter-stack-id'));

if (detectChanges === undefined || detectChanges) {
Expand Down Expand Up @@ -178,7 +178,7 @@ function MockRenderFactory<MComponent = void, TKeys extends keyof any = keyof an
options?: IMockRenderOptions,
): MockRenderFactory<MComponent, TKeys>;

function MockRenderFactory<MComponent, TKeys extends keyof any>(
function MockRenderFactory<MComponent, TKeys extends string>(
template: string | AnyType<MComponent> | InjectionToken<MComponent>,
bindings?: undefined | null | TKeys[],
options: IMockRenderOptions = {},
Expand Down
59 changes: 59 additions & 0 deletions tests/issue-621/test.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import {
Component,
EventEmitter,
Input,
Output,
} from '@angular/core';
import { MockBuilder, MockRenderFactory, ngMocks } from 'ng-mocks';

@Component({
selector: 'target',
template: `<button (click)="update.emit(value)">
{{ value }}
</button>`,
})
class TargetComponent {
@Output() public readonly update = new EventEmitter<
number | null | undefined
>();
@Input() public readonly value: number | null | undefined = null;
}

describe('issue-621', () => {
ngMocks.faster();

beforeAll(() => MockBuilder(TargetComponent));

let factory: MockRenderFactory<TargetComponent, 'update' | 'value'>;
beforeAll(
() =>
(factory = MockRenderFactory(TargetComponent, [
'update',
'value',
])),
);

it('does not proxy update inout', () => {
const fixture = factory();
expect(fixture.componentInstance.value).toEqual(undefined);
expect(fixture.point.componentInstance.value).toEqual(undefined);

fixture.componentInstance.value = 1;
expect(fixture.componentInstance.value).toEqual(1);
expect(fixture.point.componentInstance.value).toEqual(undefined);
});

it('does not proxy update inout', () => {
const fixture = factory();
expect(fixture.componentInstance.update).toEqual(undefined);

fixture.componentInstance.value = 5;
// sets the value to point
fixture.detectChanges();

// checking that the emitted value comes
// back to the middleware component
ngMocks.click('button');
expect(fixture.componentInstance.update).toEqual(5);
});
});

0 comments on commit f4dae60

Please sign in to comment.