Skip to content

Commit

Permalink
fix: don't call detectChanges when fixture is destroyed (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
timdeschryver authored Nov 23, 2019
1 parent 6989a66 commit e41c034
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 9 deletions.
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');
});

0 comments on commit e41c034

Please sign in to comment.