Skip to content

Commit

Permalink
feat: add ability to turn off auto detect changes (#329)
Browse files Browse the repository at this point in the history
  • Loading branch information
timdeschryver authored Nov 25, 2022
1 parent ce3a612 commit 50aa0ac
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 22 deletions.
13 changes: 13 additions & 0 deletions projects/testing-library/src/lib/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,19 @@ export interface RenderResult<ComponentType, WrapperType = ComponentType> extend
}

export interface RenderComponentOptions<ComponentType, Q extends Queries = typeof queries> {
/**
* @description
* Automatically detect changes as a "real" running component would do.
*
* @default
* true
*
* @example
* const component = await render(AppComponent, {
* autoDetectChanges: false
* })
*/
autoDetectChanges?: boolean;
/**
* @description
* Will call detectChanges when the component is compiled
Expand Down
18 changes: 6 additions & 12 deletions projects/testing-library/src/lib/testing-library.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export async function render<SutType, WrapperType = SutType>(
const { dom: domConfig, ...globalConfig } = getConfig();
const {
detectChanges: detectChangesOnRender = true,
autoDetectChanges = true,
declarations = [],
imports = [],
providers = [],
Expand All @@ -64,14 +65,7 @@ export async function render<SutType, WrapperType = SutType>(
defaultImports = [],
} = { ...globalConfig, ...renderOptions };

dtlConfigure({
eventWrapper: (cb) => {
const result = cb();
detectChangesForMountedFixtures();
return result;
},
...domConfig,
});
dtlConfigure(domConfig);

TestBed.configureTestingModule({
declarations: addAutoDeclarations(sut, {
Expand Down Expand Up @@ -193,7 +187,6 @@ export async function render<SutType, WrapperType = SutType>(
result = doNavigate();
}

detectChanges();
return result ?? false;
};

Expand Down Expand Up @@ -223,7 +216,6 @@ export async function render<SutType, WrapperType = SutType>(
}

fixture = await createComponent(componentContainer);

setComponentProperties(fixture, properties);
setComponentInputs(fixture, inputs);
setComponentOutputs(fixture, outputs);
Expand All @@ -245,6 +237,10 @@ export async function render<SutType, WrapperType = SutType>(
fixture.componentInstance.ngOnChanges(changes);
}

if (autoDetectChanges) {
fixture.autoDetectChanges(true);
}

detectChanges = () => {
if (isAlive) {
fixture.detectChanges();
Expand Down Expand Up @@ -395,8 +391,6 @@ async function waitForWrapper<T>(
inFakeAsync = false;
}

detectChanges();

return await dtlWaitFor(() => {
setTimeout(() => detectChanges(), 0);
if (inFakeAsync) {
Expand Down
51 changes: 41 additions & 10 deletions projects/testing-library/tests/fire-event.spec.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,48 @@
import { Component } from '@angular/core';
import { render, fireEvent, screen } from '../src/public_api';
import { FormsModule } from '@angular/forms';

@Component({
selector: 'atl-fixture',
template: ` <input type="text" data-testid="input" /> `,
})
class FixtureComponent {}
describe('fireEvent', () => {
@Component({
selector: 'atl-fixture',
template: ` <input type="text" data-testid="input" [(ngModel)]="name" name="name" />
<div>Hello {{ name }}</div>`,
})
class FixtureComponent {
name = '';
}

test('does not call detect changes when fixture is destroyed', async () => {
const { fixture } = await render(FixtureComponent);
it('automatically detect changes when event is fired', async () => {
await render(FixtureComponent, {
imports: [FormsModule],
});

fixture.destroy();
fireEvent.input(screen.getByTestId('input'), { target: { value: 'Tim' } });

// should otherwise throw
fireEvent.input(screen.getByTestId('input'), { target: { value: 'Bonjour' } });
expect(screen.getByText('Hello Tim')).toBeInTheDocument();
});

it('can disable automatic detect changes when event is fired', async () => {
const { detectChanges } = await render(FixtureComponent, {
imports: [FormsModule],
autoDetectChanges: false,
});

fireEvent.input(screen.getByTestId('input'), { target: { value: 'Tim' } });

expect(screen.queryByText('Hello Tim')).not.toBeInTheDocument();

detectChanges();

expect(screen.getByText('Hello Tim')).toBeInTheDocument();
});

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

fixture.destroy();

// should otherwise throw
fireEvent.input(screen.getByTestId('input'), { target: { value: 'Bonjour' } });
});
});

0 comments on commit 50aa0ac

Please sign in to comment.