Skip to content

Commit 24268f8

Browse files
committed
fix circular dep
1 parent 746ebf0 commit 24268f8

File tree

4 files changed

+115
-105
lines changed

4 files changed

+115
-105
lines changed

src/cdk/testing/change-detection.ts

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
/**
2+
* @license
3+
* Copyright Google LLC All Rights Reserved.
4+
*
5+
* Use of this source code is governed by an MIT-style license that can be
6+
* found in the LICENSE file at https://angular.io/license
7+
*/
8+
9+
import {BehaviorSubject, Subscription} from 'rxjs';
10+
11+
/** Represents the status of change detection batching. */
12+
export interface ChangeDetectionBatchingStatus {
13+
/** Whether change detection is batching. */
14+
isBatching: boolean;
15+
/**
16+
* An optional callback, if present it indicates that change detection should be run immediately,
17+
* while handling the batching status change. The callback should then be called as soon as change
18+
* detection is done.
19+
*/
20+
onDetectChangesNow?: () => void;
21+
}
22+
23+
/** Subject used to dispatch and listen for changes to the change detection batching status . */
24+
const batchChangeDetectionSubject = new BehaviorSubject<ChangeDetectionBatchingStatus>({
25+
isBatching: false
26+
});
27+
28+
/** The current subscription to `batchChangeDetectionSubject`. */
29+
let batchChangeDetectionSubscription: Subscription | null;
30+
31+
/**
32+
* The default handler for change detection batching status changes. This handler will be used if
33+
* the specific environment does not install its own.
34+
* @param status The new change detection batching status.
35+
*/
36+
function defaultBatchChangeDetectionHandler(status: ChangeDetectionBatchingStatus) {
37+
status.onDetectChangesNow?.();
38+
}
39+
40+
/**
41+
* Allows a test `HarnessEnvironment` to install its own handler for change detection batching
42+
* status changes.
43+
* @param handler The handler for the change detection batching status.
44+
*/
45+
export function handleChangeDetectionBatching(
46+
handler: (status: ChangeDetectionBatchingStatus) => void) {
47+
stopHandlingChangeDetectionBatching();
48+
batchChangeDetectionSubscription = batchChangeDetectionSubject.subscribe(handler);
49+
}
50+
51+
/** Allows a `HarnessEnvironment` to stop handling change detection batching status changes. */
52+
export function stopHandlingChangeDetectionBatching() {
53+
batchChangeDetectionSubscription?.unsubscribe();
54+
batchChangeDetectionSubscription = null;
55+
}
56+
57+
/**
58+
* Batches together triggering of change detection over the duration of the given function.
59+
* @param fn The function to call with batched change detection.
60+
* @param triggerBeforeAndAfter Optionally trigger change detection once before and after the batch
61+
* operation. If false, change detection will not be triggered.
62+
* @return The result of the given function.
63+
*/
64+
async function batchChangeDetection<T>(fn: () => Promise<T>, triggerBeforeAndAfter: boolean) {
65+
// If change detection batching is already in progress, just run the function.
66+
if (batchChangeDetectionSubject.getValue().isBatching) {
67+
return await fn();
68+
}
69+
70+
// If nothing is handling change detection batching, install the default handler.
71+
if (!batchChangeDetectionSubscription) {
72+
batchChangeDetectionSubject.subscribe(defaultBatchChangeDetectionHandler);
73+
}
74+
75+
if (triggerBeforeAndAfter) {
76+
await new Promise(resolve => batchChangeDetectionSubject.next({
77+
isBatching: true,
78+
onDetectChangesNow: resolve,
79+
}));
80+
const result = await fn();
81+
await new Promise(resolve => batchChangeDetectionSubject.next({
82+
isBatching: false,
83+
onDetectChangesNow: resolve,
84+
}));
85+
return result;
86+
} else {
87+
batchChangeDetectionSubject.next({isBatching: true});
88+
const result = await fn();
89+
batchChangeDetectionSubject.next({isBatching: false});
90+
return result;
91+
}
92+
}
93+
94+
/**
95+
* Disables the harness system's auto change detection for the duration of the given function.
96+
* @param fn The function to disable auto change detection for.
97+
* @return The result of the given function.
98+
*/
99+
export async function noAutoChangeDetection<T>(fn: () => Promise<T>) {
100+
return batchChangeDetection(fn, false);
101+
}
102+
103+
/**
104+
* Resolves the given list of async values in parallel (i.e. via Promise.all) while batching change
105+
* detection over the entire operation such that change detection occurs exactly once before
106+
* resolving the values and once after.
107+
* @param values The async values to resolve in parallel with batched change detection.
108+
* @return The resolved values.
109+
*/
110+
export async function parallel<T>(values: Iterable<T | PromiseLike<T>>) {
111+
return batchChangeDetection(() => Promise.all(values), true);
112+
}

src/cdk/testing/component-harness.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {parallel} from '@angular/cdk/testing';
9+
import {parallel} from './change-detection';
1010
import {TestElement} from './test-element';
1111

1212
/** An async function that returns a promise when called. */

src/cdk/testing/harness-environment.ts

Lines changed: 1 addition & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {BehaviorSubject, Subscription} from 'rxjs';
9+
import {parallel} from './change-detection';
1010
import {
1111
AsyncFactoryFn,
1212
ComponentHarness,
@@ -37,109 +37,6 @@ type ParsedQueries<T extends ComponentHarness> = {
3737
harnessTypes: Set<ComponentHarnessConstructor<T>>,
3838
};
3939

40-
/** Represents the status of change detection batching. */
41-
export interface ChangeDetectionBatchingStatus {
42-
/** Whether change detection is batching. */
43-
isBatching: boolean;
44-
/**
45-
* An optional callback, if present it indicates that change detection should be run immediately,
46-
* while handling the batching status change. The callback should then be called as soon as change
47-
* detection is done.
48-
*/
49-
onDetectChangesNow?: () => void;
50-
}
51-
52-
/** Subject used to dispatch and listen for changes to the change detection batching status . */
53-
const batchChangeDetectionSubject = new BehaviorSubject<ChangeDetectionBatchingStatus>({
54-
isBatching: false
55-
});
56-
57-
/** The current subscription to `batchChangeDetectionSubject`. */
58-
let batchChangeDetectionSubscription: Subscription | null;
59-
60-
/**
61-
* The default handler for change detection batching status changes. This handler will be used if
62-
* the specific environment does not install its own.
63-
* @param status The new change detection batching status.
64-
*/
65-
function defaultBatchChangeDetectionHandler(status: ChangeDetectionBatchingStatus) {
66-
status.onDetectChangesNow?.();
67-
}
68-
69-
/**
70-
* Allows a test `HarnessEnvironment` to install its own handler for change detection batching
71-
* status changes.
72-
* @param handler The handler for the change detection batching status.
73-
*/
74-
export function handleChangeDetectionBatching(
75-
handler: (status: ChangeDetectionBatchingStatus) => void) {
76-
stopHandlingChangeDetectionBatching();
77-
batchChangeDetectionSubscription = batchChangeDetectionSubject.subscribe(handler);
78-
}
79-
80-
/** Allows a `HarnessEnvironment` to stop handling change detection batching status changes. */
81-
export function stopHandlingChangeDetectionBatching() {
82-
batchChangeDetectionSubscription?.unsubscribe();
83-
batchChangeDetectionSubscription = null;
84-
}
85-
86-
/**
87-
* Batches together triggering of change detection over the duration of the given function.
88-
* @param fn The function to call with batched change detection.
89-
* @param triggerBeforeAndAfter Optionally trigger change detection once before and after the batch
90-
* operation. If false, change detection will not be triggered.
91-
* @return The result of the given function.
92-
*/
93-
async function batchChangeDetection<T>(fn: () => Promise<T>, triggerBeforeAndAfter: boolean) {
94-
// If change detection batching is already in progress, just run the function.
95-
if (batchChangeDetectionSubject.getValue().isBatching) {
96-
return await fn();
97-
}
98-
99-
// If nothing is handling change detection batching, install the default handler.
100-
if (!batchChangeDetectionSubscription) {
101-
batchChangeDetectionSubject.subscribe(defaultBatchChangeDetectionHandler);
102-
}
103-
104-
if (triggerBeforeAndAfter) {
105-
await new Promise(resolve => batchChangeDetectionSubject.next({
106-
isBatching: true,
107-
onDetectChangesNow: resolve,
108-
}));
109-
const result = await fn();
110-
await new Promise(resolve => batchChangeDetectionSubject.next({
111-
isBatching: false,
112-
onDetectChangesNow: resolve,
113-
}));
114-
return result;
115-
} else {
116-
batchChangeDetectionSubject.next({isBatching: true});
117-
const result = await fn();
118-
batchChangeDetectionSubject.next({isBatching: false});
119-
return result;
120-
}
121-
}
122-
123-
/**
124-
* Disables the harness system's auto change detection for the duration of the given function.
125-
* @param fn The function to disable auto change detection for.
126-
* @return The result of the given function.
127-
*/
128-
export async function noAutoChangeDetection<T>(fn: () => Promise<T>) {
129-
return batchChangeDetection(fn, false);
130-
}
131-
132-
/**
133-
* Resolves the given list of async values in parallel (i.e. via Promise.all) while batching change
134-
* detection over the entire operation such that change detection occurs exactly once before
135-
* resolving the values and once after.
136-
* @param values The async values to resolve in parallel with batched change detection.
137-
* @return The resolved values.
138-
*/
139-
export async function parallel<T>(values: Iterable<T | PromiseLike<T>>) {
140-
return batchChangeDetection(() => Promise.all(values), true);
141-
}
142-
14340
/**
14441
* Base harness environment class that can be extended to allow `ComponentHarness`es to be used in
14542
* different test environments (e.g. testbed, protractor, etc.). This class implements the

src/cdk/testing/public-api.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ export * from './harness-environment';
1111
export * from './test-element';
1212
export * from './element-dimensions';
1313
export * from './text-filtering';
14+
export * from './change-detection';

0 commit comments

Comments
 (0)