-
Notifications
You must be signed in to change notification settings - Fork 6.8k
feat(cdk/testing): allow disabling & batching of change detection #20464
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
129f6ff
to
f000788
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm
a6cc4ed
to
24268f8
Compare
Feedback addressed |
2a93195
to
4dc6dc6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, just a few docs nits
4df0c67
to
32ae7be
Compare
0b97f1b
to
5843ae7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. nice work. One comment that should resolve the CI failures you were seeing
src/cdk/testing/change-detection.ts
Outdated
isDisabled: true, | ||
onDetectChangesNow: resolve, | ||
})); | ||
const result = await fn(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If the specified function fails here, we will never restore the disabled state of the auto change-detection, and change detection will never run at all. This causes the CI failures you're seeing in the gulp jobs as those run all tests (like a usual CLI project) in a single Karma process. This is actually great as it unveiled this issue that could surface for consumers.
The fix is to wrap this with a try/finally
and always restore the state of change detection. In tests, it can commonly happen that errors are expected & silently handled. In such situations consecutive tests just fail randomly with all kinds of errors as change detection for harnesses is disabled permanently (as seen with the CI failures for this PR; it was hard figuring out there is actually a "silent" error). It was a test in the radio harnesses using expectAsync
and toBeRejectedWith
😄
// If the function fails, we still want to restore the auto change detection state as
// otherwise change detection could be disabled unexpectedly forever. In some cases,
// errors are expected in tests and therefore silently captured. This would mean that
// consecutive tests relying on auto change detection could break without any hint about
// disabled auto change detection.
try {
result = await fn();
} finally {
await new Promise(resolve => autoChangeDetectionSubject.next({
isDisabled: false,
onDetectChangesNow: resolve,
}));
}
We also need to do the same below with triggerBeforeAndAfter = false
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For later reference: The select tests for example failed as selectHarness.open
was not reflected due to disabled change detection. The options were undefined then and .click
resulted in a runtime exception.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you so much for looking into this! That makes total sense. I was going crazy trying to debug this on Friday
f556fae
to
733ab57
Compare
733ab57
to
b8f0971
Compare
…AutoChangeDetection`
b8f0971
to
2bcf7fd
Compare
…gular#20464) * feat(cdk/testing): allow disabling & batching of change detection * feat(cdk/testing): address feedback * feat(cdk/testing): split batchCD into 2 functions, `parallel` and `noAutoChangeDetection` * feat(cdk/testing): address feedback * feat(cdk/testing): fix some CI issues * feat(cdk/testing): fix circular dep * feat(cdk/testing): update docs * feat(cdk/testing): address feedback * feat(cdk/testing): address comments * feat(cdk/testing): fix `parallel` to take a function * feat(cdk/testing): ensure change detection completes even if test code throws * feat(cdk/testing): fix misplaced tests
This issue has been automatically locked due to inactivity. Read more about our automatic conversation locking policy. This action has been performed automatically by a bot. |
This PR introduces 2 new APIs that give users more fine-grained control over change detection when working with harnesses:
manualChangeDetection
, can be used to disable the harness's automatic change detection for a block of code, e.g.parallel
, can be used to resolve several async values in parallel viaPromise.all
while also batching change detection so that it only happens once before resolving the values and once after. This is useful for optimizing the performance of tests, e.g.Using the new
parallel
in theHarnessPredicate
resolution code results in a signigicant performance gain:Using it in tests that perform many actions simultaneously again results in a significant performance gain: