Update to Jest 29 (#26088)

## Summary

- yarn.lock diff +-6249, **small pr**
- use jest-environment-jsdom by default
- uncaught error from jsdom is an error object instead of strings
- abortSignal.reason is read-only in jsdom and node,
https://developer.mozilla.org/en-US/docs/Web/API/AbortSignal/reason

## How did you test this change?

ci green

---------

Co-authored-by: Sebastian Silbermann <silbermann.sebastian@gmail.com>
This commit is contained in:
Ming Ye 2023-02-10 00:07:49 +08:00 committed by GitHub
parent 28fcae062b
commit 5940934967
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
66 changed files with 2978 additions and 3803 deletions

View File

@ -11,7 +11,7 @@
"classnames": "^2.2.5",
"codemirror": "^5.40.0",
"core-js": "^2.4.1",
"jest-diff": "^25.1.0",
"jest-diff": "^29.4.1",
"prop-types": "^15.6.0",
"query-string": "^4.2.3",
"react": "^15.4.1",

View File

@ -1,7 +1,7 @@
// copied from scripts/jest/matchers/toWarnDev.js
'use strict';
const jestDiff = require('jest-diff').default;
const {diff: jestDiff} = require('jest-diff');
const util = require('util');
function shouldIgnoreConsoleError(format, args) {

View File

@ -7,47 +7,17 @@
resolved "https://registry.yarnpkg.com/@babel/standalone/-/standalone-7.12.10.tgz#f77f6750d0ab88c7c23234dd2d2f3800f170a573"
integrity sha512-e3sJ7uwwjiGWv7qeATKrP+Mjltr6JEurPh3yR0dBb9ie2YDnKl52lO82f+Ha+HAtyxTHfsPIXwgFmWKsCT2zOQ==
"@jest/types@^25.5.0":
version "25.5.0"
resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d"
integrity sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==
"@jest/schemas@^29.4.0":
version "29.4.0"
resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.0.tgz#0d6ad358f295cc1deca0b643e6b4c86ebd539f17"
integrity sha512-0E01f/gOZeNTG76i5eWWSupvSHaIINrTie7vCyjiYFKgzNdyEGd12BUv4oNBFHOqlHDbtoJi3HrQ38KCC90NsQ==
dependencies:
"@types/istanbul-lib-coverage" "^2.0.0"
"@types/istanbul-reports" "^1.1.1"
"@types/yargs" "^15.0.0"
chalk "^3.0.0"
"@sinclair/typebox" "^0.25.16"
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz#4ba8ddb720221f432e443bd5f9117fd22cfd4762"
integrity sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==
"@types/istanbul-lib-report@*":
version "3.0.0"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686"
integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==
dependencies:
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-reports@^1.1.1":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz#e875cc689e47bce549ec81f3df5e6f6f11cfaeb2"
integrity sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==
dependencies:
"@types/istanbul-lib-coverage" "*"
"@types/istanbul-lib-report" "*"
"@types/yargs-parser@*":
version "15.0.0"
resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-15.0.0.tgz#cb3f9f741869e20cce330ffbeb9271590483882d"
integrity sha512-FA/BWv8t8ZWJ+gEOnLLd8ygxH/2UFbAvgEonyfN6yWGLKc7zVjbpl2Y4CTjid9h2RfgPP6SEt6uHwEOply00yw==
"@types/yargs@^15.0.0":
version "15.0.11"
resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.11.tgz#361d7579ecdac1527687bcebf9946621c12ab78c"
integrity sha512-jfcNBxHFYJ4nPIacsi3woz1+kvUO6s1CyeEhtnDHBjHUMNj5UlW2GynmnSgiJJEdNg9yW5C8lfoNRZrHGv5EqA==
dependencies:
"@types/yargs-parser" "*"
"@sinclair/typebox@^0.25.16":
version "0.25.21"
resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.21.tgz#763b05a4b472c93a8db29b2c3e359d55b29ce272"
integrity sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g==
abab@^1.0.3:
version "1.0.4"
@ -184,11 +154,6 @@ ansi-regex@^3.0.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
ansi-regex@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
@ -201,13 +166,18 @@ ansi-styles@^3.0.0, ansi-styles@^3.2.1:
dependencies:
color-convert "^1.9.0"
ansi-styles@^4.0.0, ansi-styles@^4.1.0:
ansi-styles@^4.1.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
dependencies:
color-convert "^2.0.1"
ansi-styles@^5.0.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b"
integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==
anymatch@^1.3.0:
version "1.3.2"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a"
@ -1655,10 +1625,10 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.4.1:
escape-string-regexp "^1.0.5"
supports-color "^5.3.0"
chalk@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4"
integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==
chalk@^4.0.0:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
@ -2409,10 +2379,10 @@ detect-port-alt@1.1.6:
address "^1.0.1"
debug "^2.6.0"
diff-sequences@^25.2.6:
version "25.2.6"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd"
integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg==
diff-sequences@^29.3.1:
version "29.3.1"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.3.1.tgz#104b5b95fe725932421a9c6e5b4bef84c3f2249e"
integrity sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==
diff@^3.2.0:
version "3.5.0"
@ -4599,15 +4569,15 @@ jest-diff@^20.0.3:
jest-matcher-utils "^20.0.3"
pretty-format "^20.0.3"
jest-diff@^25.1.0:
version "25.5.0"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.5.0.tgz#1dd26ed64f96667c068cef026b677dfa01afcfa9"
integrity sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A==
jest-diff@^29.4.1:
version "29.4.1"
resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.4.1.tgz#9a6dc715037e1fa7a8a44554e7d272088c4029bd"
integrity sha512-uazdl2g331iY56CEyfbNA0Ut7Mn2ulAG5vUaEHXycf1L6IPyuImIxSz4F0VYBKi7LYIuxOwTZzK3wh5jHzASMw==
dependencies:
chalk "^3.0.0"
diff-sequences "^25.2.6"
jest-get-type "^25.2.6"
pretty-format "^25.5.0"
chalk "^4.0.0"
diff-sequences "^29.3.1"
jest-get-type "^29.2.0"
pretty-format "^29.4.1"
jest-docblock@^20.0.3:
version "20.0.3"
@ -4631,10 +4601,10 @@ jest-environment-node@^20.0.3:
jest-mock "^20.0.3"
jest-util "^20.0.3"
jest-get-type@^25.2.6:
version "25.2.6"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877"
integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==
jest-get-type@^29.2.0:
version "29.2.0"
resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.2.0.tgz#726646f927ef61d583a3b3adb1ab13f3a5036408"
integrity sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==
jest-haste-map@^20.0.4:
version "20.0.5"
@ -6359,15 +6329,14 @@ pretty-format@^20.0.3:
ansi-regex "^2.1.1"
ansi-styles "^3.0.0"
pretty-format@^25.5.0:
version "25.5.0"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.5.0.tgz#7873c1d774f682c34b8d48b6743a2bf2ac55791a"
integrity sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==
pretty-format@^29.4.1:
version "29.4.1"
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.4.1.tgz#0da99b532559097b8254298da7c75a0785b1751c"
integrity sha512-dt/Z761JUVsrIKaY215o1xQJBGlSmTx/h4cSqXqjHLnU1+Kt+mavVE7UgqJJO5ukx5HjSswHfmXz4LjS2oIJfg==
dependencies:
"@jest/types" "^25.5.0"
ansi-regex "^5.0.0"
ansi-styles "^4.0.0"
react-is "^16.12.0"
"@jest/schemas" "^29.4.0"
ansi-styles "^5.0.0"
react-is "^18.0.0"
private@^0.1.6, private@^0.1.7, private@^0.1.8:
version "0.1.8"
@ -6595,11 +6564,16 @@ react-error-overlay@^4.0.1:
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-4.0.1.tgz#417addb0814a90f3a7082eacba7cee588d00da89"
integrity sha512-xXUbDAZkU08aAkjtUvldqbvI04ogv+a1XdHxvYuHPYKIVk/42BIOD0zSKTHAWV4+gDy3yGm283z2072rA2gdtw==
react-is@^16.12.0, react-is@^16.8.1:
react-is@^16.8.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
react-is@^18.0.0:
version "18.2.0"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
react-scripts@^1.0.11:
version "1.1.5"
resolved "https://registry.yarnpkg.com/react-scripts/-/react-scripts-1.1.5.tgz#3041610ab0826736b52197711a4c4e3756e97768"

View File

@ -2,18 +2,20 @@
"dependencies": {
"@babel/plugin-transform-modules-commonjs": "^7.10.4",
"@babel/preset-react": "^7.10.4",
"jest": "^26.5.3"
"jest": "^29.4.1"
},
"jest": {
"setupFilesAfterEnv": ["./setupTests.js"]
"setupFilesAfterEnv": [
"./setupTests.js"
]
},
"scripts": {
"install-all": "cd react-14 && yarn && cd ../react-15 && yarn && cd ../react-16 && yarn && cd ../react-17 && yarn && cd ..",
"lint": "node lint-runtimes.js",
"pretest": "yarn install-all && yarn lint",
"test-jsxdev-dev": "BABEL_ENV=development NODE_ENV=development jest",
"test-jsx-dev": "BABEL_ENV=production NODE_ENV=development jest",
"test-jsx-prod": "BABEL_ENV=production NODE_ENV=production jest",
"test-jsxdev-dev": "BABEL_ENV=development NODE_ENV=development jest --env=jsdom",
"test-jsx-dev": "BABEL_ENV=production NODE_ENV=development jest --env=jsdom",
"test-jsx-prod": "BABEL_ENV=production NODE_ENV=production jest --env=jsdom",
"test": "yarn test-jsxdev-dev && yarn test-jsx-dev && yarn test-jsx-prod"
}
}

View File

@ -5,7 +5,7 @@
const expect = global.expect;
const jestDiff = require('jest-diff').default;
const {diff: jestDiff} = require('jest-diff');
const util = require('util');
function shouldIgnoreConsoleError(format, args) {

File diff suppressed because it is too large Load Diff

View File

@ -36,6 +36,7 @@
"@babel/preset-flow": "^7.10.4",
"@babel/preset-react": "^7.10.4",
"@babel/traverse": "^7.11.0",
"abortcontroller-polyfill": "^1.7.5",
"art": "0.10.1",
"babel-plugin-syntax-trailing-function-commas": "^6.5.0",
"chalk": "^3.0.0",
@ -58,7 +59,7 @@
"eslint-plugin-no-function-declare-after-return": "^1.0.0",
"eslint-plugin-react": "^6.7.1",
"eslint-plugin-react-internal": "link:./scripts/eslint-rules",
"fbjs-scripts": "1.2.0",
"fbjs-scripts": "^3.0.1",
"filesize": "^6.0.1",
"flow-bin": "^0.199.0",
"flow-remove-types": "^2.198.2",
@ -69,9 +70,11 @@
"hermes-eslint": "^0.9.0",
"hermes-parser": "^0.9.0",
"jasmine-check": "^1.0.0-rc.0",
"jest": "^26.6.3",
"jest-cli": "^26.6.3",
"jest-diff": "^26.6.2",
"jest": "^29.4.1",
"jest-cli": "^29.4.1",
"jest-diff": "^29.4.1",
"jest-environment-jsdom": "^29.4.1",
"jest-jasmine2": "^29.4.1",
"jest-snapshot-serializer-raw": "^1.1.0",
"minimatch": "^3.0.4",
"minimist": "^1.2.3",
@ -79,6 +82,7 @@
"ncp": "^2.0.0",
"pacote": "^10.3.0",
"prettier": "2.8.3",
"pretty-format": "^29.4.1",
"prop-types": "^15.6.2",
"random-seed": "^0.3.0",
"react-lifecycles-compat": "^3.0.4",

View File

@ -344,6 +344,8 @@ describe('createEventTarget', () => {
"right": 0,
"top": 0,
"width": 0,
"x": 0,
"y": 0,
}
`);
target.setBoundingClientRect({x: 10, y: 20, width: 100, height: 200});

View File

@ -19,7 +19,7 @@
},
"homepage": "https://reactjs.org/",
"peerDependencies": {
"jest": "^23.0.1 || ^24.0.0 || ^25.1.0",
"jest": "^23.0.1 || ^24.0.0 || ^25.1.0 || ^26.0.0 || ^27.0.0 || ^28.0.0 || ^29.0.0",
"react": "^18.2.0",
"react-test-renderer": "^18.2.0"
},

View File

@ -29,8 +29,8 @@ export function act<T>(scope: () => Thenable<T> | T): Thenable<T> {
);
}
// $FlowFixMe: _isMockFunction doesn't exist on function
if (setTimeout._isMockFunction !== true) {
// $FlowFixMe: Flow doesn't know about global Jest object
if (!jest.isMockFunction(setTimeout)) {
throw Error(
"This version of `act` requires Jest's timer mocks " +
'(i.e. jest.useFakeTimers).',

View File

@ -61,8 +61,14 @@ env.beforeEach(() => {
// Use utils.js#withErrorsOrWarningsIgnored instead of directly mutating this array.
global._ignoredErrorOrWarningMessages = [];
function shouldIgnoreConsoleErrorOrWarn(args) {
const firstArg = args[0];
if (typeof firstArg !== 'string') {
let firstArg = args[0];
if (
firstArg !== null &&
typeof firstArg === 'object' &&
String(firstArg).indexOf('Error: Uncaught [') === 0
) {
firstArg = String(firstArg);
} else if (typeof firstArg !== 'string') {
return false;
}
const shouldFilter = global._ignoredErrorOrWarningMessages.some(

View File

@ -65,9 +65,14 @@ describe('InvalidEventListeners', () => {
if (!__DEV__) {
expect(console.error).toHaveBeenCalledTimes(1);
expect(console.error.calls.argsFor(0)[0]).toMatch(
'Expected `onClick` listener to be a function, ' +
'instead got a value of `string` type.',
expect(console.error.calls.argsFor(0)[0]).toEqual(
expect.objectContaining({
detail: expect.objectContaining({
message:
'Expected `onClick` listener to be a function, instead got a value of `string` type.',
}),
type: 'unhandled exception',
}),
);
}
});

View File

@ -98,17 +98,21 @@ describe('ReactDOMConsoleErrorReporting', () => {
expect(console.error.calls.all().map(c => c.args)).toEqual([
[
// Reported because we're in a browser click event:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[
// This one is jsdom-only. Real browser deduplicates it.
// (In DEV, we have a nested event due to guarded callback.)
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
]);
@ -124,9 +128,11 @@ describe('ReactDOMConsoleErrorReporting', () => {
expect(console.error.calls.all().map(c => c.args)).toEqual([
[
// Reported because we're in a browser click event:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
]);
@ -178,17 +184,21 @@ describe('ReactDOMConsoleErrorReporting', () => {
expect(console.error.calls.all().map(c => c.args)).toEqual([
[
// Reported due to the guarded callback:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[
// This is only duplicated with createRoot
// because it retries once with a sync render.
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[
@ -260,17 +270,21 @@ describe('ReactDOMConsoleErrorReporting', () => {
expect(console.error.calls.all().map(c => c.args)).toEqual([
[
// Reported by jsdom due to the guarded callback:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[
// This is only duplicated with createRoot
// because it retries once with a sync render.
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[
@ -336,9 +350,11 @@ describe('ReactDOMConsoleErrorReporting', () => {
expect(console.error.calls.all().map(c => c.args)).toEqual([
[
// Reported due to the guarded callback:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[
@ -406,9 +422,11 @@ describe('ReactDOMConsoleErrorReporting', () => {
expect(console.error.calls.all().map(c => c.args)).toEqual([
[
// Reported by jsdom due to the guarded callback:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[
@ -474,9 +492,11 @@ describe('ReactDOMConsoleErrorReporting', () => {
expect(console.error.calls.all().map(c => c.args)).toEqual([
[
// Reported due to the guarded callback:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[
@ -544,9 +564,11 @@ describe('ReactDOMConsoleErrorReporting', () => {
expect(console.error.calls.all().map(c => c.args)).toEqual([
[
// Reported by jsdom due to the guarded callback:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[
@ -631,17 +653,21 @@ describe('ReactDOMConsoleErrorReporting', () => {
[expect.stringContaining('ReactDOM.render is no longer supported')],
[
// Reported because we're in a browser click event:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[
// This one is jsdom-only. Real browser deduplicates it.
// (In DEV, we have a nested event due to guarded callback.)
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
]);
@ -657,9 +683,11 @@ describe('ReactDOMConsoleErrorReporting', () => {
expect(console.error.calls.all().map(c => c.args)).toEqual([
[
// Reported because we're in a browser click event:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
]);
@ -706,9 +734,11 @@ describe('ReactDOMConsoleErrorReporting', () => {
[expect.stringContaining('ReactDOM.render is no longer supported')],
[
// Reported due to the guarded callback:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[
@ -776,9 +806,11 @@ describe('ReactDOMConsoleErrorReporting', () => {
[expect.stringContaining('ReactDOM.render is no longer supported')],
[
// Reported by jsdom due to the guarded callback:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[
@ -846,9 +878,11 @@ describe('ReactDOMConsoleErrorReporting', () => {
[expect.stringContaining('ReactDOM.render is no longer supported')],
[
// Reported due to the guarded callback:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[
@ -919,9 +953,11 @@ describe('ReactDOMConsoleErrorReporting', () => {
[expect.stringContaining('ReactDOM.render is no longer supported')],
[
// Reported by jsdom due to the guarded callback:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[
@ -989,9 +1025,11 @@ describe('ReactDOMConsoleErrorReporting', () => {
[expect.stringContaining('ReactDOM.render is no longer supported')],
[
// Reported due to the guarded callback:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[
@ -1062,9 +1100,11 @@ describe('ReactDOMConsoleErrorReporting', () => {
[expect.stringContaining('ReactDOM.render is no longer supported')],
[
// Reported by jsdom due to the guarded callback:
expect.stringContaining('Error: Uncaught [Error: Boom]'),
expect.objectContaining({
message: 'Boom',
detail: expect.objectContaining({
message: 'Boom',
}),
type: 'unhandled exception',
}),
],
[

View File

@ -16,8 +16,8 @@ describe('ReactDOMEventListener', () => {
beforeEach(() => {
window.TextEvent = function () {};
jest.resetModules();
React = require('react');
jest.isolateModules(() => {
React = require('react');
OuterReactDOM = require('react-dom');
});
jest.isolateModules(() => {

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -38,6 +39,15 @@ let hasErrored = false;
let fatalError = undefined;
let renderOptions;
function resetJSDOM(markup) {
// Test Environment
const jsdom = new JSDOM(markup, {
runScripts: 'dangerously',
});
window = jsdom.window;
document = jsdom.window.document;
}
describe('ReactDOMFizzServer', () => {
beforeEach(() => {
jest.resetModules();
@ -71,15 +81,7 @@ describe('ReactDOMFizzServer', () => {
textCache = new Map();
// Test Environment
const jsdom = new JSDOM(
'<!DOCTYPE html><html><head></head><body><div id="container">',
{
runScripts: 'dangerously',
},
);
window = jsdom.window;
document = jsdom.window.document;
resetJSDOM('<!DOCTYPE html><html><head></head><body><div id="container">');
container = document.getElementById('container');
buffer = '';
@ -168,12 +170,7 @@ describe('ReactDOMFizzServer', () => {
// We also want to execute any scripts that are embedded.
// We assume that we have now received a proper fragment of HTML.
const bufferedContent = buffer;
// Test Environment
const jsdom = new JSDOM(bufferedContent, {
runScripts: 'dangerously',
});
window = jsdom.window;
document = jsdom.window.document;
resetJSDOM(bufferedContent);
container = document;
buffer = '';
await withLoadingReadyState(async () => {
@ -1512,7 +1509,7 @@ describe('ReactDOMFizzServer', () => {
function normalizeCodeLocInfo(str) {
return (
str &&
str.replace(/\n +(?:at|in) ([\S]+)[^\n]*/g, function (m, name) {
String(str).replace(/\n +(?:at|in) ([\S]+)[^\n]*/g, function (m, name) {
return '\n in ' + name + ' (at **)';
})
);
@ -4964,12 +4961,7 @@ describe('ReactDOMFizzServer', () => {
describe('title children', () => {
function prepareJSDOMForTitle() {
// Test Environment
const jsdom = new JSDOM('<!DOCTYPE html><html><head>\u0000', {
runScripts: 'dangerously',
});
window = jsdom.window;
document = jsdom.window.document;
resetJSDOM('<!DOCTYPE html><html><head>\u0000');
container = document.getElementsByTagName('head')[0];
}

View File

@ -205,9 +205,7 @@ describe('ReactDOMFizzServerBrowser', () => {
const result = await readResult(stream);
expect(result).toContain('Loading');
expect(errors).toEqual([
'The render was aborted by the server without a reason.',
]);
expect(errors).toEqual(['The operation was aborted.']);
});
it('should reject if aborting before the shell is complete', async () => {
@ -228,10 +226,6 @@ describe('ReactDOMFizzServerBrowser', () => {
await jest.runAllTimers();
const theReason = new Error('aborted for reasons');
// @TODO this is a hack to work around lack of support for abortSignal.reason in node
// The abort call itself should set this property but since we are testing in node we
// set it here manually
controller.signal.reason = theReason;
controller.abort(theReason);
let caughtError = null;
@ -273,22 +267,14 @@ describe('ReactDOMFizzServerBrowser', () => {
} catch (error) {
caughtError = error;
}
expect(caughtError.message).toBe(
'The render was aborted by the server without a reason.',
);
expect(errors).toEqual([
'The render was aborted by the server without a reason.',
]);
expect(caughtError.message).toBe('The operation was aborted.');
expect(errors).toEqual(['The operation was aborted.']);
});
it('should reject if passing an already aborted signal', async () => {
const errors = [];
const controller = new AbortController();
const theReason = new Error('aborted for reasons');
// @TODO this is a hack to work around lack of support for abortSignal.reason in node
// The abort call itself should set this property but since we are testing in node we
// set it here manually
controller.signal.reason = theReason;
controller.abort(theReason);
const promise = ReactDOMFizzServer.renderToReadableStream(
@ -436,10 +422,6 @@ describe('ReactDOMFizzServerBrowser', () => {
},
});
// @TODO this is a hack to work around lack of support for abortSignal.reason in node
// The abort call itself should set this property but since we are testing in node we
// set it here manually
controller.signal.reason = 'foobar';
controller.abort('foobar');
expect(errors).toEqual(['foobar', 'foobar']);
@ -477,10 +459,6 @@ describe('ReactDOMFizzServerBrowser', () => {
},
});
// @TODO this is a hack to work around lack of support for abortSignal.reason in node
// The abort call itself should set this property but since we are testing in node we
// set it here manually
controller.signal.reason = new Error('uh oh');
controller.abort(new Error('uh oh'));
expect(errors).toEqual(['uh oh', 'uh oh']);

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
let JSDOM;

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';

View File

@ -208,9 +208,7 @@ describe('ReactDOMFizzStaticBrowser', () => {
const prelude = await readContent(result.prelude);
expect(prelude).toContain('Loading');
expect(errors).toEqual([
'The render was aborted by the server without a reason.',
]);
expect(errors).toEqual(['The operation was aborted.']);
});
// @gate experimental
@ -232,10 +230,6 @@ describe('ReactDOMFizzStaticBrowser', () => {
await jest.runAllTimers();
const theReason = new Error('aborted for reasons');
// @TODO this is a hack to work around lack of support for abortSignal.reason in node
// The abort call itself should set this property but since we are testing in node we
// set it here manually
controller.signal.reason = theReason;
controller.abort(theReason);
let caughtError = null;
@ -278,12 +272,8 @@ describe('ReactDOMFizzStaticBrowser', () => {
} catch (error) {
caughtError = error;
}
expect(caughtError.message).toBe(
'The render was aborted by the server without a reason.',
);
expect(errors).toEqual([
'The render was aborted by the server without a reason.',
]);
expect(caughtError.message).toBe('The operation was aborted.');
expect(errors).toEqual(['The operation was aborted.']);
});
// @gate experimental
@ -291,10 +281,6 @@ describe('ReactDOMFizzStaticBrowser', () => {
const errors = [];
const controller = new AbortController();
const theReason = new Error('aborted for reasons');
// @TODO this is a hack to work around lack of support for abortSignal.reason in node
// The abort call itself should set this property but since we are testing in node we
// set it here manually
controller.signal.reason = theReason;
controller.abort(theReason);
const promise = ReactDOMFizzStatic.prerender(
@ -356,10 +342,6 @@ describe('ReactDOMFizzStaticBrowser', () => {
},
});
// @TODO this is a hack to work around lack of support for abortSignal.reason in node
// The abort call itself should set this property but since we are testing in node we
// set it here manually
controller.signal.reason = 'foobar';
controller.abort('foobar');
await resultPromise;
@ -400,10 +382,6 @@ describe('ReactDOMFizzStaticBrowser', () => {
},
});
// @TODO this is a hack to work around lack of support for abortSignal.reason in node
// The abort call itself should set this property but since we are testing in node we
// set it here manually
controller.signal.reason = new Error('uh oh');
controller.abort(new Error('uh oh'));
await resultPromise;

View File

@ -5,11 +5,9 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment node
*/
// TODO: This should actually run in `@jest-environment node` but we currently
// run an old jest that doesn't support AbortController so we use DOM for now.
'use strict';
let React;
@ -212,9 +210,7 @@ describe('ReactDOMFizzStaticNode', () => {
const prelude = await readContent(result.prelude);
expect(prelude).toContain('Loading');
expect(errors).toEqual([
'The render was aborted by the server without a reason.',
]);
expect(errors).toEqual(['This operation was aborted']);
});
// @gate experimental
@ -236,10 +232,6 @@ describe('ReactDOMFizzStaticNode', () => {
await jest.runAllTimers();
const theReason = new Error('aborted for reasons');
// @TODO this is a hack to work around lack of support for abortSignal.reason in node
// The abort call itself should set this property but since we are testing in node we
// set it here manually
controller.signal.reason = theReason;
controller.abort(theReason);
let caughtError = null;
@ -282,12 +274,8 @@ describe('ReactDOMFizzStaticNode', () => {
} catch (error) {
caughtError = error;
}
expect(caughtError.message).toBe(
'The render was aborted by the server without a reason.',
);
expect(errors).toEqual([
'The render was aborted by the server without a reason.',
]);
expect(caughtError.message).toBe('This operation was aborted');
expect(errors).toEqual(['This operation was aborted']);
});
// @gate experimental
@ -295,10 +283,6 @@ describe('ReactDOMFizzStaticNode', () => {
const errors = [];
const controller = new AbortController();
const theReason = new Error('aborted for reasons');
// @TODO this is a hack to work around lack of support for abortSignal.reason in node
// The abort call itself should set this property but since we are testing in node we
// set it here manually
controller.signal.reason = theReason;
controller.abort(theReason);
const promise = ReactDOMFizzStatic.prerenderToNodeStreams(
@ -362,10 +346,6 @@ describe('ReactDOMFizzStaticNode', () => {
await jest.runAllTimers();
// @TODO this is a hack to work around lack of support for abortSignal.reason in node
// The abort call itself should set this property but since we are testing in node we
// set it here manually
controller.signal.reason = 'foobar';
controller.abort('foobar');
await resultPromise;
@ -408,10 +388,6 @@ describe('ReactDOMFizzStaticNode', () => {
await jest.runAllTimers();
// @TODO this is a hack to work around lack of support for abortSignal.reason in node
// The abort call itself should set this property but since we are testing in node we
// set it here manually
controller.signal.reason = new Error('uh oh');
controller.abort(new Error('uh oh'));
await resultPromise;

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -23,6 +24,7 @@ let ReactDOMClient;
let ReactDOMFizzServer;
let Suspense;
let textCache;
let window;
let document;
let writable;
const CSPnonce = null;
@ -32,6 +34,15 @@ let hasErrored = false;
let fatalError = undefined;
let renderOptions;
function resetJSDOM(markup) {
// Test Environment
const jsdom = new JSDOM(markup, {
runScripts: 'dangerously',
});
window = jsdom.window;
document = jsdom.window.document;
}
describe('ReactDOMFloat', () => {
beforeEach(() => {
jest.resetModules();
@ -46,14 +57,7 @@ describe('ReactDOMFloat', () => {
textCache = new Map();
// Test Environment
const jsdom = new JSDOM(
'<!DOCTYPE html><html><head></head><body><div id="container">',
{
runScripts: 'dangerously',
},
);
document = jsdom.window.document;
resetJSDOM('<!DOCTYPE html><html><head></head><body><div id="container">');
container = document.getElementById('container');
buffer = '';
@ -137,15 +141,11 @@ describe('ReactDOMFloat', () => {
// We also want to execute any scripts that are embedded.
// We assume that we have now received a proper fragment of HTML.
const bufferedContent = buffer;
// Test Environment
const jsdom = new JSDOM(bufferedContent, {
runScripts: 'dangerously',
});
document = jsdom.window.document;
resetJSDOM(bufferedContent);
container = document;
buffer = '';
await withLoadingReadyState(async () => {
await replaceScriptsAndMove(jsdom.window, null, document.documentElement);
await replaceScriptsAndMove(window, null, document.documentElement);
}, document);
}

View File

@ -3,6 +3,8 @@
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -49,7 +51,11 @@ describe('ReactDOMServerHydration', () => {
if (format instanceof Error) {
return 'Caught [' + format.message + ']';
}
if (format.indexOf('Error: Uncaught [') === 0) {
if (
format !== null &&
typeof format === 'object' &&
String(format).indexOf('Error: Uncaught [') === 0
) {
// Ignore errors captured by jsdom and their stacks.
// We only want console errors in this suite.
return null;

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -19,7 +20,7 @@ let ReactDOMServer;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -20,7 +21,7 @@ let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -20,7 +21,7 @@ let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -18,7 +19,7 @@ let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -19,7 +20,7 @@ let ReactDOMServer;
let ReactTestUtils;
function initModules() {
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -18,7 +19,7 @@ let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
/* eslint-disable no-func-assign */
@ -35,7 +36,7 @@ let clearYields;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -20,7 +21,7 @@ let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -19,7 +20,7 @@ let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
PropTypes = require('prop-types');
React = require('react');
ReactDOM = require('react-dom');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -19,7 +20,7 @@ let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -18,7 +19,7 @@ let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -18,7 +19,7 @@ let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -18,7 +18,7 @@ let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');

View File

@ -18,7 +18,7 @@ let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -18,7 +19,7 @@ let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -23,7 +24,7 @@ let clearYields;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -18,7 +19,7 @@ let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
/* eslint-disable no-script-url */
@ -149,7 +150,7 @@ function runTests(itRenders, itRejectsRendering, expectToReject) {
describe('ReactDOMServerIntegration - Untrusted URLs', () => {
function initModules() {
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');
@ -181,7 +182,7 @@ describe('ReactDOMServerIntegration - Untrusted URLs', () => {
describe('ReactDOMServerIntegration - Untrusted URLs - disableJavaScriptURLs', () => {
function initModules() {
jest.resetModuleRegistry();
jest.resetModules();
const ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactFeatureFlags.disableJavaScriptURLs = true;

View File

@ -18,7 +18,7 @@ let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -16,7 +16,7 @@ let ReactDOMServer;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOMServer = require('react-dom/server');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -94,7 +95,7 @@ class TestAppClass extends React.Component {
describe('ReactDOMServerPartialHydration', () => {
beforeEach(() => {
jest.resetModuleRegistry();
jest.resetModules();
ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactFeatureFlags.enableSuspenseCallback = true;
@ -3119,7 +3120,7 @@ describe('ReactDOMServerPartialHydration', () => {
// We're now partially hydrated.
await act(async () => {
form.dispatchEvent(
new Event('submit', {
new window.Event('submit', {
bubbles: true,
}),
);

View File

@ -125,7 +125,7 @@ function TODO_scheduleContinuousSchedulerTask(fn) {
describe('ReactDOMServerSelectiveHydration', () => {
beforeEach(() => {
jest.resetModuleRegistry();
jest.resetModules();
ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactFeatureFlags.enableCreateEventHandleAPI = true;
@ -990,7 +990,7 @@ describe('ReactDOMServerSelectiveHydration', () => {
beforeEach(async () => {
document.body.innerHTML = '';
jest.resetModuleRegistry();
jest.resetModules();
let OuterReactDOMClient;
let InnerReactDOMClient;
jest.isolateModules(() => {

View File

@ -21,7 +21,7 @@ let SuspenseList;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
let JSDOM;

View File

@ -5,6 +5,7 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
@ -18,7 +19,7 @@ let ReactTestUtils;
function initModules() {
// Reset warning cache.
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactDOM = require('react-dom');
ReactDOMServer = require('react-dom/server');

View File

@ -20,7 +20,7 @@ function FunctionComponent(props) {
describe('ReactFunctionComponent', () => {
beforeEach(() => {
jest.resetModuleRegistry();
jest.resetModules();
PropTypes = require('prop-types');
React = require('react');
ReactDOM = require('react-dom');

View File

@ -20,7 +20,7 @@ describe('ReactServerRenderingBrowser', () => {
React = require('react');
ReactDOMServer = require('react-dom/server');
// For extra isolation between what would be two bundles on npm
jest.resetModuleRegistry();
jest.resetModules();
ReactDOMServerBrowser = require('react-dom/server.browser');
});

View File

@ -5,12 +5,11 @@
* LICENSE file in the root directory of this source tree.
*
* @emails react-core
* @jest-environment ./scripts/jest/ReactDOMServerIntegrationEnvironment
*/
'use strict';
global.TextEncoder = require('util').TextEncoder;
let React;
let ReactDOM;
let ReactDOMClient;

View File

@ -14,7 +14,7 @@ describe('EventPluginRegistry', () => {
let createPlugin;
beforeEach(() => {
jest.resetModuleRegistry();
jest.resetModules();
// These tests are intentionally testing the private injection interface.
// The public API surface of this is covered by other tests so
// if `EventPluginRegistry` is ever deleted, these tests should be

View File

@ -18,7 +18,7 @@ let act;
describe('ReactIncrementalUpdates', () => {
beforeEach(() => {
jest.resetModuleRegistry();
jest.resetModules();
React = require('react');
ReactNoop = require('react-noop-renderer');

View File

@ -10,7 +10,7 @@ const SEED = process.env.FUZZ_TEST_SEED || 'default';
const prettyFormatPkg = require('pretty-format');
function prettyFormat(thing) {
return prettyFormatPkg(thing, {
return prettyFormatPkg.format(thing, {
plugins: [
prettyFormatPkg.plugins.ReactElement,
prettyFormatPkg.plugins.ReactTestComponent,

View File

@ -582,10 +582,6 @@ describe('ReactFlightDOMBrowser', () => {
expect(container.innerHTML).toBe('<p>(loading)</p>');
await act(async () => {
// @TODO this is a hack to work around lack of support for abortSignal.reason in node
// The abort call itself should set this property but since we are testing in node we
// set it here manually
controller.signal.reason = 'for reasons';
controller.abort('for reasons');
});
const expectedValue = __DEV__

View File

@ -14,7 +14,7 @@ const ReactFeatureFlags = require('shared/ReactFeatureFlags');
ReactFeatureFlags.replayFailedUnitOfWorkWithInvokeGuardedCallback = false;
const React = require('react');
const ReactTestRenderer = require('react-test-renderer');
const prettyFormat = require('pretty-format');
const {format: prettyFormat} = require('pretty-format');
// Isolate noop renderer
jest.resetModules();

View File

@ -23,6 +23,7 @@ describe('SchedulerNoDOM', () => {
jest.resetModules();
jest.useFakeTimers();
delete global.setImmediate;
delete global.MessageChannel;
jest.unmock('scheduler');
Scheduler = require('scheduler');

View File

@ -15,6 +15,7 @@
.*/node_modules/create-react-class/.*
.*/node_modules/react-native-web/.*
.*/node_modules/fbjs/lib/keyMirrorRecursive.js.flow
.*/node_modules/resolve/test/.*
.*/__mocks__/.*
.*/__tests__/.*

View File

@ -0,0 +1,32 @@
'use strict';
const {TestEnvironment: JSDOMEnvironment} = require('jest-environment-jsdom');
const {TestEnvironment: NodeEnvironment} = require('jest-environment-node');
/**
* Test environment for testing integration of react-dom (browser) with react-dom/server (node)
*/
class ReactDOMServerIntegrationEnvironment extends NodeEnvironment {
constructor(config, context) {
super(config, context);
this.domEnvironment = new JSDOMEnvironment(config, context);
this.global.window = this.domEnvironment.dom.window;
this.global.document = this.global.window.document;
this.global.navigator = this.global.window.navigator;
this.global.Node = this.global.window.Node;
}
async setup() {
await super.setup();
await this.domEnvironment.setup();
}
async teardown() {
await this.domEnvironment.teardown();
await super.teardown();
}
}
module.exports = ReactDOMServerIntegrationEnvironment;

View File

@ -20,10 +20,19 @@ module.exports = {
rootDir: process.cwd(),
roots: ['<rootDir>/packages', '<rootDir>/scripts'],
collectCoverageFrom: ['packages/**/*.js'],
timers: 'fake',
fakeTimers: {
enableGlobally: true,
legacyFakeTimers: true,
},
snapshotFormat: {
escapeString: true,
printBasicPrototype: true,
},
snapshotSerializers: [require.resolve('jest-snapshot-serializer-raw')],
testSequencer: require.resolve('./jestSequencer'),
testEnvironment: 'jsdom',
testRunner: 'jasmine2',
};

View File

@ -1,6 +1,6 @@
'use strict';
const jestDiff = require('jest-diff').default;
const {diff: jestDiff} = require('jest-diff');
const util = require('util');
const shouldIgnoreConsoleError = require('../shouldIgnoreConsoleError');

View File

@ -60,16 +60,16 @@ module.exports = {
process: function (src, filePath) {
if (filePath.match(/\.css$/)) {
// Don't try to parse CSS modules; they aren't needed for tests anyway.
return '';
return {code: ''};
}
if (filePath.match(/\.coffee$/)) {
return coffee.compile(src, {bare: true});
return {code: coffee.compile(src, {bare: true})};
}
if (filePath.match(/\.ts$/) && !filePath.match(/\.d\.ts$/)) {
return tsPreprocessor.compile(src, filePath);
return {code: tsPreprocessor.compile(src, filePath)};
}
if (filePath.match(/\.json$/)) {
return src;
return {code: src};
}
if (!filePath.match(/\/third_party\//)) {
// for test files, we also apply the async-await transform, but we want to
@ -95,22 +95,24 @@ module.exports = {
plugins.push(pathToTransformReactVersionPragma);
}
let sourceAst = hermesParser.parse(src, {babel: true});
return babel.transformFromAstSync(
sourceAst,
src,
Object.assign(
{filename: path.relative(process.cwd(), filePath)},
babelOptions,
{
plugins,
sourceMaps: process.env.JEST_ENABLE_SOURCE_MAPS
? process.env.JEST_ENABLE_SOURCE_MAPS
: false,
}
)
);
return {
code: babel.transformFromAstSync(
sourceAst,
src,
Object.assign(
{filename: path.relative(process.cwd(), filePath)},
babelOptions,
{
plugins,
sourceMaps: process.env.JEST_ENABLE_SOURCE_MAPS
? process.env.JEST_ENABLE_SOURCE_MAPS
: false,
}
)
).code,
};
}
return src;
return {code: src};
},
getCacheKey: createCacheKeyFunction(

View File

@ -35,4 +35,7 @@ if (typeof window !== 'undefined') {
global.cancelIdleCallback = function (callbackID) {
clearTimeout(callbackID);
};
} else {
global.AbortController =
require('abortcontroller-polyfill/dist/cjs-ponyfill').AbortController;
}

View File

@ -23,6 +23,17 @@ module.exports = function shouldIgnoreConsoleError(format, args) {
// We haven't finished migrating our tests to use createRoot.
return true;
}
} else if (
format != null &&
typeof format.message === 'string' &&
typeof format.stack === 'string' &&
args.length === 0
) {
if (format.stack.indexOf('Error: Uncaught [') === 0) {
// This looks like an uncaught error from invokeGuardedCallback() wrapper
// in development that is reported by jest-environment-jsdom. Ignore because it's noisy.
return true;
}
}
} else {
if (

2710
yarn.lock

File diff suppressed because it is too large Load Diff