Skip to content

Commit 6a7c5ae

Browse files
atscottalxhub
authored andcommitted
refactor(core): allow disabling checkNoChanges with zoneless (angular#57416)
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. PR Close angular#57416
1 parent 455cd1e commit 6a7c5ae

File tree

2 files changed

+38
-19
lines changed

2 files changed

+38
-19
lines changed

packages/core/test/component_fixture_spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,4 +563,22 @@ describe('ComponentFixture with zoneless', () => {
563563
const fixture = TestBed.createComponent(App);
564564
await expectAsync(fixture.whenStable()).toBeRejected();
565565
});
566+
567+
it('can disable checkNoChanges', () => {
568+
@Component({
569+
template: '{{thing}}',
570+
standalone: true,
571+
})
572+
class App {
573+
thing = 1;
574+
ngAfterViewChecked() {
575+
++this.thing;
576+
}
577+
}
578+
579+
const fixture = TestBed.createComponent(App);
580+
expect(() => fixture.detectChanges(false /*checkNoChanges*/)).not.toThrow();
581+
// still throws if checkNoChanges is not disabled
582+
expect(() => fixture.detectChanges()).toThrowError(/ExpressionChanged/);
583+
});
566584
});

packages/core/testing/src/component_fixture.ts

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import {TestBedApplicationErrorHandler} from './application_error_handler';
3434

3535
interface TestAppRef {
3636
externalTestViews: Set<ViewRef>;
37+
skipCheckNoChangesForExternalTestViews: Set<ViewRef>;
3738
}
3839

3940
/**
@@ -131,27 +132,27 @@ export class ComponentFixture<T> {
131132
* Trigger a change detection cycle for the component.
132133
*/
133134
detectChanges(checkNoChanges = true): void {
134-
if (this.zonelessEnabled && !checkNoChanges) {
135-
throw new Error(
136-
'Cannot disable `checkNoChanges` in this configuration. ' +
137-
'Use `fixture.componentRef.hostView.changeDetectorRef.detectChanges()` instead.',
138-
);
139-
}
140-
141135
this._effectRunner.flush();
142-
if (this.zonelessEnabled) {
143-
this._appRef.tick();
144-
} else {
145-
// Run the change detection inside the NgZone so that any async tasks as part of the change
146-
// detection are captured by the zone and can be waited for in isStable.
147-
// Run any effects that were created/dirtied during change detection. Such effects might become
148-
// dirty in response to input signals changing.
149-
this._ngZone.run(() => {
150-
this.changeDetectorRef.detectChanges();
151-
if (checkNoChanges) {
136+
const originalCheckNoChanges = this.componentRef.changeDetectorRef.checkNoChanges;
137+
try {
138+
if (!checkNoChanges) {
139+
this.componentRef.changeDetectorRef.checkNoChanges = () => {};
140+
}
141+
142+
if (this.zonelessEnabled) {
143+
this._appRef.tick();
144+
} else {
145+
// Run the change detection inside the NgZone so that any async tasks as part of the change
146+
// detection are captured by the zone and can be waited for in isStable.
147+
// Run any effects that were created/dirtied during change detection. Such effects might become
148+
// dirty in response to input signals changing.
149+
this._ngZone.run(() => {
150+
this.changeDetectorRef.detectChanges();
152151
this.checkNoChanges();
153-
}
154-
});
152+
});
153+
}
154+
} finally {
155+
this.componentRef.changeDetectorRef.checkNoChanges = originalCheckNoChanges;
155156
}
156157
this._effectRunner.flush();
157158
}

0 commit comments

Comments
 (0)