Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c175bca

Browse files
atscottAndrewKushnir
authored andcommitted
fix(core): DeferBlockFixture.render should not wait for stability (#55271)
The `DeferBlockFixture.render` function should not await the `whenStable` promise of the fixture. This does not allow developers to test any intermediate states that might occur between rendering the initial content and the full app stability. fixes #55235 PR Close #55271
1 parent 86967af commit c175bca

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

‎packages/core/src/defer/instructions.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -694,15 +694,16 @@ export function triggerPrefetching(tDetails: TDeferBlockDetails, lView: LView, t
694694
* @param tDetails Static information about this defer block.
695695
* @param lView LView of a host view.
696696
*/
697-
export function triggerResourceLoading(tDetails: TDeferBlockDetails, lView: LView, tNode: TNode) {
697+
export function triggerResourceLoading(
698+
tDetails: TDeferBlockDetails, lView: LView, tNode: TNode): Promise<unknown> {
698699
const injector = lView[INJECTOR]!;
699700
const tView = lView[TVIEW];
700701

701702
if (tDetails.loadingState !== DeferDependenciesLoadingState.NOT_STARTED) {
702703
// If the loading status is different from initial one, it means that
703704
// the loading of dependencies is in progress and there is nothing to do
704705
// in this function. All details can be obtained from the `tDetails` object.
705-
return;
706+
return tDetails.loadingPromise ?? Promise.resolve();
706707
}
707708

708709
const lDetails = getLDeferBlockDetails(lView, tNode);
@@ -739,7 +740,7 @@ export function triggerResourceLoading(tDetails: TDeferBlockDetails, lView: LVie
739740
tDetails.loadingState = DeferDependenciesLoadingState.COMPLETE;
740741
pendingTasks.remove(taskId);
741742
});
742-
return;
743+
return tDetails.loadingPromise;
743744
}
744745

745746
// Start downloading of defer block dependencies.
@@ -805,6 +806,7 @@ export function triggerResourceLoading(tDetails: TDeferBlockDetails, lView: LVie
805806
}
806807
}
807808
});
809+
return tDetails.loadingPromise;
808810
}
809811

810812
/** Utility function to render placeholder content (if present) */

‎packages/core/test/defer_fixture_spec.ts

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
*/
88

99
import {ɵPLATFORM_BROWSER_ID as PLATFORM_BROWSER_ID} from '@angular/common';
10-
import {Component, PLATFORM_ID} from '@angular/core';
10+
import {Component, PLATFORM_ID, ɵPendingTasks as PendingTasks} from '@angular/core';
1111
import {DeferBlockBehavior, DeferBlockState, TestBed} from '@angular/core/testing';
1212
import {expect} from '@angular/platform-browser/testing/src/matchers';
1313

@@ -190,6 +190,42 @@ describe('DeferFixture', () => {
190190
expect(el.querySelector('.more')).toBeDefined();
191191
});
192192

193+
it('should not wait forever if application is unstable for a long time', async () => {
194+
@Component({
195+
selector: 'defer-comp',
196+
standalone: true,
197+
imports: [SecondDeferredComp],
198+
template: `
199+
<div>
200+
@defer (on immediate) {
201+
<second-deferred-comp />
202+
}
203+
</div>
204+
`
205+
})
206+
class DeferComp {
207+
constructor(taskService: PendingTasks) {
208+
// Add a task and never remove it. Keeps application unstable forever
209+
taskService.add();
210+
}
211+
}
212+
213+
TestBed.configureTestingModule({
214+
imports: [
215+
DeferComp,
216+
SecondDeferredComp,
217+
],
218+
providers: COMMON_PROVIDERS,
219+
deferBlockBehavior: DeferBlockBehavior.Manual,
220+
});
221+
222+
const componentFixture = TestBed.createComponent(DeferComp);
223+
const deferBlock = (await componentFixture.getDeferBlocks())[0];
224+
const el = componentFixture.nativeElement as HTMLElement;
225+
await deferBlock.render(DeferBlockState.Complete);
226+
expect(el.querySelector('.more')).toBeDefined();
227+
});
228+
193229
it('should work with templates that have local refs', async () => {
194230
@Component({
195231
selector: 'defer-comp',

‎packages/core/testing/src/defer.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ export class DeferBlockFixture {
4040
const skipTimerScheduling = true;
4141
renderDeferBlockState(state, this.block.tNode, this.block.lContainer, skipTimerScheduling);
4242
this.componentFixture.detectChanges();
43-
return this.componentFixture.whenStable();
4443
}
4544

4645
/**

0 commit comments

Comments
 (0)