Skip to content

Commit

Permalink
refactor(core): allow disabling checkNoChanges with zoneless
Browse files Browse the repository at this point in the history
Disabling `checkNoChanges` in `ComponentFixture.detectChanges` was an
error for the zoneless fixture since it was not yet working. This now
allows checkNoChanges to be disabled. This option isn't really
used/shouldn't be used by anyone except the FW so marked as a refactor.
  • Loading branch information
atscott committed Aug 26, 2024
1 parent e283549 commit d743d63
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 19 deletions.
18 changes: 18 additions & 0 deletions packages/core/test/component_fixture_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -563,4 +563,22 @@ describe('ComponentFixture with zoneless', () => {
const fixture = TestBed.createComponent(App);
await expectAsync(fixture.whenStable()).toBeRejected();
});

it('can disable checkNoChanges', () => {
@Component({
template: '{{thing}}',
standalone: true,
})
class App {
thing = 1;
ngAfterViewChecked() {
++this.thing;
}
}

const fixture = TestBed.createComponent(App);
expect(() => fixture.detectChanges(false /*checkNoChanges*/)).not.toThrow();
// still throws if checkNoChanges is not disabled
expect(() => fixture.detectChanges()).toThrowError(/ExpressionChanged/);
});
});
39 changes: 20 additions & 19 deletions packages/core/testing/src/component_fixture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {TestBedApplicationErrorHandler} from './application_error_handler';

interface TestAppRef {
externalTestViews: Set<ViewRef>;
skipCheckNoChangesForExternalTestViews: Set<ViewRef>;
}

/**
Expand Down Expand Up @@ -131,27 +132,27 @@ export class ComponentFixture<T> {
* Trigger a change detection cycle for the component.
*/
detectChanges(checkNoChanges = true): void {
if (this.zonelessEnabled && !checkNoChanges) {
throw new Error(
'Cannot disable `checkNoChanges` in this configuration. ' +
'Use `fixture.componentRef.hostView.changeDetectorRef.detectChanges()` instead.',
);
}

this._effectRunner.flush();
if (this.zonelessEnabled) {
this._appRef.tick();
} else {
// Run the change detection inside the NgZone so that any async tasks as part of the change
// detection are captured by the zone and can be waited for in isStable.
// Run any effects that were created/dirtied during change detection. Such effects might become
// dirty in response to input signals changing.
this._ngZone.run(() => {
this.changeDetectorRef.detectChanges();
if (checkNoChanges) {
const originalCheckNoChanges = this.componentRef.changeDetectorRef.checkNoChanges;
try {
if (!checkNoChanges) {
this.componentRef.changeDetectorRef.checkNoChanges = () => {};
}

if (this.zonelessEnabled) {
this._appRef.tick();
} else {
// Run the change detection inside the NgZone so that any async tasks as part of the change
// detection are captured by the zone and can be waited for in isStable.
// Run any effects that were created/dirtied during change detection. Such effects might become
// dirty in response to input signals changing.
this._ngZone.run(() => {
this.changeDetectorRef.detectChanges();
this.checkNoChanges();
}
});
});
}
} finally {
this.componentRef.changeDetectorRef.checkNoChanges = originalCheckNoChanges;
}
this._effectRunner.flush();
}
Expand Down

0 comments on commit d743d63

Please sign in to comment.