@samitouri / QOS-React-2 / commits / d814473047

[Internal API only] Delete non-awaited form of act (#26339)

**This commit only affects the internal version of `act` that we use in this repo. The public `act` API is unaffected, for now.** We should always await the result of an `act` call so that any work queued in a microtask has a chance to flush. Neglecting to do this can cause us to miss bugs when testing React behavior. I codemodded all the existing `act` callers in previous PRs.

Andrew Clark committed Mar 8, 2023 at 11:46 UTC d8144730475cf2d71781e26e300d0d579ac6b8d9
1 file changed +35 -48
packages/jest-react/src/internalAct.js
+35 -48
@@ -22,7 +22,7 @@ import enqueueTask from 'shared/enqueueTask';
22
23 let actingUpdatesScopeDepth = 0;
24
25 -export function act<T>(scope: () => Thenable<T> | T): Thenable<T> {
25 +export function act<T>(scope: () => Thenable<T>): Thenable<T> {
26 if (Scheduler.unstable_flushUntilNextPaint === undefined) {
27 throw Error(
28 'This version of `act` requires a special mock build of Scheduler.',
@@ -64,58 +64,45 @@ export function act<T>(scope: () => Thenable<T> | T): Thenable<T> {
64 }
65 };
66
67 - // TODO: This would be way simpler if 1) we required a promise to be
68 - // returned and 2) we could use async/await. Since it's only our used in
69 - // our test suite, we should be able to.
67 + // TODO: This would be way simpler if we could use async/await. Move this
68 + // function to the internal-test-utils package.
69 try {
70 const result = scope();
71 if (
73 - typeof result === 'object' &&
74 - result !== null &&
75 - // $FlowFixMe[method-unbinding]
76 - typeof result.then === 'function'
72 + typeof result !== 'object' ||
73 + result === null ||
74 + typeof (result: any).then !== 'function'
75 ) {
78 - const thenableResult: Thenable<T> = (result: any);
79 - return {
80 - then(resolve: T => mixed, reject: mixed => mixed) {
81 - thenableResult.then(
82 - returnValue => {
83 - flushActWork(
84 - () => {
85 - unwind();
86 - resolve(returnValue);
87 - },
88 - error => {
89 - unwind();
90 - reject(error);
91 - },
92 - );
93 - },
94 - error => {
95 - unwind();
96 - reject(error);
97 - },
98 - );
99 - },
100 - };
101 - } else {
102 - const returnValue: T = (result: any);
103 - try {
104 - // TODO: Let's not support non-async scopes at all in our tests. Need to
105 - // migrate existing tests.
106 - let didFlushWork;
107 - do {
108 - didFlushWork = Scheduler.unstable_flushAllWithoutAsserting();
109 - } while (didFlushWork);
110 - return {
111 - then(resolve: T => mixed, reject: mixed => mixed) {
112 - resolve(returnValue);
113 - },
114 - };
115 - } finally {
116 - unwind();
117 - }
76 + throw new Error(
77 + 'The internal version of `act` used in the React repo must be passed ' +
78 + "an async function, even if doesn't await anything. This is a " +
79 + 'temporary limitation that will soon be fixed.',
80 + );
81 }
82 + const thenableResult: Thenable<T> = (result: any);
83 +
84 + return {
85 + then(resolve: T => mixed, reject: mixed => mixed) {
86 + thenableResult.then(
87 + returnValue => {
88 + flushActWork(
89 + () => {
90 + unwind();
91 + resolve(returnValue);
92 + },
93 + error => {
94 + unwind();
95 + reject(error);
96 + },
97 + );
98 + },
99 + error => {
100 + unwind();
101 + reject(error);
102 + },
103 + );
104 + },
105 + };
106 } catch (error) {
107 unwind();
108 throw error;