Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 18 additions & 9 deletions projects/testing-library/src/lib/testing-library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export async function render<SutType, WrapperType = SutType>(
renderOptions: RenderComponentOptions<SutType> | RenderDirectiveOptions<SutType, WrapperType> = {},
): Promise<RenderResult<SutType>> {
const {
detectChanges = true,
detectChanges: detectChangesOnRender = true,
declarations = [],
imports = [],
providers = [],
Expand All @@ -42,12 +42,12 @@ export async function render<SutType, WrapperType = SutType>(
componentProperties = {},
componentProviders = [],
excludeComponentDeclaration = false,
routes
routes,
} = renderOptions as RenderDirectiveOptions<SutType, WrapperType>;

TestBed.configureTestingModule({
declarations: addAutoDeclarations(sut, { declarations, excludeComponentDeclaration, template, wrapper }),
imports: addAutoImports({imports, routes}),
imports: addAutoImports({ imports, routes }),
providers: [...providers],
schemas: [...schemas],
});
Expand All @@ -66,15 +66,24 @@ export async function render<SutType, WrapperType = SutType>(

await TestBed.compileComponents();

if (detectChanges) {
fixture.detectChanges();
let isAlive = true;
fixture.componentRef.onDestroy(() => (isAlive = false));

function detectChanges() {
if (isAlive) {
fixture.detectChanges();
}
}

if (detectChangesOnRender) {
detectChanges();
}

const eventsWithDetectChanges = Object.keys(fireEvent).reduce(
(events, key) => {
events[key] = (element: HTMLElement, options?: {}) => {
const result = fireEvent[key](element, options);
fixture.detectChanges();
detectChanges();
return result;
};
return events;
Expand All @@ -93,8 +102,8 @@ export async function render<SutType, WrapperType = SutType>(
const href = typeof elementOrPath === 'string' ? elementOrPath : elementOrPath.getAttribute('href');

let result;
await zone.run(() => result = router.navigate([basePath + href]));
fixture.detectChanges();
await zone.run(() => (result = router.navigate([basePath + href])));
detectChanges();
return result;
}
const debugElement = fixture.debugElement.query(By.directive(sut));
Expand All @@ -104,7 +113,7 @@ export async function render<SutType, WrapperType = SutType>(
debugElement,
container: fixture.nativeElement,
debug: (element = fixture.nativeElement) => console.log(prettyDOM(element)),
detectChanges: () => fixture.detectChanges(),
detectChanges,
...getQueriesForElement(fixture.nativeElement, queries),
...eventsWithDetectChanges,
type: createType(eventsWithDetectChanges),
Expand Down
9 changes: 9 additions & 0 deletions projects/testing-library/tests/detect-changes.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,13 @@ describe('detectChanges', () => {

expect(getByTestId('button').innerHTML).toBe('Button updated after 400ms');
}));

test('does not throw on a destroyed fixture', async () => {
const { getByTestId, type, fixture } = await render(FixtureComponent, { imports: [ReactiveFormsModule] });

fixture.destroy();

type(getByTestId('input'), 'What a great day!');
expect(getByTestId('button').innerHTML).toBe('Button');
});
});
20 changes: 20 additions & 0 deletions projects/testing-library/tests/fire-event.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { Component } from '@angular/core';
import { render } from '../src/public_api';

@Component({
selector: 'fixture',
template: `
<input type="text" data-testid="input" />
`,
})
class FixtureComponent {}

test('does not call detect changes when fixture is destroyed', async () => {
const component = await render(FixtureComponent);

component.fixture.destroy();

// should otherwise throw
component.input(component.getByTestId('input'), { target: { value: 'Bonjour' } });
component.type(component.getByTestId('input'), 'Alles klar');
});