angular/packages/platform-browser/testing/src/browser.ts
Alex Rickabaugh 38c9f08c8d refactor(core): decouple effects from change detection (#51049)
Previously effects were queued as they became dirty, and this queue was
flushed at various checkpoints during the change detection cycle. The result
was that change detection _was_ the effect runner, and without executing CD,
effects would not execute. This leads a particular tradeoff:

* effects are subject to unidirectional data flow (bad for dx)
* effects don't cause a new round of CD (good/bad depending on use case)
* effects can be used to implement control flow efficiently (desirable)

This commit changes the scheduling mechanism. Effects are now scheduled via
the microtask queue. This changes the tradeoffs:

* effects are no longer limited by unidirectional data flow (easy dx)
* effects registered in the Angular zone will trigger CD after they run
  (same as `Promise.resolve` really)
* the public `effect()` type of effect probably isn't a good building block
  for our built-in control flow, and we'll need a new internal abstraction.

As `effect()` is in developer preview, changing the execution timing is not
considered breaking even though it may impact current users.

PR Close #51049
2023-09-12 08:12:56 -07:00

44 lines
1.4 KiB
TypeScript

/**
* @license
* Copyright Google LLC All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
import {PlatformLocation} from '@angular/common';
import {MockPlatformLocation} from '@angular/common/testing';
import {APP_ID, createPlatformFactory, NgModule, PLATFORM_INITIALIZER, platformCore, provideZoneChangeDetection, StaticProvider, ɵEffectScheduler as EffectScheduler, ɵZoneAwareQueueingScheduler as ZoneAwareQueueingScheduler} from '@angular/core';
import {BrowserModule, ɵBrowserDomAdapter as BrowserDomAdapter} from '@angular/platform-browser';
function initBrowserTests() {
BrowserDomAdapter.makeCurrent();
}
const _TEST_BROWSER_PLATFORM_PROVIDERS: StaticProvider[] =
[{provide: PLATFORM_INITIALIZER, useValue: initBrowserTests, multi: true}];
/**
* Platform for testing
*
* @publicApi
*/
export const platformBrowserTesting =
createPlatformFactory(platformCore, 'browserTesting', _TEST_BROWSER_PLATFORM_PROVIDERS);
/**
* NgModule for testing.
*
* @publicApi
*/
@NgModule({
exports: [BrowserModule],
providers: [
{provide: APP_ID, useValue: 'a'},
provideZoneChangeDetection(),
{provide: PlatformLocation, useClass: MockPlatformLocation},
{provide: ZoneAwareQueueingScheduler},
{provide: EffectScheduler, useExisting: ZoneAwareQueueingScheduler},
]
})
export class BrowserTestingModule {
}