don't fire missing act() warnings for react-art (#15975)
* use toWarnDev for dom fixture tests forks toWarnDev from root into fixture/dom, updates tes tests to use it * disable act() warnings for react-art() - For 'secondary' renderers like react-act, we don't want to fire missing act() warnings; the wrapping renderer will fire warnings anyway, and when it flushes, it flushes effects *across* renderers. - I could have used isPrimaryRenderer as the flag, but this is marked as false for react-test-renderer, and we *do* want the warning to fire for it. Hence a new flag. * add missing dependency `art` to fixtures/dom
Sunil Pai committed
Jun 24, 2019 at 19:18 UTC
fce15f14d38d680f3bdee3a124e9e94e91520e16
12 files changed
+509
-39
fixtures/dom/package.json
+2
@@ -7,9 +7,11 @@
7
},
8
"dependencies": {
9
"@babel/standalone": "^7.0.0",
10
+ "art": "^0.10.3",
11
"classnames": "^2.2.5",
12
"codemirror": "^5.40.0",
13
"core-js": "^2.4.1",
14
+ "jest-diff": "^24.8.0",
15
"prop-types": "^15.6.0",
16
"query-string": "^4.2.3",
17
"react": "^15.4.1",
fixtures/dom/src/index.test.js
+91
-38
@@ -9,22 +9,17 @@
9
10
import React from 'react';
11
import ReactDOM from 'react-dom';
12
+import ReactART from 'react-art';
13
+import ARTSVGMode from 'art/modes/svg';
14
+import ARTCurrentMode from 'art/modes/current';
15
import TestUtils from 'react-dom/test-utils';
16
import TestRenderer from 'react-test-renderer';
17
15
-let spy;
16
-beforeEach(() => {
17
- spy = jest.spyOn(console, 'error').mockImplementation(() => {});
18
-});
18
+ARTCurrentMode.setCurrent(ARTSVGMode);
19
20
-function confirmWarning() {
21
- expect(spy).toHaveBeenCalledWith(
22
- expect.stringContaining(
23
- "It looks like you're using the wrong act() around your test interactions."
24
- ),
25
- ''
26
- );
27
-}
20
+global.__DEV__ = process.env.NODE_ENV !== 'production';
21
+
22
+expect.extend(require('./toWarnDev'));
23
24
function App(props) {
25
return 'hello world';
@@ -34,29 +29,33 @@ it("doesn't warn when you use the right act + renderer: dom", () => {
29
TestUtils.act(() => {
30
TestUtils.renderIntoDocument(<App />);
31
});
37
- expect(spy).not.toHaveBeenCalled();
32
});
33
34
it("doesn't warn when you use the right act + renderer: test", () => {
35
TestRenderer.act(() => {
36
TestRenderer.create(<App />);
37
});
44
- expect(spy).not.toHaveBeenCalled();
38
});
39
47
-it('works with createRoot().render combo', () => {
40
+it('warns when using createRoot() + .render', () => {
41
const root = ReactDOM.unstable_createRoot(document.createElement('div'));
49
- TestRenderer.act(() => {
50
- root.render(<App />);
42
+ expect(() => {
43
+ TestRenderer.act(() => {
44
+ root.render(<App />);
45
+ });
46
+ }).toWarnDev(["It looks like you're using the wrong act()"], {
47
+ withoutStack: true,
48
});
52
- confirmWarning();
49
});
50
51
it('warns when using the wrong act version - test + dom: render', () => {
56
- TestRenderer.act(() => {
57
- TestUtils.renderIntoDocument(<App />);
52
+ expect(() => {
53
+ TestRenderer.act(() => {
54
+ TestUtils.renderIntoDocument(<App />);
55
+ });
56
+ }).toWarnDev(["It looks like you're using the wrong act()"], {
57
+ withoutStack: true,
58
});
59
- confirmWarning();
59
});
60
61
it('warns when using the wrong act version - test + dom: updates', () => {
@@ -67,29 +66,35 @@ it('warns when using the wrong act version - test + dom: updates', () => {
66
return ctr;
67
}
68
TestUtils.renderIntoDocument(<Counter />);
70
- TestRenderer.act(() => {
71
- setCtr(1);
72
- });
73
- confirmWarning();
69
+ expect(() => {
70
+ TestRenderer.act(() => {
71
+ setCtr(1);
72
+ });
73
+ }).toWarnDev([
74
+ 'An update to Counter inside a test was not wrapped in act',
75
+ "It looks like you're using the wrong act()",
76
+ ]);
77
});
78
79
it('warns when using the wrong act version - dom + test: .create()', () => {
77
- TestUtils.act(() => {
78
- TestRenderer.create(<App />);
80
+ expect(() => {
81
+ TestUtils.act(() => {
82
+ TestRenderer.create(<App />);
83
+ });
84
+ }).toWarnDev(["It looks like you're using the wrong act()"], {
85
+ withoutStack: true,
86
});
80
- confirmWarning();
87
});
88
89
it('warns when using the wrong act version - dom + test: .update()', () => {
84
- let root;
85
- // use the right one here so we don't get the first warning
86
- TestRenderer.act(() => {
87
- root = TestRenderer.create(<App key="one" />);
90
+ const root = TestRenderer.create(<App key="one" />);
91
+ expect(() => {
92
+ TestUtils.act(() => {
93
+ root.update(<App key="two" />);
94
+ });
95
+ }).toWarnDev(["It looks like you're using the wrong act()"], {
96
+ withoutStack: true,
97
});
89
- TestUtils.act(() => {
90
- root.update(<App key="two" />);
91
- });
92
- confirmWarning();
98
});
99
100
it('warns when using the wrong act version - dom + test: updates', () => {
@@ -100,8 +105,56 @@ it('warns when using the wrong act version - dom + test: updates', () => {
105
return ctr;
106
}
107
const root = TestRenderer.create(<Counter />);
108
+ expect(() => {
109
+ TestUtils.act(() => {
110
+ setCtr(1);
111
+ });
112
+ }).toWarnDev([
113
+ 'An update to Counter inside a test was not wrapped in act',
114
+ "It looks like you're using the wrong act()",
115
+ ]);
116
+});
117
+
118
+const {Surface, Group, Shape} = ReactART;
119
+function ARTTest(props) {
120
+ return (
121
+ <Surface width={150} height={200}>
122
+ <Group>
123
+ <Shape
124
+ d="M0,0l50,0l0,50l-50,0z"
125
+ fill={new ReactART.LinearGradient(['black', 'white'])}
126
+ key="a"
127
+ width={50}
128
+ height={50}
129
+ x={50}
130
+ y={50}
131
+ opacity={0.1}
132
+ />
133
+ <Shape
134
+ fill="#3C5A99"
135
+ key="b"
136
+ scale={0.5}
137
+ x={50}
138
+ y={50}
139
+ title="This is an F"
140
+ cursor="pointer">
141
+ M64.564,38.583H54l0.008-5.834c0-3.035,0.293-4.666,4.657-4.666
142
+ h5.833V16.429h-9.33c-11.213,0-15.159,5.654-15.159,15.16v6.994
143
+ h-6.99v11.652h6.99v33.815H54V50.235h9.331L64.564,38.583z
144
+ </Shape>
145
+ </Group>
146
+ </Surface>
147
+ );
148
+}
149
+
150
+it('does not warn when nesting react-act inside react-dom', () => {
151
TestUtils.act(() => {
104
- setCtr(1);
152
+ TestUtils.renderIntoDocument(<ARTTest />);
153
+ });
154
+});
155
+
156
+it('does not warn when nesting react-act inside react-test-renderer', () => {
157
+ TestRenderer.act(() => {
158
+ TestRenderer.create(<ARTTest />);
159
});
106
- confirmWarning();
160
});
fixtures/dom/src/toWarnDev.js
new
+291
@@ -0,0 +1,291 @@
1
+// copied from scripts/jest/matchers/toWarnDev.js
2
+'use strict';
3
+
4
+const jestDiff = require('jest-diff');
5
+const util = require('util');
6
+
7
+function shouldIgnoreConsoleError(format, args) {
8
+ if (__DEV__) {
9
+ if (typeof format === 'string') {
10
+ if (format.indexOf('Error: Uncaught [') === 0) {
11
+ // This looks like an uncaught error from invokeGuardedCallback() wrapper
12
+ // in development that is reported by jsdom. Ignore because it's noisy.
13
+ return true;
14
+ }
15
+ if (format.indexOf('The above error occurred') === 0) {
16
+ // This looks like an error addendum from ReactFiberErrorLogger.
17
+ // Ignore it too.
18
+ return true;
19
+ }
20
+ }
21
+ } else {
22
+ if (
23
+ format != null &&
24
+ typeof format.message === 'string' &&
25
+ typeof format.stack === 'string' &&
26
+ args.length === 0
27
+ ) {
28
+ // In production, ReactFiberErrorLogger logs error objects directly.
29
+ // They are noisy too so we'll try to ignore them.
30
+ return true;
31
+ }
32
+ }
33
+ // Looks legit
34
+ return false;
35
+}
36
+
37
+function normalizeCodeLocInfo(str) {
38
+ return str && str.replace(/at .+?:\d+/g, 'at **');
39
+}
40
+
41
+const createMatcherFor = consoleMethod =>
42
+ function matcher(callback, expectedMessages, options = {}) {
43
+ if (__DEV__) {
44
+ // Warn about incorrect usage of matcher.
45
+ if (typeof expectedMessages === 'string') {
46
+ expectedMessages = [expectedMessages];
47
+ } else if (!Array.isArray(expectedMessages)) {
48
+ throw Error(
49
+ `toWarnDev() requires a parameter of type string or an array of strings ` +
50
+ `but was given ${typeof expectedMessages}.`
51
+ );
52
+ }
53
+ if (
54
+ options != null &&
55
+ (typeof options !== 'object' || Array.isArray(options))
56
+ ) {
57
+ throw new Error(
58
+ 'toWarnDev() second argument, when present, should be an object. ' +
59
+ 'Did you forget to wrap the messages into an array?'
60
+ );
61
+ }
62
+ if (arguments.length > 3) {
63
+ // `matcher` comes from Jest, so it's more than 2 in practice
64
+ throw new Error(
65
+ 'toWarnDev() received more than two arguments. ' +
66
+ 'Did you forget to wrap the messages into an array?'
67
+ );
68
+ }
69
+
70
+ const withoutStack = options.withoutStack;
71
+ const warningsWithoutComponentStack = [];
72
+ const warningsWithComponentStack = [];
73
+ const unexpectedWarnings = [];
74
+
75
+ let lastWarningWithMismatchingFormat = null;
76
+ let lastWarningWithExtraComponentStack = null;
77
+
78
+ // Catch errors thrown by the callback,
79
+ // But only rethrow them if all test expectations have been satisfied.
80
+ // Otherwise an Error in the callback can mask a failed expectation,
81
+ // and result in a test that passes when it shouldn't.
82
+ let caughtError;
83
+
84
+ const isLikelyAComponentStack = message =>
85
+ typeof message === 'string' && message.includes('\n in ');
86
+
87
+ const consoleSpy = (format, ...args) => {
88
+ // Ignore uncaught errors reported by jsdom
89
+ // and React addendums because they're too noisy.
90
+ if (
91
+ consoleMethod === 'error' &&
92
+ shouldIgnoreConsoleError(format, args)
93
+ ) {
94
+ return;
95
+ }
96
+
97
+ const message = util.format(format, ...args);
98
+ const normalizedMessage = normalizeCodeLocInfo(message);
99
+
100
+ // Remember if the number of %s interpolations
101
+ // doesn't match the number of arguments.
102
+ // We'll fail the test if it happens.
103
+ let argIndex = 0;
104
+ format.replace(/%s/g, () => argIndex++);
105
+ if (argIndex !== args.length) {
106
+ lastWarningWithMismatchingFormat = {
107
+ format,
108
+ args,
109
+ expectedArgCount: argIndex,
110
+ };
111
+ }
112
+
113
+ // Protect against accidentally passing a component stack
114
+ // to warning() which already injects the component stack.
115
+ if (
116
+ args.length >= 2 &&
117
+ isLikelyAComponentStack(args[args.length - 1]) &&
118
+ isLikelyAComponentStack(args[args.length - 2])
119
+ ) {
120
+ lastWarningWithExtraComponentStack = {
121
+ format,
122
+ };
123
+ }
124
+
125
+ for (let index = 0; index < expectedMessages.length; index++) {
126
+ const expectedMessage = expectedMessages[index];
127
+ if (
128
+ normalizedMessage === expectedMessage ||
129
+ normalizedMessage.includes(expectedMessage)
130
+ ) {
131
+ if (isLikelyAComponentStack(normalizedMessage)) {
132
+ warningsWithComponentStack.push(normalizedMessage);
133
+ } else {
134
+ warningsWithoutComponentStack.push(normalizedMessage);
135
+ }
136
+ expectedMessages.splice(index, 1);
137
+ return;
138
+ }
139
+ }
140
+
141
+ let errorMessage;
142
+ if (expectedMessages.length === 0) {
143
+ errorMessage =
144
+ 'Unexpected warning recorded: ' +
145
+ this.utils.printReceived(normalizedMessage);
146
+ } else if (expectedMessages.length === 1) {
147
+ errorMessage =
148
+ 'Unexpected warning recorded: ' +
149
+ jestDiff(expectedMessages[0], normalizedMessage);
150
+ } else {
151
+ errorMessage =
152
+ 'Unexpected warning recorded: ' +
153
+ jestDiff(expectedMessages, [normalizedMessage]);
154
+ }
155
+
156
+ // Record the call stack for unexpected warnings.
157
+ // We don't throw an Error here though,
158
+ // Because it might be suppressed by ReactFiberScheduler.
159
+ unexpectedWarnings.push(new Error(errorMessage));
160
+ };
161
+
162
+ // TODO Decide whether we need to support nested toWarn* expectations.
163
+ // If we don't need it, add a check here to see if this is already our spy,
164
+ // And throw an error.
165
+ const originalMethod = console[consoleMethod];
166
+
167
+ // Avoid using Jest's built-in spy since it can't be removed.
168
+ console[consoleMethod] = consoleSpy;
169
+
170
+ try {
171
+ callback();
172
+ } catch (error) {
173
+ caughtError = error;
174
+ } finally {
175
+ // Restore the unspied method so that unexpected errors fail tests.
176
+ console[consoleMethod] = originalMethod;
177
+
178
+ // Any unexpected Errors thrown by the callback should fail the test.
179
+ // This should take precedence since unexpected errors could block warnings.
180
+ if (caughtError) {
181
+ throw caughtError;
182
+ }
183
+
184
+ // Any unexpected warnings should be treated as a failure.
185
+ if (unexpectedWarnings.length > 0) {
186
+ return {
187
+ message: () => unexpectedWarnings[0].stack,
188
+ pass: false,
189
+ };
190
+ }
191
+
192
+ // Any remaining messages indicate a failed expectations.
193
+ if (expectedMessages.length > 0) {
194
+ return {
195
+ message: () =>
196
+ `Expected warning was not recorded:\n ${this.utils.printReceived(
197
+ expectedMessages[0]
198
+ )}`,
199
+ pass: false,
200
+ };
201
+ }
202
+
203
+ if (typeof withoutStack === 'number') {
204
+ // We're expecting a particular number of warnings without stacks.
205
+ if (withoutStack !== warningsWithoutComponentStack.length) {
206
+ return {
207
+ message: () =>
208
+ `Expected ${withoutStack} warnings without a component stack but received ${
209
+ warningsWithoutComponentStack.length
210
+ }:\n` +
211
+ warningsWithoutComponentStack.map(warning =>
212
+ this.utils.printReceived(warning)
213
+ ),
214
+ pass: false,
215
+ };
216
+ }
217
+ } else if (withoutStack === true) {
218
+ // We're expecting that all warnings won't have the stack.
219
+ // If some warnings have it, it's an error.
220
+ if (warningsWithComponentStack.length > 0) {
221
+ return {
222
+ message: () =>
223
+ `Received warning unexpectedly includes a component stack:\n ${this.utils.printReceived(
224
+ warningsWithComponentStack[0]
225
+ )}\nIf this warning intentionally includes the component stack, remove ` +
226
+ `{withoutStack: true} from the toWarnDev() call. If you have a mix of ` +
227
+ `warnings with and without stack in one toWarnDev() call, pass ` +
228
+ `{withoutStack: N} where N is the number of warnings without stacks.`,
229
+ pass: false,
230
+ };
231
+ }
232
+ } else if (withoutStack === false || withoutStack === undefined) {
233
+ // We're expecting that all warnings *do* have the stack (default).
234
+ // If some warnings don't have it, it's an error.
235
+ if (warningsWithoutComponentStack.length > 0) {
236
+ return {
237
+ message: () =>
238
+ `Received warning unexpectedly does not include a component stack:\n ${this.utils.printReceived(
239
+ warningsWithoutComponentStack[0]
240
+ )}\nIf this warning intentionally omits the component stack, add ` +
241
+ `{withoutStack: true} to the toWarnDev() call.`,
242
+ pass: false,
243
+ };
244
+ }
245
+ } else {
246
+ throw Error(
247
+ `The second argument for toWarnDev(), when specified, must be an object. It may have a ` +
248
+ `property called "withoutStack" whose value may be undefined, boolean, or a number. ` +
249
+ `Instead received ${typeof withoutStack}.`
250
+ );
251
+ }
252
+
253
+ if (lastWarningWithMismatchingFormat !== null) {
254
+ return {
255
+ message: () =>
256
+ `Received ${
257
+ lastWarningWithMismatchingFormat.args.length
258
+ } arguments for a message with ${
259
+ lastWarningWithMismatchingFormat.expectedArgCount
260
+ } placeholders:\n ${this.utils.printReceived(
261
+ lastWarningWithMismatchingFormat.format
262
+ )}`,
263
+ pass: false,
264
+ };
265
+ }
266
+
267
+ if (lastWarningWithExtraComponentStack !== null) {
268
+ return {
269
+ message: () =>
270
+ `Received more than one component stack for a warning:\n ${this.utils.printReceived(
271
+ lastWarningWithExtraComponentStack.format
272
+ )}\nDid you accidentally pass a stack to warning() as the last argument? ` +
273
+ `Don't forget warning() already injects the component stack automatically.`,
274
+ pass: false,
275
+ };
276
+ }
277
+
278
+ return {pass: true};
279
+ }
280
+ } else {
281
+ // Any uncaught errors or warnings should fail tests in production mode.
282
+ callback();
283
+
284
+ return {pass: true};
285
+ }
286
+ };
287
+
288
+module.exports = {
289
+ toLowPriorityWarnDev: createMatcherFor('warn'),
290
+ toWarnDev: createMatcherFor('error'),
291
+};
fixtures/dom/yarn.lock
+107
@@ -6,6 +6,40 @@
6
version "7.0.0"
7
resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.0.0.tgz#856446641620c1c5f0ca775621d478324ebd1f52"
8
9
+"@jest/types@^24.8.0":
10
+ version "24.8.0"
11
+ resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.8.0.tgz#f31e25948c58f0abd8c845ae26fcea1491dea7ad"
12
+ integrity sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==
13
+ dependencies:
14
+ "@types/istanbul-lib-coverage" "^2.0.0"
15
+ "@types/istanbul-reports" "^1.1.1"
16
+ "@types/yargs" "^12.0.9"
17
+
18
+"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
19
+ version "2.0.1"
20
+ resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff"
21
+ integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==
22
+
23
+"@types/istanbul-lib-report@*":
24
+ version "1.1.1"
25
+ resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#e5471e7fa33c61358dd38426189c037a58433b8c"
26
+ integrity sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg==
27
+ dependencies:
28
+ "@types/istanbul-lib-coverage" "*"
29
+
30
+"@types/istanbul-reports@^1.1.1":
31
+ version "1.1.1"
32
+ resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a"
33
+ integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==
34
+ dependencies:
35
+ "@types/istanbul-lib-coverage" "*"
36
+ "@types/istanbul-lib-report" "*"
37
+
38
+"@types/yargs@^12.0.9":
39
+ version "12.0.12"
40
+ resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.12.tgz#45dd1d0638e8c8f153e87d296907659296873916"
41
+ integrity sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw==
42
+
43
abab@^1.0.3:
44
version "1.0.3"
45
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.3.tgz#b81de5f7274ec4e756d797cd834f303642724e5d"
@@ -140,6 +174,11 @@ ansi-regex@^3.0.0:
174
version "3.0.0"
175
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
176
177
+ansi-regex@^4.0.0:
178
+ version "4.1.0"
179
+ resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
180
+ integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
181
+
182
ansi-styles@^2.2.1:
183
version "2.2.1"
184
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
@@ -150,6 +189,13 @@ ansi-styles@^3.0.0, ansi-styles@^3.1.0:
189
dependencies:
190
color-convert "^1.9.0"
191
192
+ansi-styles@^3.2.0, ansi-styles@^3.2.1:
193
+ version "3.2.1"
194
+ resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
195
+ integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
196
+ dependencies:
197
+ color-convert "^1.9.0"
198
+
199
anymatch@^1.3.0:
200
version "1.3.0"
201
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507"
@@ -249,6 +295,11 @@ arrify@^1.0.0, arrify@^1.0.1:
295
version "1.0.1"
296
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
297
298
+art@^0.10.3:
299
+ version "0.10.3"
300
+ resolved "https://registry.yarnpkg.com/art/-/art-0.10.3.tgz#b01d84a968ccce6208df55a733838c96caeeaea2"
301
+ integrity sha512-HXwbdofRTiJT6qZX/FnchtldzJjS3vkLJxQilc3Xj+ma2MXjY4UAyQ0ls1XZYVnDvVIBiFZbC6QsvtW86TD6tQ==
302
+
303
asap@~2.0.3:
304
version "2.0.5"
305
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f"
@@ -1466,6 +1517,15 @@ chalk@^2.0.0, chalk@^2.1.0:
1517
escape-string-regexp "^1.0.5"
1518
supports-color "^4.0.0"
1519
1520
+chalk@^2.0.1:
1521
+ version "2.4.2"
1522
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
1523
+ integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
1524
+ dependencies:
1525
+ ansi-styles "^3.2.1"
1526
+ escape-string-regexp "^1.0.5"
1527
+ supports-color "^5.3.0"
1528
+
1529
chokidar@^1.6.0, chokidar@^1.7.0:
1530
version "1.7.0"
1531
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
@@ -2058,6 +2118,11 @@ detect-port-alt@1.1.3:
2118
address "^1.0.1"
2119
debug "^2.6.0"
2120
2121
+diff-sequences@^24.3.0:
2122
+ version "24.3.0"
2123
+ resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.3.0.tgz#0f20e8a1df1abddaf4d9c226680952e64118b975"
2124
+ integrity sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw==
2125
+
2126
diff@^3.2.0:
2127
version "3.3.0"
2128
resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.0.tgz#056695150d7aa93237ca7e378ac3b1682b7963b9"
@@ -3119,6 +3184,11 @@ has-flag@^2.0.0:
3184
version "2.0.0"
3185
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
3186
3187
+has-flag@^3.0.0:
3188
+ version "3.0.0"
3189
+ resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
3190
+ integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
3191
+
3192
has-unicode@^2.0.0:
3193
version "2.0.1"
3194
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -3770,6 +3840,16 @@ jest-diff@^20.0.3:
3840
jest-matcher-utils "^20.0.3"
3841
pretty-format "^20.0.3"
3842
3843
+jest-diff@^24.8.0:
3844
+ version "24.8.0"
3845
+ resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.8.0.tgz#146435e7d1e3ffdf293d53ff97e193f1d1546172"
3846
+ integrity sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g==
3847
+ dependencies:
3848
+ chalk "^2.0.1"
3849
+ diff-sequences "^24.3.0"
3850
+ jest-get-type "^24.8.0"
3851
+ pretty-format "^24.8.0"
3852
+
3853
jest-docblock@^20.0.3:
3854
version "20.0.3"
3855
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-20.0.3.tgz#17bea984342cc33d83c50fbe1545ea0efaa44712"
@@ -3789,6 +3869,11 @@ jest-environment-node@^20.0.3:
3869
jest-mock "^20.0.3"
3870
jest-util "^20.0.3"
3871
3872
+jest-get-type@^24.8.0:
3873
+ version "24.8.0"
3874
+ resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.8.0.tgz#a7440de30b651f5a70ea3ed7ff073a32dfe646fc"
3875
+ integrity sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==
3876
+
3877
jest-haste-map@^20.0.4:
3878
version "20.0.5"
3879
resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-20.0.5.tgz#abad74efb1a005974a7b6517e11010709cab9112"
@@ -5243,6 +5328,16 @@ pretty-format@^20.0.3:
5328
ansi-regex "^2.1.1"
5329
ansi-styles "^3.0.0"
5330
5331
+pretty-format@^24.8.0:
5332
+ version "24.8.0"
5333
+ resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.8.0.tgz#8dae7044f58db7cb8be245383b565a963e3c27f2"
5334
+ integrity sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==
5335
+ dependencies:
5336
+ "@jest/types" "^24.8.0"
5337
+ ansi-regex "^4.0.0"
5338
+ ansi-styles "^3.2.0"
5339
+ react-is "^16.8.4"
5340
+
5341
private@^0.1.6:
5342
version "0.1.6"
5343
resolved "https://registry.yarnpkg.com/private/-/private-0.1.6.tgz#55c6a976d0f9bafb9924851350fe47b9b5fbb7c1"
@@ -5429,6 +5524,11 @@ react-error-overlay@^1.0.10:
5524
settle-promise "1.0.0"
5525
source-map "0.5.6"
5526
5527
+react-is@^16.8.4:
5528
+ version "16.8.6"
5529
+ resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
5530
+ integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==
5531
+
5532
react-scripts@^1.0.11:
5533
version "1.0.11"
5534
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-1.0.11.tgz#483d49e27f417ec981ae415a4456120a2a2bc8c1"
@@ -6248,6 +6348,13 @@ supports-color@^4.0.0, supports-color@^4.2.1:
6348
dependencies:
6349
has-flag "^2.0.0"
6350
6351
+supports-color@^5.3.0:
6352
+ version "5.5.0"
6353
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
6354
+ integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
6355
+ dependencies:
6356
+ has-flag "^3.0.0"
6357
+
6358
svgo@^0.7.0:
6359
version "0.7.1"
6360
resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.1.tgz#287320fed972cb097e72c2bb1685f96fe08f8034"
packages/react-art/src/ReactARTHostConfig.js
+3
@@ -350,6 +350,9 @@ export function shouldSetTextContent(type, props) {
350
// The ART renderer is secondary to the React DOM renderer.
351
export const isPrimaryRenderer = false;
352
353
+// The ART renderer shouldn't trigger missing act() warnings
354
+export const shouldWarnUnactedUpdates = false;
355
+
356
export const supportsMutation = true;
357
358
export function appendChild(parentInstance, child) {
packages/react-dom/src/client/ReactDOMHostConfig.js
+1
@@ -390,6 +390,7 @@ export function createTextInstance(
390
}
391
392
export const isPrimaryRenderer = true;
393
+export const shouldWarnUnactedUpdates = true;
394
// This initialization code may run even on server environments
395
// if a component just imports ReactDOM (e.g. for findDOMNode).
396
// Some environments might not have setTimeout or clearTimeout.
packages/react-native-renderer/src/ReactFabricHostConfig.js
+3
@@ -345,6 +345,9 @@ export function shouldSetTextContent(type: string, props: Props): boolean {
345
// The Fabric renderer is secondary to the existing React Native renderer.
346
export const isPrimaryRenderer = false;
347
348
+// The Fabric renderer shouldn't trigger missing act() warnings
349
+export const shouldWarnUnactedUpdates = false;
350
+
351
export const scheduleTimeout = setTimeout;
352
export const cancelTimeout = clearTimeout;
353
export const noTimeout = -1;
packages/react-native-renderer/src/ReactNativeHostConfig.js
+1
@@ -248,6 +248,7 @@ export function resetAfterCommit(containerInfo: Container): void {
248
}
249
250
export const isPrimaryRenderer = true;
251
+export const shouldWarnUnactedUpdates = true;
252
253
export const scheduleTimeout = setTimeout;
254
export const cancelTimeout = clearTimeout;
packages/react-noop-renderer/src/createReactNoop.js
+1
@@ -434,6 +434,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
434
now: Scheduler.unstable_now,
435
436
isPrimaryRenderer: true,
437
+ shouldWarnUnactedUpdates: true,
438
supportsHydration: false,
439
440
mountEventComponent(): void {
packages/react-reconciler/src/ReactFiberWorkLoop.js
+7
-1
@@ -55,6 +55,7 @@ import {
55
scheduleTimeout,
56
cancelTimeout,
57
noTimeout,
58
+ shouldWarnUnactedUpdates,
59
} from './ReactFiberHostConfig';
60
61
import {createWorkInProgress, assignFiberPropertiesInDEV} from './ReactFiber';
@@ -2420,6 +2421,7 @@ export const ReactActingRendererSigil = {};
2421
export function warnIfNotScopedWithMatchingAct(fiber: Fiber): void {
2422
if (__DEV__) {
2423
if (
2424
+ shouldWarnUnactedUpdates === true &&
2425
ReactCurrentActingRendererSigil.current !== null &&
2426
ReactCurrentActingRendererSigil.current !== ReactActingRendererSigil
2427
) {
@@ -2445,7 +2447,10 @@ export function warnIfNotScopedWithMatchingAct(fiber: Fiber): void {
2447
2448
export function warnIfNotCurrentlyActingEffectsInDEV(fiber: Fiber): void {
2449
if (__DEV__) {
2448
- if (ReactCurrentActingRendererSigil.current !== ReactActingRendererSigil) {
2450
+ if (
2451
+ shouldWarnUnactedUpdates === true &&
2452
+ ReactCurrentActingRendererSigil.current !== ReactActingRendererSigil
2453
+ ) {
2454
warningWithoutStack(
2455
false,
2456
'An update to %s ran an effect, but was not wrapped in act(...).\n\n' +
@@ -2469,6 +2474,7 @@ export function warnIfNotCurrentlyActingEffectsInDEV(fiber: Fiber): void {
2474
function warnIfNotCurrentlyActingUpdatesInDEV(fiber: Fiber): void {
2475
if (__DEV__) {
2476
if (
2477
+ shouldWarnUnactedUpdates === true &&
2478
executionContext === NoContext &&
2479
ReactCurrentActingRendererSigil.current !== ReactActingRendererSigil
2480
) {
packages/react-reconciler/src/forks/ReactFiberHostConfig.custom.js
+1
@@ -61,6 +61,7 @@ export const cancelTimeout = $$$hostConfig.clearTimeout;
61
export const noTimeout = $$$hostConfig.noTimeout;
62
export const now = $$$hostConfig.now;
63
export const isPrimaryRenderer = $$$hostConfig.isPrimaryRenderer;
64
+export const shouldWarnUnactedUpdates = $$$hostConfig.shouldWarnUnactedUpdates;
65
export const supportsMutation = $$$hostConfig.supportsMutation;
66
export const supportsPersistence = $$$hostConfig.supportsPersistence;
67
export const supportsHydration = $$$hostConfig.supportsHydration;
packages/react-test-renderer/src/ReactTestHostConfig.js
+1
@@ -261,6 +261,7 @@ export function createTextInstance(
261
}
262
263
export const isPrimaryRenderer = false;
264
+export const shouldWarnUnactedUpdates = true;
265
266
export const scheduleTimeout = setTimeout;
267
export const cancelTimeout = clearTimeout;