Skip to content

Commit

Permalink
feat: allow creation of component via its type
Browse files Browse the repository at this point in the history
  • Loading branch information
timdeschryver committed Jun 15, 2018
1 parent b260887 commit d9f292c
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 53 deletions.
3 changes: 1 addition & 2 deletions projects/ngx-testing-library/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@
"homepage": "https://github.com/tdeschryver/ngx-testing-library#readme",
"peerDependencies": {
"@angular/common": "^6.0.0-rc.0 || ^6.0.0",
"@angular/core": "^6.0.0-rc.0 || ^6.0.0",
"@angular/testing": "^6.0.0-rc.0 || ^6.0.0"
"@angular/core": "^6.0.0-rc.0 || ^6.0.0"
},
"dependencies": {
"dom-testing-library": "^2.5.0"
Expand Down
51 changes: 51 additions & 0 deletions projects/ngx-testing-library/src/lib/models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { Type } from '@angular/core';

export interface Result {
container: any;
get: (token: any, notFoundValue?: any) => any;
getComponentInstance: <T>(selectorOrComponent: string | Type<T>) => T;
debug: () => void;
detectChanges: (checkNoChanges?: boolean) => void;
fixture: any;
queryByPlaceholderText: any;
queryAllByPlaceholderText: any;
getByPlaceholderText: any;
getAllByPlaceholderText: any;
queryByText: any;
queryAllByText: any;
getByText: any;
getAllByText: any;
queryByLabelText: any;
queryAllByLabelText: any;
getByLabelText: any;
getAllByLabelText: any;
queryByAltText: any;
queryAllByAltText: any;
getByAltText: any;
getAllByAltText: any;
queryByTestId: any;
queryAllByTestId: any;
getByTestId: any;
getAllByTestId: any;
queryByTitle: any;
queryAllByTitle: any;
getByTitle: any;
getAllByTitle: any;
queryByValue: any;
queryAllByValue: any;
getByValue: any;
getAllByValue: any;
}

export interface Options {
detectChanges?: boolean;
declarations: any[];
providers?: any[];
imports?: any[];
schemas?: any[];
}

export interface ComponentInput<T> {
component: Type<T>;
parameters?: Partial<T>;
}
86 changes: 36 additions & 50 deletions projects/ngx-testing-library/src/lib/ngx-testing-library.ts
Original file line number Diff line number Diff line change
@@ -1,76 +1,62 @@
import { Component, NgModule } from '@angular/core';
import { Component, NgModule, Type } from '@angular/core';
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { getQueriesForElement, prettyDOM } from 'dom-testing-library';

import { Options, Result, ComponentInput } from './models';

@Component({ selector: 'test-component', template: '' })
class TestComponent {}

export async function createComponent(
template: string,
{ detectChanges = true, declarations = [], providers = [], imports = [], schemas = [] } = {},
): Promise<{
container: any;
get: (token: any, notFoundValue?: any) => any;
getComponentInstance: <T>(selector: string) => T;
debug: () => void;
detectChanges: (checkNoChanges?: boolean) => void;
fixture: any;
queryByPlaceholderText: any;
queryAllByPlaceholderText: any;
getByPlaceholderText: any;
getAllByPlaceholderText: any;
queryByText: any;
queryAllByText: any;
getByText: any;
getAllByText: any;
queryByLabelText: any;
queryAllByLabelText: any;
getByLabelText: any;
getAllByLabelText: any;
queryByAltText: any;
queryAllByAltText: any;
getByAltText: any;
getAllByAltText: any;
queryByTestId: any;
queryAllByTestId: any;
getByTestId: any;
getAllByTestId: any;
queryByTitle: any;
queryAllByTitle: any;
getByTitle: any;
getAllByTitle: any;
queryByValue: any;
queryAllByValue: any;
getByValue: any;
getAllByValue: any;
}> {
export async function createComponent(template: string, options: Options): Promise<Result>;
export async function createComponent<T>(component: ComponentInput<T>, options: Options): Promise<Result>;
export async function createComponent<T>(
templateOrComponent: string | ComponentInput<T>,
{ detectChanges = true, declarations = [], providers = [], imports = [], schemas = [] }: Options,
): Promise<Result> {
const isTemplate = typeof templateOrComponent === 'string';
const extraDeclarations = isTemplate ? [TestComponent] : [];

TestBed.configureTestingModule({
declarations: [TestComponent, ...declarations],
declarations: [...declarations, ...extraDeclarations],
providers: [...providers],
imports: [...imports],
schemas: [...schemas],
});

TestBed.overrideComponent(TestComponent, {
set: {
template,
},
});
if (isTemplate) {
TestBed.overrideComponent(TestComponent, {
set: {
template: <string>templateOrComponent,
},
});
}

await TestBed.compileComponents();

const fixture = TestBed.createComponent(TestComponent);
if (detectChanges) {
fixture.detectChanges();
let fixture;
if (isTemplate) {
fixture = TestBed.createComponent(TestComponent);
if (detectChanges) {
fixture.detectChanges();
}
} else {
const { component, parameters = [] } = <ComponentInput<T>>templateOrComponent;
fixture = TestBed.createComponent(component);
for (const key of Object.keys(parameters)) {
fixture.componentInstance[key] = parameters[key];
}
}

// Currently this isn't perfect because the typings from dom-testing-library are for TS 2.8
return {
fixture,
container: fixture.nativeElement,
get: TestBed.get,
getComponentInstance: <T>(selector: string) => fixture.debugElement.query(By.css(selector)).componentInstance as T,
getComponentInstance: <C>(selectorOrComponent: string | C) =>
typeof selectorOrComponent === 'string'
? fixture.debugElement.query(By.css(selectorOrComponent)).componentInstance
: fixture.componentInstance,
debug: () => console.log(prettyDOM(fixture.nativeElement)),
detectChanges: (checkNoChanges?: boolean) => fixture.detectChanges(checkNoChanges),
...getQueriesForElement(fixture.nativeElement),
Expand Down
1 change: 1 addition & 0 deletions projects/ngx-testing-library/src/public_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
* Public API Surface of ngx-testing-library
*/

export * from './lib/models';
export * from './lib/ngx-testing-library';
export { fireEvent } from 'dom-testing-library';
71 changes: 70 additions & 1 deletion projects/ngx-testing-library/tests/counter.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class CounterComponent {
}

test('Counter actions', async () => {
const { detectChanges, getByText, getByTestId, debug } = await createComponent('<counter [counter]="10"></counter>', {
const { detectChanges, getByText, getByTestId } = await createComponent('<counter [counter]="10"></counter>', {
declarations: [CounterComponent],
});

Expand Down Expand Up @@ -54,3 +54,72 @@ test('Counter actions - fireEvent', async () => {
expect(getByText('Current Count: 12')).toBeTruthy();
expect(getByTestId('count').textContent).toBe('Current Count: 12');
});

test('Counter actions via component', async () => {
const { getComponentInstance } = await createComponent<CounterComponent>(
{
component: CounterComponent,
parameters: {
counter: 10,
},
},
{
declarations: [CounterComponent],
},
);

const counter = getComponentInstance(CounterComponent);
counter.increment();
counter.increment();
counter.increment();
expect(counter.counter).toBe(13);

counter.decrement();
expect(counter.counter).toBe(12);
});

test('Counter actions via component without parameters', async () => {
const { getComponentInstance } = await createComponent<CounterComponent>(
{
component: CounterComponent,
},
{
declarations: [CounterComponent],
},
);

const counter = getComponentInstance(CounterComponent);
counter.increment();
counter.increment();
counter.increment();
expect(counter.counter).toBe(3);

counter.decrement();
expect(counter.counter).toBe(2);
});

test('Counter via component - test template', async () => {
const { getByText, detectChanges, getByTestId } = await createComponent<CounterComponent>(
{
component: CounterComponent,
parameters: {
counter: 10,
},
},
{
declarations: [CounterComponent],
},
);

getByText('+').click();
getByText('+').click();
getByText('+').click();
detectChanges();
expect(getByText('Current Count: 13')).toBeTruthy();
expect(getByTestId('count').textContent).toBe('Current Count: 13');

getByText('-').click();
detectChanges();
expect(getByText('Current Count: 12')).toBeTruthy();
expect(getByTestId('count').textContent).toBe('Current Count: 12');
});

0 comments on commit d9f292c

Please sign in to comment.