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
This commit is contained in:
Sunil Pai 2019-06-24 19:18:26 +01:00 committed by GitHub
parent 20f3546963
commit fce15f14d3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 511 additions and 41 deletions

View File

@ -7,9 +7,11 @@
},
"dependencies": {
"@babel/standalone": "^7.0.0",
"art": "^0.10.3",
"classnames": "^2.2.5",
"codemirror": "^5.40.0",
"core-js": "^2.4.1",
"jest-diff": "^24.8.0",
"prop-types": "^15.6.0",
"query-string": "^4.2.3",
"react": "^15.4.1",

View File

@ -9,22 +9,17 @@
import React from 'react';
import ReactDOM from 'react-dom';
import ReactART from 'react-art';
import ARTSVGMode from 'art/modes/svg';
import ARTCurrentMode from 'art/modes/current';
import TestUtils from 'react-dom/test-utils';
import TestRenderer from 'react-test-renderer';
let spy;
beforeEach(() => {
spy = jest.spyOn(console, 'error').mockImplementation(() => {});
});
ARTCurrentMode.setCurrent(ARTSVGMode);
function confirmWarning() {
expect(spy).toHaveBeenCalledWith(
expect.stringContaining(
"It looks like you're using the wrong act() around your test interactions."
),
''
);
}
global.__DEV__ = process.env.NODE_ENV !== 'production';
expect.extend(require('./toWarnDev'));
function App(props) {
return 'hello world';
@ -34,29 +29,33 @@ it("doesn't warn when you use the right act + renderer: dom", () => {
TestUtils.act(() => {
TestUtils.renderIntoDocument(<App />);
});
expect(spy).not.toHaveBeenCalled();
});
it("doesn't warn when you use the right act + renderer: test", () => {
TestRenderer.act(() => {
TestRenderer.create(<App />);
});
expect(spy).not.toHaveBeenCalled();
});
it('works with createRoot().render combo', () => {
it('warns when using createRoot() + .render', () => {
const root = ReactDOM.unstable_createRoot(document.createElement('div'));
TestRenderer.act(() => {
root.render(<App />);
expect(() => {
TestRenderer.act(() => {
root.render(<App />);
});
}).toWarnDev(["It looks like you're using the wrong act()"], {
withoutStack: true,
});
confirmWarning();
});
it('warns when using the wrong act version - test + dom: render', () => {
TestRenderer.act(() => {
TestUtils.renderIntoDocument(<App />);
expect(() => {
TestRenderer.act(() => {
TestUtils.renderIntoDocument(<App />);
});
}).toWarnDev(["It looks like you're using the wrong act()"], {
withoutStack: true,
});
confirmWarning();
});
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', () => {
return ctr;
}
TestUtils.renderIntoDocument(<Counter />);
TestRenderer.act(() => {
setCtr(1);
});
confirmWarning();
expect(() => {
TestRenderer.act(() => {
setCtr(1);
});
}).toWarnDev([
'An update to Counter inside a test was not wrapped in act',
"It looks like you're using the wrong act()",
]);
});
it('warns when using the wrong act version - dom + test: .create()', () => {
TestUtils.act(() => {
TestRenderer.create(<App />);
expect(() => {
TestUtils.act(() => {
TestRenderer.create(<App />);
});
}).toWarnDev(["It looks like you're using the wrong act()"], {
withoutStack: true,
});
confirmWarning();
});
it('warns when using the wrong act version - dom + test: .update()', () => {
let root;
// use the right one here so we don't get the first warning
TestRenderer.act(() => {
root = TestRenderer.create(<App key="one" />);
const root = TestRenderer.create(<App key="one" />);
expect(() => {
TestUtils.act(() => {
root.update(<App key="two" />);
});
}).toWarnDev(["It looks like you're using the wrong act()"], {
withoutStack: true,
});
TestUtils.act(() => {
root.update(<App key="two" />);
});
confirmWarning();
});
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', () => {
return ctr;
}
const root = TestRenderer.create(<Counter />);
TestUtils.act(() => {
setCtr(1);
});
confirmWarning();
expect(() => {
TestUtils.act(() => {
setCtr(1);
});
}).toWarnDev([
'An update to Counter inside a test was not wrapped in act',
"It looks like you're using the wrong act()",
]);
});
const {Surface, Group, Shape} = ReactART;
function ARTTest(props) {
return (
<Surface width={150} height={200}>
<Group>
<Shape
d="M0,0l50,0l0,50l-50,0z"
fill={new ReactART.LinearGradient(['black', 'white'])}
key="a"
width={50}
height={50}
x={50}
y={50}
opacity={0.1}
/>
<Shape
fill="#3C5A99"
key="b"
scale={0.5}
x={50}
y={50}
title="This is an F"
cursor="pointer">
M64.564,38.583H54l0.008-5.834c0-3.035,0.293-4.666,4.657-4.666
h5.833V16.429h-9.33c-11.213,0-15.159,5.654-15.159,15.16v6.994
h-6.99v11.652h6.99v33.815H54V50.235h9.331L64.564,38.583z
</Shape>
</Group>
</Surface>
);
}
it('does not warn when nesting react-act inside react-dom', () => {
TestUtils.act(() => {
TestUtils.renderIntoDocument(<ARTTest />);
});
});
it('does not warn when nesting react-act inside react-test-renderer', () => {
TestRenderer.act(() => {
TestRenderer.create(<ARTTest />);
});
});

View File

@ -0,0 +1,291 @@
// copied from scripts/jest/matchers/toWarnDev.js
'use strict';
const jestDiff = require('jest-diff');
const util = require('util');
function shouldIgnoreConsoleError(format, args) {
if (__DEV__) {
if (typeof format === 'string') {
if (format.indexOf('Error: Uncaught [') === 0) {
// This looks like an uncaught error from invokeGuardedCallback() wrapper
// in development that is reported by jsdom. Ignore because it's noisy.
return true;
}
if (format.indexOf('The above error occurred') === 0) {
// This looks like an error addendum from ReactFiberErrorLogger.
// Ignore it too.
return true;
}
}
} else {
if (
format != null &&
typeof format.message === 'string' &&
typeof format.stack === 'string' &&
args.length === 0
) {
// In production, ReactFiberErrorLogger logs error objects directly.
// They are noisy too so we'll try to ignore them.
return true;
}
}
// Looks legit
return false;
}
function normalizeCodeLocInfo(str) {
return str && str.replace(/at .+?:\d+/g, 'at **');
}
const createMatcherFor = consoleMethod =>
function matcher(callback, expectedMessages, options = {}) {
if (__DEV__) {
// Warn about incorrect usage of matcher.
if (typeof expectedMessages === 'string') {
expectedMessages = [expectedMessages];
} else if (!Array.isArray(expectedMessages)) {
throw Error(
`toWarnDev() requires a parameter of type string or an array of strings ` +
`but was given ${typeof expectedMessages}.`
);
}
if (
options != null &&
(typeof options !== 'object' || Array.isArray(options))
) {
throw new Error(
'toWarnDev() second argument, when present, should be an object. ' +
'Did you forget to wrap the messages into an array?'
);
}
if (arguments.length > 3) {
// `matcher` comes from Jest, so it's more than 2 in practice
throw new Error(
'toWarnDev() received more than two arguments. ' +
'Did you forget to wrap the messages into an array?'
);
}
const withoutStack = options.withoutStack;
const warningsWithoutComponentStack = [];
const warningsWithComponentStack = [];
const unexpectedWarnings = [];
let lastWarningWithMismatchingFormat = null;
let lastWarningWithExtraComponentStack = null;
// Catch errors thrown by the callback,
// But only rethrow them if all test expectations have been satisfied.
// Otherwise an Error in the callback can mask a failed expectation,
// and result in a test that passes when it shouldn't.
let caughtError;
const isLikelyAComponentStack = message =>
typeof message === 'string' && message.includes('\n in ');
const consoleSpy = (format, ...args) => {
// Ignore uncaught errors reported by jsdom
// and React addendums because they're too noisy.
if (
consoleMethod === 'error' &&
shouldIgnoreConsoleError(format, args)
) {
return;
}
const message = util.format(format, ...args);
const normalizedMessage = normalizeCodeLocInfo(message);
// Remember if the number of %s interpolations
// doesn't match the number of arguments.
// We'll fail the test if it happens.
let argIndex = 0;
format.replace(/%s/g, () => argIndex++);
if (argIndex !== args.length) {
lastWarningWithMismatchingFormat = {
format,
args,
expectedArgCount: argIndex,
};
}
// Protect against accidentally passing a component stack
// to warning() which already injects the component stack.
if (
args.length >= 2 &&
isLikelyAComponentStack(args[args.length - 1]) &&
isLikelyAComponentStack(args[args.length - 2])
) {
lastWarningWithExtraComponentStack = {
format,
};
}
for (let index = 0; index < expectedMessages.length; index++) {
const expectedMessage = expectedMessages[index];
if (
normalizedMessage === expectedMessage ||
normalizedMessage.includes(expectedMessage)
) {
if (isLikelyAComponentStack(normalizedMessage)) {
warningsWithComponentStack.push(normalizedMessage);
} else {
warningsWithoutComponentStack.push(normalizedMessage);
}
expectedMessages.splice(index, 1);
return;
}
}
let errorMessage;
if (expectedMessages.length === 0) {
errorMessage =
'Unexpected warning recorded: ' +
this.utils.printReceived(normalizedMessage);
} else if (expectedMessages.length === 1) {
errorMessage =
'Unexpected warning recorded: ' +
jestDiff(expectedMessages[0], normalizedMessage);
} else {
errorMessage =
'Unexpected warning recorded: ' +
jestDiff(expectedMessages, [normalizedMessage]);
}
// Record the call stack for unexpected warnings.
// We don't throw an Error here though,
// Because it might be suppressed by ReactFiberScheduler.
unexpectedWarnings.push(new Error(errorMessage));
};
// TODO Decide whether we need to support nested toWarn* expectations.
// If we don't need it, add a check here to see if this is already our spy,
// And throw an error.
const originalMethod = console[consoleMethod];
// Avoid using Jest's built-in spy since it can't be removed.
console[consoleMethod] = consoleSpy;
try {
callback();
} catch (error) {
caughtError = error;
} finally {
// Restore the unspied method so that unexpected errors fail tests.
console[consoleMethod] = originalMethod;
// Any unexpected Errors thrown by the callback should fail the test.
// This should take precedence since unexpected errors could block warnings.
if (caughtError) {
throw caughtError;
}
// Any unexpected warnings should be treated as a failure.
if (unexpectedWarnings.length > 0) {
return {
message: () => unexpectedWarnings[0].stack,
pass: false,
};
}
// Any remaining messages indicate a failed expectations.
if (expectedMessages.length > 0) {
return {
message: () =>
`Expected warning was not recorded:\n ${this.utils.printReceived(
expectedMessages[0]
)}`,
pass: false,
};
}
if (typeof withoutStack === 'number') {
// We're expecting a particular number of warnings without stacks.
if (withoutStack !== warningsWithoutComponentStack.length) {
return {
message: () =>
`Expected ${withoutStack} warnings without a component stack but received ${
warningsWithoutComponentStack.length
}:\n` +
warningsWithoutComponentStack.map(warning =>
this.utils.printReceived(warning)
),
pass: false,
};
}
} else if (withoutStack === true) {
// We're expecting that all warnings won't have the stack.
// If some warnings have it, it's an error.
if (warningsWithComponentStack.length > 0) {
return {
message: () =>
`Received warning unexpectedly includes a component stack:\n ${this.utils.printReceived(
warningsWithComponentStack[0]
)}\nIf this warning intentionally includes the component stack, remove ` +
`{withoutStack: true} from the toWarnDev() call. If you have a mix of ` +
`warnings with and without stack in one toWarnDev() call, pass ` +
`{withoutStack: N} where N is the number of warnings without stacks.`,
pass: false,
};
}
} else if (withoutStack === false || withoutStack === undefined) {
// We're expecting that all warnings *do* have the stack (default).
// If some warnings don't have it, it's an error.
if (warningsWithoutComponentStack.length > 0) {
return {
message: () =>
`Received warning unexpectedly does not include a component stack:\n ${this.utils.printReceived(
warningsWithoutComponentStack[0]
)}\nIf this warning intentionally omits the component stack, add ` +
`{withoutStack: true} to the toWarnDev() call.`,
pass: false,
};
}
} else {
throw Error(
`The second argument for toWarnDev(), when specified, must be an object. It may have a ` +
`property called "withoutStack" whose value may be undefined, boolean, or a number. ` +
`Instead received ${typeof withoutStack}.`
);
}
if (lastWarningWithMismatchingFormat !== null) {
return {
message: () =>
`Received ${
lastWarningWithMismatchingFormat.args.length
} arguments for a message with ${
lastWarningWithMismatchingFormat.expectedArgCount
} placeholders:\n ${this.utils.printReceived(
lastWarningWithMismatchingFormat.format
)}`,
pass: false,
};
}
if (lastWarningWithExtraComponentStack !== null) {
return {
message: () =>
`Received more than one component stack for a warning:\n ${this.utils.printReceived(
lastWarningWithExtraComponentStack.format
)}\nDid you accidentally pass a stack to warning() as the last argument? ` +
`Don't forget warning() already injects the component stack automatically.`,
pass: false,
};
}
return {pass: true};
}
} else {
// Any uncaught errors or warnings should fail tests in production mode.
callback();
return {pass: true};
}
};
module.exports = {
toLowPriorityWarnDev: createMatcherFor('warn'),
toWarnDev: createMatcherFor('error'),
};

View File

@ -6,6 +6,40 @@
version "7.0.0"
resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.0.0.tgz#856446641620c1c5f0ca775621d478324ebd1f52"
"@jest/types@^24.8.0":
version "24.8.0"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-24.8.0.tgz#f31e25948c58f0abd8c845ae26fcea1491dea7ad"
integrity sha512-g17UxVr2YfBtaMUxn9u/4+siG1ptg9IGYAYwvpwn61nBg779RXnjE/m7CxYcIzEt0AbHZZAHSEZNhkE2WxURVg==
dependencies:
"@types/istanbul-lib-coverage" "^2.0.0"
"@types/istanbul-reports" "^1.1.1"
"@types/yargs" "^12.0.9"
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.1.tgz#42995b446db9a48a11a07ec083499a860e9138ff"
integrity sha512-hRJD2ahnnpLgsj6KWMYSrmXkM3rm2Dl1qkx6IOFD5FnuNPXJIG5L0dhgKXCYTRMGzU4n0wImQ/xfmRc4POUFlg==
"@types/istanbul-lib-report@*":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz#e5471e7fa33c61358dd38426189c037a58433b8c"
integrity sha512-3BUTyMzbZa2DtDI2BkERNC6jJw2Mr2Y0oGI7mRxYNBPxppbtEK1F66u3bKwU2g+wxwWI7PAoRpJnOY1grJqzHg==
dependencies:
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-reports@^1.1.1":
version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.1.tgz#7a8cbf6a406f36c8add871625b278eaf0b0d255a"
integrity sha512-UpYjBi8xefVChsCoBpKShdxTllC9pwISirfoZsUa2AAdQg/Jd2KQGtSbw+ya7GPo7x/wAPlH6JBhKhAsXUEZNA==
dependencies:
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-lib-report" "*"
"@types/yargs@^12.0.9":
version "12.0.12"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-12.0.12.tgz#45dd1d0638e8c8f153e87d296907659296873916"
integrity sha512-SOhuU4wNBxhhTHxYaiG5NY4HBhDIDnJF60GU+2LqHAdKKer86//e4yg69aENCtQ04n0ovz+tq2YPME5t5yp4pw==
abab@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.3.tgz#b81de5f7274ec4e756d797cd834f303642724e5d"
@ -140,6 +174,11 @@ ansi-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
ansi-regex@^4.0.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997"
integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==
ansi-styles@^2.2.1:
version "2.2.1"
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:
dependencies:
color-convert "^1.9.0"
ansi-styles@^3.2.0, ansi-styles@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
dependencies:
color-convert "^1.9.0"
anymatch@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507"
@ -249,6 +295,11 @@ arrify@^1.0.0, arrify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
art@^0.10.3:
version "0.10.3"
resolved "https://registry.yarnpkg.com/art/-/art-0.10.3.tgz#b01d84a968ccce6208df55a733838c96caeeaea2"
integrity sha512-HXwbdofRTiJT6qZX/FnchtldzJjS3vkLJxQilc3Xj+ma2MXjY4UAyQ0ls1XZYVnDvVIBiFZbC6QsvtW86TD6tQ==
asap@~2.0.3:
version "2.0.5"
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f"
@ -1466,6 +1517,15 @@ chalk@^2.0.0, chalk@^2.1.0:
escape-string-regexp "^1.0.5"
supports-color "^4.0.0"
chalk@^2.0.1:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
dependencies:
ansi-styles "^3.2.1"
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chokidar@^1.6.0, chokidar@^1.7.0:
version "1.7.0"
resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468"
@ -2058,6 +2118,11 @@ detect-port-alt@1.1.3:
address "^1.0.1"
debug "^2.6.0"
diff-sequences@^24.3.0:
version "24.3.0"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.3.0.tgz#0f20e8a1df1abddaf4d9c226680952e64118b975"
integrity sha512-xLqpez+Zj9GKSnPWS0WZw1igGocZ+uua8+y+5dDNTT934N3QuY1sp2LkHzwiaYQGz60hMq0pjAshdeXm5VUOEw==
diff@^3.2.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.0.tgz#056695150d7aa93237ca7e378ac3b1682b7963b9"
@ -3119,6 +3184,11 @@ has-flag@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51"
has-flag@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@ -3770,6 +3840,16 @@ jest-diff@^20.0.3:
jest-matcher-utils "^20.0.3"
pretty-format "^20.0.3"
jest-diff@^24.8.0:
version "24.8.0"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.8.0.tgz#146435e7d1e3ffdf293d53ff97e193f1d1546172"
integrity sha512-wxetCEl49zUpJ/bvUmIFjd/o52J+yWcoc5ZyPq4/W1LUKGEhRYDIbP1KcF6t+PvqNrGAFk4/JhtxDq/Nnzs66g==
dependencies:
chalk "^2.0.1"
diff-sequences "^24.3.0"
jest-get-type "^24.8.0"
pretty-format "^24.8.0"
jest-docblock@^20.0.3:
version "20.0.3"
resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-20.0.3.tgz#17bea984342cc33d83c50fbe1545ea0efaa44712"
@ -3789,6 +3869,11 @@ jest-environment-node@^20.0.3:
jest-mock "^20.0.3"
jest-util "^20.0.3"
jest-get-type@^24.8.0:
version "24.8.0"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.8.0.tgz#a7440de30b651f5a70ea3ed7ff073a32dfe646fc"
integrity sha512-RR4fo8jEmMD9zSz2nLbs2j0zvPpk/KCEz3a62jJWbd2ayNo0cb+KFRxPHVhE4ZmgGJEQp0fosmNz84IfqM8cMQ==
jest-haste-map@^20.0.4:
version "20.0.5"
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:
ansi-regex "^2.1.1"
ansi-styles "^3.0.0"
pretty-format@^24.8.0:
version "24.8.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.8.0.tgz#8dae7044f58db7cb8be245383b565a963e3c27f2"
integrity sha512-P952T7dkrDEplsR+TuY7q3VXDae5Sr7zmQb12JU/NDQa/3CH7/QW0yvqLcGN6jL+zQFKaoJcPc+yJxMTGmosqw==
dependencies:
"@jest/types" "^24.8.0"
ansi-regex "^4.0.0"
ansi-styles "^3.2.0"
react-is "^16.8.4"
private@^0.1.6:
version "0.1.6"
resolved "https://registry.yarnpkg.com/private/-/private-0.1.6.tgz#55c6a976d0f9bafb9924851350fe47b9b5fbb7c1"
@ -5429,6 +5524,11 @@ react-error-overlay@^1.0.10:
settle-promise "1.0.0"
source-map "0.5.6"
react-is@^16.8.4:
version "16.8.6"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==
react-scripts@^1.0.11:
version "1.0.11"
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:
dependencies:
has-flag "^2.0.0"
supports-color@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
dependencies:
has-flag "^3.0.0"
svgo@^0.7.0:
version "0.7.1"
resolved "https://registry.yarnpkg.com/svgo/-/svgo-0.7.1.tgz#287320fed972cb097e72c2bb1685f96fe08f8034"

View File

@ -350,6 +350,9 @@ export function shouldSetTextContent(type, props) {
// The ART renderer is secondary to the React DOM renderer.
export const isPrimaryRenderer = false;
// The ART renderer shouldn't trigger missing act() warnings
export const shouldWarnUnactedUpdates = false;
export const supportsMutation = true;
export function appendChild(parentInstance, child) {

View File

@ -390,6 +390,7 @@ export function createTextInstance(
}
export const isPrimaryRenderer = true;
export const shouldWarnUnactedUpdates = true;
// This initialization code may run even on server environments
// if a component just imports ReactDOM (e.g. for findDOMNode).
// Some environments might not have setTimeout or clearTimeout.

View File

@ -345,6 +345,9 @@ export function shouldSetTextContent(type: string, props: Props): boolean {
// The Fabric renderer is secondary to the existing React Native renderer.
export const isPrimaryRenderer = false;
// The Fabric renderer shouldn't trigger missing act() warnings
export const shouldWarnUnactedUpdates = false;
export const scheduleTimeout = setTimeout;
export const cancelTimeout = clearTimeout;
export const noTimeout = -1;

View File

@ -248,6 +248,7 @@ export function resetAfterCommit(containerInfo: Container): void {
}
export const isPrimaryRenderer = true;
export const shouldWarnUnactedUpdates = true;
export const scheduleTimeout = setTimeout;
export const cancelTimeout = clearTimeout;

View File

@ -434,6 +434,7 @@ function createReactNoop(reconciler: Function, useMutation: boolean) {
now: Scheduler.unstable_now,
isPrimaryRenderer: true,
shouldWarnUnactedUpdates: true,
supportsHydration: false,
mountEventComponent(): void {

View File

@ -55,6 +55,7 @@ import {
scheduleTimeout,
cancelTimeout,
noTimeout,
shouldWarnUnactedUpdates,
} from './ReactFiberHostConfig';
import {createWorkInProgress, assignFiberPropertiesInDEV} from './ReactFiber';
@ -2420,6 +2421,7 @@ export const ReactActingRendererSigil = {};
export function warnIfNotScopedWithMatchingAct(fiber: Fiber): void {
if (__DEV__) {
if (
shouldWarnUnactedUpdates === true &&
ReactCurrentActingRendererSigil.current !== null &&
ReactCurrentActingRendererSigil.current !== ReactActingRendererSigil
) {
@ -2445,7 +2447,10 @@ export function warnIfNotScopedWithMatchingAct(fiber: Fiber): void {
export function warnIfNotCurrentlyActingEffectsInDEV(fiber: Fiber): void {
if (__DEV__) {
if (ReactCurrentActingRendererSigil.current !== ReactActingRendererSigil) {
if (
shouldWarnUnactedUpdates === true &&
ReactCurrentActingRendererSigil.current !== ReactActingRendererSigil
) {
warningWithoutStack(
false,
'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 {
function warnIfNotCurrentlyActingUpdatesInDEV(fiber: Fiber): void {
if (__DEV__) {
if (
shouldWarnUnactedUpdates === true &&
executionContext === NoContext &&
ReactCurrentActingRendererSigil.current !== ReactActingRendererSigil
) {

View File

@ -61,6 +61,7 @@ export const cancelTimeout = $$$hostConfig.clearTimeout;
export const noTimeout = $$$hostConfig.noTimeout;
export const now = $$$hostConfig.now;
export const isPrimaryRenderer = $$$hostConfig.isPrimaryRenderer;
export const shouldWarnUnactedUpdates = $$$hostConfig.shouldWarnUnactedUpdates;
export const supportsMutation = $$$hostConfig.supportsMutation;
export const supportsPersistence = $$$hostConfig.supportsPersistence;
export const supportsHydration = $$$hostConfig.supportsHydration;

View File

@ -261,6 +261,7 @@ export function createTextInstance(
}
export const isPrimaryRenderer = false;
export const shouldWarnUnactedUpdates = true;
export const scheduleTimeout = setTimeout;
export const cancelTimeout = clearTimeout;