Skip to content

Commit 770fd9b

Browse files
committed
feat(host): allow to pass initial inputs when creating component
Also second parameter can trigger change detection to render view with initial inputs immediately
1 parent 08df9a6 commit 770fd9b

File tree

3 files changed

+56
-9
lines changed

3 files changed

+56
-9
lines changed

projects/ngx-testing/src/lib/factories.ts

+21-7
Original file line numberDiff line numberDiff line change
@@ -6,26 +6,35 @@ import { HostComponentService } from './host-component.service';
66
import { HostDirectiveService } from './host-directive.service';
77
import { NgxTestingModule } from './ngx-testing.module';
88
import {
9+
ComponentInputs,
910
TestingComponentModuleExtras,
1011
TestingDirectiveModuleExtras,
1112
} from './types';
1213

1314
export interface TestingFactory<T, H extends Host> {
1415
testModule: NgxTestingModule<T>;
1516
getHost(): H;
16-
createComponent(): Promise<H>;
17+
createComponent(
18+
inputs?: ComponentInputs<T>,
19+
detectChanges?: boolean,
20+
): Promise<H>;
1721
}
1822

1923
export function getTestingForComponent<T>(
2024
type: Type<T>,
2125
extras?: TestingComponentModuleExtras,
2226
): TestingFactory<T, HostComponentService<T>> {
2327
const testModule = NgxTestingModule.forComponent<T>(type, extras);
28+
2429
const getHost = () =>
25-
TestBed.get(HostComponentService) as HostComponentService<T>;
26-
const createComponent = () =>
30+
TestBed.inject(HostComponentService) as HostComponentService<T>;
31+
32+
const createComponent = (
33+
inputs?: ComponentInputs<T>,
34+
detectChanges?: boolean,
35+
) =>
2736
getHost()
28-
.createComponent()
37+
.createComponent(inputs, detectChanges)
2938
.then(getHost);
3039

3140
return { testModule, getHost, createComponent };
@@ -36,11 +45,16 @@ export function getTestingForDirective<T>(
3645
extras?: TestingDirectiveModuleExtras,
3746
): TestingFactory<T, HostDirectiveService<T>> {
3847
const testModule = NgxTestingModule.forDirective<T>(type, extras);
48+
3949
const getHost = () =>
40-
TestBed.get(HostDirectiveService) as HostDirectiveService<T>;
41-
const createComponent = () =>
50+
TestBed.inject(HostDirectiveService) as HostDirectiveService<T>;
51+
52+
const createComponent = (
53+
inputs?: ComponentInputs<T>,
54+
detectChanges?: boolean,
55+
) =>
4256
getHost()
43-
.createComponent()
57+
.createComponent(inputs, detectChanges)
4458
.then(getHost);
4559

4660
return { testModule, getHost, createComponent };

projects/ngx-testing/src/lib/host.ts

+22-2
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { By } from '@angular/platform-browser';
1010

1111
import { HostGeneratorService } from './host-generator.service';
1212
import { TestTypeToken } from './tokens';
13-
import { AsHostComponent, DebugElementTyped } from './types';
13+
import { AsHostComponent, ComponentInputs, DebugElementTyped } from './types';
1414

1515
export abstract class Host<T = any> implements OnDestroy {
1616
private hostGeneratorService = this.injector.get(HostGeneratorService);
@@ -63,12 +63,32 @@ export abstract class Host<T = any> implements OnDestroy {
6363
}
6464
}
6565

66-
async createComponent(): Promise<ComponentFixture<AsHostComponent<T>>> {
66+
async createComponent(
67+
inputs?: ComponentInputs<T>,
68+
detectChanges = false,
69+
): Promise<ComponentFixture<AsHostComponent<T>>> {
6770
await this.compileComponents();
6871
this._fixture = TestBed.createComponent(this.hostComponentType);
72+
73+
if (inputs) {
74+
this.setInputs(inputs);
75+
}
76+
77+
if (detectChanges) {
78+
this.detectChanges();
79+
}
80+
6981
return this._fixture;
7082
}
7183

84+
setInputs(inputs: ComponentInputs<T>, detectChanges = false) {
85+
Object.assign(this.hostComponent, inputs);
86+
87+
if (detectChanges) {
88+
this.detectChanges();
89+
}
90+
}
91+
7292
overrideHostTemplate(tpl: string): void {
7393
TestBed.overrideTemplate(this.hostComponentType, tpl);
7494
}

projects/ngx-testing/src/lib/types.ts

+13
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,19 @@ export interface HostComponent<T> {
4141
export type AsHostComponent<T> = HostComponent<T> &
4242
{ [K in keyof T]: T[K] extends EventEmitter<infer A> ? OutputMock<A> : T[K] };
4343

44+
/**
45+
* Represents inputs of component `T`
46+
*/
47+
export type ComponentInputs<T> = Partial<
48+
ExcludePropsByType<T, EventEmitter<any> | Function>
49+
>;
50+
51+
export type FilterKeysByType<T, E> = {
52+
[K in keyof T]: T[K] extends E ? never : K;
53+
}[keyof T];
54+
55+
export type ExcludePropsByType<T, K> = Pick<T, FilterKeysByType<T, K>>;
56+
4457
export type TemplateBindings = ComponentFactory<any>['inputs'];
4558
export type TemplateBinding = TemplateBindings extends Array<infer T>
4659
? T

0 commit comments

Comments
 (0)