diff --git a/.circleci/config.yml b/.circleci/config.yml index 33113f6c43b2..fcee3ee8e014 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -90,6 +90,20 @@ jobs: - store_test_results: path: reports/junit + test-node-14: + working_directory: ~/jest + docker: + - image: circleci/node:14 + steps: + - checkout + - restore-cache: *restore-cache + - run: *install + - save-cache: *save-cache + - run: + command: yarn test-ci-partial + - store_test_results: + path: reports/junit + test-browser: working_directory: ~/jest docker: @@ -123,7 +137,8 @@ workflows: - test-node-8 - test-node-10 - test-node-12 - - test-node-13 # current + - test-node-13 + - test-node-14 # current - test-jest-circus - test-browser - test-or-deploy-website: diff --git a/.eslintrc.js b/.eslintrc.js index 075a0c763dfd..d04c2f900797 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -132,7 +132,7 @@ module.exports = { '**/__mocks__/**', '**/?(*.)(spec|test).js?(x)', 'scripts/**', - 'eslintImportResolver.js', + 'babel.config.js', 'testSetupFile.js', ], }, @@ -146,4 +146,7 @@ module.exports = { 'prettier/prettier': 2, 'sort-imports': [2, {ignoreDeclarationSort: true}], }, + settings: { + 'import/ignore': ['react-native'], + }, }; diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index e7da849d85fe..78c1927a0e6f 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -57,7 +57,7 @@ jobs: fail-fast: false matrix: # https://github.com/actions/setup-node/issues/27 - node-version: [8.17.0, 10.x, 12.x, 13.x] + node-version: [8.17.0, 10.x, 12.x, 13.x, 14.x] os: [ubuntu-latest, macOS-latest, windows-latest] runs-on: ${{ matrix.os }} diff --git a/.vscode/launch.json b/.vscode/launch.json index f4106b4f6605..5de4feacd272 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -7,10 +7,15 @@ { "type": "node", "request": "launch", - "name": "Debug Jest with current test file", - "program": "${workspaceFolder}/packages/jest-cli/bin/jest.js", - "args": ["--runInBand", "${file}"], - "runtimeArgs": ["-r", "flow-remove-types/register"] + "name": "Jest Current File", + "program": "${workspaceFolder}/node_modules/.bin/jest", + "args": ["${fileBasenameNoExtension}"], + "console": "integratedTerminal", + "internalConsoleOptions": "neverOpen", + "disableOptimisticBPs": true, + "windows": { + "program": "${workspaceFolder}/node_modules/jest/bin/jest" + } } ] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 0478de9c2561..0dcce386c953 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,5 +9,6 @@ "jest.pathToJest": "yarn jest --", "editor.codeActionsOnSave": { "source.fixAll.eslint": true - } + }, + "typescript.tsdk": "node_modules/typescript/lib" } diff --git a/CHANGELOG.md b/CHANGELOG.md index 24cb6c37ea17..91f04725fe98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,15 +3,45 @@ ### Features - `[@jest/globals]` New package so Jest's globals can be explicitly imported ([#9801](https://github.com/facebook/jest/pull/9801)) +- `[jest-core]` Show coverage of sources related to tests in changed files ([#9769](https://github.com/facebook/jest/pull/9769)) +- `[jest-runtime]` Populate `require.cache` ([#9841](https://github.com/facebook/jest/pull/9841)) - `[jest-snapshot]`: Make prettier optional for inline snapshots - fall back to string replacement ([#7792](https://github.com/facebook/jest/pull/7792)) ### Fixes +- `[expect]` Prints the Symbol name into the error message with a custom asymmetric matcher ([#9888](https://github.com/facebook/jest/pull/9888)) +- `[@jest/environment]` Make sure not to reference Jest types ([#9875](https://github.com/facebook/jest/pull/9875)) +- `[jest-message-util]` Code frame printing should respect `--noStackTrace` flag ([#9866](https://github.com/facebook/jest/pull/9866)) +- `[jest-runtime]` Support importing CJS from ESM using `import` statements ([#9850](https://github.com/facebook/jest/pull/9850)) +- `[jest-runtime]` Support importing parallel dynamic `import`s ([#9858](https://github.com/facebook/jest/pull/9858)) +- `[jest-transform]` Improve source map handling when instrumenting transformed code ([#9811](https://github.com/facebook/jest/pull/9811)) + +### Chore & Maintenance + +### Performance + +- `[jest-resolve]` Update `resolve` to a version using native `realpath`, which is faster than the default JS implementation ([#9872](https://github.com/facebook/jest/pull/9872)) +- `[jest-resolve]` Pass custom cached `realpath` function to `resolve` ([#9873](https://github.com/facebook/jest/pull/9873)) + +## 25.4.0 + +- `[expect]` Support `async function`s in `toThrow` ([#9817](https://github.com/facebook/jest/pull/9817)) +- `[jest-console]` Add code frame to `console.error` and `console.warn` ([#9741](https://github.com/facebook/jest/pull/9741)) +- `[jest-runtime, jest-jasmine2, jest-circus]` Experimental, limited ECMAScript Modules support ([#9772](https://github.com/facebook/jest/pull/9772) & [#9842](https://github.com/facebook/jest/pull/9842)) + +### Fixes + - `[expect]` Restore support for passing functions to `toHaveLength` matcher ([#9796](https://github.com/facebook/jest/pull/9796)) - `[jest-changed-files]` `--only-changed` should include staged files ([#9799](https://github.com/facebook/jest/pull/9799)) +- `[jest-circus]` Throw on nested test definitions ([#9828](https://github.com/facebook/jest/pull/9828)) +- `[jest-each]` `each` will throw an error when called with too many arguments ([#9818](https://github.com/facebook/jest/pull/9818)) +- `[jest-runner]` Don't print warning to stdout when using `--json` ([#9843](https://github.com/facebook/jest/pull/9843)) ### Chore & Maintenance +- `[*]` Do not generate TypeScript declaration source maps ([#9822](https://github.com/facebook/jest/pull/9822)) +- `[*]` Transpile code for Node 8.3, not 8.0 ([#9827](https://github.com/facebook/jest/pull/9827)) + ### Performance ## 25.3.0 diff --git a/babel.config.js b/babel.config.js index 343d46ea18ae..b01524bb0f50 100644 --- a/babel.config.js +++ b/babel.config.js @@ -5,6 +5,11 @@ * LICENSE file in the root directory of this source tree. */ +const semver = require('semver'); +const pkg = require('./package.json'); + +const supportedNodeVersion = semver.minVersion(pkg.engines.node).version; + module.exports = { babelrcRoots: ['examples/*'], // we don't wanna run the transforms in this file over react native @@ -15,7 +20,7 @@ module.exports = { 'babel-plugin-typescript-strip-namespaces', 'babel-plugin-replace-ts-export-assignment', require.resolve( - './scripts/babel-plugin-jest-replace-ts-require-assignment.js' + './scripts/babel-plugin-jest-replace-ts-require-assignment.js', ), ], presets: ['@babel/preset-typescript'], @@ -31,7 +36,7 @@ module.exports = { { exclude: ['@babel/plugin-proposal-dynamic-import'], shippedProposals: true, - targets: {node: 8}, + targets: {node: supportedNodeVersion}, }, ], ], @@ -48,7 +53,7 @@ module.exports = { '@babel/preset-env', { shippedProposals: true, - targets: {node: 8}, + targets: {node: supportedNodeVersion}, }, ], ], diff --git a/docs/JestPlatform.md b/docs/JestPlatform.md index 31f89f6eb6f2..47b7140a732e 100644 --- a/docs/JestPlatform.md +++ b/docs/JestPlatform.md @@ -119,7 +119,7 @@ You can read more about `jest-validate` in the [readme file](https://github.com/ ## jest-worker -Module used for parallelization of tasks. Exports a class `Worker` that takes the path of Node.js module and lets you call the module's exported methods as if they were class methods, returning a promise that resolves when the specified method finishes its execution in a forked process. +Module used for parallelization of tasks. Exports a class `JestWorker` that takes the path of Node.js module and lets you call the module's exported methods as if they were class methods, returning a promise that resolves when the specified method finishes its execution in a forked process. ### Example diff --git a/e2e/Utils.ts b/e2e/Utils.ts index 614831acae17..f377c53e5916 100644 --- a/e2e/Utils.ts +++ b/e2e/Utils.ts @@ -14,6 +14,7 @@ import {ExecaReturnValue, sync as spawnSync} from 'execa'; import makeDir = require('make-dir'); import rimraf = require('rimraf'); import dedent = require('dedent'); +import which = require('which'); interface RunResult extends ExecaReturnValue { status: number; @@ -47,7 +48,7 @@ export const linkJestPackage = (packageName: string, cwd: Config.Path) => { const destination = path.resolve(cwd, 'node_modules/', packageName); makeDir.sync(destination); rimraf.sync(destination); - fs.symlinkSync(packagePath, destination, 'dir'); + fs.symlinkSync(packagePath, destination, 'junction'); }; export const makeTemplate = ( @@ -105,6 +106,7 @@ export const writeSymlinks = ( fs.symlinkSync( path.resolve(directory, ...fileOrPath.split('/')), path.resolve(directory, ...symLinkPath.split('/')), + 'junction', ); }); }; @@ -260,3 +262,19 @@ export const normalizeIcons = (str: string) => { .replace(new RegExp('\u00D7', 'g'), '\u2715') .replace(new RegExp('\u221A', 'g'), '\u2713'); }; + +// Certain environments (like CITGM and GH Actions) do not come with mercurial installed +let hgIsInstalled: boolean | null = null; + +export const testIfHg = (...args: Parameters) => { + if (hgIsInstalled === null) { + hgIsInstalled = which.sync('hg', {nothrow: true}) !== null; + } + + if (hgIsInstalled) { + test(...args); + } else { + console.warn('Mercurial (hg) is not installed - skipping some tests'); + test.skip(...args); + } +}; diff --git a/e2e/__tests__/__snapshots__/beforeAllFiltered.ts.snap b/e2e/__tests__/__snapshots__/beforeAllFiltered.ts.snap index 247de33015d5..77cb833acb56 100644 --- a/e2e/__tests__/__snapshots__/beforeAllFiltered.ts.snap +++ b/e2e/__tests__/__snapshots__/beforeAllFiltered.ts.snap @@ -1,19 +1,29 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Correct BeforeAll run ensures the BeforeAll of ignored suite is not run 1`] = ` - console.log __tests__/beforeAllFiltered.test.js:10 + console.log beforeAll 1 - console.log __tests__/beforeAllFiltered.test.js:13 + at log (__tests__/beforeAllFiltered.test.js:10:13) + + console.log beforeEach 1 - console.log __tests__/beforeAllFiltered.test.js:22 + at log (__tests__/beforeAllFiltered.test.js:13:13) + + console.log It Foo - console.log __tests__/beforeAllFiltered.test.js:16 + at log (__tests__/beforeAllFiltered.test.js:22:13) + + console.log afterEach 1 - console.log __tests__/beforeAllFiltered.test.js:19 + at log (__tests__/beforeAllFiltered.test.js:16:13) + + console.log afterAll 1 + at log (__tests__/beforeAllFiltered.test.js:19:13) + `; diff --git a/e2e/__tests__/__snapshots__/beforeEachQueue.ts.snap b/e2e/__tests__/__snapshots__/beforeEachQueue.ts.snap index a665905a9f06..4acca9e4a59d 100644 --- a/e2e/__tests__/__snapshots__/beforeEachQueue.ts.snap +++ b/e2e/__tests__/__snapshots__/beforeEachQueue.ts.snap @@ -1,19 +1,29 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`Correct beforeEach order ensures the correct order for beforeEach 1`] = ` - console.log __tests__/beforeEachQueue.test.js:10 + console.log BeforeEach - console.log __tests__/beforeEachQueue.test.js:14 + at Object.log (__tests__/beforeEachQueue.test.js:10:13) + + console.log It Foo - console.log __tests__/beforeEachQueue.test.js:17 + at Object.log (__tests__/beforeEachQueue.test.js:14:13) + + console.log BeforeEach Inline Foo - console.log __tests__/beforeEachQueue.test.js:10 + at Object.log (__tests__/beforeEachQueue.test.js:17:15) + + console.log BeforeEach - console.log __tests__/beforeEachQueue.test.js:22 + at Object.log (__tests__/beforeEachQueue.test.js:10:13) + + console.log It Bar + at Object.log (__tests__/beforeEachQueue.test.js:22:13) + `; diff --git a/e2e/__tests__/__snapshots__/console.test.ts.snap b/e2e/__tests__/__snapshots__/console.test.ts.snap index 8077db761de9..161e2e9e4c21 100644 --- a/e2e/__tests__/__snapshots__/console.test.ts.snap +++ b/e2e/__tests__/__snapshots__/console.test.ts.snap @@ -4,14 +4,40 @@ exports[`console printing 1`] = ` PASS __tests__/console.test.js ● Console - console.log __tests__/console.test.js:10 + console.log This is a log message. - console.info __tests__/console.test.js:12 + + at Object.log (__tests__/console.test.js:10:11) + + console.info This is an info message. - console.warn __tests__/console.test.js:14 + + at Object.info (__tests__/console.test.js:12:11) + + console.warn This is a warning message. - console.error __tests__/console.test.js:16 + + 12 | console.info('This is an info message.'); + 13 | + > 14 | console.warn('This is a warning message.'); + | ^ + 15 | + 16 | console.error('This is an error message.'); + 17 | }); + + at Object.warn (__tests__/console.test.js:14:11) + + console.error This is an error message. + + 14 | console.warn('This is a warning message.'); + 15 | + > 16 | console.error('This is an error message.'); + | ^ + 17 | }); + 18 | + + at Object.error (__tests__/console.test.js:16:11) `; exports[`console printing 2`] = ` @@ -23,18 +49,41 @@ Ran all test suites. `; exports[`console printing with --verbose 1`] = ` - console.log __tests__/console.test.js:10 + console.log This is a log message. - console.info __tests__/console.test.js:12 + at Object.log (__tests__/console.test.js:10:11) + + console.info This is an info message. - console.warn __tests__/console.test.js:14 + at Object.info (__tests__/console.test.js:12:11) + + console.warn This is a warning message. - console.error __tests__/console.test.js:16 + 12 | console.info('This is an info message.'); + 13 | + > 14 | console.warn('This is a warning message.'); + | ^ + 15 | + 16 | console.error('This is an error message.'); + 17 | }); + + at Object.warn (__tests__/console.test.js:14:11) + + console.error This is an error message. + 14 | console.warn('This is a warning message.'); + 15 | + > 16 | console.error('This is an error message.'); + | ^ + 17 | }); + 18 | + + at Object.error (__tests__/console.test.js:16:11) + `; exports[`console printing with --verbose 2`] = ` @@ -56,17 +105,25 @@ exports[`does not error out when using winston 2`] = ` PASS __tests__/console.test.js ● Console - console.log node_modules/winston/lib/winston/transports/console.js:79 + console.log {"level":"info","message":"Log message from winston"} - - console.log node_modules/winston/lib/winston/transports/console.js:79 + + at Console.log (node_modules/winston/lib/winston/transports/console.js:79:23) + + console.log {"message":"Info message from winston","level":"info"} - - console.log node_modules/winston/lib/winston/transports/console.js:79 + + at Console.log (node_modules/winston/lib/winston/transports/console.js:79:23) + + console.log {"message":"Warn message from winston","level":"warn"} - - console.log node_modules/winston/lib/winston/transports/console.js:79 + + at Console.log (node_modules/winston/lib/winston/transports/console.js:79:23) + + console.log {"message":"Error message from winston","level":"error"} + + at Console.log (node_modules/winston/lib/winston/transports/console.js:79:23) `; exports[`does not error out when using winston 3`] = ` diff --git a/e2e/__tests__/__snapshots__/consoleAfterTeardown.test.ts.snap b/e2e/__tests__/__snapshots__/consoleAfterTeardown.test.ts.snap index 80308c7d489c..c75128492c2e 100644 --- a/e2e/__tests__/__snapshots__/consoleAfterTeardown.test.ts.snap +++ b/e2e/__tests__/__snapshots__/consoleAfterTeardown.test.ts.snap @@ -15,6 +15,6 @@ PASS __tests__/console.test.js 14 | }); 15 | - at BufferedConsole.log (../../packages/jest-console/build/BufferedConsole.js:199:10) + at BufferedConsole.log (../../packages/jest-console/build/BufferedConsole.js:201:10) at log (__tests__/console.test.js:12:13) `; diff --git a/e2e/__tests__/__snapshots__/consoleLogOutputWhenRunInBand.test.ts.snap b/e2e/__tests__/__snapshots__/consoleLogOutputWhenRunInBand.test.ts.snap index fb009e134aed..571dd419e639 100644 --- a/e2e/__tests__/__snapshots__/consoleLogOutputWhenRunInBand.test.ts.snap +++ b/e2e/__tests__/__snapshots__/consoleLogOutputWhenRunInBand.test.ts.snap @@ -17,7 +17,9 @@ Ran all test suites. `; exports[`prints console.logs when run with forceExit 3`] = ` - console.log __tests__/a-banana.js:1 + console.log Hey + at Object. (__tests__/a-banana.js:1:1) + `; diff --git a/e2e/__tests__/__snapshots__/declarationErrors.test.ts.snap b/e2e/__tests__/__snapshots__/declarationErrors.test.ts.snap index ee816f95e8a1..017f5cc6d332 100644 --- a/e2e/__tests__/__snapshots__/declarationErrors.test.ts.snap +++ b/e2e/__tests__/__snapshots__/declarationErrors.test.ts.snap @@ -16,7 +16,7 @@ exports[`warns if describe returns a Promise 1`] = ` 14 | }); at Object.describe (__tests__/describeReturnPromise.test.js:11:1) - + `; @@ -36,6 +36,6 @@ exports[`warns if describe returns something 1`] = ` 14 | }); at Object.describe (__tests__/describeReturnSomething.test.js:11:1) - + `; diff --git a/e2e/__tests__/__snapshots__/each.test.ts.snap b/e2e/__tests__/__snapshots__/each.test.ts.snap index 188a2727b2b9..98edb0ecb406 100644 --- a/e2e/__tests__/__snapshots__/each.test.ts.snap +++ b/e2e/__tests__/__snapshots__/each.test.ts.snap @@ -205,7 +205,7 @@ FAIL __tests__/failure.test.js 28 | ({left, right}) => { > 29 | expect(left).toBe(right); | ^ - 30 | } + 30 | }, 31 | ); 32 | @@ -222,7 +222,7 @@ FAIL __tests__/failure.test.js 39 | ({left, right}) => { > 40 | expect(left).toBe(right); | ^ - 41 | } + 41 | }, 42 | ); 43 | @@ -239,7 +239,7 @@ FAIL __tests__/failure.test.js 39 | ({left, right}) => { > 40 | expect(left).toBe(right); | ^ - 41 | } + 41 | }, 42 | ); 43 | @@ -256,7 +256,7 @@ FAIL __tests__/failure.test.js 46 | word => { > 47 | expect(/z/.test(word)).toBe(true); | ^ - 48 | } + 48 | }, 49 | ); 50 | @@ -273,7 +273,7 @@ FAIL __tests__/failure.test.js 46 | word => { > 47 | expect(/z/.test(word)).toBe(true); | ^ - 48 | } + 48 | }, 49 | ); 50 | @@ -290,7 +290,7 @@ FAIL __tests__/failure.test.js 46 | word => { > 47 | expect(/z/.test(word)).toBe(true); | ^ - 48 | } + 48 | }, 49 | ); 50 | @@ -308,7 +308,7 @@ FAIL __tests__/failure.test.js > 59 | expect(left).toBe(right); | ^ 60 | }); - 61 | } + 61 | }, 62 | ); at Object.toBe (__tests__/failure.test.js:59:20) @@ -325,7 +325,7 @@ FAIL __tests__/failure.test.js > 59 | expect(left).toBe(right); | ^ 60 | }); - 61 | } + 61 | }, 62 | ); at Object.toBe (__tests__/failure.test.js:59:20) @@ -342,7 +342,7 @@ FAIL __tests__/failure.test.js > 71 | expect(left).toBe(right); | ^ 72 | }); - 73 | } + 73 | }, 74 | ); at Object.toBe (__tests__/failure.test.js:71:20) @@ -359,7 +359,7 @@ FAIL __tests__/failure.test.js > 71 | expect(left).toBe(right); | ^ 72 | }); - 73 | } + 73 | }, 74 | ); at Object.toBe (__tests__/failure.test.js:71:20) diff --git a/e2e/__tests__/__snapshots__/errorOnDeprecated.test.ts.snap b/e2e/__tests__/__snapshots__/errorOnDeprecated.test.ts.snap index 613a80ca77b8..ab3b25ed0f25 100644 --- a/e2e/__tests__/__snapshots__/errorOnDeprecated.test.ts.snap +++ b/e2e/__tests__/__snapshots__/errorOnDeprecated.test.ts.snap @@ -138,7 +138,7 @@ FAIL __tests__/jasmine.objectContaining.test.js 9 | test('jasmine.objectContaining', () => { 10 | expect({input: 'trash', output: 'trash'}).toEqual( - > 11 | jasmine.objectContaining({output: 'trash'}) + > 11 | jasmine.objectContaining({output: 'trash'}), | ^ 12 | ); 13 | }); diff --git a/e2e/__tests__/__snapshots__/expectAsyncMatcher.test.ts.snap b/e2e/__tests__/__snapshots__/expectAsyncMatcher.test.ts.snap index b7d07fa98db9..0c2dd06fe47c 100644 --- a/e2e/__tests__/__snapshots__/expectAsyncMatcher.test.ts.snap +++ b/e2e/__tests__/__snapshots__/expectAsyncMatcher.test.ts.snap @@ -77,7 +77,7 @@ FAIL __tests__/failure.test.js 21 | it('fail with expected promise values and not', () => > 22 | expect(Promise.resolve([1, 2])).resolves.not.toHaveLengthAsync( | ^ - 23 | Promise.resolve(2) + 23 | Promise.resolve(2), 24 | )); 25 | diff --git a/e2e/__tests__/__snapshots__/jest.config.js.test.ts.snap b/e2e/__tests__/__snapshots__/jest.config.js.test.ts.snap index 498c5c97bfd8..db94a91b08e4 100644 --- a/e2e/__tests__/__snapshots__/jest.config.js.test.ts.snap +++ b/e2e/__tests__/__snapshots__/jest.config.js.test.ts.snap @@ -1,9 +1,11 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`traverses directory tree up until it finds jest.config 1`] = ` - console.log ../../../__tests__/a-banana.js:3 + console.log <>/jest.config.js/some/nested/directory + at Object.log (__tests__/a-banana.js:3:27) + `; exports[`traverses directory tree up until it finds jest.config 2`] = ` diff --git a/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap b/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap index d43ffe5dce4f..ed248a26f289 100644 --- a/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap +++ b/e2e/__tests__/__snapshots__/moduleNameMapper.test.ts.snap @@ -36,7 +36,7 @@ FAIL __tests__/index.js 12 | module.exports = () => 'test'; 13 | - at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:540:17) + at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:545:17) at Object.require (index.js:10:1) `; @@ -65,6 +65,6 @@ FAIL __tests__/index.js 12 | module.exports = () => 'test'; 13 | - at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:540:17) + at createNoMappedModuleFoundError (../../packages/jest-resolve/build/index.js:545:17) at Object.require (index.js:10:1) `; diff --git a/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap b/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap new file mode 100644 index 000000000000..c16d98c7fafb --- /dev/null +++ b/e2e/__tests__/__snapshots__/nativeEsm.test.ts.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`on node ^12.16.0 || >=13.2.0 runs test with native ESM 1`] = ` +Test Suites: 1 passed, 1 total +Tests: 11 passed, 11 total +Snapshots: 0 total +Time: <> +Ran all test suites. +`; diff --git a/e2e/__tests__/__snapshots__/nestedTestDefinitions.test.ts.snap b/e2e/__tests__/__snapshots__/nestedTestDefinitions.test.ts.snap new file mode 100644 index 000000000000..daba859d0094 --- /dev/null +++ b/e2e/__tests__/__snapshots__/nestedTestDefinitions.test.ts.snap @@ -0,0 +1,40 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`print correct error message with nested test definitions inside describe 1`] = ` +FAIL __tests__/nestedTestWithinDescribe.js + in describe + ✕ outer test + + ● in describe › outer test + + Tests cannot be nested. Test "inner test" cannot run because it is nested within "outer test". + + 14 | expect(getTruthy()).toBeTruthy(); + 15 | + > 16 | test('inner test', () => { + | ^ + 17 | expect(getTruthy()).toBeTruthy(); + 18 | }); + 19 | }); + + at Object.test (__tests__/nestedTestWithinDescribe.js:16:5) +`; + +exports[`print correct error message with nested test definitions outside describe 1`] = ` +FAIL __tests__/nestedTestOutsideDescribe.js + ✕ outer test + + ● outer test + + Tests cannot be nested. Test "inner test" cannot run because it is nested within "outer test". + + 13 | expect(getTruthy()).toBeTruthy(); + 14 | + > 15 | test('inner test', () => { + | ^ + 16 | expect(getTruthy()).toEqual('This test should not have run'); + 17 | }); + 18 | }); + + at Object.test (__tests__/nestedTestOutsideDescribe.js:15:3) +`; diff --git a/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap b/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap index a62a66e69f80..062640b2406a 100644 --- a/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap +++ b/e2e/__tests__/__snapshots__/resolveNoFileExtensions.test.ts.snap @@ -37,6 +37,6 @@ FAIL __tests__/test.js | ^ 9 | - at Resolver.resolveModule (../../packages/jest-resolve/build/index.js:296:11) + at Resolver.resolveModule (../../packages/jest-resolve/build/index.js:299:11) at Object.require (index.js:8:18) `; diff --git a/e2e/__tests__/__snapshots__/stackTraceSourceMapsWithCoverage.test.ts.snap b/e2e/__tests__/__snapshots__/stackTraceSourceMapsWithCoverage.test.ts.snap new file mode 100644 index 000000000000..fa3a2f7871ab --- /dev/null +++ b/e2e/__tests__/__snapshots__/stackTraceSourceMapsWithCoverage.test.ts.snap @@ -0,0 +1,20 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`processes stack traces and code frames with source maps with coverage 1`] = ` +FAIL __tests__/fails.ts + ✕ fails + + ● fails + + This did not work! + + 11 | + 12 | export function error() { + > 13 | throw new Error('This did not work!'); + | ^ + 14 | } + 15 | + + at Object.error (lib.ts:13:9) + at Object. (__tests__/fails.ts:10:3) +`; diff --git a/e2e/__tests__/__snapshots__/toMatchInlineSnapshot.test.ts.snap b/e2e/__tests__/__snapshots__/toMatchInlineSnapshot.test.ts.snap index 1abfcc0e03ad..a64fb6a82fde 100644 --- a/e2e/__tests__/__snapshots__/toMatchInlineSnapshot.test.ts.snap +++ b/e2e/__tests__/__snapshots__/toMatchInlineSnapshot.test.ts.snap @@ -71,7 +71,7 @@ test('handles property matchers', () => { Object { "createdAt": Any, } - \` + \`, ); }); @@ -85,7 +85,7 @@ expect({createdAt: "string"}).toMatchInlineSnapshot( Object { "createdAt": Any, } -\` +\`, ); }); `; @@ -98,7 +98,7 @@ test('handles property matchers', () => { Object { "createdAt": Any, } - \` + \`, ); }); @@ -112,7 +112,7 @@ test('handles property matchers', () => { Object { "createdAt": Any, } - \` + \`, ); }); @@ -192,7 +192,7 @@ test('removes obsolete external snapshots', () => { exports[`supports async matchers 1`] = ` test('inline snapshots', async () => { expect(Promise.resolve('success')).resolves.toMatchInlineSnapshot( - \`"success"\` + \`"success"\`, ); expect(Promise.reject('fail')).rejects.toMatchInlineSnapshot(\`"fail"\`); }); @@ -221,7 +221,7 @@ expect.extend({ createdAt: expect.any(Date), id: expect.any(Number), }, - ...args + ...args, ); }, }); @@ -242,7 +242,7 @@ test('inline snapshots', () => { "id": Any, "name": "LeBron James", } - \` + \`, ); expect(user).toMatchUserInlineSnapshot(\` Object { diff --git a/e2e/__tests__/__snapshots__/toThrowErrorMatchingInlineSnapshot.test.ts.snap b/e2e/__tests__/__snapshots__/toThrowErrorMatchingInlineSnapshot.test.ts.snap index eb1a037f29aa..7e68215ed3f3 100644 --- a/e2e/__tests__/__snapshots__/toThrowErrorMatchingInlineSnapshot.test.ts.snap +++ b/e2e/__tests__/__snapshots__/toThrowErrorMatchingInlineSnapshot.test.ts.snap @@ -3,7 +3,7 @@ exports[`should support rejecting promises 1`] = ` test('should support rejecting promises', async () => { await expect( - Promise.reject(new Error('octopus')) + Promise.reject(new Error('octopus')), ).rejects.toThrowErrorMatchingInlineSnapshot(\`"octopus"\`); }); diff --git a/e2e/__tests__/__snapshots__/transform.test.ts.snap b/e2e/__tests__/__snapshots__/transform.test.ts.snap index 142251e90fc7..5ccf71e5a934 100644 --- a/e2e/__tests__/__snapshots__/transform.test.ts.snap +++ b/e2e/__tests__/__snapshots__/transform.test.ts.snap @@ -6,7 +6,7 @@ FAIL __tests__/ignoredFile.test.js babel-jest: Babel ignores __tests__/ignoredFile.test.js - make sure to include the file in Jest's transformIgnorePatterns as well. - at loadBabelConfig (../../../packages/babel-jest/build/index.js:227:13) + at loadBabelConfig (../../../packages/babel-jest/build/index.js:178:13) `; exports[`babel-jest instruments only specific files and collects coverage 1`] = ` diff --git a/e2e/__tests__/__snapshots__/v8Coverage.test.ts.snap b/e2e/__tests__/__snapshots__/v8Coverage.test.ts.snap new file mode 100644 index 000000000000..a3fabf97c9d7 --- /dev/null +++ b/e2e/__tests__/__snapshots__/v8Coverage.test.ts.snap @@ -0,0 +1,16 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`on node >=10 prints coverage 1`] = ` +" console.log + 42 + + at Object.log (__tests__/Thing.test.js:10:9) + +----------|---------|----------|---------|---------|------------------- +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s +----------|---------|----------|---------|---------|------------------- +All files | 100 | 100 | 100 | 100 | + Thing.js | 100 | 100 | 100 | 100 | + x.css | 100 | 100 | 100 | 100 | +----------|---------|----------|---------|---------|-------------------" +`; diff --git a/e2e/__tests__/beforeAllFiltered.ts b/e2e/__tests__/beforeAllFiltered.ts index fdd03d373486..7d0a5cf4fbc5 100644 --- a/e2e/__tests__/beforeAllFiltered.ts +++ b/e2e/__tests__/beforeAllFiltered.ts @@ -10,7 +10,11 @@ import runJest from '../runJest'; describe('Correct BeforeAll run', () => { it('ensures the BeforeAll of ignored suite is not run', () => { - const result = runJest('before-all-filtered'); - expect(wrap(result.stdout.replace(/\\/g, '/'))).toMatchSnapshot(); + let {stdout} = runJest('before-all-filtered'); + + // for some reason Circus does not have the `Object` part + stdout = stdout.replace(/at Object.log \(/g, 'at log ('); + + expect(wrap(stdout)).toMatchSnapshot(); }); }); diff --git a/e2e/__tests__/consoleLogOutputWhenRunInBand.test.ts b/e2e/__tests__/consoleLogOutputWhenRunInBand.test.ts index e49a61328672..3e505c906365 100644 --- a/e2e/__tests__/consoleLogOutputWhenRunInBand.test.ts +++ b/e2e/__tests__/consoleLogOutputWhenRunInBand.test.ts @@ -15,6 +15,8 @@ const DIR = path.resolve(__dirname, '../console-log-output-when-run-in-band'); beforeEach(() => cleanup(DIR)); afterAll(() => cleanup(DIR)); +const nodeMajorVersion = Number(process.versions.node.split('.')[0]); + test('prints console.logs when run with forceExit', () => { writeFiles(DIR, { '__tests__/a-banana.js': ` @@ -23,12 +25,26 @@ test('prints console.logs when run with forceExit', () => { 'package.json': '{}', }); - const {stderr, stdout, exitCode} = runJest(DIR, [ + const {stderr, exitCode, ...res} = runJest(DIR, [ '-i', '--ci=false', '--forceExit', ]); + let {stdout} = res; + const {rest, summary} = extractSummary(stderr); + + if (nodeMajorVersion < 12) { + expect(stdout).toContain( + 'at Object..test (__tests__/a-banana.js:1:1)', + ); + + stdout = stdout.replace( + 'at Object..test (__tests__/a-banana.js:1:1)', + 'at Object. (__tests__/a-banana.js:1:1)', + ); + } + expect(exitCode).toBe(0); expect(wrap(rest)).toMatchSnapshot(); expect(wrap(summary)).toMatchSnapshot(); diff --git a/e2e/__tests__/declarationErrors.test.ts b/e2e/__tests__/declarationErrors.test.ts index e0c10bb09a3f..d0d1dda1db16 100644 --- a/e2e/__tests__/declarationErrors.test.ts +++ b/e2e/__tests__/declarationErrors.test.ts @@ -12,7 +12,8 @@ const normalizeCircusJasmine = (str: string) => wrap( str .replace(/console\.log .+:\d+/, 'console.log') - .replace(/.+addSpecsToSuite (.+:\d+:\d+).+\n/g, ''), + .replace(/.+addSpecsToSuite (.+:\d+:\d+).+\n/g, '') + .replace(/.+_dispatchDescribe (.+:\d+:\d+).+\n/g, ''), ); it('warns if describe returns a Promise', () => { diff --git a/e2e/__tests__/jestChangedFiles.test.ts b/e2e/__tests__/jestChangedFiles.test.ts index 5b8e3014cd7b..480e1d966187 100644 --- a/e2e/__tests__/jestChangedFiles.test.ts +++ b/e2e/__tests__/jestChangedFiles.test.ts @@ -10,8 +10,7 @@ import * as path from 'path'; import {wrap} from 'jest-snapshot-serializer-raw'; import {findRepos, getChangedFilesForRoots} from 'jest-changed-files'; import {skipSuiteOnWindows} from '@jest/test-utils'; -import which = require('which'); -import {cleanup, run, writeFiles} from '../Utils'; +import {cleanup, run, testIfHg, writeFiles} from '../Utils'; import runJest from '../runJest'; skipSuiteOnWindows(); @@ -24,14 +23,6 @@ const HG = 'hg --config ui.username=jest_test'; beforeEach(() => cleanup(DIR)); afterEach(() => cleanup(DIR)); -// Certain environments (like CITGM and GH Actions) do not come with mercurial installed -const hgIsInstalled = which.sync('hg', {nothrow: true}) !== null; -const testIfHg = hgIsInstalled ? test : test.skip; - -if (!hgIsInstalled) { - console.warn('Mercurial (hg) is not installed - skipping some tests'); -} - testIfHg('gets hg SCM roots and dedupes them', async () => { writeFiles(DIR, { 'first-repo/file1.txt': 'file1', diff --git a/e2e/__tests__/nativeEsm.test.ts b/e2e/__tests__/nativeEsm.test.ts new file mode 100644 index 000000000000..e8addfb934f3 --- /dev/null +++ b/e2e/__tests__/nativeEsm.test.ts @@ -0,0 +1,36 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {resolve} from 'path'; +import wrap from 'jest-snapshot-serializer-raw'; +import {onNodeVersions} from '@jest/test-utils'; +import runJest, {getConfig} from '../runJest'; +import {extractSummary} from '../Utils'; + +const DIR = resolve(__dirname, '../native-esm'); + +test('test config is without transform', () => { + const {configs} = getConfig(DIR); + + expect(configs).toHaveLength(1); + expect(configs[0].transform).toEqual([]); +}); + +// The versions vm.Module was introduced +onNodeVersions('^12.16.0 || >=13.2.0', () => { + test('runs test with native ESM', () => { + const {exitCode, stderr, stdout} = runJest(DIR, [], { + nodeOptions: '--experimental-vm-modules', + }); + + const {summary} = extractSummary(stderr); + + expect(wrap(summary)).toMatchSnapshot(); + expect(stdout).toBe(''); + expect(exitCode).toBe(0); + }); +}); diff --git a/e2e/__tests__/nestedTestDefinitions.test.ts b/e2e/__tests__/nestedTestDefinitions.test.ts new file mode 100644 index 000000000000..0a26d4fc14c5 --- /dev/null +++ b/e2e/__tests__/nestedTestDefinitions.test.ts @@ -0,0 +1,57 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {wrap} from 'jest-snapshot-serializer-raw'; +import {isJestCircusRun} from '@jest/test-utils'; +import runJest from '../runJest'; +import {extractSummary} from '../Utils'; + +const cleanupRunnerStack = (stderr: string) => + wrap( + stderr + .split('\n') + .filter( + line => + !line.includes('packages/jest-jasmine2/build') && + !line.includes('packages/jest-circus/build'), + ) + .join('\n'), + ); + +test('print correct error message with nested test definitions outside describe', () => { + const result = runJest('nested-test-definitions', ['outside']); + + expect(result.exitCode).toBe(1); + + const summary = extractSummary(result.stderr); + + expect(cleanupRunnerStack(summary.rest)).toMatchSnapshot(); +}); + +test('print correct error message with nested test definitions inside describe', () => { + const result = runJest('nested-test-definitions', ['within']); + + expect(result.exitCode).toBe(1); + + const summary = extractSummary(result.stderr); + + expect(cleanupRunnerStack(summary.rest)).toMatchSnapshot(); +}); + +test('print correct message when nesting describe inside it', () => { + if (!isJestCircusRun()) { + return; + } + + const result = runJest('nested-test-definitions', ['nestedDescribeInTest']); + + expect(result.exitCode).toBe(1); + + expect(result.stderr).toContain( + 'Cannot nest a describe inside a test. Describe block "inner describe" cannot run because it is nested within "test".', + ); +}); diff --git a/e2e/__tests__/onlyChanged.test.ts b/e2e/__tests__/onlyChanged.test.ts index 3a7ff38da596..947a11d50ddc 100644 --- a/e2e/__tests__/onlyChanged.test.ts +++ b/e2e/__tests__/onlyChanged.test.ts @@ -8,7 +8,7 @@ import {tmpdir} from 'os'; import * as path from 'path'; import runJest from '../runJest'; -import {cleanup, run, writeFiles} from '../Utils'; +import {cleanup, run, testIfHg, writeFiles} from '../Utils'; const DIR = path.resolve(tmpdir(), 'jest_only_changed'); const GIT = 'git -c user.name=jest_test -c user.email=jest_test@test.com'; @@ -137,6 +137,39 @@ test('report test coverage for only changed files', () => { expect(stdout).not.toMatch('b.js'); }); +test('report test coverage of source on test file change under only changed files', () => { + writeFiles(DIR, { + '__tests__/a.test.js': ` + require('../a'); + test('a1', () => expect(1).toBe(1)); + `, + 'a.js': 'module.exports = {}', + 'package.json': JSON.stringify({ + jest: { + collectCoverage: true, + coverageReporters: ['text'], + testEnvironment: 'node', + }, + }), + }); + + run(`${GIT} init`, DIR); + run(`${GIT} add .`, DIR); + run(`${GIT} commit --no-gpg-sign -m "first"`, DIR); + + writeFiles(DIR, { + '__tests__/a.test.js': ` + require('../a'); + test('a1', () => expect(1).toBe(1)); + test('a2', () => expect(2).toBe(2)); + `, + }); + + const {stdout} = runJest(DIR, ['--only-changed']); + + expect(stdout).toMatch('a.js'); +}); + test('do not pickup non-tested files when reporting coverage on only changed files', () => { writeFiles(DIR, { 'a.js': 'module.exports = {}', @@ -252,7 +285,7 @@ test('onlyChanged in config is overwritten by --all or testPathPattern', () => { expect(stderr).toMatch(/PASS __tests__(\/|\\)file3.test.js/); }); -test('gets changed files for hg', async () => { +testIfHg('gets changed files for hg', async () => { if (process.env.CI) { // Circle and Travis have very old version of hg (v2, and current // version is v4.2) and its API changed since then and not compatible diff --git a/e2e/__tests__/resolveBrowserField.test.ts b/e2e/__tests__/resolveBrowserField.test.ts index f2e9383ed22c..2c37924e2bc5 100644 --- a/e2e/__tests__/resolveBrowserField.test.ts +++ b/e2e/__tests__/resolveBrowserField.test.ts @@ -63,8 +63,10 @@ test('preserves module identity for symlinks when using browser field resolution const {stdout, stderr, exitCode} = runJest(DIR, ['--no-watchman']); expect(stderr).toContain('Test Suites: 1 passed, 1 total'); expect(wrap(stdout.trim())).toMatchInlineSnapshot(` - console.log packages/needs-preserved-id/index.js:1 + console.log needs-preserved-id executed + + at Object. (packages/needs-preserved-id/index.js:1:13) `); expect(exitCode).toEqual(0); }); diff --git a/e2e/__tests__/stackTraceSourceMapsWithCoverage.test.ts b/e2e/__tests__/stackTraceSourceMapsWithCoverage.test.ts new file mode 100644 index 000000000000..4ac65f38e890 --- /dev/null +++ b/e2e/__tests__/stackTraceSourceMapsWithCoverage.test.ts @@ -0,0 +1,22 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import * as path from 'path'; +import wrap from 'jest-snapshot-serializer-raw'; +import {extractSummary, run} from '../Utils'; +import runJest from '../runJest'; + +it('processes stack traces and code frames with source maps with coverage', () => { + const dir = path.resolve( + __dirname, + '../stack-trace-source-maps-with-coverage', + ); + run('yarn', dir); + const {stderr} = runJest(dir, ['--no-cache', '--coverage']); + + // Should report an error at source line 13 in lib.ts at line 10 of the test + expect(wrap(extractSummary(stderr).rest)).toMatchSnapshot(); +}); diff --git a/e2e/__tests__/v8Coverage.test.ts b/e2e/__tests__/v8Coverage.test.ts index 97dfea44252f..902d324aab10 100644 --- a/e2e/__tests__/v8Coverage.test.ts +++ b/e2e/__tests__/v8Coverage.test.ts @@ -14,6 +14,7 @@ const DIR = path.resolve(__dirname, '../v8-coverage'); onNodeVersions('>=10', () => { test('prints coverage', () => { const sourcemapDir = path.join(DIR, 'no-sourcemap'); + const {stdout, exitCode} = runJest( sourcemapDir, ['--coverage', '--coverage-provider', 'v8'], @@ -23,24 +24,6 @@ onNodeVersions('>=10', () => { ); expect(exitCode).toBe(0); - expect( - '\n' + - stdout - .split('\n') - .map(s => s.trimRight()) - .join('\n') + - '\n', - ).toEqual(` - console.log __tests__/Thing.test.js:10 - 42 - -----------|---------|----------|---------|---------|------------------- -File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s -----------|---------|----------|---------|---------|------------------- -All files | 100 | 100 | 100 | 100 | - Thing.js | 100 | 100 | 100 | 100 | - x.css | 100 | 100 | 100 | 100 | -----------|---------|----------|---------|---------|------------------- -`); + expect(stdout).toMatchSnapshot(); }); }); diff --git a/e2e/__tests__/workerForceExit.test.ts b/e2e/__tests__/workerForceExit.test.ts index 884b2987c953..ec27fa0cd197 100644 --- a/e2e/__tests__/workerForceExit.test.ts +++ b/e2e/__tests__/workerForceExit.test.ts @@ -42,11 +42,11 @@ test('prints a warning if a worker is force exited', () => { }); `, }); - const {exitCode, stderr, stdout} = runJest(DIR, ['--maxWorkers=2']); + const {exitCode, stderr} = runJest(DIR, ['--maxWorkers=2']); expect(exitCode).toBe(0); verifyNumPassed(stderr); - expect(stdout).toContain('A worker process has failed to exit gracefully'); + expect(stderr).toContain('A worker process has failed to exit gracefully'); }); test('force exits a worker that fails to exit gracefully', async () => { diff --git a/e2e/coverage-handlebars/__tests__/greet.js b/e2e/coverage-handlebars/__tests__/greet.js index f5775645112e..ac8485e7e7a2 100644 --- a/e2e/coverage-handlebars/__tests__/greet.js +++ b/e2e/coverage-handlebars/__tests__/greet.js @@ -8,6 +8,6 @@ const greet = require('../greet.hbs'); test('am', () => { expect(greet({am: true, name: 'Joe'})).toEqual( - '

Good\n morning\nJoe!

\n' + '

Good\n morning\nJoe!

\n', ); }); diff --git a/e2e/coverage-report/notRequiredInTestSuite.js b/e2e/coverage-report/notRequiredInTestSuite.js index 8bbc209edb50..7d3ca5a4b994 100644 --- a/e2e/coverage-report/notRequiredInTestSuite.js +++ b/e2e/coverage-report/notRequiredInTestSuite.js @@ -7,7 +7,7 @@ throw new Error( `this error should not be a problem because` + - `this file is never required or executed` + `this file is never required or executed`, ); // Flow annotations to make sure istanbul can instrument non ES6 source diff --git a/e2e/custom-test-sequencer/testSequencerAsync.js b/e2e/custom-test-sequencer/testSequencerAsync.js index cf379c64752d..15b562b85d8d 100644 --- a/e2e/custom-test-sequencer/testSequencerAsync.js +++ b/e2e/custom-test-sequencer/testSequencerAsync.js @@ -13,7 +13,7 @@ class CustomSequencer extends Sequencer { setTimeout(() => { const copyTests = Array.from(tests); resolve( - copyTests.sort((testA, testB) => (testA.path > testB.path ? 1 : -1)) + copyTests.sort((testA, testB) => (testA.path > testB.path ? 1 : -1)), ); }, 50); }); diff --git a/e2e/each/__tests__/describeOnly.test.js b/e2e/each/__tests__/describeOnly.test.js index 854ecd89d8b3..577c4e25bdcb 100644 --- a/e2e/each/__tests__/describeOnly.test.js +++ b/e2e/each/__tests__/describeOnly.test.js @@ -23,5 +23,5 @@ describe.each([[false, true]])( it('fails', () => { expect(left).toBe(right); }); - } + }, ); diff --git a/e2e/each/__tests__/eachException.test.js b/e2e/each/__tests__/eachException.test.js index 4e017576ac68..1cb350067c4e 100644 --- a/e2e/each/__tests__/eachException.test.js +++ b/e2e/each/__tests__/eachException.test.js @@ -13,7 +13,7 @@ it.each` 'throws exception when one argument too few are supplied $left == $right', ({left, right}) => { expect(left).toBe(right); - } + }, ); it.each` @@ -23,5 +23,5 @@ it.each` 'throws exception when not enough arguments are supplied $left == $right', ({left, right}) => { expect(left).toBe(right); - } + }, ); diff --git a/e2e/each/__tests__/eachOnly.test.js b/e2e/each/__tests__/eachOnly.test.js index 9be757e5b1ab..ea6a8cf19d18 100644 --- a/e2e/each/__tests__/eachOnly.test.js +++ b/e2e/each/__tests__/eachOnly.test.js @@ -37,5 +37,5 @@ it.each` 'Should not be ran: fails all rows expected $left == $right', ({left, right}) => { expect(left).toBe(right); - } + }, ); diff --git a/e2e/each/__tests__/eachSkip.test.js b/e2e/each/__tests__/eachSkip.test.js index 3ca62df48835..fa4f7ed1cac7 100644 --- a/e2e/each/__tests__/eachSkip.test.js +++ b/e2e/each/__tests__/eachSkip.test.js @@ -35,7 +35,7 @@ it.skip.each` 'Should not be ran: fails all rows expected $left == $right', ({left, right}) => { expect(left).toBe(right); - } + }, ); describe.skip.each([ diff --git a/e2e/each/__tests__/failure.test.js b/e2e/each/__tests__/failure.test.js index 7175885bb7ad..ee25783ee553 100644 --- a/e2e/each/__tests__/failure.test.js +++ b/e2e/each/__tests__/failure.test.js @@ -27,7 +27,7 @@ it.each` 'template table fails on one row expected: $left == $right', ({left, right}) => { expect(left).toBe(right); - } + }, ); it.each` @@ -38,14 +38,14 @@ it.each` 'template table fails on all rows expected: $left == $right', ({left, right}) => { expect(left).toBe(right); - } + }, ); test.each(['red', 'green', 'bean'])( "The word %s contains the letter 'z'", word => { expect(/z/.test(word)).toBe(true); - } + }, ); describe.each` @@ -58,7 +58,7 @@ describe.each` it('fails ', () => { expect(left).toBe(right); }); - } + }, ); describe.each([ @@ -70,5 +70,5 @@ describe.each([ it('fails', () => { expect(left).toBe(right); }); - } + }, ); diff --git a/e2e/each/__tests__/success.test.js b/e2e/each/__tests__/success.test.js index 523a4542e513..da26207f78d1 100644 --- a/e2e/each/__tests__/success.test.js +++ b/e2e/each/__tests__/success.test.js @@ -9,7 +9,7 @@ test.each(['red', 'green', 'bean'])( "The word %s contains the letter 'e'", word => { expect(/e/.test(word)).toBe(true); - } + }, ); it.each([ diff --git a/e2e/error-on-deprecated/__tests__/jasmine.objectContaining.test.js b/e2e/error-on-deprecated/__tests__/jasmine.objectContaining.test.js index 3b9683aba277..993a375b1a41 100644 --- a/e2e/error-on-deprecated/__tests__/jasmine.objectContaining.test.js +++ b/e2e/error-on-deprecated/__tests__/jasmine.objectContaining.test.js @@ -8,6 +8,6 @@ test('jasmine.objectContaining', () => { expect({input: 'trash', output: 'trash'}).toEqual( - jasmine.objectContaining({output: 'trash'}) + jasmine.objectContaining({output: 'trash'}), ); }); diff --git a/e2e/expect-async-matcher/__tests__/failure.test.js b/e2e/expect-async-matcher/__tests__/failure.test.js index 206948d90a9b..5f9a4880e173 100644 --- a/e2e/expect-async-matcher/__tests__/failure.test.js +++ b/e2e/expect-async-matcher/__tests__/failure.test.js @@ -20,5 +20,5 @@ it('fail with expected promise values', () => it('fail with expected promise values and not', () => expect(Promise.resolve([1, 2])).resolves.not.toHaveLengthAsync( - Promise.resolve(2) + Promise.resolve(2), )); diff --git a/e2e/expect-async-matcher/__tests__/success.test.js b/e2e/expect-async-matcher/__tests__/success.test.js index 8f597b9788ea..ed4a169f6a08 100644 --- a/e2e/expect-async-matcher/__tests__/success.test.js +++ b/e2e/expect-async-matcher/__tests__/success.test.js @@ -20,5 +20,5 @@ it('works with expected promise values', () => it('works with expected promise values and not', () => expect(Promise.resolve([1, 2])).resolves.not.toHaveLengthAsync( - Promise.resolve(1) + Promise.resolve(1), )); diff --git a/e2e/expect-async-matcher/matchers.js b/e2e/expect-async-matcher/matchers.js index 842139ca1ba6..b148b807b44b 100644 --- a/e2e/expect-async-matcher/matchers.js +++ b/e2e/expect-async-matcher/matchers.js @@ -8,7 +8,7 @@ export async function toHaveLengthAsync( received: any, - lengthPromise: Promise + lengthPromise: Promise, ) { const length = await lengthPromise; diff --git a/e2e/expect-in-vm/__tests__/expect-in-vm.test.js b/e2e/expect-in-vm/__tests__/expect-in-vm.test.js index 32b9ce2d7754..183364245d92 100644 --- a/e2e/expect-in-vm/__tests__/expect-in-vm.test.js +++ b/e2e/expect-in-vm/__tests__/expect-in-vm.test.js @@ -14,7 +14,7 @@ it('correctly expects RegExp inside a new VM context', () => { `(function(require, module, exports, __dirname, __filename, expect) { expect('ab12cd').toMatch(/ab12cd/); })`, - global + global, ); const module = { @@ -28,6 +28,6 @@ it('correctly expects RegExp inside a new VM context', () => { module.exports, __dirname, __filename, - expect + expect, ); }); diff --git a/e2e/jasmine-async/__tests__/promiseBeforeAll.test.js b/e2e/jasmine-async/__tests__/promiseBeforeAll.test.js index 42ce500c408c..f3a40d8f9159 100644 --- a/e2e/jasmine-async/__tests__/promiseBeforeAll.test.js +++ b/e2e/jasmine-async/__tests__/promiseBeforeAll.test.js @@ -15,7 +15,7 @@ describe('promise beforeAll', () => { process.nextTick(resolve); }).then(() => { flag = 1; - }) + }), ); beforeAll(() => new Promise(resolve => setTimeout(resolve, 10)), 500); diff --git a/e2e/jasmine-async/__tests__/promiseBeforeEach.test.js b/e2e/jasmine-async/__tests__/promiseBeforeEach.test.js index 846eeb8e6636..45c16c2ef6de 100644 --- a/e2e/jasmine-async/__tests__/promiseBeforeEach.test.js +++ b/e2e/jasmine-async/__tests__/promiseBeforeEach.test.js @@ -13,7 +13,7 @@ describe('promise beforeEach', () => { process.nextTick(resolve); }).then(() => { this.flag = 1; - }) + }), ); // passing tests diff --git a/e2e/jasmine-async/__tests__/promiseIt.test.js b/e2e/jasmine-async/__tests__/promiseIt.test.js index aa688659a7d9..c02d38788494 100644 --- a/e2e/jasmine-async/__tests__/promiseIt.test.js +++ b/e2e/jasmine-async/__tests__/promiseIt.test.js @@ -31,7 +31,7 @@ describe('promise it', () => { new Promise(resolve => { if (this.someContextValue !== 'value') { throw new Error( - 'expected this.someContextValue to be set: ' + this.someContextValue + 'expected this.someContextValue to be set: ' + this.someContextValue, ); } resolve(); @@ -90,13 +90,13 @@ describe('promise it', () => { it( 'succeeds if the test finishes in time', () => new Promise(resolve => setTimeout(resolve, 10)), - 250 + 250, ); // failing tests it( 'fails if a custom timeout is exceeded', () => new Promise(resolve => setTimeout(resolve, 100)), - 10 + 10, ); }); diff --git a/e2e/native-esm/__tests__/native-esm.test.js b/e2e/native-esm/__tests__/native-esm.test.js new file mode 100644 index 000000000000..0603e5d67e1d --- /dev/null +++ b/e2e/native-esm/__tests__/native-esm.test.js @@ -0,0 +1,107 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {readFileSync} from 'fs'; +import {createRequire} from 'module'; +import {dirname, resolve} from 'path'; +import {fileURLToPath} from 'url'; +import {jest as jestObject} from '@jest/globals'; +import staticImportedStateful from '../stateful.mjs'; +import staticImportedStatefulFromCjs from '../fromCjs.mjs'; +import {double} from '../index'; + +test('should have correct import.meta', () => { + expect(typeof require).toBe('undefined'); + expect(typeof jest).toBe('undefined'); + expect(import.meta).toEqual({ + url: expect.any(String), + }); + expect( + import.meta.url.endsWith('/e2e/native-esm/__tests__/native-esm.test.js'), + ).toBe(true); +}); + +test('should double stuff', () => { + expect(double(1)).toBe(2); +}); + +test('should support importing node core modules', () => { + const dir = dirname(fileURLToPath(import.meta.url)); + const packageJsonPath = resolve(dir, '../package.json'); + + expect(JSON.parse(readFileSync(packageJsonPath, 'utf8'))).toEqual({ + jest: { + testEnvironment: 'node', + transform: {}, + }, + type: 'module', + }); +}); + +test('dynamic import should work', async () => { + const {double: importedDouble} = await import('../index'); + + expect(importedDouble).toBe(double); + expect(importedDouble(1)).toBe(2); +}); + +test('import cjs', async () => { + const {default: half} = await import('../commonjs.cjs'); + + expect(half(4)).toBe(2); +}); + +test('require(cjs) and import(cjs) should share caches', async () => { + const require = createRequire(import.meta.url); + + const {default: importedStateful} = await import('../stateful.cjs'); + const requiredStateful = require('../stateful.cjs'); + + expect(importedStateful()).toBe(1); + expect(importedStateful()).toBe(2); + expect(requiredStateful()).toBe(3); + expect(importedStateful()).toBe(4); + expect(requiredStateful()).toBe(5); + expect(requiredStateful()).toBe(6); +}); + +test('import from mjs and import(mjs) should share caches', async () => { + const {default: importedStateful} = await import('../stateful.mjs'); + + expect(importedStateful()).toBe(1); + expect(importedStateful()).toBe(2); + expect(staticImportedStateful()).toBe(3); + expect(importedStateful()).toBe(4); + expect(staticImportedStateful()).toBe(5); + expect(staticImportedStateful()).toBe(6); +}); + +test('import cjs via import statement', () => { + expect(staticImportedStatefulFromCjs(4)).toBe(2); +}); + +test('handle unlinked dynamic imports', async () => { + const {double: deepDouble} = await import('../dynamicImport'); + + expect(deepDouble).toBe(double); + + expect(deepDouble(4)).toBe(8); +}); + +test('can import `jest` object', () => { + expect(jestObject).toBeDefined(); +}); + +test('handle dynamic imports of the same module in parallel', async () => { + const [{double: first}, {double: second}] = await Promise.all([ + import('../anotherDynamicImport.js'), + import('../anotherDynamicImport.js'), + ]); + + expect(first).toBe(second); + expect(first(2)).toBe(4); +}); diff --git a/e2e/native-esm/anotherDynamicImport.js b/e2e/native-esm/anotherDynamicImport.js new file mode 100644 index 000000000000..84b87a513c85 --- /dev/null +++ b/e2e/native-esm/anotherDynamicImport.js @@ -0,0 +1,8 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +export * from './index'; diff --git a/e2e/native-esm/commonjs.cjs b/e2e/native-esm/commonjs.cjs new file mode 100644 index 000000000000..dcb0cfd461fb --- /dev/null +++ b/e2e/native-esm/commonjs.cjs @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +module.exports = function half(num) { + return num / 2; +}; diff --git a/e2e/native-esm/dynamicImport.js b/e2e/native-esm/dynamicImport.js new file mode 100644 index 000000000000..84b87a513c85 --- /dev/null +++ b/e2e/native-esm/dynamicImport.js @@ -0,0 +1,8 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +export * from './index'; diff --git a/e2e/native-esm/fromCjs.mjs b/e2e/native-esm/fromCjs.mjs new file mode 100644 index 000000000000..6f625f8ff51e --- /dev/null +++ b/e2e/native-esm/fromCjs.mjs @@ -0,0 +1,8 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +export {default} from './commonjs.cjs'; diff --git a/e2e/native-esm/index.js b/e2e/native-esm/index.js new file mode 100644 index 000000000000..19bd49f5543e --- /dev/null +++ b/e2e/native-esm/index.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +export function double(num) { + return num * 2; +} diff --git a/e2e/native-esm/package.json b/e2e/native-esm/package.json new file mode 100644 index 000000000000..5a90624bc1fe --- /dev/null +++ b/e2e/native-esm/package.json @@ -0,0 +1,7 @@ +{ + "type": "module", + "jest": { + "testEnvironment": "node", + "transform": {} + } +} diff --git a/e2e/native-esm/stateful.cjs b/e2e/native-esm/stateful.cjs new file mode 100644 index 000000000000..cda0aec7cdcd --- /dev/null +++ b/e2e/native-esm/stateful.cjs @@ -0,0 +1,13 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +let num = 0; + +module.exports = function inc() { + num++; + return num; +}; diff --git a/e2e/native-esm/stateful.mjs b/e2e/native-esm/stateful.mjs new file mode 100644 index 000000000000..485da62bd3c3 --- /dev/null +++ b/e2e/native-esm/stateful.mjs @@ -0,0 +1,13 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +let num = 0; + +export default function inc() { + num++; + return num; +} diff --git a/e2e/nested-test-definitions/__tests__/nestedDescribeInTest.js b/e2e/nested-test-definitions/__tests__/nestedDescribeInTest.js new file mode 100644 index 000000000000..186e795484c7 --- /dev/null +++ b/e2e/nested-test-definitions/__tests__/nestedDescribeInTest.js @@ -0,0 +1,18 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +const {getTruthy} = require('../index'); + +test('test', () => { + expect(getTruthy()).toBeTruthy(); + + describe('inner describe', () => { + // nothing to see here + }); +}); diff --git a/e2e/nested-test-definitions/__tests__/nestedTestOutsideDescribe.js b/e2e/nested-test-definitions/__tests__/nestedTestOutsideDescribe.js new file mode 100644 index 000000000000..b8c6eb9726c0 --- /dev/null +++ b/e2e/nested-test-definitions/__tests__/nestedTestOutsideDescribe.js @@ -0,0 +1,18 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +const {getTruthy} = require('../index'); + +test('outer test', () => { + expect(getTruthy()).toBeTruthy(); + + test('inner test', () => { + expect(getTruthy()).toEqual('This test should not have run'); + }); +}); diff --git a/e2e/nested-test-definitions/__tests__/nestedTestWithinDescribe.js b/e2e/nested-test-definitions/__tests__/nestedTestWithinDescribe.js new file mode 100644 index 000000000000..30160cee5a4b --- /dev/null +++ b/e2e/nested-test-definitions/__tests__/nestedTestWithinDescribe.js @@ -0,0 +1,20 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +const {getTruthy} = require('../index'); + +describe('in describe', () => { + test('outer test', () => { + expect(getTruthy()).toBeTruthy(); + + test('inner test', () => { + expect(getTruthy()).toBeTruthy(); + }); + }); +}); diff --git a/e2e/nested-test-definitions/index.js b/e2e/nested-test-definitions/index.js new file mode 100644 index 000000000000..849dbee86e41 --- /dev/null +++ b/e2e/nested-test-definitions/index.js @@ -0,0 +1,10 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +'use strict'; + +module.exports.getTruthy = () => true; diff --git a/e2e/nested-test-definitions/package.json b/e2e/nested-test-definitions/package.json new file mode 100644 index 000000000000..0ded940b7cb7 --- /dev/null +++ b/e2e/nested-test-definitions/package.json @@ -0,0 +1,5 @@ +{ + "jest": { + "testEnvironment": "jsdom" + } +} diff --git a/e2e/reset-modules/__tests__/resetModules.test.js b/e2e/reset-modules/__tests__/resetModules.test.js index 01eea7be6e20..f0d09ff11d8c 100644 --- a/e2e/reset-modules/__tests__/resetModules.test.js +++ b/e2e/reset-modules/__tests__/resetModules.test.js @@ -12,7 +12,7 @@ global.testObject = new Proxy( get: function getter(target, key) { return key; }, - } + }, ); test('jest.resetModules should not error when _isMockFunction is defined but not boolean', () => { jest.resetModules(); diff --git a/e2e/resolve-with-paths/__tests__/resolveWithPaths.test.js b/e2e/resolve-with-paths/__tests__/resolveWithPaths.test.js index 43a4dd97402e..f6891ea61742 100644 --- a/e2e/resolve-with-paths/__tests__/resolveWithPaths.test.js +++ b/e2e/resolve-with-paths/__tests__/resolveWithPaths.test.js @@ -10,19 +10,19 @@ import {resolve} from 'path'; test('finds a module relative to one of the given paths', () => { expect(require.resolve('./mod.js', {paths: ['../dir']})).toEqual( - resolve(__dirname, '..', 'dir', 'mod.js') + resolve(__dirname, '..', 'dir', 'mod.js'), ); }); test('finds a module without a leading "./" relative to one of the given paths', () => { expect(require.resolve('mod.js', {paths: ['../dir']})).toEqual( - resolve(__dirname, '..', 'dir', 'mod.js') + resolve(__dirname, '..', 'dir', 'mod.js'), ); }); test('finds a node_module above one of the given paths', () => { expect(require.resolve('mod', {paths: ['../dir']})).toEqual( - resolve(__dirname, '..', 'node_modules', 'mod', 'index.js') + resolve(__dirname, '..', 'node_modules', 'mod', 'index.js'), ); }); @@ -32,12 +32,12 @@ test('finds a native node module when paths are given', () => { test('throws an error if the module cannot be found from given paths', () => { expect(() => require.resolve('./mod.js', {paths: ['..']})).toThrowError( - "Cannot resolve module './mod.js' from paths ['..'] from " + "Cannot resolve module './mod.js' from paths ['..'] from ", ); }); test('throws module not found error if the module cannot be found from given paths', () => { expect(() => require.resolve('./mod.js', {paths: ['..']})).toThrow( - expect.objectContaining({code: 'MODULE_NOT_FOUND'}) + expect.objectContaining({code: 'MODULE_NOT_FOUND'}), ); }); diff --git a/e2e/resolve/__tests__/resolve.test.js b/e2e/resolve/__tests__/resolve.test.js index bd993a99f8aa..e3d3500d6b8c 100644 --- a/e2e/resolve/__tests__/resolve.test.js +++ b/e2e/resolve/__tests__/resolve.test.js @@ -66,7 +66,7 @@ test('should resolve filename.json', () => { test('should preserve identity for symlinks', () => { expect(require('../../../packages/jest-resolve')).toBe( - require('jest-resolve') + require('jest-resolve'), ); }); @@ -113,7 +113,7 @@ test('should throw module not found error if the module has dependencies that ca Test7.js __tests__/resolve.test.js\n `, - }) + }), ); }); @@ -122,6 +122,6 @@ test('should throw module not found error if the module cannot be found', () => expect.objectContaining({ code: 'MODULE_NOT_FOUND', message: "Cannot find module 'Test8' from 'resolve.test.js'", - }) + }), ); }); diff --git a/e2e/snapshot/__tests__/snapshot.test.js b/e2e/snapshot/__tests__/snapshot.test.js index 22722a34f77d..280d16caba18 100644 --- a/e2e/snapshot/__tests__/snapshot.test.js +++ b/e2e/snapshot/__tests__/snapshot.test.js @@ -30,7 +30,7 @@ describe('snapshot', () => { it('cannot be used with .not', () => { expect(() => expect('').not.toMatchSnapshot()).toThrow( - 'Snapshot matchers cannot be used with not' + 'Snapshot matchers cannot be used with not', ); }); diff --git a/e2e/stack-trace-source-maps-with-coverage/__tests__/fails.ts b/e2e/stack-trace-source-maps-with-coverage/__tests__/fails.ts new file mode 100644 index 000000000000..583175c89ed7 --- /dev/null +++ b/e2e/stack-trace-source-maps-with-coverage/__tests__/fails.ts @@ -0,0 +1,11 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +import {error} from '../lib'; + +it('fails', () => { + error(); +}); diff --git a/e2e/stack-trace-source-maps-with-coverage/lib.ts b/e2e/stack-trace-source-maps-with-coverage/lib.ts new file mode 100644 index 000000000000..9fffd6978ab1 --- /dev/null +++ b/e2e/stack-trace-source-maps-with-coverage/lib.ts @@ -0,0 +1,14 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ +interface NotUsedButTakesUpLines { + a: number; + b: string; +} + +export function error() { + throw new Error('This did not work!'); +} diff --git a/e2e/stack-trace-source-maps-with-coverage/package.json b/e2e/stack-trace-source-maps-with-coverage/package.json new file mode 100644 index 000000000000..f8fbad2d8bca --- /dev/null +++ b/e2e/stack-trace-source-maps-with-coverage/package.json @@ -0,0 +1,13 @@ +{ + "jest": { + "rootDir": "./", + "transform": { + "^.+\\.(ts)$": "/preprocessor.js" + }, + "testEnvironment": "node", + "testRegex": "fails" + }, + "dependencies": { + "typescript": "^3.7.4" + } +} diff --git a/e2e/stack-trace-source-maps-with-coverage/preprocessor.js b/e2e/stack-trace-source-maps-with-coverage/preprocessor.js new file mode 100644 index 000000000000..133d42ec44a2 --- /dev/null +++ b/e2e/stack-trace-source-maps-with-coverage/preprocessor.js @@ -0,0 +1,21 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const tsc = require('typescript'); + +module.exports = { + process(src, path) { + return tsc.transpileModule(src, { + compilerOptions: { + inlineSourceMap: true, + module: tsc.ModuleKind.CommonJS, + target: 'es5', + }, + fileName: path, + }).outputText; + }, +}; diff --git a/e2e/stack-trace-source-maps-with-coverage/yarn.lock b/e2e/stack-trace-source-maps-with-coverage/yarn.lock new file mode 100644 index 000000000000..e9f19f98faf0 --- /dev/null +++ b/e2e/stack-trace-source-maps-with-coverage/yarn.lock @@ -0,0 +1,8 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +typescript@^3.7.4: + version "3.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.8.3.tgz#409eb8544ea0335711205869ec458ab109ee1061" + integrity sha512-MYlEfn5VrLNsgudQTVJeNaQFUAI7DkhnOjdpAp4T+ku1TfQClewlbSuTVHiA+8skNBgaf02TL/kLOvig4y3G8w== diff --git a/e2e/typescript-coverage/typescriptPreprocessor.js b/e2e/typescript-coverage/typescriptPreprocessor.js index f70981612673..8633bdab5a95 100644 --- a/e2e/typescript-coverage/typescriptPreprocessor.js +++ b/e2e/typescript-coverage/typescriptPreprocessor.js @@ -17,7 +17,7 @@ module.exports = { module: tsc.ModuleKind.CommonJS, }, path, - [] + [], ); } return src; diff --git a/examples/angular/app.component.spec.ts b/examples/angular/app.component.spec.ts index acd80ab8fd2d..86136edd82f6 100644 --- a/examples/angular/app.component.spec.ts +++ b/examples/angular/app.component.spec.ts @@ -8,7 +8,7 @@ const getTitleFn = jest.fn().mockReturnValue(title); const dataServiceSpy = jest.fn().mockImplementation( (): Partial => ({ getTitle: getTitleFn, - }) + }), ); describe('AppComponent', () => { @@ -36,7 +36,7 @@ describe('AppComponent', () => { fixture.detectChanges(); const compiled = fixture.debugElement.nativeElement; expect(compiled.querySelector('h1').textContent).toContain( - `Welcome to ${title}!` + `Welcome to ${title}!`, ); }); }); diff --git a/examples/angular/setupJest.js b/examples/angular/setupJest.js index c8a41202d6e7..64db898071a7 100644 --- a/examples/angular/setupJest.js +++ b/examples/angular/setupJest.js @@ -14,5 +14,5 @@ const testingModule = require('@angular/platform-browser-dynamic/testing'); getTestBed().initTestEnvironment( testingModule.BrowserDynamicTestingModule, - testingModule.platformBrowserDynamicTesting() + testingModule.platformBrowserDynamicTesting(), ); diff --git a/examples/async/__mocks__/request.js b/examples/async/__mocks__/request.js index 51784974d8fa..e593301d672f 100644 --- a/examples/async/__mocks__/request.js +++ b/examples/async/__mocks__/request.js @@ -15,7 +15,7 @@ export default function request(url) { ? resolve(users[userID]) : reject({ error: 'User with ' + userID + ' not found.', - }) + }), ); }); } diff --git a/examples/async/__tests__/user.test.js b/examples/async/__tests__/user.test.js index 2e02f9e727dc..a81de93b1cd4 100644 --- a/examples/async/__tests__/user.test.js +++ b/examples/async/__tests__/user.test.js @@ -45,7 +45,7 @@ test('tests error with promises', async () => { return user.getUserName(2).catch(e => expect(e).toEqual({ error: 'User with 2 not found.', - }) + }), ); }); diff --git a/examples/manual-mocks/__tests__/file_summarizer.test.js b/examples/manual-mocks/__tests__/file_summarizer.test.js index d097ab7cdb73..2429e47acf5c 100644 --- a/examples/manual-mocks/__tests__/file_summarizer.test.js +++ b/examples/manual-mocks/__tests__/file_summarizer.test.js @@ -18,7 +18,7 @@ describe('listFilesInDirectorySync', () => { it('includes all files in the directory in the summary', () => { const FileSummarizer = require('../FileSummarizer'); const fileSummary = FileSummarizer.summarizeFilesInDirectorySync( - '/path/to' + '/path/to', ); expect(fileSummary.length).toBe(2); diff --git a/examples/react-native/__tests__/__snapshots__/intro.test.js.snap b/examples/react-native/__tests__/__snapshots__/intro.test.js.snap index a66c7c754b14..206581daf942 100644 --- a/examples/react-native/__tests__/__snapshots__/intro.test.js.snap +++ b/examples/react-native/__tests__/__snapshots__/intro.test.js.snap @@ -61,7 +61,6 @@ exports[`renders the FlatList component 1`] = ` initialNumToRender={10} keyExtractor={[Function]} maxToRenderPerBatch={10} - numColumns={1} onContentSizeChange={[Function]} onEndReachedThreshold={2} onLayout={[Function]} @@ -106,17 +105,6 @@ exports[`renders the FlatList component 1`] = ` `; -exports[`renders the Image component 1`] = ` - -`; - exports[`renders the TextInput component 1`] = ` { expect(tree).toMatchSnapshot(); }); -it('renders the Image component', done => { - Image.getSize('path.jpg', (width, height) => { - const tree = renderer.create().toJSON(); - expect(tree).toMatchSnapshot(); - done(); - }); -}); - it('renders the TextInput component', () => { const tree = renderer .create() @@ -52,7 +38,7 @@ it('renders the FlatList component', () => { data={['apple', 'banana', 'kiwi']} keyExtractor={item => item} renderItem={({item}) => {item}} - /> + />, ) .toJSON(); expect(tree).toMatchSnapshot(); diff --git a/examples/react-native/package.json b/examples/react-native/package.json index c98a8cbc51db..dc50dbedb875 100644 --- a/examples/react-native/package.json +++ b/examples/react-native/package.json @@ -7,15 +7,15 @@ "test": "jest" }, "dependencies": { - "react": "16.9.0", - "react-native": "0.61.5" + "react": "16.11.0", + "react-native": "0.62.0" }, "devDependencies": { "@babel/core": "*", "@babel/preset-env": "*", "babel-jest": "*", "jest": "*", - "metro-react-native-babel-preset": "*", - "react-test-renderer": "16.9.0" + "metro-react-native-babel-preset": "^0.58.0", + "react-test-renderer": "16.11.0" } } diff --git a/examples/react-testing-library/__tests__/CheckboxWithLabel-test.js b/examples/react-testing-library/__tests__/CheckboxWithLabel-test.js index 73aeeb99f4e6..cfc95680c90b 100644 --- a/examples/react-testing-library/__tests__/CheckboxWithLabel-test.js +++ b/examples/react-testing-library/__tests__/CheckboxWithLabel-test.js @@ -10,7 +10,7 @@ afterEach(cleanup); it('CheckboxWithLabel changes the text after click', () => { const {queryByLabelText, getByLabelText} = render( - + , ); expect(queryByLabelText(/off/i)).toBeTruthy(); diff --git a/examples/react/__tests__/CheckboxWithLabel-test.js b/examples/react/__tests__/CheckboxWithLabel-test.js index 494504ca9cc5..b887304d42aa 100644 --- a/examples/react/__tests__/CheckboxWithLabel-test.js +++ b/examples/react/__tests__/CheckboxWithLabel-test.js @@ -15,7 +15,7 @@ it('CheckboxWithLabel changes the text after click', () => { inputRef={checkboxInputRef} labelOn="On" labelOff="Off" - /> + />, ); const labelNode = checkboxLabelRef.current; diff --git a/examples/snapshot/__tests__/link.react.test.js b/examples/snapshot/__tests__/link.react.test.js index fd9b87115c42..1d9300b82772 100644 --- a/examples/snapshot/__tests__/link.react.test.js +++ b/examples/snapshot/__tests__/link.react.test.js @@ -27,7 +27,7 @@ it('properly escapes quotes', () => { it('changes the class when hovered', () => { const component = renderer.create( - Facebook + Facebook, ); let tree = component.toJSON(); expect(tree).toMatchSnapshot(); diff --git a/examples/typescript/__tests__/CheckboxWithLabel-test.tsx b/examples/typescript/__tests__/CheckboxWithLabel-test.tsx index 59afe50a027f..85159d2d4b15 100644 --- a/examples/typescript/__tests__/CheckboxWithLabel-test.tsx +++ b/examples/typescript/__tests__/CheckboxWithLabel-test.tsx @@ -15,7 +15,7 @@ it('CheckboxWithLabel changes the text after click', () => { inputRef={checkboxInputRef} labelOn="On" labelOff="Off" - /> + />, ); const labelNode = checkboxLabelRef.current; diff --git a/lerna.json b/lerna.json index 6c27659d1a81..b6e56f7c55fc 100644 --- a/lerna.json +++ b/lerna.json @@ -1,5 +1,5 @@ { - "version": "25.3.0", + "version": "25.4.0", "npmClient": "yarn", "packages": [ "packages/*" diff --git a/package.json b/package.json index 337123a5d1f9..8658d7699537 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "fast-check": "^1.13.0", "find-process": "^1.4.1", "glob": "^7.1.1", + "globby": "^10.0.2", "graceful-fs": "^4.2.3", "isbinaryfile": "^4.0.0", "istanbul-lib-coverage": "^3.0.0", @@ -74,6 +75,7 @@ "realpath-native": "^2.0.0", "resolve": "^1.15.0", "rimraf": "^3.0.0", + "semver": "^6.3.0", "slash": "^3.0.0", "string-length": "^3.1.0", "strip-ansi": "^6.0.0", @@ -126,22 +128,8 @@ "arrowParens": "avoid", "overrides": [ { - "excludeFiles": [ - "e2e/__tests__/**/*", - "website/versioned_docs/**/*.md" - ], - "files": [ - "examples/**/*", - "scripts/**/*", - "e2e/*/**/*", - "website/*.js", - "website/*/**/*", - "eslintImportResolver.js", - "babel.config.js" - ], + "files": "website/**/*.js", "options": { - "printWidth": 80, - "singleQuote": true, "trailingComma": "es5" } } diff --git a/packages/babel-jest/package.json b/packages/babel-jest/package.json index bc29e23c19a5..a6eca647bef5 100644 --- a/packages/babel-jest/package.json +++ b/packages/babel-jest/package.json @@ -1,7 +1,7 @@ { "name": "babel-jest", "description": "Jest plugin to use babel for transformation.", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -18,11 +18,11 @@ } }, "dependencies": { - "@jest/transform": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/transform": "^25.4.0", + "@jest/types": "^25.4.0", "@types/babel__core": "^7.1.7", "babel-plugin-istanbul": "^6.0.0", - "babel-preset-jest": "^25.3.0", + "babel-preset-jest": "^25.4.0", "chalk": "^3.0.0", "slash": "^3.0.0" }, diff --git a/packages/babel-plugin-jest-hoist/package.json b/packages/babel-plugin-jest-hoist/package.json index e46bfbd5f680..de303f8cfdff 100644 --- a/packages/babel-plugin-jest-hoist/package.json +++ b/packages/babel-plugin-jest-hoist/package.json @@ -1,6 +1,6 @@ { "name": "babel-plugin-jest-hoist", - "version": "25.2.6", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/babel-preset-jest/package.json b/packages/babel-preset-jest/package.json index 676b6dbcd1d1..9695bdbed32c 100644 --- a/packages/babel-preset-jest/package.json +++ b/packages/babel-preset-jest/package.json @@ -1,6 +1,6 @@ { "name": "babel-preset-jest", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -9,7 +9,7 @@ "license": "MIT", "main": "index.js", "dependencies": { - "babel-plugin-jest-hoist": "^25.2.6", + "babel-plugin-jest-hoist": "^25.4.0", "babel-preset-current-node-syntax": "^0.1.2" }, "peerDependencies": { diff --git a/packages/expect/package.json b/packages/expect/package.json index 48f17a6dabf2..04dbdb74f56a 100644 --- a/packages/expect/package.json +++ b/packages/expect/package.json @@ -1,6 +1,6 @@ { "name": "expect", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -18,11 +18,11 @@ }, "browser": "build-es5/index.js", "dependencies": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.4.0", "ansi-styles": "^4.0.0", "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.3.0", - "jest-message-util": "^25.3.0", + "jest-matcher-utils": "^25.4.0", + "jest-message-util": "^25.4.0", "jest-regex-util": "^25.2.6" }, "devDependencies": { diff --git a/packages/expect/src/__tests__/__snapshots__/extend.test.js.snap b/packages/expect/src/__tests__/__snapshots__/extend.test.js.snap index b1b67afefea8..68129f9c16d7 100644 --- a/packages/expect/src/__tests__/__snapshots__/extend.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/extend.test.js.snap @@ -53,3 +53,15 @@ exports[`is available globally when matcher is unary 1`] = `expected 15 to be di exports[`is available globally when matcher is variadic 1`] = `expected 15 to be within range 1 - 3`; exports[`is ok if there is no message specified 1`] = `No message was specified for this matcher.`; + +exports[`prints the Symbol into the error message 1`] = ` +expect(received).toEqual(expected) // deep equality + +- Expected - 1 ++ Received + 1 + + Object { +- "a": toBeSymbol, ++ "a": Symbol(foo), + } +`; diff --git a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap index e442e66efcaf..652e3020ab90 100644 --- a/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap +++ b/packages/expect/src/__tests__/__snapshots__/matchers.test.js.snap @@ -10,7 +10,7 @@ Resolved to value: 4 exports[`.rejects fails non-promise value "a" 1`] = ` expect(received).rejects.toBeDefined() -Matcher error: received value must be a promise +Matcher error: received value must be a promise or a function returning a promise Received has type: string Received has value: "a" @@ -19,7 +19,7 @@ Received has value: "a" exports[`.rejects fails non-promise value [1] 1`] = ` expect(received).rejects.toBeDefined() -Matcher error: received value must be a promise +Matcher error: received value must be a promise or a function returning a promise Received has type: array Received has value: [1] @@ -28,7 +28,7 @@ Received has value: [1] exports[`.rejects fails non-promise value [Function anonymous] 1`] = ` expect(received).rejects.toBeDefined() -Matcher error: received value must be a promise +Matcher error: received value must be a promise or a function returning a promise Received has type: function Received has value: [Function anonymous] @@ -37,7 +37,7 @@ Received has value: [Function anonymous] exports[`.rejects fails non-promise value {"a": 1} 1`] = ` expect(received).rejects.toBeDefined() -Matcher error: received value must be a promise +Matcher error: received value must be a promise or a function returning a promise Received has type: object Received has value: {"a": 1} @@ -46,7 +46,7 @@ Received has value: {"a": 1} exports[`.rejects fails non-promise value 4 1`] = ` expect(received).rejects.not.toBeDefined() -Matcher error: received value must be a promise +Matcher error: received value must be a promise or a function returning a promise Received has type: number Received has value: 4 @@ -55,7 +55,7 @@ Received has value: 4 exports[`.rejects fails non-promise value null 1`] = ` expect(received).rejects.not.toBeDefined() -Matcher error: received value must be a promise +Matcher error: received value must be a promise or a function returning a promise Received has value: null `; @@ -63,7 +63,7 @@ Received has value: null exports[`.rejects fails non-promise value true 1`] = ` expect(received).rejects.not.toBeDefined() -Matcher error: received value must be a promise +Matcher error: received value must be a promise or a function returning a promise Received has type: boolean Received has value: true @@ -72,7 +72,7 @@ Received has value: true exports[`.rejects fails non-promise value undefined 1`] = ` expect(received).rejects.not.toBeDefined() -Matcher error: received value must be a promise +Matcher error: received value must be a promise or a function returning a promise Received has value: undefined `; diff --git a/packages/expect/src/__tests__/extend.test.js b/packages/expect/src/__tests__/extend.test.js index 7861eafe5852..11b915332fee 100644 --- a/packages/expect/src/__tests__/extend.test.js +++ b/packages/expect/src/__tests__/extend.test.js @@ -23,6 +23,12 @@ jestExpect.extend({ return {message, pass}; }, + toBeSymbol(actual, expected) { + const pass = actual === expected; + const message = () => `expected ${actual} to be Symbol ${expected}`; + + return {message, pass}; + }, toBeWithinRange(actual, floor, ceiling) { const pass = actual >= floor && actual <= ceiling; const message = pass @@ -137,3 +143,14 @@ it('defines asymmetric variadic matchers that can be prefixed by not', () => { }), ).not.toThrow(); }); + +it('prints the Symbol into the error message', () => { + const foo = Symbol('foo'); + const bar = Symbol('bar'); + + expect(() => + jestExpect({a: foo}).toEqual({ + a: jestExpect.toBeSymbol(bar), + }), + ).toThrowErrorMatchingSnapshot(); +}); diff --git a/packages/expect/src/__tests__/matchers.test.js b/packages/expect/src/__tests__/matchers.test.js index 89f25a561ea8..4223f4e53475 100644 --- a/packages/expect/src/__tests__/matchers.test.js +++ b/packages/expect/src/__tests__/matchers.test.js @@ -56,6 +56,12 @@ describe('.rejects', () => { await jestExpect(fn()).rejects.toThrow('some error'); }); + it('should reject async function to toThrow', async () => { + await expect(async () => { + throw new Error('Test'); + }).rejects.toThrow('Test'); + }); + ['a', [1], () => {}, {a: 1}].forEach(value => { it(`fails non-promise value ${stringify(value)} synchronously`, () => { let error; diff --git a/packages/expect/src/index.ts b/packages/expect/src/index.ts index 80adf7d3c686..c715cd97354d 100644 --- a/packages/expect/src/index.ts +++ b/packages/expect/src/index.ts @@ -189,7 +189,7 @@ const makeRejectMatcher = ( matcherName: string, matcher: RawMatcherFn, isNot: boolean, - actual: Promise, + actual: Promise | (() => Promise), outerErr: JestAssertionError, ): PromiseMatcherFn => (...args) => { const options = { @@ -197,11 +197,16 @@ const makeRejectMatcher = ( promise: 'rejects', }; - if (!isPromise(actual)) { + const actualWrapper: Promise = + typeof actual === 'function' ? actual() : actual; + + if (!isPromise(actualWrapper)) { throw new JestAssertionError( matcherUtils.matcherErrorMessage( matcherUtils.matcherHint(matcherName, undefined, '', options), - `${matcherUtils.RECEIVED_COLOR('received')} value must be a promise`, + `${matcherUtils.RECEIVED_COLOR( + 'received', + )} value must be a promise or a function returning a promise`, matcherUtils.printWithType( 'Received', actual, @@ -213,7 +218,7 @@ const makeRejectMatcher = ( const innerErr = new JestAssertionError(); - return actual.then( + return actualWrapper.then( result => { outerErr.message = matcherUtils.matcherHint(matcherName, undefined, '', options) + diff --git a/packages/expect/src/jestMatchersObject.ts b/packages/expect/src/jestMatchersObject.ts index bf08dca6db08..24b2c087071c 100644 --- a/packages/expect/src/jestMatchersObject.ts +++ b/packages/expect/src/jestMatchersObject.ts @@ -78,7 +78,7 @@ export const setMatchers = ( } toAsymmetricMatcher() { - return `${this.toString()}<${this.sample.join(', ')}>`; + return `${this.toString()}<${this.sample.map(String).join(', ')}>`; } } diff --git a/packages/expect/src/matchers.ts b/packages/expect/src/matchers.ts index cd7274425fb0..de234b24b0b3 100644 --- a/packages/expect/src/matchers.ts +++ b/packages/expect/src/matchers.ts @@ -628,10 +628,7 @@ const matchers: MatchersObject = { promise: this.promise, }; - if ( - typeof received !== 'string' && - (!received || typeof received.length !== 'number') - ) { + if (typeof received?.length !== 'number') { throw new Error( matcherErrorMessage( matcherHint(matcherName, undefined, undefined, options), diff --git a/packages/jest-changed-files/package.json b/packages/jest-changed-files/package.json index 9abd11d0157c..454b06e57b69 100644 --- a/packages/jest-changed-files/package.json +++ b/packages/jest-changed-files/package.json @@ -1,6 +1,6 @@ { "name": "jest-changed-files", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,7 +17,7 @@ } }, "dependencies": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.4.0", "execa": "^3.2.0", "throat": "^5.0.0" }, diff --git a/packages/jest-circus/package.json b/packages/jest-circus/package.json index 053fae413eca..da9d3547d944 100644 --- a/packages/jest-circus/package.json +++ b/packages/jest-circus/package.json @@ -1,6 +1,6 @@ { "name": "jest-circus", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -18,20 +18,20 @@ }, "dependencies": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^25.3.0", - "@jest/test-result": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/environment": "^25.4.0", + "@jest/test-result": "^25.4.0", + "@jest/types": "^25.4.0", "chalk": "^3.0.0", "co": "^4.6.0", - "expect": "^25.3.0", + "expect": "^25.4.0", "is-generator-fn": "^2.0.0", - "jest-each": "^25.3.0", - "jest-matcher-utils": "^25.3.0", - "jest-message-util": "^25.3.0", - "jest-runtime": "^25.3.0", - "jest-snapshot": "^25.3.0", - "jest-util": "^25.3.0", - "pretty-format": "^25.3.0", + "jest-each": "^25.4.0", + "jest-matcher-utils": "^25.4.0", + "jest-message-util": "^25.4.0", + "jest-runtime": "^25.4.0", + "jest-snapshot": "^25.4.0", + "jest-util": "^25.4.0", + "pretty-format": "^25.4.0", "stack-utils": "^1.0.1", "throat": "^5.0.0" }, diff --git a/packages/jest-circus/src/eventHandler.ts b/packages/jest-circus/src/eventHandler.ts index 7c3a0f9299f4..2e1327a8ad6b 100644 --- a/packages/jest-circus/src/eventHandler.ts +++ b/packages/jest-circus/src/eventHandler.ts @@ -36,7 +36,14 @@ const eventHandler: Circus.EventHandler = ( } case 'start_describe_definition': { const {blockName, mode} = event; - const {currentDescribeBlock} = state; + const {currentDescribeBlock, currentlyRunningTest} = state; + + if (currentlyRunningTest) { + throw new Error( + `Cannot nest a describe inside a test. Describe block "${blockName}" cannot run because it is nested within "${currentlyRunningTest.name}".`, + ); + } + const describeBlock = makeDescribe(blockName, currentDescribeBlock, mode); currentDescribeBlock.children.push(describeBlock); state.currentDescribeBlock = describeBlock; @@ -88,8 +95,15 @@ const eventHandler: Circus.EventHandler = ( break; } case 'add_test': { - const {currentDescribeBlock} = state; + const {currentDescribeBlock, currentlyRunningTest} = state; const {asyncError, fn, mode, testName: name, timeout} = event; + + if (currentlyRunningTest) { + throw new Error( + `Tests cannot be nested. Test "${name}" cannot run because it is nested within "${currentlyRunningTest.name}".`, + ); + } + const test = makeTest( fn, mode, diff --git a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapter.ts b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapter.ts index 026ba3f54c7c..a7fdf68cb0d9 100644 --- a/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapter.ts +++ b/packages/jest-circus/src/legacy-code-todo-rewrite/jestAdapter.ts @@ -76,9 +76,24 @@ const jestAdapter = async ( } }); - config.setupFilesAfterEnv.forEach(path => runtime.requireModule(path)); + for (const path of config.setupFilesAfterEnv) { + const esm = runtime.unstable_shouldLoadAsEsm(path); + + if (esm) { + await runtime.unstable_importModule(path); + } else { + runtime.requireModule(path); + } + } + + const esm = runtime.unstable_shouldLoadAsEsm(testPath); + + if (esm) { + await runtime.unstable_importModule(testPath); + } else { + runtime.requireModule(testPath); + } - runtime.requireModule(testPath); const results = await runAndTransformResultsToJestFormat({ config, globalConfig, diff --git a/packages/jest-cli/package.json b/packages/jest-cli/package.json index a7e640f5d876..f556af3d0144 100644 --- a/packages/jest-cli/package.json +++ b/packages/jest-cli/package.json @@ -1,7 +1,7 @@ { "name": "jest-cli", "description": "Delightful JavaScript Testing.", - "version": "25.3.0", + "version": "25.4.0", "main": "build/index.js", "types": "build/index.d.ts", "typesVersions": { @@ -12,16 +12,16 @@ } }, "dependencies": { - "@jest/core": "^25.3.0", - "@jest/test-result": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/core": "^25.4.0", + "@jest/test-result": "^25.4.0", + "@jest/types": "^25.4.0", "chalk": "^3.0.0", "exit": "^0.1.2", "import-local": "^3.0.2", "is-ci": "^2.0.0", - "jest-config": "^25.3.0", - "jest-util": "^25.3.0", - "jest-validate": "^25.3.0", + "jest-config": "^25.4.0", + "jest-util": "^25.4.0", + "jest-validate": "^25.4.0", "prompts": "^2.0.1", "realpath-native": "^2.0.0", "yargs": "^15.3.1" diff --git a/packages/jest-cli/src/init/__tests__/init.test.js b/packages/jest-cli/src/init/__tests__/init.test.js index afc2acdca315..874a6d958c75 100644 --- a/packages/jest-cli/src/init/__tests__/init.test.js +++ b/packages/jest-cli/src/init/__tests__/init.test.js @@ -11,7 +11,6 @@ import * as path from 'path'; import prompts from 'prompts'; import {constants} from 'jest-config'; import init from '../'; -import {onNodeVersions} from '@jest/test-utils'; const {JEST_CONFIG_EXT_ORDER} = constants; @@ -56,20 +55,18 @@ describe('init', () => { expect(evaluatedConfig).toEqual({}); }); - onNodeVersions('^13.2.0', () => { - it('should generate empty config with mjs extension', async () => { - prompts.mockReturnValueOnce({}); + it('should generate empty config with mjs extension', async () => { + prompts.mockReturnValueOnce({}); - await init(resolveFromFixture('type_module')); + await init(resolveFromFixture('type_module')); - const writtenJestConfigFilename = fs.writeFileSync.mock.calls[0][0]; - const writtenJestConfig = fs.writeFileSync.mock.calls[0][1]; + const writtenJestConfigFilename = fs.writeFileSync.mock.calls[0][0]; + const writtenJestConfig = fs.writeFileSync.mock.calls[0][1]; - expect(writtenJestConfigFilename.endsWith('.mjs')).toBe(true); + expect(writtenJestConfigFilename.endsWith('.mjs')).toBe(true); - expect(typeof writtenJestConfig).toBe('string'); - expect(writtenJestConfig.split('\n')[3]).toBe('export default {'); - }); + expect(typeof writtenJestConfig).toBe('string'); + expect(writtenJestConfig.split('\n')[3]).toBe('export default {'); }); }); diff --git a/packages/jest-config/package.json b/packages/jest-config/package.json index f3f74d08f554..7cf920caf17f 100644 --- a/packages/jest-config/package.json +++ b/packages/jest-config/package.json @@ -1,6 +1,6 @@ { "name": "jest-config", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -18,22 +18,22 @@ }, "dependencies": { "@babel/core": "^7.1.0", - "@jest/test-sequencer": "^25.3.0", - "@jest/types": "^25.3.0", - "babel-jest": "^25.3.0", + "@jest/test-sequencer": "^25.4.0", + "@jest/types": "^25.4.0", + "babel-jest": "^25.4.0", "chalk": "^3.0.0", "deepmerge": "^4.2.2", "glob": "^7.1.1", - "jest-environment-jsdom": "^25.3.0", - "jest-environment-node": "^25.3.0", + "jest-environment-jsdom": "^25.4.0", + "jest-environment-node": "^25.4.0", "jest-get-type": "^25.2.6", - "jest-jasmine2": "^25.3.0", + "jest-jasmine2": "^25.4.0", "jest-regex-util": "^25.2.6", - "jest-resolve": "^25.3.0", - "jest-util": "^25.3.0", - "jest-validate": "^25.3.0", + "jest-resolve": "^25.4.0", + "jest-util": "^25.4.0", + "jest-validate": "^25.4.0", "micromatch": "^4.0.2", - "pretty-format": "^25.3.0", + "pretty-format": "^25.4.0", "realpath-native": "^2.0.0" }, "devDependencies": { diff --git a/packages/jest-console/package.json b/packages/jest-console/package.json index e5501896ebfe..ba663dc366ca 100644 --- a/packages/jest-console/package.json +++ b/packages/jest-console/package.json @@ -1,6 +1,6 @@ { "name": "@jest/console", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,9 +17,10 @@ } }, "dependencies": { - "@jest/source-map": "^25.2.6", + "@jest/types": "^25.4.0", "chalk": "^3.0.0", - "jest-util": "^25.3.0", + "jest-message-util": "^25.4.0", + "jest-util": "^25.4.0", "slash": "^3.0.0" }, "devDependencies": { diff --git a/packages/jest-console/src/BufferedConsole.ts b/packages/jest-console/src/BufferedConsole.ts index 2ac94ac5c83b..2bf53f350f72 100644 --- a/packages/jest-console/src/BufferedConsole.ts +++ b/packages/jest-console/src/BufferedConsole.ts @@ -9,7 +9,7 @@ import assert = require('assert'); import {Console} from 'console'; import {format} from 'util'; import chalk = require('chalk'); -import {SourceMapRegistry, getCallsite} from '@jest/source-map'; +import {ErrorWithStack} from 'jest-util'; import type { ConsoleBuffer, LogCounters, @@ -23,18 +23,16 @@ export default class BufferedConsole extends Console { private _counters: LogCounters; private _timers: LogTimers; private _groupDepth: number; - private _getSourceMaps: () => SourceMapRegistry | null | undefined; - constructor(getSourceMaps: () => SourceMapRegistry | null | undefined) { + constructor() { const buffer: ConsoleBuffer = []; super({ write: (message: string) => { - BufferedConsole.write(buffer, 'log', message, null, getSourceMaps()); + BufferedConsole.write(buffer, 'log', message, null); return true; }, } as NodeJS.WritableStream); - this._getSourceMaps = getSourceMaps; this._buffer = buffer; this._counters = {}; this._timers = {}; @@ -46,10 +44,17 @@ export default class BufferedConsole extends Console { type: LogType, message: LogMessage, level?: number | null, - sourceMaps?: SourceMapRegistry | null, ): ConsoleBuffer { - const callsite = getCallsite(level != null ? level : 2, sourceMaps); - const origin = callsite.getFileName() + ':' + callsite.getLineNumber(); + const stackLevel = level != null ? level : 2; + const rawStack = new ErrorWithStack(undefined, BufferedConsole.write).stack; + + invariant(rawStack, 'always have a stack trace'); + + const origin = rawStack + .split('\n') + .slice(stackLevel) + .filter(Boolean) + .join('\n'); buffer.push({ message, @@ -66,7 +71,6 @@ export default class BufferedConsole extends Console { type, ' '.repeat(this._groupDepth) + message, 3, - this._getSourceMaps(), ); } @@ -163,3 +167,9 @@ export default class BufferedConsole extends Console { return this._buffer.length ? this._buffer : undefined; } } + +function invariant(condition: unknown, message?: string): asserts condition { + if (!condition) { + throw new Error(message); + } +} diff --git a/packages/jest-console/src/getConsoleOutput.ts b/packages/jest-console/src/getConsoleOutput.ts index 09a3232b557e..1c3dba19f898 100644 --- a/packages/jest-console/src/getConsoleOutput.ts +++ b/packages/jest-console/src/getConsoleOutput.ts @@ -5,44 +5,68 @@ * LICENSE file in the root directory of this source tree. */ -import * as path from 'path'; import chalk = require('chalk'); -import slash = require('slash'); +import { + StackTraceConfig, + StackTraceOptions, + formatStackTrace, +} from 'jest-message-util'; import type {ConsoleBuffer} from './types'; export default ( + // TODO: remove in 26 root: string, verbose: boolean, buffer: ConsoleBuffer, + // TODO: make mandatory and take Config.ProjectConfig in 26 + config: StackTraceConfig = { + rootDir: root, + testMatch: [], + }, ): string => { const TITLE_INDENT = verbose ? ' ' : ' '; const CONSOLE_INDENT = TITLE_INDENT + ' '; - return buffer.reduce((output, {type, message, origin}) => { - origin = slash(path.relative(root, origin)); + const logEntries = buffer.reduce((output, {type, message, origin}) => { message = message .split(/\n/) .map(line => CONSOLE_INDENT + line) .join('\n'); let typeMessage = 'console.' + type; + let noStackTrace = true; + let noCodeFrame = true; + if (type === 'warn') { message = chalk.yellow(message); typeMessage = chalk.yellow(typeMessage); + noStackTrace = false; + noCodeFrame = false; } else if (type === 'error') { message = chalk.red(message); typeMessage = chalk.red(typeMessage); + noStackTrace = false; + noCodeFrame = false; } + const options: StackTraceOptions = { + noCodeFrame, + noStackTrace, + }; + + const formattedStackTrace = formatStackTrace(origin, config, options); + return ( output + TITLE_INDENT + chalk.dim(typeMessage) + - ' ' + - chalk.dim(origin) + '\n' + - message + - '\n' + message.trimRight() + + '\n' + + chalk.dim(formattedStackTrace.trimRight()) + + '\n\n' ); }, ''); + + return logEntries.trimRight() + '\n'; }; diff --git a/packages/jest-console/tsconfig.json b/packages/jest-console/tsconfig.json index 719bab0f554b..a436b61458e6 100644 --- a/packages/jest-console/tsconfig.json +++ b/packages/jest-console/tsconfig.json @@ -5,7 +5,8 @@ "outDir": "build" }, "references": [ - {"path": "../jest-source-map"}, + {"path": "../jest-message-util"}, + {"path": "../jest-types"}, {"path": "../jest-util"} ] } diff --git a/packages/jest-core/package.json b/packages/jest-core/package.json index ac2c69310ddb..19a6c5d804b8 100644 --- a/packages/jest-core/package.json +++ b/packages/jest-core/package.json @@ -1,7 +1,7 @@ { "name": "@jest/core", "description": "Delightful JavaScript Testing.", - "version": "25.3.0", + "version": "25.4.0", "main": "build/jest.js", "types": "build/jest.d.ts", "typesVersions": { @@ -12,28 +12,28 @@ } }, "dependencies": { - "@jest/console": "^25.3.0", - "@jest/reporters": "^25.3.0", - "@jest/test-result": "^25.3.0", - "@jest/transform": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/console": "^25.4.0", + "@jest/reporters": "^25.4.0", + "@jest/test-result": "^25.4.0", + "@jest/transform": "^25.4.0", + "@jest/types": "^25.4.0", "ansi-escapes": "^4.2.1", "chalk": "^3.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.3", - "jest-changed-files": "^25.3.0", - "jest-config": "^25.3.0", - "jest-haste-map": "^25.3.0", - "jest-message-util": "^25.3.0", + "jest-changed-files": "^25.4.0", + "jest-config": "^25.4.0", + "jest-haste-map": "^25.4.0", + "jest-message-util": "^25.4.0", "jest-regex-util": "^25.2.6", - "jest-resolve": "^25.3.0", - "jest-resolve-dependencies": "^25.3.0", - "jest-runner": "^25.3.0", - "jest-runtime": "^25.3.0", - "jest-snapshot": "^25.3.0", - "jest-util": "^25.3.0", - "jest-validate": "^25.3.0", - "jest-watcher": "^25.3.0", + "jest-resolve": "^25.4.0", + "jest-resolve-dependencies": "^25.4.0", + "jest-runner": "^25.4.0", + "jest-runtime": "^25.4.0", + "jest-snapshot": "^25.4.0", + "jest-util": "^25.4.0", + "jest-validate": "^25.4.0", + "jest-watcher": "^25.4.0", "micromatch": "^4.0.2", "p-each-series": "^2.1.0", "realpath-native": "^2.0.0", @@ -42,7 +42,7 @@ "strip-ansi": "^6.0.0" }, "devDependencies": { - "@jest/test-sequencer": "^25.3.0", + "@jest/test-sequencer": "^25.4.0", "@types/exit": "^0.1.30", "@types/graceful-fs": "^4.1.2", "@types/micromatch": "^4.0.0", diff --git a/packages/jest-core/src/SearchSource.ts b/packages/jest-core/src/SearchSource.ts index 7a2c6a863cc6..48c630f2adb4 100644 --- a/packages/jest-core/src/SearchSource.ts +++ b/packages/jest-core/src/SearchSource.ts @@ -51,13 +51,22 @@ const toTests = (context: Context, tests: Array) => path, })); +const hasSCM = (changedFilesInfo: ChangedFiles) => { + const {repos} = changedFilesInfo; + // no SCM (git/hg/...) is found in any of the roots. + const noSCM = Object.values(repos).every(scm => scm.size === 0); + return !noSCM; +}; + export default class SearchSource { private _context: Context; + private _dependencyResolver: DependencyResolver | null; private _testPathCases: TestPathCases = []; constructor(context: Context) { const {config} = context; this._context = context; + this._dependencyResolver = null; const rootPattern = new RegExp( config.roots.map(dir => escapePathForRegex(dir + path.sep)).join('|'), @@ -92,6 +101,17 @@ export default class SearchSource { } } + private _getOrBuildDependencyResolver(): DependencyResolver { + if (!this._dependencyResolver) { + this._dependencyResolver = new DependencyResolver( + this._context.resolver, + this._context.hasteFS, + buildSnapshotResolver(this._context.config), + ); + } + return this._dependencyResolver; + } + private _filterTestPathsWithStats( allPaths: Array, testPathPattern?: string, @@ -155,11 +175,7 @@ export default class SearchSource { allPaths: Set, collectCoverage: boolean, ): SearchResult { - const dependencyResolver = new DependencyResolver( - this._context.resolver, - this._context.hasteFS, - buildSnapshotResolver(this._context.config), - ); + const dependencyResolver = this._getOrBuildDependencyResolver(); if (!collectCoverage) { return { @@ -240,14 +256,11 @@ export default class SearchSource { changedFilesInfo: ChangedFiles, collectCoverage: boolean, ): SearchResult { - const {repos, changedFiles} = changedFilesInfo; - // no SCM (git/hg/...) is found in any of the roots. - const noSCM = (Object.keys(repos) as Array< - keyof ChangedFiles['repos'] - >).every(scm => repos[scm].size === 0); - return noSCM - ? {noSCM: true, tests: []} - : this.findRelatedTests(changedFiles, collectCoverage); + if (!hasSCM(changedFilesInfo)) { + return {noSCM: true, tests: []}; + } + const {changedFiles} = changedFilesInfo; + return this.findRelatedTests(changedFiles, collectCoverage); } private _getTestPaths( @@ -272,9 +285,14 @@ export default class SearchSource { const options = {nocase: true, windows: false}; paths = paths - .map(p => path.resolve(this._context.config.cwd, p)) - .map(p => micromatch(allFiles, p.replace(/\\/g, '\\\\'), options)[0]) - .filter(p => p); + .map(p => { + const relativePath = path + .resolve(this._context.config.cwd, p) + .replace(/\\/g, '\\\\'); + const match = micromatch(allFiles, relativePath, options); + return match[0]; + }) + .filter(Boolean); } if (globalConfig.runTestsByPath && paths && paths.length) { @@ -323,4 +341,24 @@ export default class SearchSource { return searchResult; } + + findRelatedSourcesFromTestsInChangedFiles( + changedFilesInfo: ChangedFiles, + ): Array { + if (!hasSCM(changedFilesInfo)) { + return []; + } + const {changedFiles} = changedFilesInfo; + const dependencyResolver = this._getOrBuildDependencyResolver(); + const relatedSourcesSet = new Set(); + changedFiles.forEach(filePath => { + if (this.isTestFilePath(filePath)) { + const sourcePaths = dependencyResolver.resolve(filePath, { + skipNodeResolution: this._context.config.skipNodeResolution, + }); + sourcePaths.forEach(sourcePath => relatedSourcesSet.add(sourcePath)); + } + }); + return Array.from(relatedSourcesSet); + } } diff --git a/packages/jest-core/src/TestScheduler.ts b/packages/jest-core/src/TestScheduler.ts index 3211459f2148..bf455a2e05c1 100644 --- a/packages/jest-core/src/TestScheduler.ts +++ b/packages/jest-core/src/TestScheduler.ts @@ -44,6 +44,7 @@ export type TestSchedulerContext = { firstRun: boolean; previousSuccess: boolean; changedFiles?: Set; + sourcesRelatedToTestsInChangedFiles?: Set; }; export default class TestScheduler { private _dispatcher: ReporterDispatcher; @@ -175,12 +176,14 @@ export default class TestScheduler { showStatus: !runInBand, }); - const testRunners = Object.create(null); + const testRunners: {[key: string]: TestRunner} = Object.create(null); contexts.forEach(({config}) => { if (!testRunners[config.runner]) { const Runner: typeof TestRunner = require(config.runner); testRunners[config.runner] = new Runner(this._globalConfig, { - changedFiles: this._context && this._context.changedFiles, + changedFiles: this._context?.changedFiles, + sourcesRelatedToTestsInChangedFiles: this._context + ?.sourcesRelatedToTestsInChangedFiles, }); } }); @@ -272,7 +275,9 @@ export default class TestScheduler { if (!isDefault && collectCoverage) { this.addReporter( new CoverageReporter(this._globalConfig, { - changedFiles: this._context && this._context.changedFiles, + changedFiles: this._context?.changedFiles, + sourcesRelatedToTestsInChangedFiles: this._context + ?.sourcesRelatedToTestsInChangedFiles, }), ); } @@ -302,7 +307,9 @@ export default class TestScheduler { if (collectCoverage) { this.addReporter( new CoverageReporter(this._globalConfig, { - changedFiles: this._context && this._context.changedFiles, + changedFiles: this._context?.changedFiles, + sourcesRelatedToTestsInChangedFiles: this._context + ?.sourcesRelatedToTestsInChangedFiles, }), ); } diff --git a/packages/jest-core/src/__tests__/SearchSource.test.ts b/packages/jest-core/src/__tests__/SearchSource.test.ts index 292e5e4b986a..0a6815062c85 100644 --- a/packages/jest-core/src/__tests__/SearchSource.test.ts +++ b/packages/jest-core/src/__tests__/SearchSource.test.ts @@ -531,4 +531,64 @@ describe('SearchSource', () => { } }); }); + + describe('findRelatedSourcesFromTestsInChangedFiles', () => { + const rootDir = path.resolve( + __dirname, + '../../../jest-runtime/src/__tests__/test_root', + ); + + beforeEach(async () => { + const {options: config} = normalize( + { + haste: { + hasteImplModulePath: path.resolve( + __dirname, + '../../../jest-haste-map/src/__tests__/haste_impl.js', + ), + providesModuleNodeModules: [], + }, + name: 'SearchSource-findRelatedSourcesFromTestsInChangedFiles-tests', + rootDir, + }, + {} as Config.Argv, + ); + const context = await Runtime.createContext(config, { + maxWorkers, + watchman: false, + }); + searchSource = new SearchSource(context); + }); + + it('return empty set if no SCM', () => { + const requireRegularModule = path.join( + rootDir, + 'RequireRegularModule.js', + ); + const sources = searchSource.findRelatedSourcesFromTestsInChangedFiles({ + changedFiles: new Set([requireRegularModule]), + repos: { + git: new Set(), + hg: new Set(), + }, + }); + expect(sources).toEqual([]); + }); + + it('return sources required by tests', () => { + const regularModule = path.join(rootDir, 'RegularModule.js'); + const requireRegularModule = path.join( + rootDir, + 'RequireRegularModule.js', + ); + const sources = searchSource.findRelatedSourcesFromTestsInChangedFiles({ + changedFiles: new Set([requireRegularModule]), + repos: { + git: new Set('/path/to/git'), + hg: new Set(), + }, + }); + expect(sources).toEqual([regularModule]); + }); + }); }); diff --git a/packages/jest-core/src/runJest.ts b/packages/jest-core/src/runJest.ts index 38bcb8dc95be..bea930899c0d 100644 --- a/packages/jest-core/src/runJest.ts +++ b/packages/jest-core/src/runJest.ts @@ -34,13 +34,12 @@ import type {Filter, TestRunData} from './types'; const getTestPaths = async ( globalConfig: Config.GlobalConfig, - context: Context, + source: SearchSource, outputStream: NodeJS.WriteStream, changedFiles: ChangedFiles | undefined, jestHooks: JestHookEmitter, filter?: Filter, ) => { - const source = new SearchSource(context); const data = await source.getTestPaths(globalConfig, changedFiles, filter); if (!data.tests.length && globalConfig.onlyChanged && data.noSCM) { @@ -167,11 +166,14 @@ export default async function runJest({ } } + const searchSources = contexts.map(context => new SearchSource(context)); + const testRunData: TestRunData = await Promise.all( - contexts.map(async context => { + contexts.map(async (context, index) => { + const searchSource = searchSources[index]; const matches = await getTestPaths( globalConfig, - context, + searchSource, outputStream, changedFilesPromise && (await changedFilesPromise), jestHooks, @@ -242,9 +244,22 @@ export default async function runJest({ } if (changedFilesPromise) { - testSchedulerContext.changedFiles = ( - await changedFilesPromise - ).changedFiles; + const changedFilesInfo = await changedFilesPromise; + if (changedFilesInfo.changedFiles) { + testSchedulerContext.changedFiles = changedFilesInfo.changedFiles; + const sourcesRelatedToTestsInChangedFilesArray = contexts + .map((_, index) => { + const searchSource = searchSources[index]; + const relatedSourceFromTestsInChangedFiles = searchSource.findRelatedSourcesFromTestsInChangedFiles( + changedFilesInfo, + ); + return relatedSourceFromTestsInChangedFiles; + }) + .reduce((total, paths) => total.concat(paths), []); + testSchedulerContext.sourcesRelatedToTestsInChangedFiles = new Set( + sourcesRelatedToTestsInChangedFilesArray, + ); + } } const results = await new TestScheduler( diff --git a/packages/jest-diff/package.json b/packages/jest-diff/package.json index 56d44250aa38..561942c03c01 100644 --- a/packages/jest-diff/package.json +++ b/packages/jest-diff/package.json @@ -1,6 +1,6 @@ { "name": "jest-diff", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -20,7 +20,7 @@ "chalk": "^3.0.0", "diff-sequences": "^25.2.6", "jest-get-type": "^25.2.6", - "pretty-format": "^25.3.0" + "pretty-format": "^25.4.0" }, "devDependencies": { "@jest/test-utils": "^25.3.0", diff --git a/packages/jest-each/package.json b/packages/jest-each/package.json index 2b3b94de400c..316149df7c50 100644 --- a/packages/jest-each/package.json +++ b/packages/jest-each/package.json @@ -1,6 +1,6 @@ { "name": "jest-each", - "version": "25.3.0", + "version": "25.4.0", "description": "Parameterised tests for Jest", "main": "build/index.js", "types": "build/index.d.ts", @@ -25,11 +25,11 @@ "author": "Matt Phillips (mattphillips)", "license": "MIT", "dependencies": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.4.0", "chalk": "^3.0.0", "jest-get-type": "^25.2.6", - "jest-util": "^25.3.0", - "pretty-format": "^25.3.0" + "jest-util": "^25.4.0", + "pretty-format": "^25.4.0" }, "engines": { "node": ">= 8.3" diff --git a/packages/jest-each/src/__tests__/__snapshots__/index.test.ts.snap b/packages/jest-each/src/__tests__/__snapshots__/index.test.ts.snap new file mode 100644 index 000000000000..af1a9318ba07 --- /dev/null +++ b/packages/jest-each/src/__tests__/__snapshots__/index.test.ts.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`throws an error when not called with the right number of arguments 1`] = `"\`.each\` must only be called with an Array or Tagged Template Literal."`; diff --git a/packages/jest-each/src/__tests__/index.test.ts b/packages/jest-each/src/__tests__/index.test.ts index 06b23edd9afc..40ba0c391700 100644 --- a/packages/jest-each/src/__tests__/index.test.ts +++ b/packages/jest-each/src/__tests__/index.test.ts @@ -32,3 +32,17 @@ describe('template', () => { }); }); }); + +test('throws an error when not called with the right number of arguments', () => { + expect(() => + each( + [ + [1, 1, 2], + [1, 2, 3], + [2, 1, 3], + ], + 'seems like a title but should not be here', + () => {}, + ), + ).toThrowErrorMatchingSnapshot(); +}); diff --git a/packages/jest-each/src/index.ts b/packages/jest-each/src/index.ts index 85a213b0cf47..9836bd2136cb 100644 --- a/packages/jest-each/src/index.ts +++ b/packages/jest-each/src/index.ts @@ -15,6 +15,13 @@ const install = ( table: Global.EachTable, ...data: Global.TemplateData ) => { + const bindingWithArray = data.length === 0; + const bindingWithTemplate = Array.isArray(table) && !!(table as any).raw; + if (!bindingWithArray && !bindingWithTemplate) { + throw new Error( + '`.each` must only be called with an Array or Tagged Template Literal.', + ); + } const test = (title: string, test: Global.EachTestFn, timeout?: number) => bind(g.test)(table, ...data)(title, test, timeout); test.skip = bind(g.test.skip)(table, ...data); diff --git a/packages/jest-environment-jsdom/package.json b/packages/jest-environment-jsdom/package.json index c355720a4eb9..06c38b58c389 100644 --- a/packages/jest-environment-jsdom/package.json +++ b/packages/jest-environment-jsdom/package.json @@ -1,6 +1,6 @@ { "name": "jest-environment-jsdom", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,11 +17,11 @@ } }, "dependencies": { - "@jest/environment": "^25.3.0", - "@jest/fake-timers": "^25.3.0", - "@jest/types": "^25.3.0", - "jest-mock": "^25.3.0", - "jest-util": "^25.3.0", + "@jest/environment": "^25.4.0", + "@jest/fake-timers": "^25.4.0", + "@jest/types": "^25.4.0", + "jest-mock": "^25.4.0", + "jest-util": "^25.4.0", "jsdom": "^15.2.1" }, "devDependencies": { diff --git a/packages/jest-environment-node/package.json b/packages/jest-environment-node/package.json index 96512c431199..cfec5d2b3eb0 100644 --- a/packages/jest-environment-node/package.json +++ b/packages/jest-environment-node/package.json @@ -1,6 +1,6 @@ { "name": "jest-environment-node", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,11 +17,11 @@ } }, "dependencies": { - "@jest/environment": "^25.3.0", - "@jest/fake-timers": "^25.3.0", - "@jest/types": "^25.3.0", - "jest-mock": "^25.3.0", - "jest-util": "^25.3.0", + "@jest/environment": "^25.4.0", + "@jest/fake-timers": "^25.4.0", + "@jest/types": "^25.4.0", + "jest-mock": "^25.4.0", + "jest-util": "^25.4.0", "semver": "^6.3.0" }, "devDependencies": { diff --git a/packages/jest-environment/package.json b/packages/jest-environment/package.json index 27858e12e838..4e68a7f81dd6 100644 --- a/packages/jest-environment/package.json +++ b/packages/jest-environment/package.json @@ -1,6 +1,6 @@ { "name": "@jest/environment", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,9 +17,9 @@ } }, "dependencies": { - "@jest/fake-timers": "^25.3.0", - "@jest/types": "^25.3.0", - "jest-mock": "^25.3.0" + "@jest/fake-timers": "^25.4.0", + "@jest/types": "^25.4.0", + "jest-mock": "^25.4.0" }, "devDependencies": { "@types/node": "*" diff --git a/packages/jest-environment/tsconfig.json b/packages/jest-environment/tsconfig.json index 658545960324..efa01e2b2db4 100644 --- a/packages/jest-environment/tsconfig.json +++ b/packages/jest-environment/tsconfig.json @@ -1,6 +1,8 @@ { "extends": "../../tsconfig.json", "compilerOptions": { + // we don't want `@types/jest` to be referenced + "types": ["node"], "rootDir": "src", "outDir": "build" }, diff --git a/packages/jest-fake-timers/package.json b/packages/jest-fake-timers/package.json index dca478ad1ac4..e3a22a68beb7 100644 --- a/packages/jest-fake-timers/package.json +++ b/packages/jest-fake-timers/package.json @@ -1,6 +1,6 @@ { "name": "@jest/fake-timers", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,10 +17,10 @@ } }, "dependencies": { - "@jest/types": "^25.3.0", - "jest-message-util": "^25.3.0", - "jest-mock": "^25.3.0", - "jest-util": "^25.3.0", + "@jest/types": "^25.4.0", + "jest-message-util": "^25.4.0", + "jest-mock": "^25.4.0", + "jest-util": "^25.4.0", "lolex": "^5.0.0" }, "devDependencies": { diff --git a/packages/jest-globals/package.json b/packages/jest-globals/package.json index 80ac807c888e..c216d3beda23 100644 --- a/packages/jest-globals/package.json +++ b/packages/jest-globals/package.json @@ -1,6 +1,6 @@ { "name": "@jest/globals", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -20,9 +20,9 @@ } }, "dependencies": { - "@jest/environment": "^25.3.0", - "@jest/types": "^25.3.0", - "expect": "^25.3.0" + "@jest/environment": "^25.4.0", + "@jest/types": "^25.4.0", + "expect": "^25.4.0" }, "publishConfig": { "access": "public" diff --git a/packages/jest-haste-map/package.json b/packages/jest-haste-map/package.json index 418e16f9aa00..8d8db4832b20 100644 --- a/packages/jest-haste-map/package.json +++ b/packages/jest-haste-map/package.json @@ -1,6 +1,6 @@ { "name": "jest-haste-map", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,13 +17,13 @@ } }, "dependencies": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.4.0", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.3", "jest-serializer": "^25.2.6", - "jest-util": "^25.3.0", - "jest-worker": "^25.2.6", + "jest-util": "^25.4.0", + "jest-worker": "^25.4.0", "micromatch": "^4.0.2", "sane": "^4.0.3", "walker": "^1.0.7", diff --git a/packages/jest-haste-map/src/lib/__tests__/dependencyExtractor.test.js b/packages/jest-haste-map/src/lib/__tests__/dependencyExtractor.test.js index 516b5741b598..6ce7e444fae9 100644 --- a/packages/jest-haste-map/src/lib/__tests__/dependencyExtractor.test.js +++ b/packages/jest-haste-map/src/lib/__tests__/dependencyExtractor.test.js @@ -232,7 +232,7 @@ describe('dependencyExtractor', () => { "dep2", ); if (jest.requireActual(\`dep3\`).cond) {} - require + jest .requireActual('dep4'); // Bad @@ -252,7 +252,7 @@ describe('dependencyExtractor', () => { "dep2", ); if (jest.requireMock(\`dep3\`).cond) {} - require + jest .requireMock('dep4'); // Bad @@ -272,7 +272,7 @@ describe('dependencyExtractor', () => { "dep2", ); if (jest.genMockFromModule(\`dep3\`).cond) {} - require + jest .requireMock('dep4'); // Bad diff --git a/packages/jest-jasmine2/package.json b/packages/jest-jasmine2/package.json index 5f7c1bdcd015..6a00b3ee56c7 100644 --- a/packages/jest-jasmine2/package.json +++ b/packages/jest-jasmine2/package.json @@ -1,6 +1,6 @@ { "name": "jest-jasmine2", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -18,21 +18,21 @@ }, "dependencies": { "@babel/traverse": "^7.1.0", - "@jest/environment": "^25.3.0", + "@jest/environment": "^25.4.0", "@jest/source-map": "^25.2.6", - "@jest/test-result": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/test-result": "^25.4.0", + "@jest/types": "^25.4.0", "chalk": "^3.0.0", "co": "^4.6.0", - "expect": "^25.3.0", + "expect": "^25.4.0", "is-generator-fn": "^2.0.0", - "jest-each": "^25.3.0", - "jest-matcher-utils": "^25.3.0", - "jest-message-util": "^25.3.0", - "jest-runtime": "^25.3.0", - "jest-snapshot": "^25.3.0", - "jest-util": "^25.3.0", - "pretty-format": "^25.3.0", + "jest-each": "^25.4.0", + "jest-matcher-utils": "^25.4.0", + "jest-message-util": "^25.4.0", + "jest-runtime": "^25.4.0", + "jest-snapshot": "^25.4.0", + "jest-util": "^25.4.0", + "pretty-format": "^25.4.0", "throat": "^5.0.0" }, "devDependencies": { diff --git a/packages/jest-jasmine2/src/index.ts b/packages/jest-jasmine2/src/index.ts index f8ab81713895..03d2eebdc851 100644 --- a/packages/jest-jasmine2/src/index.ts +++ b/packages/jest-jasmine2/src/index.ts @@ -155,7 +155,15 @@ async function jasmine2( testPath, }); - config.setupFilesAfterEnv.forEach(path => runtime.requireModule(path)); + for (const path of config.setupFilesAfterEnv) { + const esm = runtime.unstable_shouldLoadAsEsm(path); + + if (esm) { + await runtime.unstable_importModule(path); + } else { + runtime.requireModule(path); + } + } if (globalConfig.enabledTestsMap) { env.specFilter = (spec: Spec) => { @@ -169,7 +177,14 @@ async function jasmine2( env.specFilter = (spec: Spec) => testNameRegex.test(spec.getFullName()); } - runtime.requireModule(testPath); + const esm = runtime.unstable_shouldLoadAsEsm(testPath); + + if (esm) { + await runtime.unstable_importModule(testPath); + } else { + runtime.requireModule(testPath); + } + await env.execute(); const results = await reporter.getResults(); diff --git a/packages/jest-jasmine2/src/jasmine/Env.ts b/packages/jest-jasmine2/src/jasmine/Env.ts index 48e6b82fd4b4..a94173a7321f 100644 --- a/packages/jest-jasmine2/src/jasmine/Env.ts +++ b/packages/jest-jasmine2/src/jasmine/Env.ts @@ -566,11 +566,7 @@ export default function (j$: Jasmine) { // This check throws an error to warn the user about the edge-case. if (currentSpec !== null) { throw new Error( - 'Tests cannot be nested. Test `' + - spec.description + - '` cannot run because it is nested within `' + - currentSpec.description + - '`.', + `Tests cannot be nested. Test "${spec.description}" cannot run because it is nested within "${currentSpec.description}".`, ); } currentDeclarationSuite.addChild(spec); diff --git a/packages/jest-leak-detector/package.json b/packages/jest-leak-detector/package.json index 6f8faab05595..1cfcbab61a70 100644 --- a/packages/jest-leak-detector/package.json +++ b/packages/jest-leak-detector/package.json @@ -1,6 +1,6 @@ { "name": "jest-leak-detector", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -18,7 +18,7 @@ }, "dependencies": { "jest-get-type": "^25.2.6", - "pretty-format": "^25.3.0" + "pretty-format": "^25.4.0" }, "devDependencies": { "@types/weak-napi": "^1.0.0", diff --git a/packages/jest-matcher-utils/package.json b/packages/jest-matcher-utils/package.json index 54232319d6ce..d0e896a247f4 100644 --- a/packages/jest-matcher-utils/package.json +++ b/packages/jest-matcher-utils/package.json @@ -1,7 +1,7 @@ { "name": "jest-matcher-utils", "description": "A set of utility functions for expect and related packages", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -22,9 +22,9 @@ }, "dependencies": { "chalk": "^3.0.0", - "jest-diff": "^25.3.0", + "jest-diff": "^25.4.0", "jest-get-type": "^25.2.6", - "pretty-format": "^25.3.0" + "pretty-format": "^25.4.0" }, "devDependencies": { "@jest/test-utils": "^25.3.0", diff --git a/packages/jest-message-util/package.json b/packages/jest-message-util/package.json index 51c2c28b8f43..4f579e9d82da 100644 --- a/packages/jest-message-util/package.json +++ b/packages/jest-message-util/package.json @@ -1,6 +1,6 @@ { "name": "jest-message-util", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -21,7 +21,7 @@ }, "dependencies": { "@babel/code-frame": "^7.0.0", - "@jest/types": "^25.3.0", + "@jest/types": "^25.4.0", "@types/stack-utils": "^1.0.1", "chalk": "^3.0.0", "micromatch": "^4.0.2", diff --git a/packages/jest-message-util/src/__tests__/__snapshots__/messages.test.ts.snap b/packages/jest-message-util/src/__tests__/__snapshots__/messages.test.ts.snap index 8fb8249ca9b5..99256df0436c 100644 --- a/packages/jest-message-util/src/__tests__/__snapshots__/messages.test.ts.snap +++ b/packages/jest-message-util/src/__tests__/__snapshots__/messages.test.ts.snap @@ -7,6 +7,18 @@ exports[`.formatExecError() 1`] = ` " `; +exports[`codeframe 1`] = ` +" ● Test suite failed to run + + Whoops! + + > 1 | throw new Error(\\"Whoops!\\"); + | ^ + + at Object. (file.js:1:7) +" +`; + exports[`formatStackTrace should strip node internals 1`] = ` " Unix test @@ -23,6 +35,43 @@ exports[`formatStackTrace should strip node internals 1`] = ` " `; +exports[`getConsoleOutput does not print code frame when noCodeFrame = true 1`] = ` +" + at Object. (file.js:1:7) + " +`; + +exports[`getConsoleOutput does not print codeframe when noStackTrace = true 1`] = ` +" + at Object. (file.js:1:7) + " +`; + +exports[`getConsoleOutput prints code frame and stacktrace 1`] = ` +" + > 1 | throw new Error(\\"Whoops!\\"); + | ^ + + at Object. (file.js:1:7) + " +`; + +exports[`no codeframe 1`] = ` +" ● Test suite failed to run + + Whoops! + + at Object. (file.js:1:7) +" +`; + +exports[`no stack 1`] = ` +" ● Test suite failed to run + + Whoops! +" +`; + exports[`retains message in babel code frame error 1`] = ` " Babel test @@ -30,7 +79,7 @@ exports[`retains message in babel code frame error 1`] = ` packages/react/src/forwardRef.js: Unexpected token, expected , (20:10) 18 | false, - 19 | 'forwardRef requires a render function but received a \`memo\` ' + 19 | 'forwardRef requires a render function but received a \`memo\` ' > 20 | 'component. Instead of forwardRef(memo(...)), use ' + | ^ 21 | 'memo(forwardRef(...)).', diff --git a/packages/jest-message-util/src/__tests__/messages.test.ts b/packages/jest-message-util/src/__tests__/messages.test.ts index 667038690713..e4b3d3bf8dad 100644 --- a/packages/jest-message-util/src/__tests__/messages.test.ts +++ b/packages/jest-message-util/src/__tests__/messages.test.ts @@ -6,7 +6,17 @@ * */ -import {formatExecError, formatResultsErrors} from '..'; +import {readFileSync} from 'fs'; +import slash = require('slash'); +import tempy = require('tempy'); +import {formatExecError, formatResultsErrors, formatStackTrace} from '..'; + +const rootDir = tempy.directory(); + +jest.mock('fs', () => ({ + ...jest.requireActual('fs'), + readFileSync: jest.fn(), +})); const unixStackTrace = ` ` + @@ -61,7 +71,7 @@ const babelStack = ` packages/react/src/forwardRef.js: Unexpected token, expected , (20:10) \u001b[0m \u001b[90m 18 | \u001b[39m \u001b[36mfalse\u001b[39m\u001b[33m,\u001b[39m - \u001b[90m 19 | \u001b[39m \u001b[32m'forwardRef requires a render function but received a \`memo\` '\u001b[39m + \u001b[90m 19 | \u001b[39m \u001b[32m'forwardRef requires a render function but received a \`memo\` '\u001b[39m \u001b[31m\u001b[1m>\u001b[22m\u001b[39m\u001b[90m 20 | \u001b[39m \u001b[32m'component. Instead of forwardRef(memo(...)), use '\u001b[39m \u001b[33m+\u001b[39m \u001b[90m | \u001b[39m \u001b[31m\u001b[1m^\u001b[22m\u001b[39m \u001b[90m 21 | \u001b[39m \u001b[32m'memo(forwardRef(...)).'\u001b[39m\u001b[33m,\u001b[39m @@ -69,6 +79,10 @@ const babelStack = \u001b[90m 23 | \u001b[39m } \u001b[36melse\u001b[39m \u001b[36mif\u001b[39m (\u001b[36mtypeof\u001b[39m render \u001b[33m!==\u001b[39m \u001b[32m'function'\u001b[39m) {\u001b[0m `; +beforeEach(() => { + jest.clearAllMocks(); +}); + it('should exclude jasmine from stack trace for Unix paths.', () => { const messages = formatResultsErrors( [ @@ -187,3 +201,167 @@ it('retains message in babel code frame error', () => { expect(messages).toMatchSnapshot(); }); + +it('codeframe', () => { + readFileSync.mockImplementationOnce(() => 'throw new Error("Whoops!");'); + + const message = formatExecError( + { + message: 'Whoops!', + stack: ` + at Object. (${slash(rootDir)}/file.js:1:7) + at Module._compile (internal/modules/cjs/loader.js:1158:30) + at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10) + at Module.load (internal/modules/cjs/loader.js:1002:32) + at Function.Module._load (internal/modules/cjs/loader.js:901:14) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12) +`, + }, + { + rootDir, + testMatch: [], + }, + { + noCodeFrame: false, + noStackTrace: false, + }, + 'path_test', + ); + + expect(message).toMatchSnapshot(); +}); + +it('no codeframe', () => { + readFileSync.mockImplementationOnce(() => 'throw new Error("Whoops!");'); + + const message = formatExecError( + { + message: 'Whoops!', + stack: ` + at Object. (${slash(rootDir)}/file.js:1:7) + at Module._compile (internal/modules/cjs/loader.js:1158:30) + at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10) + at Module.load (internal/modules/cjs/loader.js:1002:32) + at Function.Module._load (internal/modules/cjs/loader.js:901:14) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12) +`, + }, + { + rootDir, + testMatch: [], + }, + { + noCodeFrame: true, + noStackTrace: false, + }, + 'path_test', + ); + + expect(message).toMatchSnapshot(); +}); + +it('no stack', () => { + readFileSync.mockImplementationOnce(() => 'throw new Error("Whoops!");'); + + const message = formatExecError( + { + message: 'Whoops!', + stack: ` + at Object. (${slash(rootDir)}/file.js:1:7) + at Module._compile (internal/modules/cjs/loader.js:1158:30) + at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10) + at Module.load (internal/modules/cjs/loader.js:1002:32) + at Function.Module._load (internal/modules/cjs/loader.js:901:14) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12) +`, + }, + { + rootDir, + testMatch: [], + }, + { + // if no stack, no codeframe is implied + noCodeFrame: true, + noStackTrace: true, + }, + 'path_test', + ); + + expect(message).toMatchSnapshot(); +}); + +describe('getConsoleOutput', () => { + it('prints code frame and stacktrace', () => { + readFileSync.mockImplementationOnce(() => 'throw new Error("Whoops!");'); + const message = formatStackTrace( + ` + at Object. (${slash(rootDir)}/file.js:1:7) + at Module._compile (internal/modules/cjs/loader.js:1158:30) + at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10) + at Module.load (internal/modules/cjs/loader.js:1002:32) + at Function.Module._load (internal/modules/cjs/loader.js:901:14) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12) + `, + { + rootDir, + testMatch: [], + }, + { + noCodeFrame: false, + noStackTrace: false, + }, + 'path_test', + ); + + expect(message).toMatchSnapshot(); + }); + + it('does not print code frame when noCodeFrame = true', () => { + readFileSync.mockImplementationOnce(() => 'throw new Error("Whoops!");'); + const message = formatStackTrace( + ` + at Object. (${slash(rootDir)}/file.js:1:7) + at Module._compile (internal/modules/cjs/loader.js:1158:30) + at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10) + at Module.load (internal/modules/cjs/loader.js:1002:32) + at Function.Module._load (internal/modules/cjs/loader.js:901:14) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12) + `, + { + rootDir, + testMatch: [], + }, + { + noCodeFrame: true, + noStackTrace: false, + }, + 'path_test', + ); + + expect(message).toMatchSnapshot(); + }); + + it('does not print codeframe when noStackTrace = true', () => { + readFileSync.mockImplementationOnce(() => 'throw new Error("Whoops!");'); + const message = formatStackTrace( + ` + at Object. (${slash(rootDir)}/file.js:1:7) + at Module._compile (internal/modules/cjs/loader.js:1158:30) + at Object.Module._extensions..js (internal/modules/cjs/loader.js:1178:10) + at Module.load (internal/modules/cjs/loader.js:1002:32) + at Function.Module._load (internal/modules/cjs/loader.js:901:14) + at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:74:12) + `, + { + rootDir, + testMatch: [], + }, + { + noStackTrace: true, + }, + 'path_test', + ); + + expect(message).toMatchSnapshot(); + }); +}); diff --git a/packages/jest-message-util/src/index.ts b/packages/jest-message-util/src/index.ts index b82b512690fa..e205c823d648 100644 --- a/packages/jest-message-util/src/index.ts +++ b/packages/jest-message-util/src/index.ts @@ -38,6 +38,7 @@ export type StackTraceConfig = Pick< export type StackTraceOptions = { noStackTrace: boolean; + noCodeFrame?: boolean; }; const PATH_NODE_MODULES = `${path.sep}node_modules${path.sep}`; @@ -251,7 +252,7 @@ const formatPaths = ( export const getStackTraceLines = ( stack: string, - options: StackTraceOptions = {noStackTrace: false}, + options: StackTraceOptions = {noCodeFrame: false, noStackTrace: false}, ): Array => removeInternalStackEntries(stack.split(/\n/), options); export const getTopFrame = (lines: Array): Frame | null => { @@ -277,24 +278,26 @@ export const formatStackTrace = ( testPath?: Path, ): string => { const lines = getStackTraceLines(stack, options); - const topFrame = getTopFrame(lines); let renderedCallsite = ''; const relativeTestPath = testPath ? slash(path.relative(config.rootDir, testPath)) : null; - if (topFrame) { - const {column, file: filename, line} = topFrame; - - if (line && filename && path.isAbsolute(filename)) { - let fileContent; - try { - // TODO: check & read HasteFS instead of reading the filesystem: - // see: https://github.com/facebook/jest/pull/5405#discussion_r164281696 - fileContent = fs.readFileSync(filename, 'utf8'); - renderedCallsite = getRenderedCallsite(fileContent, line, column); - } catch (e) { - // the file does not exist or is inaccessible, we ignore + if (!options.noStackTrace && !options.noCodeFrame) { + const topFrame = getTopFrame(lines); + if (topFrame) { + const {column, file: filename, line} = topFrame; + + if (line && filename && path.isAbsolute(filename)) { + let fileContent; + try { + // TODO: check & read HasteFS instead of reading the filesystem: + // see: https://github.com/facebook/jest/pull/5405#discussion_r164281696 + fileContent = fs.readFileSync(filename, 'utf8'); + renderedCallsite = getRenderedCallsite(fileContent, line, column); + } catch (e) { + // the file does not exist or is inaccessible, we ignore + } } } } @@ -307,7 +310,9 @@ export const formatStackTrace = ( ) .join('\n'); - return `${renderedCallsite}\n${stacktrace}`; + return renderedCallsite + ? `${renderedCallsite}\n${stacktrace}` + : `\n${stacktrace}`; }; type FailedResults = Array<{ diff --git a/packages/jest-mock/package.json b/packages/jest-mock/package.json index 643937b7c382..294324e7630d 100644 --- a/packages/jest-mock/package.json +++ b/packages/jest-mock/package.json @@ -1,6 +1,6 @@ { "name": "jest-mock", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -10,7 +10,7 @@ "node": ">= 8.3" }, "dependencies": { - "@jest/types": "^25.3.0" + "@jest/types": "^25.4.0" }, "devDependencies": { "@types/node": "*" diff --git a/packages/jest-phabricator/package.json b/packages/jest-phabricator/package.json index 90965d00b5e8..3d0b2297fe44 100644 --- a/packages/jest-phabricator/package.json +++ b/packages/jest-phabricator/package.json @@ -1,6 +1,6 @@ { "name": "jest-phabricator", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -15,7 +15,7 @@ } }, "dependencies": { - "@jest/test-result": "^25.3.0" + "@jest/test-result": "^25.4.0" }, "engines": { "node": ">= 8.3" diff --git a/packages/jest-repl/package.json b/packages/jest-repl/package.json index 25e7e7df5f2a..b93eeb57cfc3 100644 --- a/packages/jest-repl/package.json +++ b/packages/jest-repl/package.json @@ -1,6 +1,6 @@ { "name": "jest-repl", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,11 +17,11 @@ } }, "dependencies": { - "@jest/transform": "^25.3.0", - "@jest/types": "^25.3.0", - "jest-config": "^25.3.0", - "jest-runtime": "^25.3.0", - "jest-validate": "^25.3.0", + "@jest/transform": "^25.4.0", + "@jest/types": "^25.4.0", + "jest-config": "^25.4.0", + "jest-runtime": "^25.4.0", + "jest-validate": "^25.4.0", "repl": "^0.1.3", "yargs": "^15.3.1" }, diff --git a/packages/jest-reporters/package.json b/packages/jest-reporters/package.json index df56ebb1ba8f..d9ca29b2bbb8 100644 --- a/packages/jest-reporters/package.json +++ b/packages/jest-reporters/package.json @@ -1,7 +1,7 @@ { "name": "@jest/reporters", "description": "Jest's reporters", - "version": "25.3.0", + "version": "25.4.0", "main": "build/index.js", "types": "build/index.d.ts", "typesVersions": { @@ -13,10 +13,10 @@ }, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^25.3.0", - "@jest/test-result": "^25.3.0", - "@jest/transform": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/console": "^25.4.0", + "@jest/test-result": "^25.4.0", + "@jest/transform": "^25.4.0", + "@jest/types": "^25.4.0", "chalk": "^3.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", @@ -26,10 +26,10 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.0.2", - "jest-haste-map": "^25.3.0", - "jest-resolve": "^25.3.0", - "jest-util": "^25.3.0", - "jest-worker": "^25.2.6", + "jest-haste-map": "^25.4.0", + "jest-resolve": "^25.4.0", + "jest-util": "^25.4.0", + "jest-worker": "^25.4.0", "slash": "^3.0.0", "source-map": "^0.6.0", "string-length": "^3.1.0", diff --git a/packages/jest-reporters/src/__tests__/coverage_worker.test.js b/packages/jest-reporters/src/__tests__/coverage_worker.test.js index b3351ba29006..86cfeecb1ab3 100644 --- a/packages/jest-reporters/src/__tests__/coverage_worker.test.js +++ b/packages/jest-reporters/src/__tests__/coverage_worker.test.js @@ -41,6 +41,7 @@ test('resolves to the result of generateEmptyCoverage upon success', async () => globalConfig, config, undefined, + undefined, ); expect(result).toEqual(42); diff --git a/packages/jest-reporters/src/coverage_reporter.ts b/packages/jest-reporters/src/coverage_reporter.ts index b769743e2ff6..1e87c21bdbd8 100644 --- a/packages/jest-reporters/src/coverage_reporter.ts +++ b/packages/jest-reporters/src/coverage_reporter.ts @@ -71,28 +71,6 @@ export default class CoverageReporter extends BaseReporter { if (testResult.coverage) { this._coverageMap.merge(testResult.coverage); } - - const sourceMaps = testResult.sourceMaps; - if (sourceMaps) { - Object.keys(sourceMaps).forEach(sourcePath => { - let inputSourceMap: RawSourceMap | undefined; - try { - const coverage: istanbulCoverage.FileCoverage = this._coverageMap.fileCoverageFor( - sourcePath, - ); - inputSourceMap = (coverage.toJSON() as any).inputSourceMap; - } finally { - if (inputSourceMap) { - this._sourceMapStore.registerMap(sourcePath, inputSourceMap); - } else { - this._sourceMapStore.registerURL( - sourcePath, - sourceMaps[sourcePath], - ); - } - } - }); - } } async onRunComplete( @@ -204,6 +182,9 @@ export default class CoverageReporter extends BaseReporter { changedFiles: this._options.changedFiles && Array.from(this._options.changedFiles), + sourcesRelatedToTestsInChangedFiles: + this._options.sourcesRelatedToTestsInChangedFiles && + Array.from(this._options.sourcesRelatedToTestsInChangedFiles), }, path: filename, }); @@ -215,13 +196,6 @@ export default class CoverageReporter extends BaseReporter { ]); } else { this._coverageMap.addFileCoverage(result.coverage); - - if (result.sourceMapPath) { - this._sourceMapStore.registerURL( - filename, - result.sourceMapPath, - ); - } } } } catch (error) { diff --git a/packages/jest-reporters/src/coverage_worker.ts b/packages/jest-reporters/src/coverage_worker.ts index 23109ffa16ee..d1894b97574c 100644 --- a/packages/jest-reporters/src/coverage_worker.ts +++ b/packages/jest-reporters/src/coverage_worker.ts @@ -40,6 +40,8 @@ export function worker({ path, globalConfig, config, - options && options.changedFiles && new Set(options.changedFiles), + options?.changedFiles && new Set(options.changedFiles), + options?.sourcesRelatedToTestsInChangedFiles && + new Set(options.sourcesRelatedToTestsInChangedFiles), ); } diff --git a/packages/jest-reporters/src/default_reporter.ts b/packages/jest-reporters/src/default_reporter.ts index ae90384cd2b8..9053fbf20eac 100644 --- a/packages/jest-reporters/src/default_reporter.ts +++ b/packages/jest-reporters/src/default_reporter.ts @@ -182,6 +182,7 @@ export default class DefaultReporter extends BaseReporter { config.cwd, !!this._globalConfig.verbose, result.console, + config, ), ); } diff --git a/packages/jest-reporters/src/generateEmptyCoverage.ts b/packages/jest-reporters/src/generateEmptyCoverage.ts index 62ab4c023f2c..38f184d61558 100644 --- a/packages/jest-reporters/src/generateEmptyCoverage.ts +++ b/packages/jest-reporters/src/generateEmptyCoverage.ts @@ -18,7 +18,6 @@ export type CoverageWorkerResult = | { kind: 'BabelCoverage'; coverage: FileCoverage; - sourceMapPath?: string | null; } | { kind: 'V8Coverage'; @@ -31,6 +30,7 @@ export default function ( globalConfig: Config.GlobalConfig, config: Config.ProjectConfig, changedFiles?: Set, + sourcesRelatedToTestsInChangedFiles?: Set, ): CoverageWorkerResult | null { const coverageOptions = { changedFiles, @@ -38,6 +38,7 @@ export default function ( collectCoverageFrom: globalConfig.collectCoverageFrom, collectCoverageOnlyFrom: globalConfig.collectCoverageOnlyFrom, coverageProvider: globalConfig.coverageProvider, + sourcesRelatedToTestsInChangedFiles, }; let coverageWorkerResult: CoverageWorkerResult | null = null; if (shouldInstrument(filename, coverageOptions, config)) { @@ -66,9 +67,11 @@ export default function ( } // Transform file with instrumentation to make sure initial coverage data is well mapped to original code. - const {code, mapCoverage, sourceMapPath} = new ScriptTransformer( - config, - ).transformSource(filename, source, true); + const {code} = new ScriptTransformer(config).transformSource( + filename, + source, + true, + ); // TODO: consider passing AST const extracted = readInitialCoverage(code); // Check extracted initial coverage is not null, this can happen when using /* istanbul ignore file */ @@ -76,7 +79,6 @@ export default function ( coverageWorkerResult = { coverage: createFileCoverage(extracted.coverageData), kind: 'BabelCoverage', - sourceMapPath: mapCoverage ? sourceMapPath : null, }; } } diff --git a/packages/jest-reporters/src/types.ts b/packages/jest-reporters/src/types.ts index ddfde5782362..d2725ead5917 100644 --- a/packages/jest-reporters/src/types.ts +++ b/packages/jest-reporters/src/types.ts @@ -37,10 +37,12 @@ export type CoverageWorker = {worker: typeof worker}; export type CoverageReporterOptions = { changedFiles?: Set; + sourcesRelatedToTestsInChangedFiles?: Set; }; export type CoverageReporterSerializedOptions = { changedFiles?: Array; + sourcesRelatedToTestsInChangedFiles?: Array; }; export type OnTestStart = (test: Test) => Promise; diff --git a/packages/jest-resolve-dependencies/package.json b/packages/jest-resolve-dependencies/package.json index d49c92582164..91ff489f1bab 100644 --- a/packages/jest-resolve-dependencies/package.json +++ b/packages/jest-resolve-dependencies/package.json @@ -1,6 +1,6 @@ { "name": "jest-resolve-dependencies", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,14 +17,14 @@ } }, "dependencies": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.4.0", "jest-regex-util": "^25.2.6", - "jest-snapshot": "^25.3.0" + "jest-snapshot": "^25.4.0" }, "devDependencies": { - "jest-haste-map": "^25.3.0", - "jest-resolve": "^25.3.0", - "jest-runtime": "^25.3.0" + "jest-haste-map": "^25.4.0", + "jest-resolve": "^25.4.0", + "jest-runtime": "^25.4.0" }, "engines": { "node": ">= 8.3" diff --git a/packages/jest-resolve/package.json b/packages/jest-resolve/package.json index fe0e8e5de75e..7dc336af75c3 100644 --- a/packages/jest-resolve/package.json +++ b/packages/jest-resolve/package.json @@ -1,6 +1,6 @@ { "name": "jest-resolve", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,18 +17,19 @@ } }, "dependencies": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.4.0", "browser-resolve": "^1.11.3", "chalk": "^3.0.0", "jest-pnp-resolver": "^1.2.1", + "read-pkg-up": "^7.0.1", "realpath-native": "^2.0.0", - "resolve": "^1.15.1", + "resolve": "^1.17.0", "slash": "^3.0.0" }, "devDependencies": { "@types/browser-resolve": "^1.11.0", "@types/resolve": "^1.14.0", - "jest-haste-map": "^25.3.0" + "jest-haste-map": "^25.4.0" }, "engines": { "node": ">= 8.3" diff --git a/packages/jest-resolve/src/defaultResolver.ts b/packages/jest-resolve/src/defaultResolver.ts index 4e990f8b65c1..0e20699364ba 100644 --- a/packages/jest-resolve/src/defaultResolver.ts +++ b/packages/jest-resolve/src/defaultResolver.ts @@ -41,25 +41,18 @@ export default function defaultResolver( moduleDirectory: options.moduleDirectory, paths: options.paths, preserveSymlinks: false, + // @ts-ignore: https://github.com/DefinitelyTyped/DefinitelyTyped/pull/44137 + realpathSync, }); - try { - // Dereference symlinks to ensure we don't create a separate - // module instance depending on how it was referenced. - const resolved = realpath(result); - - if (resolved) { - return resolved; - } - } catch { - // ignore - } - - return result; + // Dereference symlinks to ensure we don't create a separate + // module instance depending on how it was referenced. + return realpathSync(result); } export function clearDefaultResolverCache(): void { checkedPaths.clear(); + checkedRealpathPaths.clear(); } enum IPathType { @@ -97,6 +90,36 @@ function statSyncCached(path: string): IPathType { return IPathType.OTHER; } +const checkedRealpathPaths = new Map(); +function realpathCached(path: Config.Path): Config.Path { + let result = checkedRealpathPaths.get(path); + + if (result !== undefined) { + return result; + } + + try { + result = realpath(path); + } catch (error) { + if (error.code !== 'ENOENT') { + throw error; + } + } + + if (!result) { + result = path; + } + + checkedRealpathPaths.set(path, result); + + if (path !== result) { + // also cache the result in case it's ever referenced directly - no reason to `realpath` that as well + checkedRealpathPaths.set(result, result); + } + + return result; +} + /* * helper functions */ @@ -107,3 +130,7 @@ function isFile(file: Config.Path): boolean { function isDirectory(dir: Config.Path): boolean { return statSyncCached(dir) === IPathType.DIRECTORY; } + +function realpathSync(file: Config.Path): Config.Path { + return realpathCached(file); +} diff --git a/packages/jest-resolve/src/index.ts b/packages/jest-resolve/src/index.ts index 15856fb5aeb2..5cdbbd8a3ef3 100644 --- a/packages/jest-resolve/src/index.ts +++ b/packages/jest-resolve/src/index.ts @@ -15,6 +15,7 @@ import isBuiltinModule from './isBuiltinModule'; import defaultResolver, {clearDefaultResolverCache} from './defaultResolver'; import type {ResolverConfig} from './types'; import ModuleNotFoundError from './ModuleNotFoundError'; +import shouldLoadAsEsm, {clearCachedLookups} from './shouldLoadAsEsm'; type FindNodeModuleConfig = { basedir: Config.Path; @@ -100,6 +101,7 @@ class Resolver { static clearDefaultResolverCache(): void { clearDefaultResolverCache(); + clearCachedLookups(); } static findNodeModule( @@ -129,6 +131,9 @@ class Resolver { return null; } + // unstable as it should be replaced by https://github.com/nodejs/modules/issues/393, and we don't want people to use it + static unstable_shouldLoadAsEsm = shouldLoadAsEsm; + resolveModuleFromDirIfExists( dirname: Config.Path, moduleName: string, diff --git a/packages/jest-resolve/src/shouldLoadAsEsm.ts b/packages/jest-resolve/src/shouldLoadAsEsm.ts new file mode 100644 index 000000000000..a1938e70d5e6 --- /dev/null +++ b/packages/jest-resolve/src/shouldLoadAsEsm.ts @@ -0,0 +1,78 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import {dirname, extname} from 'path'; +// @ts-ignore: experimental, not added to the types +import {SyntheticModule} from 'vm'; +import type {Config} from '@jest/types'; +import readPkgUp = require('read-pkg-up'); + +const runtimeSupportsVmModules = typeof SyntheticModule === 'function'; + +const cachedFileLookups = new Map(); +const cachedDirLookups = new Map(); + +export function clearCachedLookups(): void { + cachedFileLookups.clear(); + cachedDirLookups.clear(); +} + +export default function cachedShouldLoadAsEsm(path: Config.Path): boolean { + let cachedLookup = cachedFileLookups.get(path); + + if (cachedLookup === undefined) { + cachedLookup = shouldLoadAsEsm(path); + cachedFileLookups.set(path, cachedLookup); + } + + return cachedLookup; +} + +// this is a bad version of what https://github.com/nodejs/modules/issues/393 would provide +function shouldLoadAsEsm(path: Config.Path): boolean { + if (!runtimeSupportsVmModules) { + return false; + } + + const extension = extname(path); + + if (extension === '.mjs') { + return true; + } + + if (extension === '.cjs') { + return false; + } + + // this isn't correct - we might wanna load any file as a module (using synthetic module) + // do we need an option to Jest so people can opt in to ESM for non-js? + if (extension !== '.js') { + return false; + } + + const cwd = dirname(path); + + let cachedLookup = cachedDirLookups.get(cwd); + + if (cachedLookup === undefined) { + cachedLookup = cachedPkgCheck(cwd); + cachedFileLookups.set(cwd, cachedLookup); + } + + return cachedLookup; +} + +function cachedPkgCheck(cwd: Config.Path): boolean { + // TODO: can we cache lookups somehow? + const pkg = readPkgUp.sync({cwd, normalize: false}); + + if (!pkg) { + return false; + } + + return pkg.packageJson.type === 'module'; +} diff --git a/packages/jest-runner/package.json b/packages/jest-runner/package.json index a28d896d5686..87c46de216ca 100644 --- a/packages/jest-runner/package.json +++ b/packages/jest-runner/package.json @@ -1,6 +1,6 @@ { "name": "jest-runner", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,23 +17,23 @@ } }, "dependencies": { - "@jest/console": "^25.3.0", - "@jest/environment": "^25.3.0", - "@jest/test-result": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/console": "^25.4.0", + "@jest/environment": "^25.4.0", + "@jest/test-result": "^25.4.0", + "@jest/types": "^25.4.0", "chalk": "^3.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.3", - "jest-config": "^25.3.0", + "jest-config": "^25.4.0", "jest-docblock": "^25.3.0", - "jest-haste-map": "^25.3.0", - "jest-jasmine2": "^25.3.0", - "jest-leak-detector": "^25.3.0", - "jest-message-util": "^25.3.0", - "jest-resolve": "^25.3.0", - "jest-runtime": "^25.3.0", - "jest-util": "^25.3.0", - "jest-worker": "^25.2.6", + "jest-haste-map": "^25.4.0", + "jest-jasmine2": "^25.4.0", + "jest-leak-detector": "^25.4.0", + "jest-message-util": "^25.4.0", + "jest-resolve": "^25.4.0", + "jest-runtime": "^25.4.0", + "jest-util": "^25.4.0", + "jest-worker": "^25.4.0", "source-map-support": "^0.5.6", "throat": "^5.0.0" }, @@ -42,7 +42,7 @@ "@types/graceful-fs": "^4.1.2", "@types/node": "*", "@types/source-map-support": "^0.5.0", - "jest-circus": "^25.3.0" + "jest-circus": "^25.4.0" }, "engines": { "node": ">= 8.3" diff --git a/packages/jest-runner/src/index.ts b/packages/jest-runner/src/index.ts index 9969492ad738..9cf5659426cb 100644 --- a/packages/jest-runner/src/index.ts +++ b/packages/jest-runner/src/index.ts @@ -44,6 +44,7 @@ namespace TestRunner { class TestRunner { private _globalConfig: Config.GlobalConfig; private _context: JestTestRunnerContext; + readonly isSerial?: boolean; constructor( globalConfig: Config.GlobalConfig, @@ -193,7 +194,7 @@ class TestRunner { const cleanup = async () => { const {forceExited} = await worker.end(); if (forceExited) { - console.log( + console.error( chalk.yellow( 'A worker process has failed to exit gracefully and has been force exited. ' + 'This is likely caused by tests leaking due to improper teardown. ' + diff --git a/packages/jest-runner/src/runTest.ts b/packages/jest-runner/src/runTest.ts index a617bc9d510c..dd8735be8b57 100644 --- a/packages/jest-runner/src/runTest.ts +++ b/packages/jest-runner/src/runTest.ts @@ -114,21 +114,14 @@ async function runTestInternal( ? require(config.moduleLoader) : require('jest-runtime'); - let runtime: RuntimeClass | undefined = undefined; - const consoleOut = globalConfig.useStderr ? process.stderr : process.stdout; const consoleFormatter = (type: LogType, message: LogMessage) => getConsoleOutput( config.cwd, !!globalConfig.verbose, // 4 = the console call is buried 4 stack frames deep - BufferedConsole.write( - [], - type, - message, - 4, - runtime && runtime.getSourceMaps(), - ), + BufferedConsole.write([], type, message, 4), + config, ); let testConsole; @@ -138,7 +131,7 @@ async function runTestInternal( } else if (globalConfig.verbose) { testConsole = new CustomConsole(consoleOut, consoleOut, consoleFormatter); } else { - testConsole = new BufferedConsole(() => runtime && runtime.getSourceMaps()); + testConsole = new BufferedConsole(); } const environment = new TestEnvironment(config, { @@ -153,23 +146,33 @@ async function runTestInternal( const cacheFS = {[path]: testSource}; setGlobal(environment.global, 'console', testConsole); - runtime = new Runtime(config, environment, resolver, cacheFS, { - changedFiles: context && context.changedFiles, + const runtime = new Runtime(config, environment, resolver, cacheFS, { + changedFiles: context?.changedFiles, collectCoverage: globalConfig.collectCoverage, collectCoverageFrom: globalConfig.collectCoverageFrom, collectCoverageOnlyFrom: globalConfig.collectCoverageOnlyFrom, coverageProvider: globalConfig.coverageProvider, + sourcesRelatedToTestsInChangedFiles: + context?.sourcesRelatedToTestsInChangedFiles, }); const start = Date.now(); - config.setupFiles.forEach(path => runtime!.requireModule(path)); + for (const path of config.setupFiles) { + const esm = runtime.unstable_shouldLoadAsEsm(path); + + if (esm) { + await runtime.unstable_importModule(path); + } else { + runtime.requireModule(path); + } + } const sourcemapOptions: sourcemapSupport.Options = { environment: 'node', handleUncaughtExceptions: false, retrieveSourceMap: source => { - const sourceMaps = runtime && runtime.getSourceMaps(); + const sourceMaps = runtime.getSourceMaps(); const sourceMapSource = sourceMaps && sourceMaps[source]; if (sourceMapSource) { @@ -274,7 +277,6 @@ async function runTestInternal( const coverageKeys = Object.keys(coverage); if (coverageKeys.length) { result.coverage = coverage; - result.sourceMaps = runtime.getSourceMapInfo(new Set(coverageKeys)); } } diff --git a/packages/jest-runner/src/types.ts b/packages/jest-runner/src/types.ts index 08525df5e514..4862c886ce86 100644 --- a/packages/jest-runner/src/types.ts +++ b/packages/jest-runner/src/types.ts @@ -51,6 +51,7 @@ export type TestRunnerOptions = { export type TestRunnerContext = { changedFiles?: Set; + sourcesRelatedToTestsInChangedFiles?: Set; }; export type TestRunnerSerializedContext = { @@ -63,7 +64,6 @@ export type WatcherState = { }; export interface TestWatcher extends EventEmitter { state: WatcherState; - new ({isWatchMode}: {isWatchMode: boolean}): TestWatcher; setState(state: WatcherState): void; isInterrupted(): boolean; isWatchMode(): boolean; diff --git a/packages/jest-runtime/package.json b/packages/jest-runtime/package.json index 822778a4f389..856194f2d8fc 100644 --- a/packages/jest-runtime/package.json +++ b/packages/jest-runtime/package.json @@ -1,6 +1,6 @@ { "name": "jest-runtime", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,28 +17,28 @@ } }, "dependencies": { - "@jest/console": "^25.3.0", - "@jest/environment": "^25.3.0", - "@jest/globals": "^25.3.0", + "@jest/console": "^25.4.0", + "@jest/environment": "^25.4.0", + "@jest/globals": "^25.4.0", "@jest/source-map": "^25.2.6", - "@jest/test-result": "^25.3.0", - "@jest/transform": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/test-result": "^25.4.0", + "@jest/transform": "^25.4.0", + "@jest/types": "^25.4.0", "@types/yargs": "^15.0.0", "chalk": "^3.0.0", "collect-v8-coverage": "^1.0.0", "exit": "^0.1.2", "glob": "^7.1.3", "graceful-fs": "^4.2.3", - "jest-config": "^25.3.0", - "jest-haste-map": "^25.3.0", - "jest-message-util": "^25.3.0", - "jest-mock": "^25.3.0", + "jest-config": "^25.4.0", + "jest-haste-map": "^25.4.0", + "jest-message-util": "^25.4.0", + "jest-mock": "^25.4.0", "jest-regex-util": "^25.2.6", - "jest-resolve": "^25.3.0", - "jest-snapshot": "^25.3.0", - "jest-util": "^25.3.0", - "jest-validate": "^25.3.0", + "jest-resolve": "^25.4.0", + "jest-snapshot": "^25.4.0", + "jest-util": "^25.4.0", + "jest-validate": "^25.4.0", "realpath-native": "^2.0.0", "slash": "^3.0.0", "strip-bom": "^4.0.0", @@ -50,7 +50,7 @@ "@types/glob": "^7.1.1", "@types/graceful-fs": "^4.1.2", "execa": "^3.2.0", - "jest-environment-node": "^25.3.0", + "jest-environment-node": "^25.4.0", "jest-snapshot-serializer-raw": "^1.1.0" }, "bin": "./bin/jest-runtime.js", diff --git a/packages/jest-runtime/src/__mocks__/createRuntime.js b/packages/jest-runtime/src/__mocks__/createRuntime.js index 1efc081eabfa..1512da0cb3eb 100644 --- a/packages/jest-runtime/src/__mocks__/createRuntime.js +++ b/packages/jest-runtime/src/__mocks__/createRuntime.js @@ -49,7 +49,15 @@ module.exports = async function createRuntime(filename, config) { Runtime.createResolver(config, hasteMap.moduleMap), ); - config.setupFiles.forEach(path => runtime.requireModule(path)); + for (const path of config.setupFiles) { + const esm = runtime.unstable_shouldLoadAsEsm(path); + + if (esm) { + await runtime.unstable_importModule(path); + } else { + runtime.requireModule(path); + } + } runtime.__mockRootPath = path.join(config.rootDir, 'root.js'); runtime.__mockSubdirPath = path.join( diff --git a/packages/jest-runtime/src/__tests__/runtime_require_cache.test.js b/packages/jest-runtime/src/__tests__/runtime_require_cache.test.js new file mode 100644 index 000000000000..aab7ebdea903 --- /dev/null +++ b/packages/jest-runtime/src/__tests__/runtime_require_cache.test.js @@ -0,0 +1,46 @@ +/** + * Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + * + */ + +'use strict'; + +let createRuntime; + +describe('Runtime require.cache', () => { + beforeEach(() => { + createRuntime = require('createRuntime'); + }); + + it('require.cache returns loaded module list as native Nodejs require does', () => + createRuntime(__filename).then(runtime => { + const regularModule = runtime.requireModule( + runtime.__mockRootPath, + 'RegularModule', + ).module; + const id = regularModule.id; + const cache = regularModule.require.cache; + + expect(cache[id]).toBe(regularModule); + expect(id in cache).toBeTruthy(); + expect(Object.keys(cache).includes(id)).toBeTruthy(); + expect(Object.getOwnPropertyNames(cache).includes(id)).toBeTruthy(); + })); + + it('require.cache is tolerant readonly', () => + createRuntime(__filename).then(runtime => { + const regularModule = runtime.requireModule( + runtime.__mockRootPath, + 'RegularModule', + ).module; + + delete regularModule.require.cache[regularModule.id]; + expect(regularModule.require.cache[regularModule.id]).toBe(regularModule); + + regularModule.require.cache[regularModule.id] = 'something'; + expect(regularModule.require.cache[regularModule.id]).toBe(regularModule); + })); +}); diff --git a/packages/jest-runtime/src/cli/index.ts b/packages/jest-runtime/src/cli/index.ts index e7c8e1dd3750..54857611e5c2 100644 --- a/packages/jest-runtime/src/cli/index.ts +++ b/packages/jest-runtime/src/cli/index.ts @@ -93,9 +93,22 @@ export async function run( const runtime = new Runtime(config, environment, hasteMap.resolver); - config.setupFiles.forEach(path => runtime.requireModule(path)); + for (const path of config.setupFiles) { + const esm = runtime.unstable_shouldLoadAsEsm(path); - runtime.requireModule(filePath); + if (esm) { + await runtime.unstable_importModule(path); + } else { + runtime.requireModule(path); + } + } + const esm = runtime.unstable_shouldLoadAsEsm(filePath); + + if (esm) { + await runtime.unstable_importModule(filePath); + } else { + runtime.requireModule(filePath); + } } catch (e) { console.error(chalk.red(e.stack || e)); process.on('exit', () => (process.exitCode = 1)); diff --git a/packages/jest-runtime/src/index.ts b/packages/jest-runtime/src/index.ts index d80cfd780b8e..ecb2d25f3ef8 100644 --- a/packages/jest-runtime/src/index.ts +++ b/packages/jest-runtime/src/index.ts @@ -5,9 +5,19 @@ * LICENSE file in the root directory of this source tree. */ -import {URL, fileURLToPath} from 'url'; +import {URL, fileURLToPath, pathToFileURL} from 'url'; import * as path from 'path'; -import {Script, compileFunction} from 'vm'; +import { + Script, + // @ts-ignore: experimental, not added to the types + SourceTextModule, + // @ts-ignore: experimental, not added to the types + SyntheticModule, + Context as VMContext, + // @ts-ignore: experimental, not added to the types + Module as VMModule, + compileFunction, +} from 'vm'; import * as nativeModule from 'module'; import type {Config, Global} from '@jest/types'; import type { @@ -76,6 +86,8 @@ type ResolveOptions = Parameters[1]; type BooleanObject = Record; type CacheFS = {[path: string]: string}; +type RequireCache = {[key: string]: Module}; + namespace Runtime { export type Context = JestContext; // ditch this export when moving to esm - for now we need it for to avoid faulty type elision @@ -106,6 +118,8 @@ const EVAL_RESULT_VARIABLE = 'Object.'; type RunScriptEvalResult = {[EVAL_RESULT_VARIABLE]: ModuleWrapper}; +const runtimeSupportsVmModules = typeof SyntheticModule === 'function'; + /* eslint-disable-next-line no-redeclare */ class Runtime { private _cacheFS: CacheFS; @@ -125,7 +139,7 @@ class Runtime { private _moduleMocker: typeof jestMock; private _isolatedModuleRegistry: ModuleRegistry | null; private _moduleRegistry: ModuleRegistry; - private _needsCoverageMapped: Set; + private _esmoduleRegistry: Map>; private _resolver: Resolver; private _shouldAutoMock: boolean; private _shouldMockModuleCache: BooleanObject; @@ -140,6 +154,7 @@ class Runtime { private _virtualMocks: BooleanObject; private _moduleImplementation?: typeof nativeModule.Module; private jestObjectCaches: Map; + private _hasWarnedAboutRequireCacheModification = false; constructor( config: Config.ProjectConfig, @@ -156,6 +171,7 @@ class Runtime { collectCoverageFrom: [], collectCoverageOnlyFrom: undefined, coverageProvider: 'babel', + sourcesRelatedToTestsInChangedFiles: undefined, }; this._currentlyExecutingModulePath = ''; this._environment = environment; @@ -169,7 +185,7 @@ class Runtime { this._isolatedModuleRegistry = null; this._isolatedMockRegistry = null; this._moduleRegistry = new Map(); - this._needsCoverageMapped = new Set(); + this._esmoduleRegistry = new Map(); this._resolver = resolver; this._scriptTransformer = new ScriptTransformer(config); this._shouldAutoMock = config.automock; @@ -302,6 +318,140 @@ class Runtime { return cliOptions; } + // unstable as it should be replaced by https://github.com/nodejs/modules/issues/393, and we don't want people to use it + unstable_shouldLoadAsEsm = Resolver.unstable_shouldLoadAsEsm; + + private async loadEsmModule( + modulePath: Config.Path, + query = '', + ): Promise { + const cacheKey = modulePath + query; + + if (!this._esmoduleRegistry.has(cacheKey)) { + invariant( + typeof this._environment.getVmContext === 'function', + 'ES Modules are only supported if your test environment has the `getVmContext` function', + ); + + const context = this._environment.getVmContext(); + + invariant(context); + + if (this._resolver.isCoreModule(modulePath)) { + const core = await this._importCoreModule(modulePath, context); + this._esmoduleRegistry.set(cacheKey, core); + return core; + } + + const transformedFile = this.transformFile(modulePath, { + isInternalModule: false, + supportsDynamicImport: true, + supportsStaticESM: true, + }); + + const module = new SourceTextModule(transformedFile.code, { + context, + identifier: modulePath, + importModuleDynamically: this.linkModules.bind(this), + initializeImportMeta(meta: ImportMeta) { + meta.url = pathToFileURL(modulePath).href; + }, + }); + + this._esmoduleRegistry.set( + cacheKey, + // we wanna put the linking promise in the cache so modules loaded in + // parallel can all await it. We then await it synchronously below, so + // we shouldn't get any unhandled rejections + module + .link(this.linkModules.bind(this)) + .then(() => module.evaluate()) + .then(() => module), + ); + } + + const module = this._esmoduleRegistry.get(cacheKey); + + invariant(module); + + return module; + } + + private linkModules(specifier: string, referencingModule: VMModule) { + if (specifier === '@jest/globals') { + const fromCache = this._esmoduleRegistry.get('@jest/globals'); + + if (fromCache) { + return fromCache; + } + const globals = this.getGlobalsForEsm( + referencingModule.identifier, + referencingModule.context, + ); + this._esmoduleRegistry.set('@jest/globals', globals); + + return globals; + } + + const resolved = this._resolveModule( + referencingModule.identifier, + specifier, + ); + + if ( + this._resolver.isCoreModule(resolved) || + this.unstable_shouldLoadAsEsm(resolved) + ) { + return this.loadEsmModule(resolved); + } + + return this.loadCjsAsEsm( + referencingModule.identifier, + resolved, + referencingModule.context, + ); + } + + async unstable_importModule( + from: Config.Path, + moduleName?: string, + ): Promise { + invariant( + runtimeSupportsVmModules, + 'You need to run with a version of node that supports ES Modules in the VM API.', + ); + + const modulePath = this._resolveModule(from, moduleName); + + return this.loadEsmModule(modulePath); + } + + private async loadCjsAsEsm( + from: Config.Path, + modulePath: Config.Path, + context: VMContext, + ) { + // CJS loaded via `import` should share cache with other CJS: https://github.com/nodejs/modules/issues/503 + const cjs = this.requireModuleOrMock(from, modulePath); + + const module = new SyntheticModule( + ['default'], + function () { + // @ts-ignore: TS doesn't know what `this` is + this.setExport('default', cjs); + }, + {context, identifier: modulePath}, + ); + + await module.link(() => { + throw new Error('This should never happen'); + }); + + await module.evaluate(); + + return module; + } + requireModule( from: Config.Path, moduleName?: string, @@ -331,11 +481,6 @@ class Runtime { modulePath = manualMock; } - if (moduleName === '@jest/globals') { - // @ts-ignore: we don't care that it's not assignable to T - return this.getGlobalsForFile(from); - } - if (moduleName && this._resolver.isCoreModule(moduleName)) { return this._requireCoreModule(moduleName); } @@ -526,12 +671,18 @@ class Runtime { }; } - requireModuleOrMock(from: Config.Path, moduleName: string): unknown { + requireModuleOrMock(from: Config.Path, moduleName: string): T { + // this module is unmockable + if (moduleName === '@jest/globals') { + // @ts-ignore: we don't care that it's not assignable to T + return this.getGlobalsForCjs(from); + } + try { if (this._shouldMock(from, moduleName)) { - return this.requireMock(from, moduleName); + return this.requireMock(from, moduleName); } else { - return this.requireModule(from, moduleName); + return this.requireModule(from, moduleName); } } catch (e) { const moduleNotFound = Resolver.tryCastModuleNotFoundError(e); @@ -577,6 +728,7 @@ class Runtime { this._isolatedMockRegistry = null; this._mockRegistry.clear(); this._moduleRegistry.clear(); + this._esmoduleRegistry.clear(); if (this._environment) { if (this._environment.global) { @@ -641,20 +793,9 @@ class Runtime { }); } - getSourceMapInfo(coveredFiles: Set): Record { - return Object.keys(this._sourceMapRegistry).reduce>( - (result, sourcePath) => { - if ( - coveredFiles.has(sourcePath) && - this._needsCoverageMapped.has(sourcePath) && - fs.existsSync(this._sourceMapRegistry[sourcePath]) - ) { - result[sourcePath] = this._sourceMapRegistry[sourcePath]; - } - return result; - }, - {}, - ); + // TODO - remove in Jest 26 + getSourceMapInfo(_coveredFiles: Set): Record { + return {}; } getSourceMaps(): SourceMapRegistry { @@ -795,23 +936,8 @@ class Runtime { Object.defineProperty(localModule, 'require', { value: this._createRequireImplementation(localModule, options), }); - const transformedFile = this._scriptTransformer.transform( - filename, - this._getFullTransformationOptions(options), - this._cacheFS[filename], - ); - // we only care about non-internal modules - if (!options || !options.isInternalModule) { - this._fileTransforms.set(filename, transformedFile); - } - - if (transformedFile.sourceMapPath) { - this._sourceMapRegistry[filename] = transformedFile.sourceMapPath; - if (transformedFile.mapCoverage) { - this._needsCoverageMapped.add(filename); - } - } + const transformedFile = this.transformFile(filename, options); let compiledFunction: ModuleWrapper | null = null; @@ -872,10 +998,7 @@ class Runtime { return; } - const jestObject = this._createJestObjectFor( - filename, - localModule.require as LocalModuleRequire, - ); + const jestObject = this._createJestObjectFor(filename); this.jestObjectCaches.set(filename, jestObject); @@ -907,6 +1030,24 @@ class Runtime { this._currentlyExecutingModulePath = lastExecutingModulePath; } + private transformFile(filename: string, options?: InternalModuleOptions) { + const transformedFile = this._scriptTransformer.transform( + filename, + this._getFullTransformationOptions(options), + this._cacheFS[filename], + ); + + // we only care about non-internal modules + if (!options || !options.isInternalModule) { + this._fileTransforms.set(filename, transformedFile); + } + + if (transformedFile.sourceMapPath) { + this._sourceMapRegistry[filename] = transformedFile.sourceMapPath; + } + return transformedFile; + } + private createScriptFromCode(scriptSource: string, filename: string) { try { return new Script(this.wrapCodeInModuleWrapper(scriptSource), { @@ -932,6 +1073,24 @@ class Runtime { return require(moduleName); } + private _importCoreModule(moduleName: string, context: VMContext) { + const required = this._requireCoreModule(moduleName); + + return new SyntheticModule( + ['default', ...Object.keys(required)], + function () { + // @ts-ignore: TS doesn't know what `this` is + this.setExport('default', required); + Object.entries(required).forEach(([key, value]) => { + // @ts-ignore: TS doesn't know what `this` is + this.setExport(key, value); + }); + }, + // should identifier be `node://${moduleName}`? + {context, identifier: moduleName}, + ); + } + private _getMockedNativeModule(): typeof nativeModule.Module { if (this._moduleImplementation) { return this._moduleImplementation; @@ -966,13 +1125,20 @@ class Runtime { // should we implement the class ourselves? class Module extends nativeModule.Module {} + Object.entries(nativeModule.Module).forEach(([key, value]) => { + // @ts-ignore + Module[key] = value; + }); + Module.Module = Module; if ('createRequire' in nativeModule) { Module.createRequire = createRequire; } if ('createRequireFromPath' in nativeModule) { - Module.createRequireFromPath = (filename: string | URL) => { + Module.createRequireFromPath = function createRequireFromPath( + filename: string | URL, + ) { if (typeof filename !== 'string') { const error = new TypeError( `The argument 'filename' must be string. Received '${filename}'.${ @@ -989,7 +1155,7 @@ class Runtime { }; } if ('syncBuiltinESMExports' in nativeModule) { - Module.syncBuiltinESMExports = () => {}; + Module.syncBuiltinESMExports = function syncBuiltinESMExports() {}; } this._moduleImplementation = Module; @@ -1116,11 +1282,38 @@ class Runtime { this, from.filename, )) as LocalModuleRequire; - moduleRequire.cache = Object.create(null); moduleRequire.extensions = Object.create(null); moduleRequire.requireActual = this.requireActual.bind(this, from.filename); moduleRequire.requireMock = this.requireMock.bind(this, from.filename); moduleRequire.resolve = resolve; + moduleRequire.cache = (() => { + const notPermittedMethod = () => { + if (!this._hasWarnedAboutRequireCacheModification) { + this._environment.global.console.warn( + '`require.cache` modification is not permitted', + ); + + this._hasWarnedAboutRequireCacheModification = true; + } + return true; + }; + return new Proxy(Object.create(null), { + defineProperty: notPermittedMethod, + deleteProperty: notPermittedMethod, + get: (_target, key) => + typeof key === 'string' ? this._moduleRegistry.get(key) : undefined, + getOwnPropertyDescriptor() { + return { + configurable: true, + enumerable: true, + }; + }, + has: (_target, key) => + typeof key === 'string' && this._moduleRegistry.has(key), + ownKeys: () => Array.from(this._moduleRegistry.keys()), + set: notPermittedMethod, + }); + })(); Object.defineProperty(moduleRequire, 'main', { enumerable: true, @@ -1139,10 +1332,7 @@ class Runtime { return moduleRequire; } - private _createJestObjectFor( - from: Config.Path, - localRequire: LocalModuleRequire, - ): Jest { + private _createJestObjectFor(from: Config.Path): Jest { const disableAutomock = () => { this._shouldAutoMock = false; return jestObject; @@ -1273,8 +1463,8 @@ class Runtime { isMockFunction: this._moduleMocker.isMockFunction, isolateModules, mock, - requireActual: localRequire.requireActual, - requireMock: localRequire.requireMock, + requireActual: this.requireActual.bind(this, from), + requireMock: this.requireMock.bind(this, from), resetAllMocks, resetModuleRegistry: resetModules, resetModules, @@ -1355,11 +1545,52 @@ class Runtime { throw e; } - private getGlobalsForFile(from: Config.Path): JestGlobalsValues { + private getGlobalsForCjs(from: Config.Path): JestGlobalsValues { const jest = this.jestObjectCaches.get(from); invariant(jest, 'There should always be a Jest object already'); + return {...this.getGlobalsFromEnvironment(), jest}; + } + + private async getGlobalsForEsm( + from: Config.Path, + context: VMContext, + ): Promise { + let jest = this.jestObjectCaches.get(from); + + if (!jest) { + jest = this._createJestObjectFor(from); + + this.jestObjectCaches.set(from, jest); + } + + const globals: JestGlobalsValues = { + ...this.getGlobalsFromEnvironment(), + jest, + }; + + const module = new SyntheticModule( + Object.keys(globals), + function () { + Object.entries(globals).forEach(([key, value]) => { + // @ts-ignore: TS doesn't know what `this` is + this.setExport(key, value); + }); + }, + {context, identifier: '@jest/globals'}, + ); + + await module.link(() => { + throw new Error('This should never happen'); + }); + + await module.evaluate(); + + return module; + } + + private getGlobalsFromEnvironment(): Omit { return { afterAll: this._environment.global.afterAll, afterEach: this._environment.global.afterEach, @@ -1370,7 +1601,6 @@ class Runtime { fdescribe: this._environment.global.fdescribe, fit: this._environment.global.fit, it: this._environment.global.it, - jest, test: this._environment.global.test, xdescribe: this._environment.global.xdescribe, xit: this._environment.global.xit, diff --git a/packages/jest-snapshot/package.json b/packages/jest-snapshot/package.json index 9af818004476..6ccb0c1d0284 100644 --- a/packages/jest-snapshot/package.json +++ b/packages/jest-snapshot/package.json @@ -1,6 +1,6 @@ { "name": "jest-snapshot", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -22,19 +22,19 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.0.0", - "@jest/types": "^25.3.0", + "@jest/types": "^25.4.0", "@types/prettier": "^1.19.0", "babel-preset-current-node-syntax": "^0.1.2", "chalk": "^3.0.0", - "expect": "^25.3.0", - "jest-diff": "^25.3.0", + "expect": "^25.4.0", + "jest-diff": "^25.4.0", "jest-get-type": "^25.2.6", - "jest-matcher-utils": "^25.3.0", - "jest-message-util": "^25.3.0", - "jest-resolve": "^25.3.0", + "jest-matcher-utils": "^25.4.0", + "jest-message-util": "^25.4.0", + "jest-resolve": "^25.4.0", "make-dir": "^3.0.0", "natural-compare": "^1.4.0", - "pretty-format": "^25.3.0", + "pretty-format": "^25.4.0", "semver": "^6.3.0" }, "devDependencies": { @@ -45,7 +45,7 @@ "@types/semver": "^6.0.1", "ansi-regex": "^5.0.0", "ansi-styles": "^4.2.0", - "jest-haste-map": "^25.3.0", + "jest-haste-map": "^25.4.0", "prettier": "^1.13.4" }, "peerDependencies": { diff --git a/packages/jest-test-result/package.json b/packages/jest-test-result/package.json index 5d134ded7850..fba5b4302545 100644 --- a/packages/jest-test-result/package.json +++ b/packages/jest-test-result/package.json @@ -1,6 +1,6 @@ { "name": "@jest/test-result", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,8 +17,8 @@ } }, "dependencies": { - "@jest/console": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/console": "^25.4.0", + "@jest/types": "^25.4.0", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, diff --git a/packages/jest-test-result/src/types.ts b/packages/jest-test-result/src/types.ts index 304b358c143b..ffd9c23735b6 100644 --- a/packages/jest-test-result/src/types.ts +++ b/packages/jest-test-result/src/types.ts @@ -104,6 +104,7 @@ export type TestResult = { unmatched: number; updated: number; }; + // TODO - Remove in Jest 26 sourceMaps?: { [sourcePath: string]: string; }; diff --git a/packages/jest-test-sequencer/package.json b/packages/jest-test-sequencer/package.json index eef6f9a201a5..167fe0758485 100644 --- a/packages/jest-test-sequencer/package.json +++ b/packages/jest-test-sequencer/package.json @@ -1,6 +1,6 @@ { "name": "@jest/test-sequencer", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,10 +17,10 @@ } }, "dependencies": { - "@jest/test-result": "^25.3.0", - "jest-haste-map": "^25.3.0", - "jest-runner": "^25.3.0", - "jest-runtime": "^25.3.0" + "@jest/test-result": "^25.4.0", + "jest-haste-map": "^25.4.0", + "jest-runner": "^25.4.0", + "jest-runtime": "^25.4.0" }, "engines": { "node": ">= 8.3" diff --git a/packages/jest-transform/package.json b/packages/jest-transform/package.json index d64a6809ed03..d3e250138097 100644 --- a/packages/jest-transform/package.json +++ b/packages/jest-transform/package.json @@ -1,6 +1,6 @@ { "name": "@jest/transform", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -18,15 +18,15 @@ }, "dependencies": { "@babel/core": "^7.1.0", - "@jest/types": "^25.3.0", + "@jest/types": "^25.4.0", "babel-plugin-istanbul": "^6.0.0", "chalk": "^3.0.0", "convert-source-map": "^1.4.0", "fast-json-stable-stringify": "^2.0.0", "graceful-fs": "^4.2.3", - "jest-haste-map": "^25.3.0", + "jest-haste-map": "^25.4.0", "jest-regex-util": "^25.2.6", - "jest-util": "^25.3.0", + "jest-util": "^25.4.0", "micromatch": "^4.0.2", "pirates": "^4.0.1", "realpath-native": "^2.0.0", diff --git a/packages/jest-transform/src/ScriptTransformer.ts b/packages/jest-transform/src/ScriptTransformer.ts index 1ad4109cd83a..46ae3afb049f 100644 --- a/packages/jest-transform/src/ScriptTransformer.ts +++ b/packages/jest-transform/src/ScriptTransformer.ts @@ -205,11 +205,15 @@ export default class ScriptTransformer { private _instrumentFile( filename: Config.Path, - content: string, + input: TransformedSource, supportsDynamicImport: boolean, supportsStaticESM: boolean, - ): string { - const result = babelTransform(content, { + canMapToInput: boolean, + ): TransformedSource { + const inputCode = typeof input === 'string' ? input : input.code; + const inputMap = typeof input === 'string' ? null : input.map; + + const result = babelTransform(inputCode, { auxiliaryCommentBefore: ' istanbul ignore next ', babelrc: false, caller: { @@ -228,21 +232,19 @@ export default class ScriptTransformer { cwd: this._config.rootDir, exclude: [], extension: false, + inputSourceMap: inputMap, useInlineSourceMaps: false, }, ], ], + sourceMaps: canMapToInput ? 'both' : false, }); - if (result) { - const {code} = result; - - if (code) { - return code; - } + if (result && result.code) { + return result as TransformResult; } - return content; + return input; } private _getRealPath(filepath: Config.Path): Config.Path { @@ -287,10 +289,6 @@ export default class ScriptTransformer { const transformWillInstrument = shouldCallTransform && transform && transform.canInstrument; - // If we handle the coverage instrumentation, we should try to map code - // coverage against original source with any provided source map - const mapCoverage = instrument && !transformWillInstrument; - if (code) { // This is broken: we return the code, and a path for the source map // directly from the cache. But, nothing ensures the source map actually @@ -298,7 +296,6 @@ export default class ScriptTransformer { // two separate processes write concurrently to the same cache files. return { code, - mapCoverage, originalCode: content, sourceMapPath, }; @@ -333,9 +330,8 @@ export default class ScriptTransformer { //Could be a potential freeze here. //See: https://github.com/facebook/jest/pull/5177#discussion_r158883570 const inlineSourceMap = sourcemapFromSource(transformed.code); - if (inlineSourceMap) { - transformed.map = inlineSourceMap.toJSON(); + transformed.map = inlineSourceMap.toObject(); } } catch (e) { const transformPath = this._getTransformPath(filename); @@ -347,22 +343,39 @@ export default class ScriptTransformer { } } + // Apply instrumentation to the code if necessary, keeping the instrumented code and new map + let map = transformed.map; if (!transformWillInstrument && instrument) { - code = this._instrumentFile( + /** + * We can map the original source code to the instrumented code ONLY if + * - the process of transforming the code produced a source map e.g. ts-jest + * - we did not transform the source code + * + * Otherwise we cannot make any statements about how the instrumented code corresponds to the original code, + * and we should NOT emit any source maps + * + */ + const shouldEmitSourceMaps = + (transform != null && map != null) || transform == null; + + const instrumented = this._instrumentFile( filename, - transformed.code, + transformed, supportsDynamicImport, supportsStaticESM, + shouldEmitSourceMaps, ); + + code = + typeof instrumented === 'string' ? instrumented : instrumented.code; + map = typeof instrumented === 'string' ? null : instrumented.map; } else { code = transformed.code; } - if (transformed.map) { + if (map) { const sourceMapContent = - typeof transformed.map === 'string' - ? transformed.map - : JSON.stringify(transformed.map); + typeof map === 'string' ? map : JSON.stringify(map); writeCacheFile(sourceMapPath, sourceMapContent); } else { sourceMapPath = null; @@ -372,7 +385,6 @@ export default class ScriptTransformer { return { code, - mapCoverage, originalCode: content, sourceMapPath, }; @@ -396,7 +408,6 @@ export default class ScriptTransformer { let code = content; let sourceMapPath: string | null = null; - let mapCoverage = false; const willTransform = !isInternalModule && @@ -415,12 +426,10 @@ export default class ScriptTransformer { code = transformedSource.code; sourceMapPath = transformedSource.sourceMapPath; - mapCoverage = transformedSource.mapCoverage; } return { code, - mapCoverage, originalCode: content, sourceMapPath, }; diff --git a/packages/jest-transform/src/__tests__/__snapshots__/script_transformer.test.js.snap b/packages/jest-transform/src/__tests__/__snapshots__/script_transformer.test.js.snap index 19c563f8e376..13584d3f6693 100644 --- a/packages/jest-transform/src/__tests__/__snapshots__/script_transformer.test.js.snap +++ b/packages/jest-transform/src/__tests__/__snapshots__/script_transformer.test.js.snap @@ -80,7 +80,7 @@ exports[`ScriptTransformer transforms a file properly 1`] = ` /* istanbul ignore next */ function cov_25u22311x4() { var path = "/fruits/banana.js"; - var hash = "4be0f6184160be573fc43f7c2a5877c28b7ce249"; + var hash = "3f8e915bed83285455a8a16aa04dc0cf5242d755"; var global = new Function("return this")(); var gcv = "__coverage__"; var coverageData = { @@ -104,8 +104,9 @@ function cov_25u22311x4() { }, f: {}, b: {}, + inputSourceMap: null, _coverageSchema: "1a1c01bbd47fc00a2c39e90264f33305004495a9", - hash: "4be0f6184160be573fc43f7c2a5877c28b7ce249" + hash: "3f8e915bed83285455a8a16aa04dc0cf5242d755" }; var coverage = global[gcv] || (global[gcv] = {}); @@ -125,13 +126,14 @@ function cov_25u22311x4() { cov_25u22311x4(); cov_25u22311x4().s[0]++; module.exports = "banana"; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImJhbmFuYS5qcyJdLCJuYW1lcyI6WyJtb2R1bGUiLCJleHBvcnRzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQUEsTUFBTSxDQUFDQyxPQUFQLEdBQWlCLFFBQWpCIiwic291cmNlc0NvbnRlbnQiOlsibW9kdWxlLmV4cG9ydHMgPSBcImJhbmFuYVwiOyJdfQ== `; exports[`ScriptTransformer transforms a file properly 2`] = ` /* istanbul ignore next */ function cov_23yvu8etmu() { var path = "/fruits/kiwi.js"; - var hash = "7705dd5fcfbc884dcea7062944cfb8cc5d141d1a"; + var hash = "8b5afd38d79008f13ebc229b89ef82b12ee9447a"; var global = new Function("return this")(); var gcv = "__coverage__"; var coverageData = { @@ -193,8 +195,9 @@ function cov_23yvu8etmu() { "0": 0 }, b: {}, + inputSourceMap: null, _coverageSchema: "1a1c01bbd47fc00a2c39e90264f33305004495a9", - hash: "7705dd5fcfbc884dcea7062944cfb8cc5d141d1a" + hash: "8b5afd38d79008f13ebc229b89ef82b12ee9447a" }; var coverage = global[gcv] || (global[gcv] = {}); @@ -220,6 +223,7 @@ module.exports = () => { cov_23yvu8etmu().s[1]++; return "kiwi"; }; +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImtpd2kuanMiXSwibmFtZXMiOlsibW9kdWxlIiwiZXhwb3J0cyJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQUFBLE1BQU0sQ0FBQ0MsT0FBUCxHQUFpQixNQUFNO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBTSxDQUE3QiIsInNvdXJjZXNDb250ZW50IjpbIm1vZHVsZS5leHBvcnRzID0gKCkgPT4gXCJraXdpXCI7Il19 `; exports[`ScriptTransformer uses multiple preprocessors 1`] = ` diff --git a/packages/jest-transform/src/__tests__/script_transformer.test.js b/packages/jest-transform/src/__tests__/script_transformer.test.js index 9069861c2420..b6570ee1c404 100644 --- a/packages/jest-transform/src/__tests__/script_transformer.test.js +++ b/packages/jest-transform/src/__tests__/script_transformer.test.js @@ -535,6 +535,90 @@ describe('ScriptTransformer', () => { expect(writeFileAtomic.sync).toHaveBeenCalledTimes(1); }); + it('should write a source map for the instrumented file when transformed', () => { + const transformerConfig = { + ...config, + transform: [['^.+\\.js$', 'preprocessor-with-sourcemaps']], + }; + const scriptTransformer = new ScriptTransformer(transformerConfig); + + const map = { + mappings: ';AAAA', + version: 3, + }; + + // A map from the original source to the instrumented output + /* eslint-disable sort-keys */ + const instrumentedCodeMap = { + version: 3, + sources: ['banana.js'], + names: ['content'], + mappings: ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAAA,OAAO', + sourcesContent: ['content'], + }; + /* eslint-enable */ + + require('preprocessor-with-sourcemaps').process.mockReturnValue({ + code: 'content', + map, + }); + + const result = scriptTransformer.transform( + '/fruits/banana.js', + makeGlobalConfig({ + collectCoverage: true, + }), + ); + expect(result.sourceMapPath).toEqual(expect.any(String)); + expect(writeFileAtomic.sync).toBeCalledTimes(2); + expect(writeFileAtomic.sync).toBeCalledWith( + result.sourceMapPath, + JSON.stringify(instrumentedCodeMap), + expect.anything(), + ); + + // Inline source map allows debugging of original source when running instrumented code + expect(result.code).toContain('//# sourceMappingURL'); + }); + + it('should write a source map for the instrumented file when not transformed', () => { + const scriptTransformer = new ScriptTransformer(config); + + // A map from the original source to the instrumented output + /* eslint-disable sort-keys */ + const instrumentedCodeMap = { + version: 3, + sources: ['banana.js'], + names: ['module', 'exports'], + mappings: + ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAAA,MAAM,CAACC,OAAP,GAAiB,QAAjB', + sourcesContent: ['module.exports = "banana";'], + }; + /* eslint-enable */ + + require('preprocessor-with-sourcemaps').process.mockReturnValue({ + code: 'content', + map: null, + }); + + const result = scriptTransformer.transform( + '/fruits/banana.js', + makeGlobalConfig({ + collectCoverage: true, + }), + ); + expect(result.sourceMapPath).toEqual(expect.any(String)); + expect(writeFileAtomic.sync).toBeCalledTimes(2); + expect(writeFileAtomic.sync).toBeCalledWith( + result.sourceMapPath, + JSON.stringify(instrumentedCodeMap), + expect.anything(), + ); + + // Inline source map allows debugging of original source when running instrumented code + expect(result.code).toContain('//# sourceMappingURL'); + }); + it('passes expected transform options to getCacheKey', () => { config = {...config, transform: [['^.+\\.js$', 'test_preprocessor']]}; const scriptTransformer = new ScriptTransformer(config); diff --git a/packages/jest-transform/src/shouldInstrument.ts b/packages/jest-transform/src/shouldInstrument.ts index e9d75afdbc63..d9fcdcd268c3 100644 --- a/packages/jest-transform/src/shouldInstrument.ts +++ b/packages/jest-transform/src/shouldInstrument.ts @@ -94,7 +94,12 @@ export default function shouldInstrument( } if (options.changedFiles && !options.changedFiles.has(filename)) { - return false; + if (!options.sourcesRelatedToTestsInChangedFiles) { + return false; + } + if (!options.sourcesRelatedToTestsInChangedFiles.has(filename)) { + return false; + } } return true; diff --git a/packages/jest-transform/src/types.ts b/packages/jest-transform/src/types.ts index 30075298bc26..b984980e1112 100644 --- a/packages/jest-transform/src/types.ts +++ b/packages/jest-transform/src/types.ts @@ -16,6 +16,7 @@ export type ShouldInstrumentOptions = Pick< | 'coverageProvider' > & { changedFiles?: Set; + sourcesRelatedToTestsInChangedFiles?: Set; }; export type Options = ShouldInstrumentOptions & @@ -34,6 +35,7 @@ interface FixedRawSourceMap extends SourceMapWithVersion { version: number; } +// TODO: For Jest 26 normalize this (always structured data, never a string) export type TransformedSource = | {code: string; map?: FixedRawSourceMap | string | null} | string; diff --git a/packages/jest-types/package.json b/packages/jest-types/package.json index 496567c4a25b..d4f560e9b74c 100644 --- a/packages/jest-types/package.json +++ b/packages/jest-types/package.json @@ -1,6 +1,6 @@ { "name": "@jest/types", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest-types/src/Transform.ts b/packages/jest-types/src/Transform.ts index 9c59e7b34489..2e60af1e489d 100644 --- a/packages/jest-types/src/Transform.ts +++ b/packages/jest-types/src/Transform.ts @@ -9,6 +9,6 @@ export type TransformResult = { code: string; originalCode: string; - mapCoverage: boolean; + mapCoverage?: boolean; // TODO - Remove in Jest 26 sourceMapPath: string | null; }; diff --git a/packages/jest-util/package.json b/packages/jest-util/package.json index ee065c80c263..0123d0e4d56d 100644 --- a/packages/jest-util/package.json +++ b/packages/jest-util/package.json @@ -1,6 +1,6 @@ { "name": "jest-util", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,7 +17,7 @@ } }, "dependencies": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.4.0", "chalk": "^3.0.0", "is-ci": "^2.0.0", "make-dir": "^3.0.0" diff --git a/packages/jest-validate/package.json b/packages/jest-validate/package.json index 0eac7742571e..6c6b82dcab82 100644 --- a/packages/jest-validate/package.json +++ b/packages/jest-validate/package.json @@ -1,6 +1,6 @@ { "name": "jest-validate", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -17,12 +17,12 @@ } }, "dependencies": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.4.0", "camelcase": "^5.3.1", "chalk": "^3.0.0", "jest-get-type": "^25.2.6", "leven": "^3.1.0", - "pretty-format": "^25.3.0" + "pretty-format": "^25.4.0" }, "devDependencies": { "@types/yargs": "^15.0.3" diff --git a/packages/jest-watcher/package.json b/packages/jest-watcher/package.json index d34b8fb22268..c95a55f5eb91 100644 --- a/packages/jest-watcher/package.json +++ b/packages/jest-watcher/package.json @@ -1,7 +1,7 @@ { "name": "jest-watcher", "description": "Delightful JavaScript Testing.", - "version": "25.3.0", + "version": "25.4.0", "main": "build/index.js", "types": "build/index.d.ts", "typesVersions": { @@ -12,11 +12,11 @@ } }, "dependencies": { - "@jest/test-result": "^25.3.0", - "@jest/types": "^25.3.0", + "@jest/test-result": "^25.4.0", + "@jest/types": "^25.4.0", "ansi-escapes": "^4.2.1", "chalk": "^3.0.0", - "jest-util": "^25.3.0", + "jest-util": "^25.4.0", "string-length": "^3.1.0" }, "devDependencies": { diff --git a/packages/jest-worker/README.md b/packages/jest-worker/README.md index 6efbc0587387..efc91bb9a7cb 100644 --- a/packages/jest-worker/README.md +++ b/packages/jest-worker/README.md @@ -21,10 +21,10 @@ This example covers the minimal usage: ### File `parent.js` ```javascript -import Worker from 'jest-worker'; +import JestWorker from 'jest-worker'; async function main() { - const worker = new Worker(require.resolve('./Worker')); + const worker = new JestWorker(require.resolve('./Worker')); const result = await worker.hello('Alice'); // "Hello, Alice" } @@ -47,7 +47,7 @@ Since `worker_threads` are considered experimental in Node, you have to opt-in t ## API -The only exposed method is a constructor (`Worker`) that is initialized by passing the worker path, plus an options object. +The only exposed method is a constructor (`JestWorker`) that is initialized by passing the worker path, plus an options object. ### `workerPath: string` (required) @@ -93,11 +93,11 @@ The arguments that will be passed to the `setup` method during initialization. `jest-worker` will automatically detect if `worker_threads` are available, but will not use them unless passed `enableWorkerThreads: true`. -## Worker +## JestWorker ### Methods -The returned `Worker` instance has all the exposed methods, plus some additional ones to interact with the workers itself: +The returned `JestWorker` instance has all the exposed methods, plus some additional ones to interact with the workers itself: #### `getStdout(): Readable` @@ -139,10 +139,10 @@ This example covers the standard usage: ### File `parent.js` ```javascript -import Worker from 'jest-worker'; +import JestWorker from 'jest-worker'; async function main() { - const myWorker = new Worker(require.resolve('./Worker'), { + const myWorker = new JestWorker(require.resolve('./Worker'), { exposedMethods: ['foo', 'bar', 'getWorkerId'], numWorkers: 4, }); @@ -183,10 +183,10 @@ This example covers the usage with a `computeWorkerKey` method: ### File `parent.js` ```javascript -import Worker from 'jest-worker'; +import JestWorker from 'jest-worker'; async function main() { - const myWorker = new Worker(require.resolve('./Worker'), { + const myWorker = new JestWorker(require.resolve('./Worker'), { computeWorkerKey: (method, filename) => filename, }); diff --git a/packages/jest-worker/package.json b/packages/jest-worker/package.json index d07eca4ed821..ca26e4393389 100644 --- a/packages/jest-worker/package.json +++ b/packages/jest-worker/package.json @@ -1,6 +1,6 @@ { "name": "jest-worker", - "version": "25.2.6", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", diff --git a/packages/jest/package.json b/packages/jest/package.json index 4e263e72cc2a..cafa26011e5d 100644 --- a/packages/jest/package.json +++ b/packages/jest/package.json @@ -1,7 +1,7 @@ { "name": "jest", "description": "Delightful JavaScript Testing.", - "version": "25.3.0", + "version": "25.4.0", "main": "build/jest.js", "types": "build/jest.d.ts", "typesVersions": { @@ -12,9 +12,9 @@ } }, "dependencies": { - "@jest/core": "^25.3.0", + "@jest/core": "^25.4.0", "import-local": "^3.0.2", - "jest-cli": "^25.3.0" + "jest-cli": "^25.4.0" }, "bin": "./bin/jest.js", "engines": { diff --git a/packages/pretty-format/package.json b/packages/pretty-format/package.json index 1c7a3624b2b4..30f154979fdf 100644 --- a/packages/pretty-format/package.json +++ b/packages/pretty-format/package.json @@ -1,6 +1,6 @@ { "name": "pretty-format", - "version": "25.3.0", + "version": "25.4.0", "repository": { "type": "git", "url": "https://github.com/facebook/jest.git", @@ -20,7 +20,7 @@ "browser": "build-es5/index.js", "author": "James Kyle ", "dependencies": { - "@jest/types": "^25.3.0", + "@jest/types": "^25.4.0", "ansi-regex": "^5.0.0", "ansi-styles": "^4.0.0", "react-is": "^16.12.0" diff --git a/packages/test-utils/package.json b/packages/test-utils/package.json index 5bf8cb86877e..763858ae640b 100644 --- a/packages/test-utils/package.json +++ b/packages/test-utils/package.json @@ -19,5 +19,8 @@ "ansi-regex": "^5.0.0", "ansi-styles": "^4.1.0", "semver": "^6.3.0" + }, + "engines": { + "node": ">= 8.3" } } diff --git a/scripts/babel-plugin-jest-native-globals.js b/scripts/babel-plugin-jest-native-globals.js index c1e60921917a..148a8eeb22e3 100644 --- a/scripts/babel-plugin-jest-native-globals.js +++ b/scripts/babel-plugin-jest-native-globals.js @@ -70,7 +70,7 @@ module.exports = ({template}) => { path.node.name === 'fs' && path.parent.property && ['readFileSync', 'writeFileSync', 'existsSync'].includes( - path.parent.property.name + path.parent.property.name, ) ) { if ( diff --git a/scripts/babel-plugin-jest-replace-ts-require-assignment.js b/scripts/babel-plugin-jest-replace-ts-require-assignment.js index 72451255239b..aeb5ddd2aaf1 100644 --- a/scripts/babel-plugin-jest-replace-ts-require-assignment.js +++ b/scripts/babel-plugin-jest-replace-ts-require-assignment.js @@ -23,7 +23,7 @@ module.exports = ({template}) => { moduleExportsDeclaration({ IMPORT: node.moduleReference.expression, NAME: node.id, - }) + }), ); }, }, diff --git a/scripts/browserBuild.js b/scripts/browserBuild.js index a335d47ca206..4c3257380c71 100644 --- a/scripts/browserBuild.js +++ b/scripts/browserBuild.js @@ -62,7 +62,7 @@ function browserBuild(pkgName, entryPath, destination) { alias: { chalk: path.resolve( __dirname, - '../packages/expect/build/fakeChalk.js' + '../packages/expect/build/fakeChalk.js', ), }, extensions: ['.js', '.json', '.ts'], @@ -78,7 +78,7 @@ function browserBuild(pkgName, entryPath, destination) { return; } resolve(stats); - } + }, ); }); } diff --git a/scripts/build.js b/scripts/build.js index ff06ba44adf0..7c5e0f5c3ba7 100644 --- a/scripts/build.js +++ b/scripts/build.js @@ -84,7 +84,7 @@ function buildBrowserPackage(p) { if (browser) { if (browser.indexOf(BUILD_ES5_DIR) !== 0) { throw new Error( - `browser field for ${pkgJsonPath} should start with "${BUILD_ES5_DIR}"` + `browser field for ${pkgJsonPath} should start with "${BUILD_ES5_DIR}"`, ); } let indexFile = path.resolve(srcDir, 'index.js'); @@ -113,7 +113,7 @@ function buildFile(file, silent) { process.stdout.write( chalk.dim(' \u2022 ') + path.relative(PACKAGES_DIR, file) + - ' (ignore)\n' + ' (ignore)\n', ); return; } @@ -131,7 +131,7 @@ function buildFile(file, silent) { chalk.red(' \u21D2 ') + path.relative(PACKAGES_DIR, destPath) + ' (copy)' + - '\n' + '\n', ); } else { const options = Object.assign({}, transformOptions); @@ -141,7 +141,7 @@ function buildFile(file, silent) { // The modules in the blacklist are injected into the user's sandbox // We need to guard some globals there. options.plugins.push( - require.resolve('./babel-plugin-jest-native-globals') + require.resolve('./babel-plugin-jest-native-globals'), ); } else { options.plugins = options.plugins.map(plugin => { @@ -174,7 +174,7 @@ function buildFile(file, silent) { path.relative(PACKAGES_DIR, file) + chalk.green(' \u21D2 ') + path.relative(PACKAGES_DIR, destPath) + - '\n' + '\n', ); } } diff --git a/scripts/buildTs.js b/scripts/buildTs.js index cf734188267e..9f8ed9c3c7cb 100644 --- a/scripts/buildTs.js +++ b/scripts/buildTs.js @@ -7,38 +7,41 @@ 'use strict'; +const assert = require('assert'); const fs = require('fs'); const os = require('os'); const path = require('path'); +const util = require('util'); const chalk = require('chalk'); const execa = require('execa'); +const globby = require('globby'); const rimraf = require('rimraf'); const throat = require('throat'); const {getPackages} = require('./buildUtils'); +const readFilePromise = util.promisify(fs.readFile); + const packages = getPackages(); const packagesWithTs = packages.filter(p => - fs.existsSync(path.resolve(p, 'tsconfig.json')) + fs.existsSync(path.resolve(p, 'tsconfig.json')), ); packagesWithTs.forEach(pkgDir => { const pkg = require(pkgDir + '/package.json'); - if (!pkg.types) { - throw new Error(`Package ${pkg.name} is missing \`types\` field`); - } - - if (!pkg.typesVersions) { - throw new Error(`Package ${pkg.name} is missing \`typesVersions\` field`); - } + assert.ok(pkg.types, `Package ${pkg.name} is missing \`types\` field`); + assert.ok( + pkg.typesVersions, + `Package ${pkg.name} is missing \`typesVersions\` field`, + ); - if (pkg.main.replace(/\.js$/, '.d.ts') !== pkg.types) { - throw new Error( - `\`main\` and \`types\` field of ${pkg.name} does not match` - ); - } + assert.equal( + pkg.types, + pkg.main.replace(/\.js$/, '.d.ts'), + `\`main\` and \`types\` field of ${pkg.name} does not match`, + ); }); const args = [ @@ -54,44 +57,87 @@ console.log(chalk.inverse(' Building TypeScript definition files ')); try { execa.sync('yarn', args, {stdio: 'inherit'}); console.log( - chalk.inverse.green(' Successfully built TypeScript definition files ') + chalk.inverse.green(' Successfully built TypeScript definition files '), ); } catch (e) { console.error( - chalk.inverse.red(' Unable to build TypeScript definition files ') + chalk.inverse.red(' Unable to build TypeScript definition files '), ); console.error(e.stack); process.exitCode = 1; return; } -const downlevelArgs = ['--silent', 'downlevel-dts', 'build', 'build/ts3.4']; - -console.log(chalk.inverse(' Downleveling TypeScript definition files ')); - // we want to limit the number of processes we spawn const cpus = Math.max(1, os.cpus().length - 1); Promise.all( packagesWithTs.map( - throat(cpus, pkgDir => { - // otherwise we get nested `ts3.4` directories - rimraf.sync(path.resolve(pkgDir, 'build/ts3.4')); - - return execa('yarn', downlevelArgs, {cwd: pkgDir, stdio: 'inherit'}); - }) - ) + throat(cpus, async pkgDir => { + const buildDir = path.resolve(pkgDir, 'build/**/*.d.ts'); + const ts3dot4 = path.resolve(pkgDir, 'build/ts3.4'); + + const globbed = await globby([buildDir, `!${ts3dot4}`]); + + const files = await Promise.all( + globbed.map(file => Promise.all([file, readFilePromise(file, 'utf8')])), + ); + + const filesWithReferences = files + .filter(([, content]) => content.includes('/// [ + name, + content + .split('\n') + .filter(line => line !== '/// ') + .filter(line => line.includes('/// content.length > 0) + .filter(hit => hit.length > 0) + .map(([file, references]) => + chalk.red( + `${chalk.bold( + file, + )} has the following non-node type references:\n\n${references}\n`, + ), + ) + .join('\n\n'); + + if (filesWithReferences) { + console.error(filesWithReferences); + + process.exit(1); + } + }), + ), ) + .then(() => { + const downlevelArgs = ['--silent', 'downlevel-dts', 'build', 'build/ts3.4']; + + console.log(chalk.inverse(' Downleveling TypeScript definition files ')); + + return Promise.all( + packagesWithTs.map( + throat(cpus, pkgDir => { + // otherwise we get nested `ts3.4` directories + rimraf.sync(path.resolve(pkgDir, 'build/ts3.4')); + + return execa('yarn', downlevelArgs, {cwd: pkgDir, stdio: 'inherit'}); + }), + ), + ); + }) .then(() => { console.log( chalk.inverse.green( - ' Successfully downleveled TypeScript definition files ' - ) + ' Successfully downleveled TypeScript definition files ', + ), ); }) .catch(e => { console.error( - chalk.inverse.red(' Unable to downlevel TypeScript definition files ') + chalk.inverse.red(' Unable to downlevel TypeScript definition files '), ); console.error(e.stack); process.exitCode = 1; diff --git a/scripts/buildUtils.js b/scripts/buildUtils.js index 0e0775795cc4..90e9bb71bc4a 100644 --- a/scripts/buildUtils.js +++ b/scripts/buildUtils.js @@ -5,10 +5,14 @@ * LICENSE file in the root directory of this source tree. */ +'use strict'; + +const assert = require('assert'); const fs = require('fs'); const path = require('path'); const chalk = require('chalk'); const stringLength = require('string-length'); +const rootPackage = require('../package.json'); const PACKAGES_DIR = path.resolve(__dirname, '../packages'); @@ -16,10 +20,26 @@ const OK = chalk.reset.inverse.bold.green(' DONE '); // Get absolute paths of all directories under packages/* module.exports.getPackages = function getPackages() { - return fs + const packages = fs .readdirSync(PACKAGES_DIR) .map(file => path.resolve(PACKAGES_DIR, file)) .filter(f => fs.lstatSync(path.resolve(f)).isDirectory()); + + const nodeEngineRequiremnt = rootPackage.engines.node; + + packages.forEach(packageDir => { + const pkg = require(`${packageDir}/package.json`); + + assert.ok(pkg.engines, `Engine requirement in ${pkg.name} should exist`); + + assert.equal( + pkg.engines.node, + nodeEngineRequiremnt, + `Engine requirement in ${pkg.name} should match root`, + ); + }); + + return packages; }; module.exports.adjustToTerminalWidth = function adjustToTerminalWidth(str) { diff --git a/scripts/checkCopyrightHeaders.js b/scripts/checkCopyrightHeaders.js index 12d4eb78be3c..762d0581003c 100755 --- a/scripts/checkCopyrightHeaders.js +++ b/scripts/checkCopyrightHeaders.js @@ -140,7 +140,7 @@ function check() { !IGNORED_PATTERNS.some(pattern => pattern.test(file)) && !isDirectory(file) && !isBinaryFileSync(file) && - needsCopyrightHeader(file) + needsCopyrightHeader(file), ); if (invalidFiles.length > 0) { diff --git a/scripts/mapCoverage.js b/scripts/mapCoverage.js index deab981034f4..ce146ce8c855 100644 --- a/scripts/mapCoverage.js +++ b/scripts/mapCoverage.js @@ -35,17 +35,17 @@ const map = istanbulCoverage.createCoverageMap(); const mapFileCoverage = fileCoverage => { fileCoverage.path = fileCoverage.path.replace( /(.*packages\/.*\/)(build)(\/.*)/, - '$1src$3' + '$1src$3', ); return fileCoverage; }; Object.keys(coverage).forEach(filename => - map.addFileCoverage(mapFileCoverage(coverage[filename])) + map.addFileCoverage(mapFileCoverage(coverage[filename])), ); const context = istanbulReport.createContext({coverageMap: map}); ['json', 'lcov', 'text'].forEach(reporter => - istanbulReports.create(reporter, {}).execute(context) + istanbulReports.create(reporter, {}).execute(context), ); diff --git a/scripts/verifyOldTs.js b/scripts/verifyOldTs.js index 34fbbd670a6b..e1d864cd77ca 100644 --- a/scripts/verifyOldTs.js +++ b/scripts/verifyOldTs.js @@ -35,16 +35,16 @@ try { execa.sync('yarn', ['add', 'typescript@~3.4'], {cwd, stdio: 'inherit'}); fs.writeFileSync( path.join(cwd, 'tsconfig.json'), - JSON.stringify(tsConfig, null, 2) + JSON.stringify(tsConfig, null, 2), ); fs.writeFileSync( path.join(cwd, 'index.ts'), - `import jest = require('${jestDirectory}');` + `import jest = require('${jestDirectory}');`, ); execa.sync('yarn', ['tsc', '--project', '.'], {cwd, stdio: 'inherit'}); console.log( - chalk.inverse.green(' Successfully compiled Jest with TypeScript 3.4 ') + chalk.inverse.green(' Successfully compiled Jest with TypeScript 3.4 '), ); } finally { rimraf.sync(cwd); diff --git a/scripts/watch.js b/scripts/watch.js index 0f04a8342d3a..5af9c3ee9b50 100644 --- a/scripts/watch.js +++ b/scripts/watch.js @@ -34,7 +34,7 @@ chokidar { ignoreInitial: true, ignored: /(^|[\/\\])\../, // ignore dotfiles - } + }, ) .on('all', (event, filePath) => { if ( @@ -43,7 +43,7 @@ chokidar ) { console.log( chalk.green('->'), - `${event}: ${path.relative(PACKAGES_DIR, filePath)}` + `${event}: ${path.relative(PACKAGES_DIR, filePath)}`, ); rebuild(filePath); } else { @@ -51,7 +51,7 @@ chokidar const buildFile = filePath .replace( path.join(path.sep, 'src', path.sep), - path.join(path.sep, 'build', path.sep) + path.join(path.sep, 'build', path.sep), ) .replace(/\.ts$/, '.js'); try { @@ -59,8 +59,8 @@ chokidar process.stdout.write( `${chalk.red(' \u2022 ')}${path.relative( PACKAGES_DIR, - buildFile - )} (deleted)\n` + buildFile, + )} (deleted)\n`, ); } catch (e) {} } diff --git a/testSetupFile.js b/testSetupFile.js index ef9ed18680f6..7f73aec1ef96 100644 --- a/testSetupFile.js +++ b/testSetupFile.js @@ -8,3 +8,6 @@ // Some of the `jest-runtime` tests are very slow and cause // timeouts on travis jest.setTimeout(70000); + +// this module does some funky stuff with `require.cache`, flooding the terminal with output +jest.mock('stealthy-require', () => (_, m) => m()); diff --git a/tsconfig.json b/tsconfig.json index 15f14f7381e7..2301b5e98b8b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,6 @@ "module": "commonjs", "lib": ["dom", "es2017"], "declaration": true, - "declarationMap": true, "composite": true, "emitDeclarationOnly": true, // blocked by https://github.com/chalk/chalk/pull/390 diff --git a/yarn.lock b/yarn.lock index a0c3c872c635..704b61d753aa 100644 --- a/yarn.lock +++ b/yarn.lock @@ -77,7 +77,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.0.0", "@babel/generator@^7.7.2", "@babel/generator@^7.9.0", "@babel/generator@^7.9.5": +"@babel/generator@^7.5.0", "@babel/generator@^7.7.2", "@babel/generator@^7.9.0", "@babel/generator@^7.9.5": version "7.9.5" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.9.5.tgz#27f0917741acc41e6eaaced6d68f96c3fa9afaf9" integrity sha512-GbNIxVB3ZJe3tLeDm1HSn2AhuD/mVcyLDpgtLXa5tplmWrJdF/elxB56XNqCuD6szyNkDi6wuoKXln3QeBmCHQ== @@ -846,7 +846,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-transform-typescript@^7.0.0", "@babel/plugin-transform-typescript@^7.9.0": +"@babel/plugin-transform-typescript@^7.5.0", "@babel/plugin-transform-typescript@^7.9.0": version "7.9.4" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.9.4.tgz#4bb4dde4f10bbf2d787fce9707fb09b483e33359" integrity sha512-yeWeUkKx2auDbSxRe8MusAG+n4m9BFY/v+lPjmQDgOFX5qnySkUY5oXzkp6FwPdsYqnKay6lorXYdC0n3bZO7w== @@ -1907,11 +1907,32 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" +"@nodelib/fs.scandir@2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz#3a582bdb53804c6ba6d146579c46e52130cf4a3b" + integrity sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw== + dependencies: + "@nodelib/fs.stat" "2.0.3" + run-parallel "^1.1.9" + +"@nodelib/fs.stat@2.0.3", "@nodelib/fs.stat@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz#34dc5f4cabbc720f4e60f75a747e7ecd6c175bd3" + integrity sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA== + "@nodelib/fs.stat@^1.1.2": version "1.1.3" resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== +"@nodelib/fs.walk@^1.2.3": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz#011b9202a70a6366e436ca5c065844528ab04976" + integrity sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ== + dependencies: + "@nodelib/fs.scandir" "2.1.3" + fastq "^1.6.0" + "@octokit/auth-token@^2.4.0": version "2.4.0" resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-2.4.0.tgz#b64178975218b99e4dfe948253f0673cbbb59d9f" @@ -2014,89 +2035,93 @@ dependencies: "@types/node" ">= 8" -"@react-native-community/cli-debugger-ui@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-3.0.0.tgz#d01d08d1e5ddc1633d82c7d84d48fff07bd39416" - integrity sha512-m3X+iWLsK/H7/b7PpbNO33eQayR/+M26la4ZbYe1KRke5Umg4PIWsvg21O8Tw4uJcY8LA5hsP+rBi/syBkBf0g== +"@react-native-community/cli-debugger-ui@^4.7.0": + version "4.7.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-4.7.0.tgz#4a8689f56b99378b24bbbf0ff6a89869d667f013" + integrity sha512-Z/xJ08Wz3J2fKDPrwxtQ44XSHnWsF6dnT0H2AANw63bWjnrR0E3sh8Nk8/oO+j9R7LH8S0+NHJdlniXYtL/bNg== dependencies: serve-static "^1.13.1" -"@react-native-community/cli-platform-android@^3.0.0": - version "3.1.4" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-3.1.4.tgz#61f964dc311623e60b0fb29c5f3732cc8a6f076f" - integrity sha512-ClSdY20F0gzWVLTqCv7vHjnUqOcuq10jd9GgHX6lGSc2GI+Ql3/aQg3tmG4uY3KXNNwAv3U8QCoYgg1WGfwiHA== +"@react-native-community/cli-platform-android@^4.2.0": + version "4.7.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-android/-/cli-platform-android-4.7.0.tgz#aace6b8004b8d3aae40d6affaad1c472e0310a25" + integrity sha512-Lb6D0ipmFwYLJeQy5/NI4uJpeSHw85rd84C40wwpoUfsCgZhA93WUJdFkuQEIDkfTqs5Yqgl+/szhIZdnIXPxw== dependencies: - "@react-native-community/cli-tools" "^3.0.0" - chalk "^2.4.2" + "@react-native-community/cli-tools" "^4.7.0" + chalk "^3.0.0" execa "^1.0.0" + fs-extra "^8.1.0" + glob "^7.1.3" jetifier "^1.6.2" + lodash "^4.17.15" logkitty "^0.6.0" slash "^3.0.0" xmldoc "^1.1.2" -"@react-native-community/cli-platform-ios@^3.0.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-3.2.0.tgz#c469444f5993c9e6737a4b16d78cf033e3702f00" - integrity sha512-pzEnx68H6+mHBq5jsMrr3UmAmkrLSMlC9BZ4yoUdfUXCQq6/R70zNYvH4hjUw8h2Al7Kgq53UzHUsM0ph8TSWQ== +"@react-native-community/cli-platform-ios@^4.2.0": + version "4.7.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-platform-ios/-/cli-platform-ios-4.7.0.tgz#471dcdbd2645c5650f16c0eddcca50e47ca78398" + integrity sha512-XqnxP6H6+PG/wn4+Pwas5jaTSr5n7x6v8trkPY8iO37b8sq7tJLNYznaBMROF43i0NqO48JdhquYOqnDN8FdBA== dependencies: - "@react-native-community/cli-tools" "^3.0.0" - chalk "^2.4.2" + "@react-native-community/cli-tools" "^4.7.0" + chalk "^3.0.0" + glob "^7.1.3" js-yaml "^3.13.1" + lodash "^4.17.15" + plist "^3.0.1" xcode "^2.0.0" -"@react-native-community/cli-tools@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-3.0.0.tgz#fe48b80822ed7e49b8af051f9fe41e22a2a710b1" - integrity sha512-8IhQKZdf3E4CR8T7HhkPGgorot/cLkRDgneJFDSWk/wCYZAuUh4NEAdumQV7N0jLSMWX7xxiWUPi94lOBxVY9g== +"@react-native-community/cli-tools@^4.7.0": + version "4.7.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-tools/-/cli-tools-4.7.0.tgz#83d49277e7f56fef87bdfd0ba55d2cfa20190689" + integrity sha512-llNWJEWXhGMsaHLWoieraPeWuva3kRsIEPi8oRVTybyz82JjR71mN0OFs41o1OnAR6+TR9d5cJPN+mIOESugEA== dependencies: - chalk "^2.4.2" - lodash "^4.17.5" + chalk "^3.0.0" + lodash "^4.17.15" mime "^2.4.1" - node-fetch "^2.5.0" + node-fetch "^2.6.0" -"@react-native-community/cli-types@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-3.0.0.tgz#488d46605cb05e88537e030f38da236eeda74652" - integrity sha512-ng6Tm537E/M42GjE4TRUxQyL8sRfClcL7bQWblOCoxPZzJ2J3bdALsjeG3vDnVCIfI/R0AeFalN9KjMt0+Z/Zg== +"@react-native-community/cli-types@^4.7.0": + version "4.7.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli-types/-/cli-types-4.7.0.tgz#871905753f8ff83cf10c48e8df3fdd63cd7667a0" + integrity sha512-Pw05Rsh/ENFs/Utv1SVRFfdMAn+W9yy1AOhyIKB36JX0Xw00sIZQDyZVsVfmaLSOpRpJ/qUdKWXB/WYV4XYELw== -"@react-native-community/cli@^3.0.0": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-3.2.1.tgz#2a466801eb6080a1f73358c5d740c53c24ed8c6f" - integrity sha512-bZ/bfZ+9r1gQSxp6t7+00DcpC6vmbVYSvzUCFM/yo5k8bhsDdcy8aocscIaXXVGG+v9Edri/Q7hH9ks7L18/Rg== +"@react-native-community/cli@^4.2.0": + version "4.7.0" + resolved "https://registry.yarnpkg.com/@react-native-community/cli/-/cli-4.7.0.tgz#be692631356d14fd1ffe23f25b479dca9e8e7c95" + integrity sha512-DbpxcPC7lFCJ112dPXL4DBKh5TfH0QK2OTG7uEGjfsApT4c01Lae6OMTNSssXgXTcNJApqIT5a6GXK2vSE0CEQ== dependencies: "@hapi/joi" "^15.0.3" - "@react-native-community/cli-debugger-ui" "^3.0.0" - "@react-native-community/cli-tools" "^3.0.0" - "@react-native-community/cli-types" "^3.0.0" - chalk "^2.4.2" + "@react-native-community/cli-debugger-ui" "^4.7.0" + "@react-native-community/cli-tools" "^4.7.0" + "@react-native-community/cli-types" "^4.7.0" + chalk "^3.0.0" command-exists "^1.2.8" commander "^2.19.0" compression "^1.7.1" connect "^3.6.5" cosmiconfig "^5.1.0" deepmerge "^3.2.0" - didyoumean "^1.2.1" envinfo "^7.1.0" errorhandler "^1.5.0" execa "^1.0.0" find-up "^4.1.0" - fs-extra "^7.0.1" - glob "^7.1.1" + fs-extra "^8.1.0" + glob "^7.1.3" graceful-fs "^4.1.3" inquirer "^3.0.6" - lodash "^4.17.5" - metro "^0.56.0" - metro-config "^0.56.0" - metro-core "^0.56.0" - metro-react-native-babel-transformer "^0.56.0" + leven "^3.1.0" + lodash "^4.17.15" + metro "^0.58.0" + metro-config "^0.58.0" + metro-core "^0.58.0" + metro-react-native-babel-transformer "^0.58.0" minimist "^1.2.0" mkdirp "^0.5.1" - morgan "^1.9.0" - node-notifier "^5.2.1" + node-stream-zip "^1.9.1" open "^6.2.0" ora "^3.4.0" - plist "^3.0.0" - pretty-format "^25.1.0" + pretty-format "^25.2.0" semver "^6.3.0" serve-static "^1.13.1" shell-quote "1.6.1" @@ -2443,6 +2468,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-13.11.1.tgz#49a2a83df9d26daacead30d0ccc8762b128d53c7" integrity sha512-eWQGP3qtxwL8FGneRrC5DwrJLGN4/dH1clNTuLfN81HCrxVtxRjygDTUoZJ5ASlDEeo0ppYFQjQIlXhtXpOn6g== +"@types/normalize-package-data@^2.4.0": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" + integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== + "@types/prettier@^1.19.0": version "1.19.1" resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.19.1.tgz#33509849f8e679e4add158959fdb086440e9553f" @@ -2948,6 +2978,11 @@ alphanum-sort@^1.0.0: resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= +anser@^1.4.9: + version "1.4.9" + resolved "https://registry.yarnpkg.com/anser/-/anser-1.4.9.tgz#1f85423a5dcf8da4631a341665ff675b96845760" + integrity sha512-AI+BjTeGt2+WFk4eWcqbQ7snZpDBt8SaLlj0RT2h5xfdWaiy51OjYvqwMrNzJLGy8iOAL6nKDITWO+rd4MkYEA== + ansi-colors@3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.3.tgz#57d35b8686e851e2cc04c403f1c00203976a1813" @@ -3222,6 +3257,11 @@ array-union@^1.0.1, array-union@^1.0.2: dependencies: array-uniq "^1.0.1" +array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + array-uniq@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" @@ -3258,11 +3298,6 @@ arrify@^1.0.1: resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= -art@^0.10.0: - version "0.10.3" - resolved "https://registry.yarnpkg.com/art/-/art-0.10.3.tgz#b01d84a968ccce6208df55a733838c96caeeaea2" - integrity sha512-HXwbdofRTiJT6qZX/FnchtldzJjS3vkLJxQilc3Xj+ma2MXjY4UAyQ0ls1XZYVnDvVIBiFZbC6QsvtW86TD6tQ== - asap@^2.0.0, asap@~2.0.3, asap@~2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -3483,7 +3518,7 @@ babel-preset-current-node-syntax@^0.1.2: "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -babel-preset-fbjs@^3.1.2, babel-preset-fbjs@^3.2.0: +babel-preset-fbjs@^3.2.0, babel-preset-fbjs@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/babel-preset-fbjs/-/babel-preset-fbjs-3.3.0.tgz#a6024764ea86c8e06a22d794ca8b69534d263541" integrity sha512-7QTLTCd2gwB2qGoi5epSULMHugSVgpcVt5YAeiFO9ABLrutDQzKfGwzxgZHLpugq8qMdg/DhRZDZ5CLKxBkEbw== @@ -3572,13 +3607,6 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" -basic-auth@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" - integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== - dependencies: - safe-buffer "5.1.2" - bcrypt-pbkdf@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" @@ -4351,15 +4379,6 @@ clipboard@^2.0.0: select "^1.1.2" tiny-emitter "^2.0.0" -cliui@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" - integrity sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0= - dependencies: - string-width "^1.0.1" - strip-ansi "^3.0.1" - wrap-ansi "^2.0.0" - cliui@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" @@ -4532,9 +4551,9 @@ combined-stream@^1.0.6, combined-stream@~1.0.6: delayed-stream "~1.0.0" command-exists@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.8.tgz#715acefdd1223b9c9b37110a149c6392c2852291" - integrity sha512-PM54PkseWbiiD/mMsbvW351/u+dafwTJ0ye2qB60G1aGQP9j3xK2gmMDc+R34L3nDtx4qMCitXT75mkbkGJDLw== + version "1.2.9" + resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" + integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w== commander@^2.11.0, commander@^2.19.0, commander@^2.20.0, commander@~2.20.3: version "2.20.3" @@ -5203,9 +5222,9 @@ dateformat@^3.0.0: integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== dayjs@^1.8.15: - version "1.8.24" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.24.tgz#2ef8a2ab9425eaf3318fe78825be1c571027488d" - integrity sha512-bImQZbBv86zcOWOq6fLg7r4aqMx8fScdmykA7cSh+gH1Yh8AM0Dbw0gHYrsOrza6oBBnkK+/OaR+UAa9UsMrDw== + version "1.8.25" + resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.25.tgz#d09a8696cee7191bc1289e739f96626391b9c73c" + integrity sha512-Pk36juDfQQGDCgr0Lqd1kw15w3OS6xt21JaLPE3lCfsEf8KrERGwDNwvK1tRjrjqFC0uZBJncT4smZQ4F+uV5g== debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.8, debug@^2.6.9: version "2.6.9" @@ -5255,7 +5274,7 @@ decamelize-keys@^1.0.0: decamelize "^1.1.0" map-obj "^1.0.0" -decamelize@^1.1.0, decamelize@^1.1.1, decamelize@^1.1.2, decamelize@^1.2.0: +decamelize@^1.1.0, decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -5411,11 +5430,6 @@ depd@~1.1.2: resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" integrity sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak= -depd@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - deprecation@^2.0.0, deprecation@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" @@ -5470,11 +5484,6 @@ diacritics-map@^0.1.0: resolved "https://registry.yarnpkg.com/diacritics-map/-/diacritics-map-0.1.0.tgz#6dfc0ff9d01000a2edf2865371cac316e94977af" integrity sha1-bfwP+dAQAKLt8oZTccrDFulJd68= -didyoumean@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.1.tgz#e92edfdada6537d484d73c0172fd1eba0c4976ff" - integrity sha1-6S7f2tplN9SE1zwBcv0eugxJdv8= - diff@3.5.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -5509,6 +5518,13 @@ dir-glob@^2.2.2: dependencies: path-type "^3.0.0" +dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + discontinuous-range@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a" @@ -6178,6 +6194,13 @@ eslint-plugin-react@^7.1.0: string.prototype.matchall "^4.0.2" xregexp "^4.3.0" +eslint-plugin-relay@1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-relay/-/eslint-plugin-relay-1.4.1.tgz#5af2ac13e24bd01ad17b6a4014204918d65021cd" + integrity sha512-yb+p+4AxZTi2gXN7cZRfXMBFlRa5j6TtiVeq3yHXyy+tlgYNpxi/dDrP1+tcUTNP9vdaJovnfGZ5jp6kMiH9eg== + dependencies: + graphql "^14.0.0" + eslint-rule-composer@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" @@ -6594,6 +6617,18 @@ fast-glob@^2.0.2, fast-glob@^2.2.6: merge2 "^1.2.3" micromatch "^3.1.10" +fast-glob@^3.0.3: + version "3.2.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.2.tgz#ade1a9d91148965d4bf7c51f72e1ca662d32e63d" + integrity sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.0" + merge2 "^1.3.0" + micromatch "^4.0.2" + picomatch "^2.2.1" + fast-json-stable-stringify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" @@ -6604,6 +6639,13 @@ fast-levenshtein@~2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc= +fastq@^1.6.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.7.0.tgz#fcd79a08c5bd7ec5b55cd3f5c4720db551929801" + integrity sha512-YOadQRnHd5q6PogvAR/x62BGituF2ufiEA6s8aavQANw5YKHERI4AREboX6KotzP8oX2klxYF2wcV/7bn1clfQ== + dependencies: + reusify "^1.0.4" + faye-websocket@~0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" @@ -7281,7 +7323,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.0.0, glob-parent@~5.1.0: +glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== @@ -7358,6 +7400,20 @@ globby@8.0.2, globby@^8.0.1: pify "^3.0.0" slash "^1.0.0" +globby@^10.0.2: + version "10.0.2" + resolved "https://registry.yarnpkg.com/globby/-/globby-10.0.2.tgz#277593e745acaa4646c3ab411289ec47a0392543" + integrity sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.0.3" + glob "^7.1.3" + ignore "^5.1.1" + merge2 "^1.2.3" + slash "^3.0.0" + globby@^9.2.0: version "9.2.0" resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" @@ -7448,6 +7504,13 @@ graphql-request@^1.8.2: dependencies: cross-fetch "2.2.2" +graphql@^14.0.0: + version "14.6.0" + resolved "https://registry.yarnpkg.com/graphql/-/graphql-14.6.0.tgz#57822297111e874ea12f5cd4419616930cd83e49" + integrity sha512-VKzfvHEKybTKjQVpTFrA5yUq2S9ihcZvfJAtsDBBCuV6wauPu1xl/f9ehgVf0FcEJJs4vz6ysb/ZMkGigQZseg== + dependencies: + iterall "^1.2.2" + gray-matter@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-2.1.1.tgz#3042d9adec2a1ded6a7707a9ed2380f8a17a430e" @@ -7621,10 +7684,10 @@ he@1.2.0: resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== -hermes-engine@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.2.1.tgz#25c0f1ff852512a92cb5c5cc47cf967e1e722ea2" - integrity sha512-eNHUQHuadDMJARpaqvlCZoK/Nitpj6oywq3vQ3wCwEsww5morX34mW5PmKWQTO7aU0ck0hgulxR+EVDlXygGxQ== +hermes-engine@~0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/hermes-engine/-/hermes-engine-0.4.1.tgz#2d02b295596298643c4d24b86687eb554db9e950" + integrity sha512-Y3JFC8PD7eN3KpnrzrmvMAqp0IwnZrmP/oGOptvaSu33d7Zq/8b/2lHlZZkNvRl7/I1Q0umTX8TByK7zzLfTXA== hex-color-regex@^1.1.0: version "1.1.0" @@ -7830,7 +7893,7 @@ ignore@^4.0.3, ignore@^4.0.6: resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== -ignore@^5.0.5: +ignore@^5.0.5, ignore@^5.1.1: version "5.1.4" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf" integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A== @@ -8138,11 +8201,6 @@ invariant@^2.2.2, invariant@^2.2.4: dependencies: loose-envify "^1.0.0" -invert-kv@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" - integrity sha1-EEqOSqym09jNFXqO+L+rLXo//bY= - invert-kv@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" @@ -8693,6 +8751,11 @@ isurl@^1.0.0-alpha5: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" +iterall@^1.2.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.3.0.tgz#afcb08492e2915cbd8a0884eb93a8c94d0d72fea" + integrity sha512-QZ9qOMdF+QLHxy1QIpUHUU1D5pS2CG2P69LF6L6CPjPYA/XMOmKV3PZpawHoAjHNyB0swdVTRxdYT4tbBbxqwg== + jest-get-type@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" @@ -9128,13 +9191,6 @@ lazy-cache@^2.0.2: dependencies: set-getter "^0.1.0" -lcid@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" - integrity sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU= - dependencies: - invert-kv "^1.0.0" - lcid@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" @@ -9186,6 +9242,11 @@ levn@^0.3.0, levn@~0.3.0: prelude-ls "~1.1.2" type-check "~0.3.2" +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + list-item@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/list-item/-/list-item-1.1.1.tgz#0c65d00e287cb663ccb3cb3849a77e89ec268a56" @@ -9692,13 +9753,6 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= -mem@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" - integrity sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y= - dependencies: - mimic-fn "^1.0.0" - mem@^4.0.0: version "4.3.0" resolved "https://registry.yarnpkg.com/mem/-/mem-4.3.0.tgz#461af497bc4ae09608cdb2e60eefb69bff744178" @@ -9792,7 +9846,7 @@ merge-stream@^2.0.0: resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.2.3: +merge2@^1.2.3, merge2@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81" integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw== @@ -9802,10 +9856,10 @@ methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= -metro-babel-register@^0.56.0, metro-babel-register@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.56.4.tgz#b0c627a1cfdd1bdd768f81af79481754e833a902" - integrity sha512-Phm6hMluOWYqfykftjJ1jsTpWvbgb49AC/1taxEctxUdRCZlFgZwBleJZAhQYxJD5J+ikFkEbHDzePEXb29KVA== +metro-babel-register@0.58.0: + version "0.58.0" + resolved "https://registry.yarnpkg.com/metro-babel-register/-/metro-babel-register-0.58.0.tgz#5c44786d49a044048df56cf476a2263491d4f53a" + integrity sha512-P5+G3ufhSYL6cA3a7xkbSJzzFBvtivj/PhWvGXFXnuFssDlMAX1CTktff+0gpka5Cd6B6QLt0UAMWulUAAE4Eg== dependencies: "@babel/core" "^7.0.0" "@babel/plugin-proposal-class-properties" "^7.0.0" @@ -9820,68 +9874,68 @@ metro-babel-register@^0.56.0, metro-babel-register@^0.56.4: core-js "^2.2.2" escape-string-regexp "^1.0.5" -metro-babel-transformer@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.56.4.tgz#fe1d0dc600fcf90201a5bea4d42caea10b801057" - integrity sha512-IOi4ILgZvaX7GCGHBJp79paNVOq5QxhhbyqAdEJgDP8bHfl/OVHoVKSypfrsMSKSiBrqxhIjyc4XjkXsQtkx5g== +metro-babel-transformer@0.58.0: + version "0.58.0" + resolved "https://registry.yarnpkg.com/metro-babel-transformer/-/metro-babel-transformer-0.58.0.tgz#317c83b863cceb0573943815f1711fbcbe69b106" + integrity sha512-yBX3BkRhw2TCNPhe+pmLSgsAEA3huMvnX08UwjFqSXXI1aiqzRQobn92uKd1U5MM1Vx8EtXVomlJb95ZHNAv6A== dependencies: "@babel/core" "^7.0.0" - metro-source-map "^0.56.4" + metro-source-map "0.58.0" -metro-cache@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.56.4.tgz#542f9f8a35f8fb9d5576f46fd3ab4d4f42851a7e" - integrity sha512-d1hiUSKwtRsuMxUhHVJ3tjK2BbpUlJGvTyMWohK8Wxx+0GbnWRWWFcI4vlCzlZfoK0VtZK2MJEl5t7Du1mIniQ== +metro-cache@0.58.0: + version "0.58.0" + resolved "https://registry.yarnpkg.com/metro-cache/-/metro-cache-0.58.0.tgz#630ea0a4626dfb9591c71fdb85dce14b5e9a04ec" + integrity sha512-jjW9zCTKxhgKcVkyQ6LHyna9Zdf4TK/45vvT1fPyyTk1RY82ZYjU1qs+84ycKEd08Ka4YcK9xcUew9SIDJYI8Q== dependencies: jest-serializer "^24.4.0" - metro-core "^0.56.4" + metro-core "0.58.0" mkdirp "^0.5.1" rimraf "^2.5.4" -metro-config@^0.56.0, metro-config@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.56.4.tgz#338fd8165fba59424cec427c1a881757945e57e9" - integrity sha512-O85QDHwWdMn/8ERe13y4a6vbZL0AHyO8atTvL+9BCulLEO+FQBi1iJjr3+ViLa8cf0m5dRftDsa7P47m5euk4A== +metro-config@0.58.0, metro-config@^0.58.0: + version "0.58.0" + resolved "https://registry.yarnpkg.com/metro-config/-/metro-config-0.58.0.tgz#1e24b43a5a00971d75662b1a0d3c04a13d4a1746" + integrity sha512-4vgBliXwL56vjUlYplvGMVSNrJJpkHuLcD+O20trV3FvPxKg4ZsvuOcNSxqDSMU26FCtIEJ15ojcuCbRL7KY0w== dependencies: cosmiconfig "^5.0.5" jest-validate "^24.7.0" - metro "^0.56.4" - metro-cache "^0.56.4" - metro-core "^0.56.4" + metro "0.58.0" + metro-cache "0.58.0" + metro-core "0.58.0" pretty-format "^24.7.0" -metro-core@^0.56.0, metro-core@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.56.4.tgz#67cc41b3c0bf66e9c2306f50239a1080b1e82312" - integrity sha512-hMzkBdgPt5Zm9nr/1KtIT+A6H7TNiLVCEGG5OiAXj8gTRsA2yy7wAdQpwy0xbE+zi88t/pLOzXpd3ClG/YxyWg== +metro-core@0.58.0, metro-core@^0.58.0: + version "0.58.0" + resolved "https://registry.yarnpkg.com/metro-core/-/metro-core-0.58.0.tgz#ad9f6645a2b439a3fbce7ce4e19b01b00375768a" + integrity sha512-RzXUjGFmCLOyzUqcKDvr91AldGtIOxnzNZrWUIiG8uC3kerVLo0mQp4YH3+XVm6fMNiLMg6iER7HLqD+MbpUjQ== dependencies: jest-haste-map "^24.7.1" lodash.throttle "^4.1.1" - metro-resolver "^0.56.4" + metro-resolver "0.58.0" wordwrap "^1.0.0" -metro-inspector-proxy@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.56.4.tgz#7343ff3c5908af4fd99e96b6d646e24e99816be4" - integrity sha512-E1S3MO25mWKmcLn1UQuCDiS0hf9P2Fwq8sEAX5lBLoZbehepNH+4xJ3xXSY51JX4dozBrE8GGoKL4ll3II40LA== +metro-inspector-proxy@0.58.0: + version "0.58.0" + resolved "https://registry.yarnpkg.com/metro-inspector-proxy/-/metro-inspector-proxy-0.58.0.tgz#6fefb0cdf25655919d56c82ebe09cd26eb00e636" + integrity sha512-oFqTyNTJdCdvcw1Ha6SKE7ITbSaoTbO4xpYownIoJR+WZ0ZfxbWpp225JkHuBJm9UcBAnG9c0CME924m3uBbaw== dependencies: connect "^3.6.5" debug "^2.2.0" rxjs "^5.4.3" ws "^1.1.5" - yargs "^9.0.0" + yargs "^14.2.0" -metro-minify-uglify@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.56.4.tgz#13589dfb1d43343608aacb7f78ddfcc052daa63c" - integrity sha512-BHgj7+BKEK2pHvWHUR730bIrsZwl8DPtr49x9L0j2grPZ5/UROWXzEr8VZgIss7fl64t845uu1HXNNyuSj2EhA== +metro-minify-uglify@0.58.0: + version "0.58.0" + resolved "https://registry.yarnpkg.com/metro-minify-uglify/-/metro-minify-uglify-0.58.0.tgz#7e1066954bfd4f767ba6aca7feef676ca44c68b8" + integrity sha512-vRHsA7bCi7eCn3LXLm20EfY2NoWDyYOnmWaq/N8LB0OxL2L5DXRqMYAQK+prWGJ5S1yvVnDuuNVP+peQ9851TA== dependencies: uglify-es "^3.1.9" -metro-react-native-babel-preset@*, metro-react-native-babel-preset@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.56.4.tgz#dcedc64b7ff5c0734839458e70eb0ebef6d063a8" - integrity sha512-CzbBDM9Rh6w8s1fq+ZqihAh7DDqUAcfo9pPww25+N/eJ7UK436Q7JdfxwdIPpBwLFn6o6MyYn+uwL9OEWBJarA== +metro-react-native-babel-preset@0.58.0, metro-react-native-babel-preset@^0.58.0: + version "0.58.0" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.58.0.tgz#18f48d33fe124280ffabc000ab8b42c488d762a2" + integrity sha512-MRriNW+fF6jxABsgPphocUY6mIhmCm8idcrQZ58fT3Iti2vCdtkaK32TyCGUNUptzhUe2/cbE57j4aC+eaodAA== dependencies: "@babel/plugin-proposal-class-properties" "^7.0.0" "@babel/plugin-proposal-export-default-from" "^7.0.0" @@ -9914,60 +9968,61 @@ metro-react-native-babel-preset@*, metro-react-native-babel-preset@^0.56.4: "@babel/plugin-transform-spread" "^7.0.0" "@babel/plugin-transform-sticky-regex" "^7.0.0" "@babel/plugin-transform-template-literals" "^7.0.0" - "@babel/plugin-transform-typescript" "^7.0.0" + "@babel/plugin-transform-typescript" "^7.5.0" "@babel/plugin-transform-unicode-regex" "^7.0.0" "@babel/template" "^7.0.0" react-refresh "^0.4.0" -metro-react-native-babel-transformer@^0.56.0: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.56.4.tgz#3c6e48b605c305362ee624e45ff338656e35fc1d" - integrity sha512-ng74eutuy1nyGI9+TDzzVAVfEmNPDlapV4msTQMKPi4EFqo/fBn7Ct33ME9l5E51pQBBnxt/UwcpTvd13b29kQ== +metro-react-native-babel-transformer@0.58.0, metro-react-native-babel-transformer@^0.58.0: + version "0.58.0" + resolved "https://registry.yarnpkg.com/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.58.0.tgz#5da0e5a1b83c01d11626905fa59f34fda53a21a5" + integrity sha512-3A73+cRq1eUPQ8g+hPNGgMUMCGmtQjwqHfoG1DwinAoJ/kr4WOXWWbGZo0xHJNBe/zdHGl0uHcDCp2knPglTdQ== dependencies: "@babel/core" "^7.0.0" - babel-preset-fbjs "^3.1.2" - metro-babel-transformer "^0.56.4" - metro-react-native-babel-preset "^0.56.4" - metro-source-map "^0.56.4" + babel-preset-fbjs "^3.3.0" + metro-babel-transformer "0.58.0" + metro-react-native-babel-preset "0.58.0" + metro-source-map "0.58.0" -metro-resolver@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.56.4.tgz#9876f57bca37fd1bfcffd733541e2ee4a89fad7f" - integrity sha512-Ug4ulVfpkKZ1Wu7mdYj9XLGuOqZTuWCqEhyx3siKTc/2eBwKZQXmiNo5d/IxWNvmwL/87Abeb724I6CMzMfjiQ== +metro-resolver@0.58.0: + version "0.58.0" + resolved "https://registry.yarnpkg.com/metro-resolver/-/metro-resolver-0.58.0.tgz#4d03edc52e2e25d45f16688adf3b3f268ea60df9" + integrity sha512-XFbAKvCHN2iWqKeiRARzEXn69eTDdJVJC7lu16S4dPQJ+Dy82dZBr5Es12iN+NmbJuFgrAuIHbpWrdnA9tOf6Q== dependencies: absolute-path "^0.0.0" -metro-source-map@^0.56.0, metro-source-map@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.56.4.tgz#868ccac3f3519fe14eca358bc186f63651b2b9bc" - integrity sha512-f1P9/rpFmG3Z0Jatiw2zvLItx1TwR7mXTSDj4qLDCWeVMB3kEXAr3R0ucumTW8c6HfpJljeRBWzYFXF33fd81g== +metro-source-map@0.58.0: + version "0.58.0" + resolved "https://registry.yarnpkg.com/metro-source-map/-/metro-source-map-0.58.0.tgz#e951b99f4c653239ce9323bb08339c6f1978a112" + integrity sha512-yvN1YPmejmgiiS7T1aKBiiUTHPw2Vcm3r2TZ+DY92z/9PR4alysIywrCs/fTHs8rbDcKM5VfPCKGLpkBrbKeOw== dependencies: "@babel/traverse" "^7.0.0" "@babel/types" "^7.0.0" invariant "^2.2.4" - metro-symbolicate "^0.56.4" - ob1 "^0.56.4" + metro-symbolicate "0.58.0" + ob1 "0.58.0" source-map "^0.5.6" vlq "^1.0.0" -metro-symbolicate@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.56.4.tgz#53e9d40beac9049fa75a3e620ddd47d4907ff015" - integrity sha512-8mCNNn6zV5FFKCIcRgI7736Xl+owgvYuy8qanPxZN36f7utiWRYeB+PirEBPcglBk4qQvoy2lT6oPULNXZQbbQ== +metro-symbolicate@0.58.0: + version "0.58.0" + resolved "https://registry.yarnpkg.com/metro-symbolicate/-/metro-symbolicate-0.58.0.tgz#ba9fd52549c41fc1b656adaad7c8875726dd5abe" + integrity sha512-uIVxUQC1E26qOMj13dKROhwAa2FmZk5eR0NcBqej/aXmQhpr8LjJg2sondkoLKUp827Tf/Fm9+pS4icb5XiqCw== dependencies: invariant "^2.2.4" - metro-source-map "^0.56.4" + metro-source-map "0.58.0" source-map "^0.5.6" through2 "^2.0.1" vlq "^1.0.0" -metro@^0.56.0, metro@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/metro/-/metro-0.56.4.tgz#be7e1380ee6ac3552c25ead8098eab261029e4d7" - integrity sha512-Kt3OQJQtQdts0JrKnyGdLpKHDjqYBgIfzvYrvfhmFCkKuZ8aqRlVnvpfjQ4/OBm0Fmm9NyyxbNRD9VIbj7WjnA== +metro@0.58.0, metro@^0.58.0: + version "0.58.0" + resolved "https://registry.yarnpkg.com/metro/-/metro-0.58.0.tgz#c037318c112f80dc96199780c8b401ab72cfd142" + integrity sha512-yi/REXX+/s4r7RjzXht+E+qE6nzvFIrEXO5Q61h+70Q7RODMU8EnlpXx04JYk7DevHuMhFaX+NWhCtRINzR4zA== dependencies: + "@babel/code-frame" "^7.0.0" "@babel/core" "^7.0.0" - "@babel/generator" "^7.0.0" + "@babel/generator" "^7.5.0" "@babel/parser" "^7.0.0" "@babel/plugin-external-helpers" "^7.0.0" "@babel/template" "^7.0.0" @@ -9975,9 +10030,10 @@ metro@^0.56.0, metro@^0.56.4: "@babel/types" "^7.0.0" absolute-path "^0.0.0" async "^2.4.0" - babel-preset-fbjs "^3.1.2" + babel-preset-fbjs "^3.3.0" buffer-crc32 "^0.2.13" chalk "^2.4.1" + ci-info "^2.0.0" concat-stream "^1.6.0" connect "^3.6.5" debug "^2.2.0" @@ -9993,32 +10049,33 @@ metro@^0.56.0, metro@^0.56.4: json-stable-stringify "^1.0.1" lodash.throttle "^4.1.1" merge-stream "^1.0.1" - metro-babel-register "^0.56.4" - metro-babel-transformer "^0.56.4" - metro-cache "^0.56.4" - metro-config "^0.56.4" - metro-core "^0.56.4" - metro-inspector-proxy "^0.56.4" - metro-minify-uglify "^0.56.4" - metro-react-native-babel-preset "^0.56.4" - metro-resolver "^0.56.4" - metro-source-map "^0.56.4" - metro-symbolicate "^0.56.4" + metro-babel-register "0.58.0" + metro-babel-transformer "0.58.0" + metro-cache "0.58.0" + metro-config "0.58.0" + metro-core "0.58.0" + metro-inspector-proxy "0.58.0" + metro-minify-uglify "0.58.0" + metro-react-native-babel-preset "0.58.0" + metro-resolver "0.58.0" + metro-source-map "0.58.0" + metro-symbolicate "0.58.0" mime-types "2.1.11" mkdirp "^0.5.1" node-fetch "^2.2.0" - nullthrows "^1.1.0" + nullthrows "^1.1.1" resolve "^1.5.0" rimraf "^2.5.4" serialize-error "^2.1.0" source-map "^0.5.6" + strip-ansi "^4.0.0" temp "0.8.3" throat "^4.1.0" wordwrap "^1.0.0" write-file-atomic "^1.2.0" ws "^1.1.5" xpipe "^1.0.5" - yargs "^9.0.0" + yargs "^14.2.0" microevent.ts@~0.1.1: version "0.1.1" @@ -10301,17 +10358,6 @@ moo@^0.5.0: resolved "https://registry.yarnpkg.com/moo/-/moo-0.5.1.tgz#7aae7f384b9b09f620b6abf6f74ebbcd1b65dbc4" integrity sha512-I1mnb5xn4fO80BH9BLcF0yLypy2UKl+Cb01Fu0hJRkJjlCRtxZMWkTdAtDd5ZqCOxtCkhmRwyI57vWT+1iZ67w== -morgan@^1.9.0: - version "1.10.0" - resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7" - integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ== - dependencies: - basic-auth "~2.0.1" - debug "2.6.9" - depd "~2.0.0" - on-finished "~2.3.0" - on-headers "~1.0.2" - move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -10464,7 +10510,7 @@ node-fetch@^1.0.1: encoding "^0.1.11" is-stream "^1.0.1" -node-fetch@^2.2.0, node-fetch@^2.3.0, node-fetch@^2.5.0: +node-fetch@^2.2.0, node-fetch@^2.3.0, node-fetch@^2.5.0, node-fetch@^2.6.0: version "2.6.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== @@ -10525,17 +10571,6 @@ node-modules-regexp@^1.0.0: resolved "https://registry.yarnpkg.com/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= -node-notifier@^5.2.1: - version "5.4.3" - resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.4.3.tgz#cb72daf94c93904098e28b9c590fd866e464bd50" - integrity sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q== - dependencies: - growly "^1.3.0" - is-wsl "^1.1.0" - semver "^5.5.0" - shellwords "^0.1.1" - which "^1.3.0" - node-notifier@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-6.0.0.tgz#cea319e06baa16deec8ce5cd7f133c4a46b68e12" @@ -10552,6 +10587,11 @@ node-releases@^1.1.29, node-releases@^1.1.53: resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.53.tgz#2d821bfa499ed7c5dffc5e2f28c88e78a08ee3f4" integrity sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ== +node-stream-zip@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/node-stream-zip/-/node-stream-zip-1.9.1.tgz#66d210204da7c60e2d6d685eb21a11d016981fd0" + integrity sha512-7/Xs9gkuYF0WBimz5OrSc6UVKLDTxvBG2yLGtEK8PSx94d86o/6iQLvIe/140ATz35JDqHKWIxh3GcA3u5hB0w== + nopt@^4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48" @@ -10694,7 +10734,7 @@ nth-check@^1.0.2, nth-check@~1.0.1: dependencies: boolbase "~1.0.0" -nullthrows@^1.1.0: +nullthrows@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1" integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw== @@ -10719,10 +10759,10 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -ob1@^0.56.4: - version "0.56.4" - resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.56.4.tgz#c4acb3baa42f4993a44b35b2da7c8ef443dcccec" - integrity sha512-URgFof9z2wotiYFsqlydXtQfGV81gvBI2ODy64xfd3vPo+AYom5PVDX4t4zn23t/O+S2IxqApSQM8uJAybmz7w== +ob1@0.58.0: + version "0.58.0" + resolved "https://registry.yarnpkg.com/ob1/-/ob1-0.58.0.tgz#484a1e9a63a8b79d9ea6f3a83b2a42110faac973" + integrity sha512-uZP44cbowAfHafP1k4skpWItk5iHCoRevMfrnUvYCfyNNPPJd3rfDCyj0exklWi2gDXvjlj2ObsfiqP/bs/J7Q== object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" @@ -10955,15 +10995,6 @@ os-homedir@^1.0.0: resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M= -os-locale@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" - integrity sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA== - dependencies: - execa "^0.7.0" - lcid "^1.0.0" - mem "^1.1.0" - os-locale@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" @@ -11208,6 +11239,16 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" +parse-json@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.0.0.tgz#73e5114c986d143efa3712d4ea24db9a4266f60f" + integrity sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + lines-and-columns "^1.1.6" + parse-node-version@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" @@ -11347,6 +11388,11 @@ path-type@^3.0.0: dependencies: pify "^3.0.0" +path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + pbkdf2@^3.0.3: version "3.0.17" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.17.tgz#976c206530617b14ebb32114239f7b09336e93a6" @@ -11368,7 +11414,7 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.0.7: +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.0.7, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== @@ -11440,7 +11486,7 @@ platform@^1.3.3: resolved "https://registry.yarnpkg.com/platform/-/platform-1.3.5.tgz#fb6958c696e07e2918d2eeda0f0bc9448d733444" integrity sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q== -plist@^3.0.0, plist@^3.0.1: +plist@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/plist/-/plist-3.0.1.tgz#a9b931d17c304e8912ef0ba3bdd6182baf2e1f8c" integrity sha512-GpgvHHocGRyQm74b6FWEZZVRroHKE1I0/BTjAmySaohK+cUn+hZpbqXkc3KWgW3gQYkqcQej35FohcT0FRlkRQ== @@ -12141,67 +12187,69 @@ react-dev-utils@^9.1.0: strip-ansi "5.2.0" text-table "0.2.0" -react-devtools-core@^3.6.3: - version "3.6.3" - resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-3.6.3.tgz#977d95b684c6ad28205f0c62e1e12c5f16675814" - integrity sha512-+P+eFy/yo8Z/UH9J0DqHZuUM5+RI2wl249TNvMx3J2jpUomLQa4Zxl56GEotGfw3PIP1eI+hVf1s53FlUONStQ== +react-devtools-core@^4.0.6: + version "4.6.0" + resolved "https://registry.yarnpkg.com/react-devtools-core/-/react-devtools-core-4.6.0.tgz#2443b3c6fac78b801702af188abc6d83d56224e6" + integrity sha512-sjR3KC5VvGV7X6vzR3OTutPT5VeBcSKwoIXUwihpl1Nb4dkmweEbzCTPx2PYMVAqc+NZ5tPGhqBzXV+iGg5CNA== dependencies: shell-quote "^1.6.1" - ws "^3.3.1" + ws "^7" react-dom@*, react-dom@^16.8.4: - version "16.9.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.9.0.tgz#5e65527a5e26f22ae3701131bcccaee9fb0d3962" - integrity sha512-YFT2rxO9hM70ewk9jq0y6sQk8cL02xm4+IzYBz75CQGlClQQ1Bxq0nhHF6OtSbit+AIahujJgb/CPRibFkMNJQ== + version "16.11.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.11.0.tgz#7e7c4a5a85a569d565c2462f5d345da2dd849af5" + integrity sha512-nrRyIUE1e7j8PaXSPtyRKtz+2y9ubW/ghNgqKFHHAHaeP0fpF5uXR+sq8IMRHC+ZUxw7W9NyCDTBtwWxvkb0iA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" prop-types "^15.6.2" - scheduler "^0.15.0" + scheduler "^0.17.0" react-error-overlay@^6.0.3: version "6.0.7" resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.7.tgz#1dcfb459ab671d53f660a991513cb2f0a0553108" integrity sha512-TAv1KJFh3RhqxNvhzxj6LeT5NWklP6rDr2a0jaTfsZ5wSZWHOGeqQyejUp3xxLfPt2UpyJEcVQB/zyPcmonNFA== -react-is@^16.12.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.9.0: +react-is@^16.12.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0: 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-native@0.61.5: - version "0.61.5" - resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.61.5.tgz#6e21acb56cbd75a3baeb1f70201a66f42600bba8" - integrity sha512-MXqE3NoGO0T3dUKIKkIppijBhRRMpfN6ANbhMXHDuyfA+fSilRWgCwYgR/YNCC7ntECoJYikKaNTUBB0DeQy6Q== +react-native@0.62.0: + version "0.62.0" + resolved "https://registry.yarnpkg.com/react-native/-/react-native-0.62.0.tgz#166dcab76f0b5ae36a4d7046de2cbfecfdc610f1" + integrity sha512-P21YHLaRkXTiS4xuC0BAdpwIJc8r0acYWUAOCBApqG3H4eiBe/d3b0oADz8EwTu6jBtoebydabJlScu0b/59bg== dependencies: "@babel/runtime" "^7.0.0" - "@react-native-community/cli" "^3.0.0" - "@react-native-community/cli-platform-android" "^3.0.0" - "@react-native-community/cli-platform-ios" "^3.0.0" + "@react-native-community/cli" "^4.2.0" + "@react-native-community/cli-platform-android" "^4.2.0" + "@react-native-community/cli-platform-ios" "^4.2.0" abort-controller "^3.0.0" - art "^0.10.0" + anser "^1.4.9" base64-js "^1.1.2" connect "^3.6.5" create-react-class "^15.6.3" escape-string-regexp "^1.0.5" + eslint-plugin-relay "1.4.1" event-target-shim "^5.0.1" fbjs "^1.0.0" fbjs-scripts "^1.1.0" - hermes-engine "^0.2.1" + hermes-engine "~0.4.0" invariant "^2.2.4" jsc-android "^245459.0.0" - metro-babel-register "^0.56.0" - metro-react-native-babel-transformer "^0.56.0" - metro-source-map "^0.56.0" - nullthrows "^1.1.0" + metro-babel-register "0.58.0" + metro-react-native-babel-transformer "0.58.0" + metro-source-map "0.58.0" + nullthrows "^1.1.1" pretty-format "^24.7.0" promise "^7.1.1" prop-types "^15.7.2" - react-devtools-core "^3.6.3" + react-devtools-core "^4.0.6" react-refresh "^0.4.0" regenerator-runtime "^0.13.2" - scheduler "0.15.0" + scheduler "0.17.0" stacktrace-parser "^0.1.3" + use-subscription "^1.0.0" whatwg-fetch "^3.0.0" react-refresh@^0.4.0: @@ -12209,20 +12257,20 @@ react-refresh@^0.4.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.4.2.tgz#54a277a6caaac2803d88f1d6f13c1dcfbd81e334" integrity sha512-kv5QlFFSZWo7OlJFNYbxRtY66JImuP2LcrFgyJfQaf85gSP+byzG21UbDQEYjU7f//ny8rwiEkO6py2Y+fEgAQ== -react-test-renderer@*, react-test-renderer@16.9.0, react-test-renderer@^16.0.0-0: - version "16.9.0" - resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.9.0.tgz#7ed657a374af47af88f66f33a3ef99c9610c8ae9" - integrity sha512-R62stB73qZyhrJo7wmCW9jgl/07ai+YzvouvCXIJLBkRlRqLx4j9RqcLEAfNfU3OxTGucqR2Whmn3/Aad6L3hQ== +react-test-renderer@*, react-test-renderer@16.11.0, react-test-renderer@^16.0.0-0: + version "16.11.0" + resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.11.0.tgz#72574566496462c808ac449b0287a4c0a1a7d8f8" + integrity sha512-nh9gDl8R4ut+ZNNb2EeKO5VMvTKxwzurbSMuGBoKtjpjbg8JK/u3eVPVNi1h1Ue+eYK9oSzJjb+K3lzLxyA4ag== dependencies: object-assign "^4.1.1" prop-types "^15.6.2" - react-is "^16.9.0" - scheduler "^0.15.0" + react-is "^16.8.6" + scheduler "^0.17.0" -react@*, react@16.9.0, react@^16.8.4: - version "16.9.0" - resolved "https://registry.yarnpkg.com/react/-/react-16.9.0.tgz#40ba2f9af13bc1a38d75dbf2f4359a5185c4f7aa" - integrity sha512-+7LQnFBwkiw+BobzOF6N//BdoNw0ouwmSJTEm9cglOOmsg/TMiFHZLe2sEoN5M7LgJTj9oHH0gxklfnQe66S1w== +react@*, react@16.11.0, react@^16.8.4: + version "16.11.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.11.0.tgz#d294545fe62299ccee83363599bf904e4a07fdbb" + integrity sha512-M5Y8yITaLmU0ynd0r1Yvfq98Rmll6q8AxaEe88c8e7LxO8fZ2cNgmFt0aGAS9wzf1Ao32NKXtCl+/tVVtkxq6g== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -12280,6 +12328,15 @@ read-pkg-up@^3.0.0: find-up "^2.0.0" read-pkg "^3.0.0" +read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== + dependencies: + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" + read-pkg@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" @@ -12307,6 +12364,16 @@ read-pkg@^3.0.0: normalize-package-data "^2.3.2" path-type "^3.0.0" +read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + read@1, read@~1.0.1: version "1.0.7" resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4" @@ -12677,10 +12744,10 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.0, resolve@^1.15.1, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1: - version "1.15.1" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8" - integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w== +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.13.1, resolve@^1.15.0, resolve@^1.15.1, resolve@^1.17.0, resolve@^1.3.2, resolve@^1.5.0, resolve@^1.8.1: + version "1.17.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" + integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== dependencies: path-parse "^1.0.6" @@ -12717,6 +12784,11 @@ retry@^0.10.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.10.1.tgz#e76388d217992c252750241d3d3956fed98d8ff4" integrity sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q= +reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + rfdc@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.1.4.tgz#ba72cc1367a0ccd9cf81a870b3b58bd3ad07f8c2" @@ -12786,6 +12858,11 @@ run-async@^2.2.0, run-async@^2.4.0: dependencies: is-promise "^2.1.0" +run-parallel@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.1.9.tgz#c9dd3a7cf9f4b2c4b6244e173a6ed866e61dd679" + integrity sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q== + run-queue@^1.0.0, run-queue@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" @@ -12885,10 +12962,10 @@ saxes@^3.1.9: dependencies: xmlchars "^2.1.1" -scheduler@0.15.0, scheduler@^0.15.0: - version "0.15.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.15.0.tgz#6bfcf80ff850b280fed4aeecc6513bc0b4f17f8e" - integrity sha512-xAefmSfN6jqAa7Kuq7LIJY0bwAPG3xlCj0HMEBQk1lxYiDKZscY2xJ5U/61ZTrYbmNQbXa+gc7czPkVo11tnCg== +scheduler@0.17.0, scheduler@^0.17.0: + version "0.17.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.17.0.tgz#7c9c673e4ec781fac853927916d1c426b6f3ddfe" + integrity sha512-7rro8Io3tnCPuY4la/NuI5F2yfESpnfZyT6TtkXnSWVkcu0BCDJ+8gk5ozUaFaxpIyNuWAPXrH0yFcSi28fnDA== dependencies: loose-envify "^1.1.0" object-assign "^4.1.1" @@ -14301,6 +14378,11 @@ type-fest@^0.3.0, type-fest@^0.3.1: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1" integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ== +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + type-fest@^0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.7.1.tgz#8dda65feaf03ed78f0a3f9678f1869147f7c5c48" @@ -14594,6 +14676,13 @@ urlgrey@0.4.4: resolved "https://registry.yarnpkg.com/urlgrey/-/urlgrey-0.4.4.tgz#892fe95960805e85519f1cd4389f2cb4cbb7652f" integrity sha1-iS/pWWCAXoVRnxzUOJ8stMu3ZS8= +use-subscription@^1.0.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/use-subscription/-/use-subscription-1.4.1.tgz#edcbcc220f1adb2dd4fa0b2f61b6cc308e620069" + integrity sha512-7+IIwDG/4JICrWHL/Q/ZPK5yozEnvRm6vHImu0LKwQlmWGKeiF7mbAenLlK/cTNXrTtXHU/SFASQHzB6+oSJMQ== + dependencies: + object-assign "^4.1.1" + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" @@ -14902,7 +14991,7 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= -which@1.3.1, which@^1.2.1, which@^1.2.9, which@^1.3.0, which@^1.3.1: +which@1.3.1, which@^1.2.1, which@^1.2.9, which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -15070,7 +15159,12 @@ ws@^1.1.0, ws@^1.1.5: options ">=0.0.5" ultron "1.0.x" -ws@^3.3.1, ws@~3.3.1: +ws@^7, ws@^7.0.0: + version "7.2.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" + integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ== + +ws@~3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" integrity sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA== @@ -15079,11 +15173,6 @@ ws@^3.3.1, ws@~3.3.1: safe-buffer "~5.1.0" ultron "~1.1.0" -ws@^7.0.0: - version "7.2.3" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.2.3.tgz#a5411e1fb04d5ed0efee76d26d5c46d830c39b46" - integrity sha512-HTDl9G9hbkNDk98naoR/cHDws7+EyYMOdL1BmjsZXRUjf7d+MficC4B7HLUPlSiho0vg+CWKrGIt/VJBd1xunQ== - x-is-string@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" @@ -15163,11 +15252,6 @@ xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== -y18n@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" - integrity sha1-bRX7qITAhnnA136I53WegR4H+kE= - "y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" @@ -15230,13 +15314,6 @@ yargs-parser@^18.1.1: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-7.0.0.tgz#8d0ac42f16ea55debd332caf4c4038b3e3f5dfd9" - integrity sha1-jQrELxbqVd69MyyvTEA4s+P139k= - dependencies: - camelcase "^4.1.0" - yargs-unparser@1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-1.6.0.tgz#ef25c2c769ff6bd09e4b0f9d7c605fb27846ea9f" @@ -15280,7 +15357,7 @@ yargs@^12.0.5: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -yargs@^14.2.2: +yargs@^14.2.0, yargs@^14.2.2: version "14.2.3" resolved "https://registry.yarnpkg.com/yargs/-/yargs-14.2.3.tgz#1a1c3edced1afb2a2fea33604bc6d1d8d688a414" integrity sha512-ZbotRWhF+lkjijC/VhmOT9wSgyBQ7+zr13+YLkhfsSiTriYsMzkTUFP18pFhWwBeMa5gUc1MzbhrO6/VB7c9Xg== @@ -15321,25 +15398,6 @@ yargs@^2.3.0: dependencies: wordwrap "0.0.2" -yargs@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-9.0.1.tgz#52acc23feecac34042078ee78c0c007f5085db4c" - integrity sha1-UqzCP+7Kw0BCB47njAwAf1CF20w= - dependencies: - camelcase "^4.1.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^2.0.0" - read-pkg-up "^2.0.0" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^2.0.0" - which-module "^2.0.0" - y18n "^3.2.1" - yargs-parser "^7.0.0" - yauzl@^2.4.2: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"