From 7ce229d3b080ce06b9a5c7a5e667474f3255b954 Mon Sep 17 00:00:00 2001 From: Brian Vaughn Date: Thu, 15 Aug 2019 09:53:22 -0700 Subject: [PATCH] Made some incremental progress on Jest tests --- package.json | 7 +++-- packages/react-devtools-shared/package.json | 1 + .../src/__tests__/bridge-test.js | 2 +- .../src/__tests__/console-test.js | 30 ++++++++++--------- .../src/__tests__/setupEnv.js | 16 ++++++---- .../src/__tests__/utils.js | 3 +- scripts/jest/config.devtools.js | 27 +++++++++++++++++ scripts/jest/preprocessor.js | 5 +++- yarn.lock | 17 +++++++++-- 9 files changed, 80 insertions(+), 28 deletions(-) create mode 100644 scripts/jest/config.devtools.js diff --git a/package.json b/package.json index bdbe2f9710..4dbe4b72c8 100644 --- a/package.json +++ b/package.json @@ -47,10 +47,10 @@ "error-stack-parser": "^2.0.2", "eslint": "^6.1.0", "eslint-config-fbjs": "^1.1.1", + "eslint-plugin-babel": "^5.3.0", "eslint-plugin-flowtype": "^2.25.0", "eslint-plugin-jest": "^22.15.0", "eslint-plugin-no-for-of-loops": "^1.0.0", - "eslint-plugin-babel": "^5.3.0", "eslint-plugin-react": "^6.7.1", "eslint-plugin-react-internal": "link:./scripts/eslint-rules", "fbjs-scripts": "^0.8.3", @@ -61,8 +61,8 @@ "google-closure-compiler": "20190301.0.0", "gzip-size": "^3.0.0", "jasmine-check": "^1.0.0-rc.0", - "jest": "^23.1.0", - "jest-diff": "^23.0.1", + "jest": "^23", + "jest-diff": "^23", "jest-snapshot-serializer-raw": "^1.1.0", "minimatch": "^3.0.4", "minimist": "^1.2.0", @@ -102,6 +102,7 @@ "postinstall": "node node_modules/fbjs-scripts/node/check-dev-engines.js package.json && node ./scripts/flow/createFlowConfigs.js", "debug-test": "cross-env NODE_ENV=development node --inspect-brk node_modules/.bin/jest --config ./scripts/jest/config.source.js --runInBand", "test": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.source.js", + "test-devtools": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.devtools.js", "test-persistent": "cross-env NODE_ENV=development jest --config ./scripts/jest/config.source-persistent.js", "debug-test-persistent": "cross-env NODE_ENV=development node --inspect-brk node_modules/.bin/jest --config ./scripts/jest/config.source-persistent.js --runInBand", "test-prod": "cross-env NODE_ENV=production jest --config ./scripts/jest/config.source.js", diff --git a/packages/react-devtools-shared/package.json b/packages/react-devtools-shared/package.json index 1b06dbd9ec..bedc40230e 100644 --- a/packages/react-devtools-shared/package.json +++ b/packages/react-devtools-shared/package.json @@ -8,6 +8,7 @@ "@reach/tooltip": "^0.2.2", "clipboard-js": "^0.3.6", "events": "^3.0.0", + "local-storage-fallback": "^4.1.1", "lodash.throttle": "^4.1.1", "memoize-one": "^3.1.1", "react-virtualized-auto-sizer": "^1.0.2" diff --git a/packages/react-devtools-shared/src/__tests__/bridge-test.js b/packages/react-devtools-shared/src/__tests__/bridge-test.js index ddd9e044e9..dc8886ee57 100644 --- a/packages/react-devtools-shared/src/__tests__/bridge-test.js +++ b/packages/react-devtools-shared/src/__tests__/bridge-test.js @@ -30,7 +30,7 @@ describe('Bridge', () => { expect(wall.send).toHaveBeenCalledWith('shutdown'); // Verify that the Bridge doesn't send messages after shutdown. - spyOn(console, 'warn'); + spyOnDevAndProd(console, 'warn'); wall.send.mockClear(); bridge.send('should not send'); jest.runAllTimers(); diff --git a/packages/react-devtools-shared/src/__tests__/console-test.js b/packages/react-devtools-shared/src/__tests__/console-test.js index dc6dde9f48..c05f2d43bf 100644 --- a/packages/react-devtools-shared/src/__tests__/console-test.js +++ b/packages/react-devtools-shared/src/__tests__/console-test.js @@ -13,23 +13,10 @@ describe('console', () => { let unpatchConsole; beforeEach(() => { - const Console = require('../backend/console'); + const Console = require('react-devtools-shared/src/backend/console'); patchConsole = Console.patch; unpatchConsole = Console.unpatch; - const inject = global.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject; - global.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject = internals => { - inject(internals); - - Console.registerRenderer(internals); - }; - - React = require('react'); - ReactDOM = require('react-dom'); - - const utils = require('./utils'); - act = utils.act; - // Patch a fake console so we can verify with tests below. // Patching the real console is too complicated, // because Jest itself has hooks into it as does our test env setup. @@ -46,7 +33,22 @@ describe('console', () => { Console.dangerous_setTargetConsoleForTesting(fakeConsole); + // Note the Console module only patches once, + // so it's important to patch the test console before injection. patchConsole(); + + const inject = global.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject; + global.__REACT_DEVTOOLS_GLOBAL_HOOK__.inject = internals => { + inject(internals); + + Console.registerRenderer(internals); + }; + + React = require('react'); + ReactDOM = require('react-dom'); + + const utils = require('./utils'); + act = utils.act; }); function normalizeCodeLocInfo(str) { diff --git a/packages/react-devtools-shared/src/__tests__/setupEnv.js b/packages/react-devtools-shared/src/__tests__/setupEnv.js index 0198427ad9..2b26da5dc4 100644 --- a/packages/react-devtools-shared/src/__tests__/setupEnv.js +++ b/packages/react-devtools-shared/src/__tests__/setupEnv.js @@ -1,15 +1,19 @@ -// @flow +'use strict'; -import storage from 'local-storage-fallback'; +// Import test renderer and then reset modules for two reasons: +// 1. We don't want test renderer connected to the DevTools hooks. +// 2. This enables us to work around the on-renderer limitation. +// TODO This (or the resetModules below) might be the cause of the hooks erorr in some tests +const ReactTestRenderer = require.requireActual('react-test-renderer'); -// In case async/await syntax is used in a test. -import 'regenerator-runtime/runtime'; +jest.resetModules(); + +jest.mock('react-test-renderer', () => ReactTestRenderer); // DevTools stores preferences between sessions in localStorage if (!global.hasOwnProperty('localStorage')) { - global.localStorage = storage; + global.localStorage = require('local-storage-fallback').default; } // Mimic the global we set with Webpack's DefinePlugin global.__DEV__ = process.env.NODE_ENV !== 'production'; -global.__TEST__ = process.env.NODE_ENV === 'test'; diff --git a/packages/react-devtools-shared/src/__tests__/utils.js b/packages/react-devtools-shared/src/__tests__/utils.js index 8501f30b19..4c28732e65 100644 --- a/packages/react-devtools-shared/src/__tests__/utils.js +++ b/packages/react-devtools-shared/src/__tests__/utils.js @@ -40,7 +40,8 @@ export async function actAsync( }); if (recursivelyFlush) { - while (jest.getTimerCount() > 0) { + // TODO (Jest v24) Replace with jest.getTimerCount() after we upgrade Jest + while (global.mockGetTimersCount() > 0) { // $FlowFixMe Flow doens't know about "await act()" yet await actDOM(async () => { await actTestRenderer(async () => { diff --git a/scripts/jest/config.devtools.js b/scripts/jest/config.devtools.js new file mode 100644 index 0000000000..d0a6e32b0a --- /dev/null +++ b/scripts/jest/config.devtools.js @@ -0,0 +1,27 @@ +'use strict'; + +const baseConfig = require('./config.base'); + +module.exports = Object.assign({}, baseConfig, { + testRegex: 'packages/react-devtools-shared/src/__tests__/[^]+.test.js$', + modulePathIgnorePatterns: [], + snapshotSerializers: [ + require.resolve( + '../../packages/react-devtools-shared/src/__tests__/inspectedElementSerializer.js' + ), + require.resolve( + '../../packages/react-devtools-shared/src/__tests__/storeSerializer.js' + ), + ], + setupFiles: [ + ...baseConfig.setupFiles, + require.resolve('./setupHostConfigs.js'), + require.resolve( + '../../packages/react-devtools-shared/src/__tests__/setupEnv.js' + ), + ], + // TODO (Jest v24) Rename "setupFilesAfterEnv" after Jest upgrade + setupTestFrameworkScriptFile: require.resolve( + '../../packages/react-devtools-shared/src/__tests__/setupTests.js' + ), +}); diff --git a/scripts/jest/preprocessor.js b/scripts/jest/preprocessor.js index b04daaee88..beb46268f4 100644 --- a/scripts/jest/preprocessor.js +++ b/scripts/jest/preprocessor.js @@ -43,7 +43,10 @@ const babelOptions = { // This optimization is important for extremely performance-sensitive (e.g. React source). // It's okay to disable it for tests. - [require.resolve('@babel/plugin-transform-block-scoping'), {throwIfClosureRequired: false}], + [ + require.resolve('@babel/plugin-transform-block-scoping'), + {throwIfClosureRequired: false}, + ], ], retainLines: true, }; diff --git a/yarn.lock b/yarn.lock index 9b7ac1ea78..fb14f75076 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1879,6 +1879,7 @@ array.prototype.find@^2.0.1: arrify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= arrify@^2.0.1: version "2.0.1" @@ -3513,6 +3514,11 @@ cookie@0.4.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== +cookie@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + integrity sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s= + copy-concurrently@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" @@ -7215,7 +7221,7 @@ jest-config@^23.6.0: micromatch "^2.3.11" pretty-format "^23.6.0" -jest-diff@^23.0.1, jest-diff@^23.6.0: +jest-diff@^23, jest-diff@^23.6.0: version "23.6.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.6.0.tgz#1500f3f16e850bb3d71233408089be099f610c7d" integrity sha512-Gz9l5Ov+X3aL5L37IT+8hoCUsof1CVYBb2QEkOupK64XyRR3h+uRpYIm97K7sY8diFxowR8pIGEdyfMKTixo3g== @@ -7536,7 +7542,7 @@ jest-worker@^24.6.0: merge-stream "^1.0.1" supports-color "^6.1.0" -jest@^23.1.0: +jest@^23: version "23.6.0" resolved "https://registry.yarnpkg.com/jest/-/jest-23.6.0.tgz#ad5835e923ebf6e19e7a1d7529a432edfee7813d" integrity sha512-lWzcd+HSiqeuxyhG+EnZds6iO3Y3ZEnMrfZq/OTGvF/C+Z4fPMCdhWTGSAiO2Oym9rbEXfwddHhh6jqrTF3+Lw== @@ -7941,6 +7947,13 @@ loader-utils@1.2.3, loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2. emojis-list "^2.0.0" json5 "^1.0.1" +local-storage-fallback@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/local-storage-fallback/-/local-storage-fallback-4.1.1.tgz#6dc964635c8e9ab6d522d7d88538f465b62bd161" + integrity sha512-Ka4rem1FOgvIaPMokxXTP8DgW8gjfAQSdJC8TGrplDug7vh3b0PZnY/9euG3O3cIGAvJLp33mMU6MJ13x6S+Pw== + dependencies: + cookie "^0.3.1" + locate-path@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e"